From: Alex Henrie alexhenrie24@gmail.com
--- dlls/advapi32/tests/registry.c | 136 ++++++++++++++++++++++++++++++++- 1 file changed, 135 insertions(+), 1 deletion(-)
diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c index 2afebb3365b..17085cb6b1c 100644 --- a/dlls/advapi32/tests/registry.c +++ b/dlls/advapi32/tests/registry.c @@ -911,7 +911,11 @@ static void test_get_value(void) /* Query REG_SZ using RRF_RT_REG_SZ on a zero-byte value (ok) */ strcpy(buf, sTestpath1); type = 0xdeadbeef; - size = sizeof(buf); + size = 0; + ret = pRegGetValueA(hkey_main, NULL, "TP1_ZB_SZ", RRF_RT_REG_SZ, &type, NULL, &size); + ok(ret == ERROR_SUCCESS, "ret=%ld\n", ret); + todo_wine ok(size == 1, "size=%ld\n", size); + ok(type == REG_SZ, "type=%ld\n", type); ret = pRegGetValueA(hkey_main, NULL, "TP1_ZB_SZ", RRF_RT_REG_SZ, &type, buf, &size); ok(ret == ERROR_SUCCESS, "ret=%ld\n", ret); todo_wine ok(size == 1, "size=%ld\n", size); @@ -2210,6 +2214,135 @@ static void test_string_termination(void) debugstr_an((char*)buffer, outsize), outsize, string); ok(buffer[insize] == 0, "buffer overflow at %lu %02x\n", insize, buffer[insize]);
+ /* RegGetValueA always adds the trailing '\0' */ + if (pRegGetValueA) + { + outsize = insize; + ret = pRegGetValueA(subkey, NULL, "stringtest", RRF_RT_REG_SZ, NULL, buffer, &outsize); + todo_wine ok(ret == ERROR_MORE_DATA, "RegGetValueA returned: %ld\n", ret); + todo_wine ok(outsize == insize + 1, "wrong size: %lu != %lu\n", outsize, insize + 1); + memset(buffer, 0xbd, sizeof(buffer)); + ret = pRegGetValueA(subkey, NULL, "stringtest", RRF_RT_REG_SZ, NULL, buffer, &outsize); + ok(ret == ERROR_SUCCESS, "RegGetValueA returned: %ld\n", ret); + todo_wine ok(outsize == insize + 1, "wrong size: %lu != %lu\n", outsize, insize + 1); + ok(memcmp(buffer, string, insize) == 0, "bad string: %s/%lu != %s\n", + debugstr_an((char*)buffer, insize), insize, string); + todo_wine ok(buffer[insize] == 0, "buffer overflow at %lu %02x\n", insize, buffer[insize]); + } + + RegDeleteKeyA(subkey, ""); + RegCloseKey(subkey); +} + +static void test_multistring_termination(void) +{ + HKEY subkey; + LSTATUS ret; + static const char multistring[] = "Aa\0Bb\0Cc\0"; + char name[sizeof("multistringtest")]; + BYTE buffer[sizeof(multistring)]; + DWORD insize, outsize, nsize; + + ret = RegCreateKeyA(hkey_main, "multistring_termination", &subkey); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); + + /* Off-by-one RegSetValueExA -> only one trailing '\0' */ + insize = sizeof(multistring) - 1; + ret = RegSetValueExA(subkey, "multistringtest", 0, REG_SZ, (BYTE*)multistring, insize); + ok(ret == ERROR_SUCCESS, "RegSetValueExA failed: %ld\n", ret); + outsize = 0; + ret = RegQueryValueExA(subkey, "multistringtest", NULL, NULL, NULL, &outsize); + ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed: %ld\n", ret); + ok(outsize == insize, "wrong size %lu != %lu\n", outsize, insize); + + /* Off-by-two RegSetValueExA -> adds a trailing '\0'! */ + insize = sizeof(multistring) - 2; + ret = RegSetValueExA(subkey, "multistringtest", 0, REG_SZ, (BYTE*)multistring, insize); + ok(ret == ERROR_SUCCESS, "RegSetValueExA failed: %ld\n", ret); + outsize = insize; + ret = RegQueryValueExA(subkey, "multistringtest", NULL, NULL, buffer, &outsize); + ok(ret == ERROR_MORE_DATA, "RegQueryValueExA returned: %ld\n", ret); + + /* Off-by-three RegSetValueExA -> no trailing '\0' */ + insize = sizeof(multistring) - 3; + ret = RegSetValueExA(subkey, "multistringtest", 0, REG_SZ, (BYTE*)multistring, insize); + ok(ret == ERROR_SUCCESS, "RegSetValueExA failed: %ld\n", ret); + outsize = 0; + ret = RegQueryValueExA(subkey, "multistringtest", NULL, NULL, NULL, &outsize); + ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed: %ld\n", ret); + ok(outsize == insize, "wrong size %lu != %lu\n", outsize, insize); + + /* RegQueryValueExA may return a multistring with no trailing '\0' */ + outsize = insize; + memset(buffer, 0xbd, sizeof(buffer)); + ret = RegQueryValueExA(subkey, "multistringtest", NULL, NULL, buffer, &outsize); + ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed: %ld\n", ret); + ok(outsize == insize, "wrong size: %lu != %lu\n", outsize, insize); + ok(memcmp(buffer, multistring, outsize) == 0, "bad multistring: %s/%lu != %s\n", + debugstr_an((char*)buffer, outsize), outsize, multistring); + ok(buffer[insize] == 0xbd, "buffer overflow at %lu %02x\n", insize, buffer[insize]); + + /* RegQueryValueExA adds one trailing '\0' if there is room */ + outsize = insize + 1; + memset(buffer, 0xbd, sizeof(buffer)); + ret = RegQueryValueExA(subkey, "multistringtest", NULL, NULL, buffer, &outsize); + ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed: %ld\n", ret); + ok(outsize == insize, "wrong size: %lu != %lu\n", outsize, insize); + ok(memcmp(buffer, multistring, outsize) == 0, "bad multistring: %s/%lu != %s\n", + debugstr_an((char*)buffer, outsize), outsize, multistring); + ok(buffer[insize] == 0, "buffer overflow at %lu %02x\n", insize, buffer[insize]); + + /* RegQueryValueExA doesn't add a second trailing '\0' even if there is room */ + outsize = insize + 2; + memset(buffer, 0xbd, sizeof(buffer)); + ret = RegQueryValueExA(subkey, "multistringtest", NULL, NULL, buffer, &outsize); + ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed: %ld\n", ret); + ok(outsize == insize, "wrong size: %lu != %lu\n", outsize, insize); + ok(memcmp(buffer, multistring, outsize) == 0, "bad multistring: %s/%lu != %s\n", + debugstr_an((char*)buffer, outsize), outsize, multistring); + ok(buffer[insize + 1] == 0xbd, "buffer overflow at %lu %02x\n", insize, buffer[insize + 1]); + + /* RegEnumValueA may return a multistring with no trailing '\0' */ + outsize = insize; + memset(buffer, 0xbd, sizeof(buffer)); + nsize = sizeof(name); + ret = RegEnumValueA(subkey, 0, name, &nsize, NULL, NULL, buffer, &outsize); + ok(ret == ERROR_SUCCESS, "RegEnumValueA failed: %ld\n", ret); + ok(strcmp(name, "multistringtest") == 0, "wrong name: %s\n", name); + ok(outsize == insize, "wrong size: %lu != %lu\n", outsize, insize); + ok(memcmp(buffer, multistring, outsize) == 0, "bad multistring: %s/%lu != %s\n", + debugstr_an((char*)buffer, outsize), outsize, multistring); + ok(buffer[insize] == 0xbd, "buffer overflow at %lu %02x\n", insize, buffer[insize]); + + /* RegEnumValueA adds one trailing '\0' even if there's room for two */ + outsize = insize + 2; + memset(buffer, 0xbd, sizeof(buffer)); + nsize = sizeof(name); + ret = RegEnumValueA(subkey, 0, name, &nsize, NULL, NULL, buffer, &outsize); + ok(ret == ERROR_SUCCESS, "RegEnumValueA failed: %ld\n", ret); + ok(strcmp(name, "multistringtest") == 0, "wrong name: %s\n", name); + ok(outsize == insize, "wrong size: %lu != %lu\n", outsize, insize); + ok(memcmp(buffer, multistring, outsize) == 0, "bad multistring: %s/%lu != %s\n", + debugstr_an((char*)buffer, outsize), outsize, multistring); + ok(buffer[insize] == 0, "buffer overflow at %lu %02x\n", insize, buffer[insize]); + ok(buffer[insize + 1] == 0xbd, "buffer overflow at %lu %02x\n", insize, buffer[insize]); + + /* RegGetValueA always adds one trailing '\0' even if there's room for two */ + if (pRegGetValueA) + { + outsize = insize; + ret = pRegGetValueA(subkey, NULL, "multistringtest", RRF_RT_REG_SZ, NULL, buffer, &outsize); + todo_wine ok(ret == ERROR_MORE_DATA, "RegGetValueA returned: %ld\n", ret); + todo_wine ok(outsize == insize + 1, "wrong size: %lu != %lu\n", outsize, insize + 1); + outsize = insize + 2; + memset(buffer, 0xbd, sizeof(buffer)); + ret = pRegGetValueA(subkey, NULL, "multistringtest", RRF_RT_REG_SZ, NULL, buffer, &outsize); + ok(ret == ERROR_SUCCESS, "RegGetValueA returned: %ld\n", ret); + todo_wine ok(outsize == insize + 1, "wrong size: %lu != %lu\n", outsize, insize + 1); + ok(buffer[insize] == 0, "buffer overflow at %lu %02x\n", insize, buffer[insize + 1]); + ok(buffer[insize + 1] == 0xbd, "buffer overflow at %lu %02x\n", insize, buffer[insize + 1]); + } + RegDeleteKeyA(subkey, ""); RegCloseKey(subkey); } @@ -5007,6 +5140,7 @@ START_TEST(registry) test_reg_query_value(); test_reg_query_info(); test_string_termination(); + test_multistring_termination(); test_symlinks(); test_redirection(); test_classesroot();