import gc
import os, sys, errno
+import itertools
import threading
import unittest
from platform import machine, win32_edition
DeleteKey(HKEY_CURRENT_USER, test_key_name+'\\changing_value')
DeleteKey(HKEY_CURRENT_USER, test_key_name)
+ def test_queryvalueex_race_condition(self):
+ # gh-142282: QueryValueEx could read garbage buffer under race
+ # condition when another thread changes the value size
+ done = False
+ ready = threading.Event()
+ values = [b'ham', b'spam']
+
+ class WriterThread(threading.Thread):
+ def run(self):
+ with CreateKey(HKEY_CURRENT_USER, test_key_name) as key:
+ values_iter = itertools.cycle(values)
+ while not done:
+ val = next(values_iter)
+ SetValueEx(key, 'test_value', 0, REG_BINARY, val)
+ ready.set()
+
+ thread = WriterThread()
+ thread.start()
+ try:
+ ready.wait()
+ with CreateKey(HKEY_CURRENT_USER, test_key_name) as key:
+ for _ in range(1000):
+ result, typ = QueryValueEx(key, 'test_value')
+ # The result must be one of the written values,
+ # not garbage data from uninitialized buffer
+ self.assertIn(result, values)
+ finally:
+ done = True
+ thread.join()
+ DeleteKey(HKEY_CURRENT_USER, test_key_name)
+
def test_long_key(self):
# Issue2810, in 2.6 and 3.1 when the key name was exactly 256
# characters, EnumKey raised "WindowsError: More data is
return PyErr_SetFromWindowsErrWithFunction(rc,
"RegQueryValueEx");
}
- obData = Reg2Py(retBuf, bufSize, typ);
+ obData = Reg2Py(retBuf, retSize, typ);
PyMem_Free(retBuf);
if (obData == NULL)
return NULL;