diff -r 0eeb39fc8ff5 Lib/test/test_winreg.py --- a/Lib/test/test_winreg.py Tue Dec 01 19:59:53 2015 +1100 +++ b/Lib/test/test_winreg.py Wed Dec 02 20:04:56 2015 -0600 @@ -56,7 +56,7 @@ def delete_tree(self, root, subkey): try: - hkey = OpenKey(root, subkey, KEY_ALL_ACCESS) + hkey = OpenKey(root, subkey, 0, KEY_ALL_ACCESS) except OSError: # subkey does not exist return @@ -367,6 +367,18 @@ finally: DeleteKey(HKEY_CURRENT_USER, test_key_name) + def test_read_string_containing_null(self): + # Test for issue 25778: REG_SZ should not contain null characters + try: + with CreateKey(HKEY_CURRENT_USER, test_key_name) as ck: + self.assertNotEqual(ck.handle, 0) + test_val = "A string\x00 with a null" + SetValueEx(ck, "test_name", 0, REG_SZ, test_val) + ret_val, ret_type = QueryValueEx(ck, "test_name") + self.assertEqual(ret_type, REG_SZ) + self.assertEqual(ret_val, "A string") + finally: + DeleteKey(HKEY_CURRENT_USER, test_key_name) @unittest.skipUnless(REMOTE_NAME, "Skipping remote registry tests") diff -r 0eeb39fc8ff5 PC/winreg.c --- a/PC/winreg.c Tue Dec 01 19:59:53 2015 +1100 +++ b/PC/winreg.c Wed Dec 02 20:04:56 2015 -0600 @@ -697,12 +697,8 @@ { /* the buffer may or may not have a trailing NULL */ wchar_t *data = (wchar_t *)retDataBuf; - int len = retDataSize / 2; - if (retDataSize && data[len-1] == '\0') - retDataSize -= 2; - if (retDataSize <= 0) - data = L""; - obData = PyUnicode_FromWideChar(data, retDataSize/2); + size_t len = wcsnlen(data, retDataSize / sizeof(wchar_t)); + obData = PyUnicode_FromWideChar(data, len); break; } case REG_MULTI_SZ: