From: Fabian Maurer dark.shadow4@web.de
--- dlls/kernel32/tests/environ.c | 20 +++++----- dlls/ntdll/env.c | 15 ++++++-- dlls/ntdll/tests/env.c | 70 +++++++++++++++++------------------ dlls/shcore/tests/shcore.c | 3 -- dlls/shlwapi/tests/shreg.c | 7 +--- 5 files changed, 59 insertions(+), 56 deletions(-)
diff --git a/dlls/kernel32/tests/environ.c b/dlls/kernel32/tests/environ.c index 6a7844480cc..ec5842c4a9e 100644 --- a/dlls/kernel32/tests/environ.c +++ b/dlls/kernel32/tests/environ.c @@ -404,25 +404,25 @@ static void test_ExpandEnvironmentStringsW(void) /* 6 */ { L"Long long value", L"Long long value", 17, 16 }, /* 7 */ { L"%TVAR% long long", L"abcdefghijklmnopqrstuv", 0, 15, TRUE }, /* 8 */ { L"%TVAR% long long", L"", 1, 15, TRUE }, - /* 9 */ { L"%TVAR% long long", L"", 2, 15, TRUE, TRUE }, - /* 10 */ { L"%TVAR% long long", L"", 4, 15, TRUE, TRUE }, + /* 9 */ { L"%TVAR% long long", L"", 2, 15, TRUE }, + /* 10 */ { L"%TVAR% long long", L"", 4, 15, TRUE }, /* 11 */ { L"%TVAR% long long", L"WINE", 5, 15, TRUE }, /* 12 */ { L"%TVAR% long long", L"WINE fghijklmnopqrstuv", 6, 15, TRUE, TRUE }, /* 13 */ { L"%TVAR% long long", L"WINE lghijklmnopqrstuv", 7, 15, TRUE, TRUE }, /* 14 */ { L"%TVAR% long long", L"WINE long long", 15, 15 }, /* 15 */ { L"%TVAR% long long", L"WINE long long", 16, 15 }, - /* 16 */ { L"%TVAR%%TVAR% long", L"", 4, 14, TRUE, TRUE }, + /* 16 */ { L"%TVAR%%TVAR% long", L"", 4, 14, TRUE }, /* 17 */ { L"%TVAR%%TVAR% long", L"WINE", 5, 14, TRUE }, - /* 18 */ { L"%TVAR%%TVAR% long", L"WINE", 6, 14, TRUE, TRUE }, - /* 19 */ { L"%TVAR%%TVAR% long", L"WINE", 8, 14, TRUE, TRUE }, + /* 18 */ { L"%TVAR%%TVAR% long", L"WINE", 6, 14, TRUE }, + /* 19 */ { L"%TVAR%%TVAR% long", L"WINE", 8, 14, TRUE }, /* 20 */ { L"%TVAR%%TVAR% long", L"WINEWINE", 9, 14, TRUE }, /* 21 */ { L"%TVAR%%TVAR% long", L"WINEWINE jklmnopqrstuv", 10, 14, TRUE, TRUE }, /* 22 */ { L"%TVAR%%TVAR% long", L"WINEWINE long", 14, 14 }, /* 23 */ { L"%TVAR%%TVAR% long", L"WINEWINE long", 15, 14 }, /* 24 */ { L"%TVAR% %TVAR% long", L"WINE", 5, 15, TRUE }, /* 25 */ { L"%TVAR% %TVAR% long", L"WINE ", 6, 15, TRUE }, - /* 26 */ { L"%TVAR% %TVAR% long", L"WINE ", 8, 15, TRUE, TRUE }, - /* 27 */ { L"%TVAR% %TVAR% long", L"WINE ", 9, 15, TRUE, TRUE }, + /* 26 */ { L"%TVAR% %TVAR% long", L"WINE ", 8, 15, TRUE }, + /* 27 */ { L"%TVAR% %TVAR% long", L"WINE ", 9, 15, TRUE }, /* 28 */ { L"%TVAR% %TVAR% long", L"WINE WINE", 10, 15, TRUE }, /* 29 */ { L"%TVAR% %TVAR% long", L"WINE WINE klmnopqrstuv", 11, 15, TRUE, TRUE }, /* 30 */ { L"%TVAR% %TVAR% long", L"WINE WINE llmnopqrstuv", 12, 15, TRUE, TRUE }, @@ -502,14 +502,14 @@ static void test_ExpandEnvironmentStringsA(void) /* 6 */ { "Long long value", "Long long value", 17, 16 }, /* 7 */ { "%TVAR% long long", "", 0, 16, TRUE, TRUE, TRUE }, /* 8 */ { "%TVAR% long long", "", 1, 16, TRUE, FALSE, TRUE }, - /* 9 */ { "%TVAR% long long", "", 2, 16, TRUE, TRUE, TRUE }, - /* 10 */ { "%TVAR% long long", "", 4, 16, TRUE, TRUE, TRUE }, + /* 9 */ { "%TVAR% long long", "", 2, 16, TRUE, FALSE, TRUE }, + /* 10 */ { "%TVAR% long long", "", 4, 16, TRUE, FALSE, TRUE }, /* 11 */ { "%TVAR% long long", "", 5, 16, TRUE, TRUE, TRUE }, /* 12 */ { "%TVAR% long long", "", 6, 16, TRUE, TRUE, TRUE }, /* 13 */ { "%TVAR% long long", "", 7, 16, TRUE, TRUE, TRUE }, /* 14 */ { "%TVAR% long long", "", 15, 16, FALSE, TRUE, TRUE }, /* 15 */ { "%TVAR% long long", "WINE long long", 16, 15 }, - /* 16 */ { "%TVAR%%TVAR% long", "", 4, 15, TRUE, TRUE, TRUE }, + /* 16 */ { "%TVAR%%TVAR% long", "", 4, 15, TRUE, FALSE, TRUE }, /* 17 */ { "%TVAR%%TVAR% long", "", 5, 15, TRUE, TRUE, TRUE }, /* 18 */ { "%TVAR%%TVAR% long", "", 6, 15, TRUE, TRUE, TRUE }, /* 19 */ { "%TVAR%%TVAR% long", "", 8, 15, TRUE, TRUE, TRUE }, diff --git a/dlls/ntdll/env.c b/dlls/ntdll/env.c index 720597dcaf9..58bfdbb9fe8 100644 --- a/dlls/ntdll/env.c +++ b/dlls/ntdll/env.c @@ -384,7 +384,7 @@ done: NTSTATUS WINAPI RtlExpandEnvironmentStrings( const WCHAR *renv, WCHAR *src, SIZE_T src_len, WCHAR *dst, SIZE_T count, SIZE_T *plen ) { - SIZE_T len, total_size = 1; /* 1 for terminating '\0' */ + SIZE_T len, copy, total_size = 1; /* 1 for terminating '\0' */ LPCWSTR env, var;
if (!renv) @@ -402,6 +402,7 @@ NTSTATUS WINAPI RtlExpandEnvironmentStrings( const WCHAR *renv, WCHAR *src, SIZE var = src; src += len; src_len -= len; + copy = len; } else /* we are at the start of a variable */ { @@ -413,6 +414,11 @@ NTSTATUS WINAPI RtlExpandEnvironmentStrings( const WCHAR *renv, WCHAR *src, SIZE src += len + 1; /* Skip the variable name */ src_len -= len + 1; len = wcslen(var); + copy = len; + if (count <= copy) /* Either copy the entire value, or nothing at all */ + copy = 0; + if (dst && count) /* When the variable is the last thing that fits into dst, the string is null terminated */ + dst[copy] = 0; /* Either right after, or if it doesn't fit, where it would start */ } else { @@ -420,6 +426,7 @@ NTSTATUS WINAPI RtlExpandEnvironmentStrings( const WCHAR *renv, WCHAR *src, SIZE len++; src += len; src_len -= len; + copy = len; } } else /* unfinished variable name, ignore it */ @@ -427,15 +434,17 @@ NTSTATUS WINAPI RtlExpandEnvironmentStrings( const WCHAR *renv, WCHAR *src, SIZE var = src; src += len; src_len = 0; + copy = len; } } total_size += len; if (dst) { if (count < len) len = count; - memcpy(dst, var, len * sizeof(WCHAR)); + if (count <= copy) copy = count ? count - 1 : 0; /* If the buffer is too small, we copy one character less */ + memcpy(dst, var, copy * sizeof(WCHAR)); count -= len; - dst += len; + dst += copy; } }
diff --git a/dlls/ntdll/tests/env.c b/dlls/ntdll/tests/env.c index ad653afa439..1760501a434 100644 --- a/dlls/ntdll/tests/env.c +++ b/dlls/ntdll/tests/env.c @@ -260,52 +260,52 @@ static void test_RtlExpandEnvironmentStrings(void) } tests[] = { /* 0 */ { L"Long long value", L"abcdefghijklmnopqrstuv", 0, 16 }, - /* 1 */ { L"Long long value", L"abcdefghijklmnopqrstuv", 1, 16, TRUE }, - /* 2 */ { L"Long long value", L"Lbcdefghijklmnopqrstuv", 2, 16, TRUE }, - /* 3 */ { L"Long long value", L"Locdefghijklmnopqrstuv", 3, 16, TRUE }, - /* 4 */ { L"Long long value", L"Long long valuopqrstuv", 15, 16, TRUE }, + /* 1 */ { L"Long long value", L"abcdefghijklmnopqrstuv", 1, 16 }, + /* 2 */ { L"Long long value", L"Lbcdefghijklmnopqrstuv", 2, 16 }, + /* 3 */ { L"Long long value", L"Locdefghijklmnopqrstuv", 3, 16 }, + /* 4 */ { L"Long long value", L"Long long valuopqrstuv", 15, 16 }, /* 5 */ { L"Long long value", L"Long long value", 16, 16 }, /* 6 */ { L"Long long value", L"Long long value", 17, 16 }, /* 7 */ { L"%TVAR% long long", L"abcdefghijklmnopqrstuv", 0, 15 }, - /* 8 */ { L"%TVAR% long long", L"", 1, 15, TRUE }, - /* 9 */ { L"%TVAR% long long", L"", 2, 15, TRUE }, - /* 10 */ { L"%TVAR% long long", L"", 4, 15, TRUE }, - /* 11 */ { L"%TVAR% long long", L"WINE", 5, 15, TRUE }, - /* 12 */ { L"%TVAR% long long", L"WINE fghijklmnopqrstuv", 6, 15, TRUE }, - /* 13 */ { L"%TVAR% long long", L"WINE lghijklmnopqrstuv", 7, 15, TRUE }, + /* 8 */ { L"%TVAR% long long", L"", 1, 15 }, + /* 9 */ { L"%TVAR% long long", L"", 2, 15 }, + /* 10 */ { L"%TVAR% long long", L"", 4, 15 }, + /* 11 */ { L"%TVAR% long long", L"WINE", 5, 15 }, + /* 12 */ { L"%TVAR% long long", L"WINE fghijklmnopqrstuv", 6, 15 }, + /* 13 */ { L"%TVAR% long long", L"WINE lghijklmnopqrstuv", 7, 15 }, /* 14 */ { L"%TVAR% long long", L"WINE long long", 15, 15 }, /* 15 */ { L"%TVAR% long long", L"WINE long long", 16, 15 }, - /* 16 */ { L"%TVAR%%TVAR% long", L"", 4, 14, TRUE }, - /* 17 */ { L"%TVAR%%TVAR% long", L"WINE", 5, 14, TRUE }, - /* 18 */ { L"%TVAR%%TVAR% long", L"WINE", 6, 14, TRUE }, - /* 19 */ { L"%TVAR%%TVAR% long", L"WINE", 8, 14, TRUE }, - /* 20 */ { L"%TVAR%%TVAR% long", L"WINEWINE", 9, 14, TRUE }, - /* 21 */ { L"%TVAR%%TVAR% long", L"WINEWINE jklmnopqrstuv", 10, 14, TRUE }, + /* 16 */ { L"%TVAR%%TVAR% long", L"", 4, 14 }, + /* 17 */ { L"%TVAR%%TVAR% long", L"WINE", 5, 14 }, + /* 18 */ { L"%TVAR%%TVAR% long", L"WINE", 6, 14 }, + /* 19 */ { L"%TVAR%%TVAR% long", L"WINE", 8, 14 }, + /* 20 */ { L"%TVAR%%TVAR% long", L"WINEWINE", 9, 14 }, + /* 21 */ { L"%TVAR%%TVAR% long", L"WINEWINE jklmnopqrstuv", 10, 14 }, /* 22 */ { L"%TVAR%%TVAR% long", L"WINEWINE long", 14, 14 }, /* 23 */ { L"%TVAR%%TVAR% long", L"WINEWINE long", 15, 14 }, - /* 24 */ { L"%TVAR% %TVAR% long", L"WINE", 5, 15, TRUE }, - /* 25 */ { L"%TVAR% %TVAR% long", L"WINE ", 6, 15, TRUE }, - /* 26 */ { L"%TVAR% %TVAR% long", L"WINE ", 8, 15, TRUE }, - /* 27 */ { L"%TVAR% %TVAR% long", L"WINE ", 9, 15, TRUE }, - /* 28 */ { L"%TVAR% %TVAR% long", L"WINE WINE", 10, 15, TRUE }, - /* 29 */ { L"%TVAR% %TVAR% long", L"WINE WINE klmnopqrstuv", 11, 15, TRUE }, - /* 30 */ { L"%TVAR% %TVAR% long", L"WINE WINE llmnopqrstuv", 12, 15, TRUE }, - /* 31 */ { L"%TVAR% %TVAR% long", L"WINE WINE lonnopqrstuv", 14, 15, TRUE }, + /* 24 */ { L"%TVAR% %TVAR% long", L"WINE", 5, 15 }, + /* 25 */ { L"%TVAR% %TVAR% long", L"WINE ", 6, 15 }, + /* 26 */ { L"%TVAR% %TVAR% long", L"WINE ", 8, 15 }, + /* 27 */ { L"%TVAR% %TVAR% long", L"WINE ", 9, 15 }, + /* 28 */ { L"%TVAR% %TVAR% long", L"WINE WINE", 10, 15 }, + /* 29 */ { L"%TVAR% %TVAR% long", L"WINE WINE klmnopqrstuv", 11, 15 }, + /* 30 */ { L"%TVAR% %TVAR% long", L"WINE WINE llmnopqrstuv", 12, 15 }, + /* 31 */ { L"%TVAR% %TVAR% long", L"WINE WINE lonnopqrstuv", 14, 15 }, /* 32 */ { L"%TVAR% %TVAR% long", L"WINE WINE long", 15, 15 }, /* 33 */ { L"%TVAR% %TVAR% long", L"WINE WINE long", 16, 15 }, - /* 34 */ { L"%TVAR2% long long", L"abcdefghijklmnopqrstuv", 1, 18, TRUE }, - /* 35 */ { L"%TVAR2% long long", L"%bcdefghijklmnopqrstuv", 2, 18, TRUE }, - /* 36 */ { L"%TVAR2% long long", L"%TVdefghijklmnopqrstuv", 4, 18, TRUE }, - /* 37 */ { L"%TVAR2% long long", L"%TVAR2ghijklmnopqrstuv", 7, 18, TRUE }, - /* 38 */ { L"%TVAR2% long long", L"%TVAR2%hijklmnopqrstuv", 8, 18, TRUE }, - /* 39 */ { L"%TVAR2% long long", L"%TVAR2% ijklmnopqrstuv", 9, 18, TRUE }, - /* 40 */ { L"%TVAR2% long long", L"%TVAR2% ljklmnopqrstuv", 10, 18, TRUE }, + /* 34 */ { L"%TVAR2% long long", L"abcdefghijklmnopqrstuv", 1, 18 }, + /* 35 */ { L"%TVAR2% long long", L"%bcdefghijklmnopqrstuv", 2, 18 }, + /* 36 */ { L"%TVAR2% long long", L"%TVdefghijklmnopqrstuv", 4, 18 }, + /* 37 */ { L"%TVAR2% long long", L"%TVAR2ghijklmnopqrstuv", 7, 18 }, + /* 38 */ { L"%TVAR2% long long", L"%TVAR2%hijklmnopqrstuv", 8, 18 }, + /* 39 */ { L"%TVAR2% long long", L"%TVAR2% ijklmnopqrstuv", 9, 18 }, + /* 40 */ { L"%TVAR2% long long", L"%TVAR2% ljklmnopqrstuv", 10, 18 }, /* 41 */ { L"%TVAR2% long long", L"%TVAR2% long long", 18, 18 }, /* 42 */ { L"%TVAR2% long long", L"%TVAR2% long long", 19, 18 }, - /* 43 */ { L"%TVAR long long", L"abcdefghijklmnopqrstuv", 1, 16, TRUE }, - /* 44 */ { L"%TVAR long long", L"%bcdefghijklmnopqrstuv", 2, 16, TRUE }, - /* 45 */ { L"%TVAR long long", L"%Tcdefghijklmnopqrstuv", 3, 16, TRUE }, - /* 46 */ { L"%TVAR long long", L"%TVAR long lonopqrstuv", 15, 16, TRUE }, + /* 43 */ { L"%TVAR long long", L"abcdefghijklmnopqrstuv", 1, 16 }, + /* 44 */ { L"%TVAR long long", L"%bcdefghijklmnopqrstuv", 2, 16 }, + /* 45 */ { L"%TVAR long long", L"%Tcdefghijklmnopqrstuv", 3, 16 }, + /* 46 */ { L"%TVAR long long", L"%TVAR long lonopqrstuv", 15, 16 }, /* 47 */ { L"%TVAR long long", L"%TVAR long long", 16, 16 }, /* 48 */ { L"%TVAR long long", L"%TVAR long long", 17, 16 }, }; diff --git a/dlls/shcore/tests/shcore.c b/dlls/shcore/tests/shcore.c index af6b3b392f3..731fa340e8b 100644 --- a/dlls/shcore/tests/shcore.c +++ b/dlls/shcore/tests/shcore.c @@ -567,10 +567,7 @@ static void test_SHQueryValueEx(void) ret = pSHQueryValueExA(hKey, "Test3", NULL, &type, buf, &size); ok(ret == ERROR_MORE_DATA, "Unexpected retval %ld.\n", ret);
- todo_wine - { ok(!strcmp("", buf), "Unexpanded string %s.\n", buf); - }
ok(size >= buffer_len2, "Buffer size %lu should be >= %lu.\n", size, buffer_len2); ok(type == REG_SZ, "Unexpected type %ld.\n", type); diff --git a/dlls/shlwapi/tests/shreg.c b/dlls/shlwapi/tests/shreg.c index bc411779c8f..75d4dfae7eb 100644 --- a/dlls/shlwapi/tests/shreg.c +++ b/dlls/shlwapi/tests/shreg.c @@ -290,11 +290,8 @@ static void test_SHQueryValueEx(void) broken(ERROR_SUCCESS == dwRet), /* < IE5.5*/ "Expected ERROR_MORE_DATA, got (%lu)\n", dwRet);
- todo_wine - { - ok( (0 == strcmp("", buf)) || (0 == strcmp(sTestpath2, buf)), - "Expected empty or unexpanded string (win98), got (%s)\n", buf); - } + ok( (0 == strcmp("", buf)) || (0 == strcmp(sTestpath2, buf)), + "Expected empty or unexpanded string (win98), got (%s)\n", buf);
ok( dwSize >= nUsedBuffer2 || broken(dwSize == (strlen("") + 1)), /* < IE 5.5 */