Fix a bug about REG_SZ key non-null terminated in values enumeration

This commit is contained in:
hakril
2019-08-07 09:47:31 +02:00
parent 032de6a848
commit 670bb713a2
2 changed files with 26 additions and 6 deletions
+22 -1
View File
@@ -51,11 +51,27 @@ UNICODE_RU_STRING = u"\u0441\u0443\u043a\u0430\u0020\u0431\u043b\u044f\u0442\u04
# But was the cause a special bug / reimplem due to _winreg using ANSI functions
# So create a special test with a very identifiable name / bug cause
@pytest.mark.parametrize("unistr", [UNICODE_PATH_NAME, UNICODE_RU_STRING, u""])
@pytest.mark.parametrize("unistr", ['\u52a9' * 126, UNICODE_PATH_NAME, UNICODE_RU_STRING, u""])
def test_registry_unicode_string_value(unistr):
basekeytest["tst3"] = unistr
assert basekeytest["tst3"].value == unistr
@pytest.mark.parametrize("unistr", [
# Looks like this value with this size MAY lead to non-existing NULL BYTE ?
# This bug is tested in test_registry_Reg2Py_SZ
u'c:\\users\\hakril\\appdata\\local\\temp\\test_unicode_\u4e2d\u56fd\u94f6\u884c\u7f51\u94f6\u52a9\u624bdbqsm3',
u'\u52a9' * 126,
UNICODE_PATH_NAME,
UNICODE_PATH_NAME * 10,
UNICODE_RU_STRING * 10,
UNICODE_RU_STRING
])
def test_registry_unicode_string_values_enumeration(unistr):
basekeytest["tst5"] = unistr
values_by_name = {x.name: x for x in basekeytest.values}
assert values_by_name["tst5"].value == unistr
def test_registry_unicode_multi_string():
TST_MULTI = [UNICODE_PATH_NAME, "Hello World", UNICODE_RU_STRING]
basekeytest["tst4"] = (TST_MULTI, gdef.REG_MULTI_SZ)
@@ -164,4 +180,9 @@ def test_registry_unicode_subkeys_enumerate():
assert name2 in subkey_names
# Test Py<->REG conversion bug
# [99, 0, 58, 0, 92, 0, 117, 0, 115, 0, 101, 0, 114, 0, 115, 0, 92, 0, 104, 0, 97, 0, 107, 0, 114, 0, 105, 0, 108, 0, 92, 0, 97, 0, 112, 0, 112, 0, 100, 0, 97, 0, 116, 0, 97, 0, 92, 0, 108, 0, 111, 0, 99, 0, 97, 0, 108, 0, 92, 0, 116, 0, 101, 0, 109, 0, 112, 0, 92, 0, 116, 0, 101, 0, 115, 0, 116, 0, 95, 0, 117, 0, 110, 0, 105, 0, 99, 0, 111, 0, 100, 0, 101, 0, 95, 0, 45, 78, 253, 86, 246, 148, 76, 136, 81, 127, 246, 148, 169, 82, 75, 98, 100, 0, 98, 0, 113, 0, 115, 0, 109, 0, 51, 0, 0]
# 124
# def test_registry_Reg2Py_SZ(
+4 -5
View File
@@ -18,7 +18,7 @@ class WinRegistryKey(gdef.HKEY):
_close_function = staticmethod(winproxy.RegCloseKey)
def __del__(self):
if sys.path is None: # Late shutdown (not sur winproxy is still up
if sys is None or sys.path is None: # Late shutdown (not sur winproxy is still up)
return
if self: # Not NULL handle ?
dbgprint(u"Closing registry key handle {0:#x}".format(self.value), 'REGISTRY')
@@ -62,7 +62,7 @@ def Reg2Py_SZ(buffer, size):
# Buffer is UTF16. buffer is extended-buffer
if size == 0:
return u""
if buffer[size] == 0 and buffer[size - 1] == 0:
if buffer[size - 1] == 0 and buffer[size - 2] == 0:
# NULL TERMINATED: EASY
return buffer.as_wstring()
# Not null terminated: keep last byte
@@ -198,7 +198,7 @@ class PyHKey(object):
max_name_size, max_data_size = self.get_key_size_info()
# Null terminators
max_name_size += 1
max_data_size += 1
max_data_size += 2
with ExpectWindowsError(259):
for i in itertools.count():
value_type = gdef.DWORD()
@@ -218,14 +218,13 @@ class PyHKey(object):
# Update the sizes / buffers & try again :)
max_name_size, max_data_size = self.get_key_size_info()
max_name_size += 1
max_data_size += 1
max_data_size += 2
namesize = gdef.DWORD(max_name_size)
keyname = ctypes.create_unicode_buffer(namesize.value)
datasize = gdef.DWORD(max_data_size)
databuffer = windows.utils.BUFFER(gdef.BYTE, nbelt=datasize.value)()
vobj = ENCODE_DECODE_METHODS[value_type.value][DECODE_METHOD](databuffer, datasize.value)
res.append(KeyValue(keyname.value, vobj, value_type.value))
# res.append(vobj)
return res