From c613f47ad958726c10081983300563e62e5896c4 Mon Sep 17 00:00:00 2001 From: nulano Date: Sat, 27 Mar 2021 08:44:22 +0100 Subject: [PATCH 1/5] has_madvise is only defined on _POSIX --HG-- branch : winreg-audithooks --- rpython/rlib/rmmap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py index f2e99ac292..0008cc6e9a 100644 --- a/rpython/rlib/rmmap.py +++ b/rpython/rlib/rmmap.py @@ -654,7 +654,7 @@ class MMap(object): index += self.size self.data[index] = value[0] - if has_madvise: + if _POSIX and has_madvise: def madvise(self, flags, start, length): res = c_madvise_safe(rffi.cast(PTR, rffi.ptradd(self.data, + start)), rffi.cast(size_t, length), -- GitLab From c15b7813ad23b7ddaf1a46a199cfb372312a1c4f Mon Sep 17 00:00:00 2001 From: nulano Date: Sat, 27 Mar 2021 08:45:17 +0100 Subject: [PATCH 2/5] add audithooks to winreg --HG-- branch : winreg-audithooks --- pypy/module/_winreg/interp_winreg.py | 124 ++++++++++---- pypy/module/_winreg/test/apptest_audit.py | 195 ++++++++++++++++++++++ 2 files changed, 286 insertions(+), 33 deletions(-) create mode 100644 pypy/module/_winreg/test/apptest_audit.py diff --git a/pypy/module/_winreg/interp_winreg.py b/pypy/module/_winreg/interp_winreg.py index 1c45d5350b..f53691910a 100644 --- a/pypy/module/_winreg/interp_winreg.py +++ b/pypy/module/_winreg/interp_winreg.py @@ -124,9 +124,10 @@ After calling this function, the handle is effectively invalidated, but the handle is not closed. You would call this function when you need the underlying win32 handle to exist beyond the lifetime of the handle object.""" - key = self.as_int() + w_key = self.descr_handle_get(space) + space.audit("winreg.PyHKEY.Detach", [w_key]) self.hkey = rwin32.NULL_HANDLE - return space.newint(key) + return w_key @unwrap_spec(key=int) @@ -187,6 +188,14 @@ def hkey_w(w_hkey, space): raise oefmt(space.w_TypeError, "The object is not a PyHKEY object") +def hkey_to_w_int(w_hkey, space): + if isinstance(w_hkey, W_HKEY): + return w_hkey.descr_handle_get(space) + else: + assert space.isinstance_w(w_hkey, space.w_int) + return w_hkey + + def CloseKey(space, w_hkey): """CloseKey(hkey) - Closes a previously opened registry key. @@ -223,8 +232,7 @@ If you don't know whether a FlushKey() call is required, it probably isn't.""" raiseWindowsError(space, ret, 'RegFlushKey') -@unwrap_spec(subkey="unicode", filename="unicode") -def LoadKey(space, w_hkey, subkey, filename): +def LoadKey(space, w_hkey, w_subkey, w_filename): """LoadKey(key, sub_key, file_name) - Creates a subkey under the specified key and stores registration information from a specified file into that subkey. @@ -244,6 +252,10 @@ in fileName is relative to the remote computer. The docs imply key must be in the HKEY_USER or HKEY_LOCAL_MACHINE tree""" # XXX should filename use space.fsencode_w? hkey = hkey_w(w_hkey, space) + subkey = space.realunicode_w(w_subkey) + filename = space.realunicode_w(w_filename) + space.audit("winreg.LoadKey", + [hkey_to_w_int(w_hkey, space), w_subkey, w_filename]) with rffi.scoped_unicode2wcharp(subkey) as wide_subkey: c_subkey = rffi.cast(rffi.CWCHARP, wide_subkey) with rffi.scoped_unicode2wcharp(filename) as wide_filename: @@ -253,8 +265,7 @@ The docs imply key must be in the HKEY_USER or HKEY_LOCAL_MACHINE tree""" raiseWindowsError(space, ret, 'RegLoadKey') -@unwrap_spec(filename="unicode") -def SaveKey(space, w_hkey, filename): +def SaveKey(space, w_hkey, w_filename): """ SaveKey(key, file_name) - Saves the specified key, and all its subkeys to the specified file. @@ -270,6 +281,8 @@ file_name is relative to the remote computer. The caller of this method must possess the SeBackupPrivilege security privilege. This function passes NULL for security_attributes to the API.""" hkey = hkey_w(w_hkey, space) + filename = space.realunicode_w(w_filename) + space.audit("winreg.SaveKey", [hkey_to_w_int(w_hkey, space), w_filename]) with rffi.scoped_unicode2wcharp(filename) as wide_filename: c_filename = rffi.cast(rffi.CWCHARP, wide_filename) ret = rwinreg.RegSaveKeyW(hkey, c_filename, None) @@ -277,8 +290,7 @@ privilege. This function passes NULL for security_attributes to the API.""" raiseWindowsError(space, ret, 'RegSaveKey') -@unwrap_spec(typ=int) -def SetValue(space, w_hkey, w_subkey, typ, w_value): +def SetValue(space, w_hkey, w_subkey, w_type, w_value): """ SetValue(key, sub_key, type, value) - Associates a value with a specified key. @@ -297,9 +309,12 @@ the configuration registry. This helps the registry perform efficiently. The key identified by the key parameter must have been opened with KEY_SET_VALUE access.""" + typ = space.int_w(w_type) if typ != rwinreg.REG_SZ: raise oefmt(space.w_ValueError, "Type must be winreg.REG_SZ") hkey = hkey_w(w_hkey, space) + space.audit("winreg.SetValue", + [hkey_to_w_int(w_hkey, space), w_subkey, w_type, w_value]) state = space.fromcache(CodecState) errh = state.encode_error_handler utf8 = space.utf8_w(w_subkey) @@ -332,6 +347,8 @@ Values in the registry have name, type, and data components. This method retrieves the data for a key's first value that has a NULL name. But the underlying API call doesn't return the type: Lame, DONT USE THIS!!!""" hkey = hkey_w(w_hkey, space) + space.audit("winreg.QueryValue", + [hkey_to_w_int(w_hkey, space), w_subkey, space.w_None]) if space.is_w(w_subkey, space.w_None): subkey = None else: @@ -528,8 +545,7 @@ def convert_from_regdata(space, buf, buflen, typ): return space.newbytes(buf[0:buflen]) -@unwrap_spec(value_name="unicode", typ=int) -def SetValueEx(space, w_hkey, value_name, w_reserved, typ, w_value): +def SetValueEx(space, w_hkey, w_value_name, w_reserved, w_type, w_value): """ SetValueEx(key, value_name, reserved, type, value) - Stores data in the value field of an open registry key. @@ -564,8 +580,12 @@ To open the key, use the CreateKeyEx() or OpenKeyEx() methods. Value lengths are limited by available memory. Long values (more than 2048 bytes) should be stored as files with the filenames stored in the configuration registry. This helps the registry perform efficiently.""" + typ = space.int_w(w_type) + value_name = space.realunicode_w(w_value_name) hkey = hkey_w(w_hkey, space) buf, buflen = convert_to_regdata(space, w_value, typ) + space.audit("winreg.SetValue", + [hkey_to_w_int(w_hkey, space), w_value_name, w_type, w_value]) try: with rffi.scoped_unicode2wcharp(value_name) as wide_vn: c_vn = rffi.cast(rffi.CWCHARP, wide_vn) @@ -585,6 +605,8 @@ a specified value name associated with an open registry key. key is an already open key, or any one of the predefined HKEY_* constants. value_name is a string indicating the value to query""" hkey = hkey_w(w_hkey, space) + space.audit("winreg.QueryValue", + [hkey_to_w_int(w_hkey, space), space.w_None, w_subkey]) if space.is_w(w_subkey, space.w_None): subkey = None else: @@ -624,8 +646,7 @@ value_name is a string indicating the value to query""" ]) -@unwrap_spec(subkey="unicode") -def CreateKey(space, w_hkey, subkey): +def CreateKey(space, w_hkey, w_subkey): """key = CreateKey(key, sub_key) - Creates or opens the specified key. key is an already open key, or one of the predefined HKEY_* constants @@ -637,18 +658,23 @@ If the key already exists, this function opens the existing key The return value is the handle of the opened key. If the function fails, an exception is raised.""" + subkey = space.realunicode_w(w_subkey) hkey = hkey_w(w_hkey, space) + space.audit("winreg.CreateKey", [hkey_to_w_int(w_hkey, space), w_subkey, + space.newint(r_uint(rwinreg.KEY_WRITE))]) with rffi.scoped_unicode2wcharp(subkey) as wide_subkey: c_subkey = rffi.cast(rffi.CWCHARP, wide_subkey) with lltype.scoped_alloc(rwinreg.PHKEY.TO, 1) as rethkey: ret = rwinreg.RegCreateKeyW(hkey, c_subkey, rethkey) if ret != 0: raiseWindowsError(space, ret, 'CreateKey') - return W_HKEY(space, rethkey[0]) + res = W_HKEY(space, rethkey[0]) + space.audit("winreg.OpenKey/result", [res.descr_handle_get(space)]) + return res -@unwrap_spec(sub_key="unicode", reserved=int, access=r_uint) -def CreateKeyEx(space, w_key, sub_key, reserved=0, access=rwinreg.KEY_WRITE): +@unwrap_spec(reserved=int) +def CreateKeyEx(space, w_key, w_sub_key, reserved=0, w_access=None): """key = CreateKey(key, sub_key) - Creates or opens the specified key. key is an already open key, or one of the predefined HKEY_* constants @@ -660,7 +686,13 @@ If the key already exists, this function opens the existing key The return value is the handle of the opened key. If the function fails, an exception is raised.""" + if w_access is None: + w_access = space.newint(r_uint(rwinreg.KEY_WRITE)) + access = space.c_uint_w(w_access) + sub_key = space.realunicode_w(w_sub_key) hkey = hkey_w(w_key, space) + space.audit("winreg.CreateKey", + [hkey_to_w_int(w_key, space), w_sub_key, w_access]) with rffi.scoped_unicode2wcharp(sub_key) as wide_sub_key: c_subkey = rffi.cast(rffi.CWCHARP, wide_sub_key) with lltype.scoped_alloc(rwinreg.PHKEY.TO, 1) as rethkey: @@ -669,11 +701,12 @@ If the function fails, an exception is raised.""" lltype.nullptr(rwin32.LPDWORD.TO)) if ret != 0: raiseWindowsError(space, ret, 'CreateKeyEx') - return W_HKEY(space, rethkey[0]) + res = W_HKEY(space, rethkey[0]) + space.audit("winreg.OpenKey/result", [res.descr_handle_get(space)]) + return res -@unwrap_spec(subkey="unicode") -def DeleteKey(space, w_hkey, subkey): +def DeleteKey(space, w_hkey, w_subkey): """ DeleteKey(key, subkey) - Deletes the specified key. @@ -685,7 +718,10 @@ This method can not delete keys with subkeys. If the method succeeds, the entire key, including all of its values, is removed. If the method fails, an EnvironmentError exception is raised.""" + subkey = space.realunicode_w(w_subkey) hkey = hkey_w(w_hkey, space) + space.audit("winreg.DeleteKey", + [hkey_to_w_int(w_hkey, space), w_subkey, space.newint(0)]) with rffi.scoped_unicode2wcharp(subkey) as wide_subkey: c_subkey = rffi.cast(rffi.CWCHARP, wide_subkey) ret = rwinreg.RegDeleteKeyW(hkey, c_subkey) @@ -693,13 +729,14 @@ is removed. If the method fails, an EnvironmentError exception is raised.""" raiseWindowsError(space, ret, 'RegDeleteKey') -@unwrap_spec(subkey="unicode") -def DeleteValue(space, w_hkey, subkey): +def DeleteValue(space, w_hkey, w_subkey): """DeleteValue(key, value) - Removes a named value from a registry key. key is an already open key, or any one of the predefined HKEY_* constants. value is a string that identifies the value to remove.""" + subkey = space.realunicode_w(w_subkey) hkey = hkey_w(w_hkey, space) + space.audit("winreg.DeleteValue", [hkey_to_w_int(w_hkey, space), w_subkey]) with rffi.scoped_unicode2wcharp(subkey) as wide_subkey: c_subkey = rffi.cast(rffi.CWCHARP, wide_subkey) ret = rwinreg.RegDeleteValueW(hkey, c_subkey) @@ -707,8 +744,8 @@ value is a string that identifies the value to remove.""" raiseWindowsError(space, ret, 'RegDeleteValue') -@unwrap_spec(reserved=int, access=r_uint) -def OpenKey(space, w_key, w_sub_key, reserved=0, access=rwinreg.KEY_READ): +@unwrap_spec(reserved=int) +def OpenKey(space, w_key, w_sub_key, reserved=0, w_access=None): """ key = OpenKey(key, sub_key, res = 0, sam = KEY_READ) - Opens the specified key. @@ -720,8 +757,13 @@ sam is an integer that specifies an access mask that describes the desired The result is a new handle to the specified key If the function fails, an EnvironmentError exception is raised.""" + if w_access is None: + w_access = space.newint(r_uint(rwinreg.KEY_READ)) + access = space.c_uint_w(w_access) hkey = hkey_w(w_key, space) utf8 = space.utf8_w(w_sub_key) + space.audit("winreg.OpenKey", + [hkey_to_w_int(w_key, space), w_sub_key, w_access]) state = space.fromcache(CodecState) errh = state.encode_error_handler subkeyW = utf8_encode_utf_16(utf8 + '\x00', 'strict', errh, allow_surrogates=True) @@ -732,11 +774,12 @@ If the function fails, an EnvironmentError exception is raised.""" rethkey) if ret != 0: raiseWindowsError(space, ret, 'RegOpenKeyEx') - return W_HKEY(space, rethkey[0]) + res = W_HKEY(space, rethkey[0]) + space.audit("winreg.OpenKey/result", [res.descr_handle_get(space)]) + return res -@unwrap_spec(index=int) -def EnumValue(space, w_hkey, index): +def EnumValue(space, w_hkey, w_index): """tuple = EnumValue(key, index) - Enumerates values of an open registry key. key is an already open key, or any one of the predefined HKEY_* constants. index is an integer that identifies the index of the value to retrieve. @@ -751,6 +794,8 @@ value_data is an object that holds the value data, and whose type depends on the underlying registry type. data_type is an integer that identifies the type of the value data.""" hkey = hkey_w(w_hkey, space) + index = space.int_w(w_index) + space.audit("winreg.EnumValue", [hkey_to_w_int(w_hkey, space), w_index]) null_dword = lltype.nullptr(rwin32.LPDWORD.TO) with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as valueSize: @@ -804,8 +849,7 @@ data_type is an integer that identifies the type of the value data.""" ]) -@unwrap_spec(index=int) -def EnumKey(space, w_hkey, index): +def EnumKey(space, w_hkey, w_index): """string = EnumKey(key, index) - Enumerates subkeys of an open registry key. key is an already open key, or any one of the predefined HKEY_* constants. @@ -815,6 +859,8 @@ The function retrieves the name of one subkey each time it is called. It is typically called repeatedly until an EnvironmentError exception is raised, indicating no more values are available.""" hkey = hkey_w(w_hkey, space) + index = space.int_w(w_index) + space.audit("winreg.EnumKey", [hkey_to_w_int(w_hkey, space), w_index]) null_dword = lltype.nullptr(rwin32.LPDWORD.TO) # The Windows docs claim that the max key name length is 255 @@ -848,6 +894,7 @@ An integer that identifies the number of values this key has. A long integer that identifies when the key was last modified (if available) as 100's of nanoseconds since Jan 1, 1600.""" hkey = hkey_w(w_hkey, space) + space.audit("winreg.QueryInfoKey", [hkey_to_w_int(w_hkey, space)]) with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as nSubKeys: with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as nValues: with lltype.scoped_alloc(rwin32.PFILETIME.TO, 1) as ft: @@ -879,6 +926,7 @@ key is the predefined handle to connect to. The return value is the handle of the opened key. If the function fails, an EnvironmentError exception is raised.""" hkey = hkey_w(w_hkey, space) + space.audit("winreg.ConnectRegistry", [w_machine, hkey_to_w_int(w_hkey, space)]) if space.is_none(w_machine): with lltype.scoped_alloc(rwinreg.PHKEY.TO, 1) as rethkey: ret = rwinreg.RegConnectRegistryW(None, hkey, rethkey) @@ -901,6 +949,7 @@ If the function fails, an EnvironmentError exception is raised.""" def ExpandEnvironmentStrings(space, w_source): "string = ExpandEnvironmentStrings(string) - Expand environment vars." + space.audit("winreg.ExpandEnvironmentStrings", [w_source]) try: source, source_ulen = space.utf8_len_w(w_source) res, res_ulen = rwinreg.ExpandEnvironmentStrings(source, source_ulen) @@ -948,11 +997,12 @@ def DisableReflectionKey(space, w_key): If the key is not on the reflection list, the function succeeds but has no effect. Disabling reflection for a key does not affect reflection of any subkeys.""" + hkey = hkey_w(w_key, space) + space.audit("winreg.DisableReflectionKey", [hkey_to_w_int(w_key, space)]) if not _RegDisableReflectionKey.check(): raise oefmt(space.w_NotImplementedError, "not implemented on this platform") else: - hkey = hkey_w(w_key, space) ret = _RegDisableReflectionKey.call(hkey) if ret != 0: raiseWindowsError(space, ret, 'RegDisableReflectionKey') @@ -963,11 +1013,12 @@ def EnableReflectionKey(space, w_key): Will generally raise NotImplemented if executed on a 32-bit Operating System. Restoring reflection for a key does not affect reflection of any subkeys.""" + hkey = hkey_w(w_key, space) + space.audit("winreg.EnableReflectionKey", [hkey_to_w_int(w_key, space)]) if not _RegEnableReflectionKey.check(): raise oefmt(space.w_NotImplementedError, "not implemented on this platform") else: - hkey = hkey_w(w_key, space) ret = _RegEnableReflectionKey.call(hkey) if ret != 0: raiseWindowsError(space, ret, 'RegEnableReflectionKey') @@ -977,11 +1028,12 @@ def QueryReflectionKey(space, w_key): """bool = QueryReflectionKey(hkey) - Determines the reflection state for the specified key. Will generally raise NotImplemented if executed on a 32-bit Operating System.""" + hkey = hkey_w(w_key, space) + space.audit("winreg.QueryReflectionKey", [hkey_to_w_int(w_key, space)]) if not _RegQueryReflectionKey.check(): raise oefmt(space.w_NotImplementedError, "not implemented on this platform") else: - hkey = hkey_w(w_key, space) with lltype.scoped_alloc(rwin32.LPBOOL.TO, 1) as isDisabled: ret = _RegQueryReflectionKey.call(hkey, isDisabled) if ret != 0: @@ -989,8 +1041,8 @@ def QueryReflectionKey(space, w_key): return space.newbool(intmask(isDisabled[0]) != 0) -@unwrap_spec(sub_key="unicode", access=r_uint, reserved=int) -def DeleteKeyEx(space, w_key, sub_key, access=rwinreg.KEY_WOW64_64KEY, reserved=0): +@unwrap_spec(reserved=int) +def DeleteKeyEx(space, w_key, w_sub_key, w_access=None, reserved=0): """DeleteKeyEx(key, sub_key, sam, res) - Deletes the specified key. key is an already open key, or any one of the predefined HKEY_* constants. @@ -1005,11 +1057,17 @@ def DeleteKeyEx(space, w_key, sub_key, access=rwinreg.KEY_WOW64_64KEY, reserved= If the method succeeds, the entire key, including all of its values, is removed. If the method fails, a WindowsError exception is raised. On unsupported Windows versions, NotImplementedError is raised.""" + if w_access is None: + w_access = space.newint(r_uint(rwinreg.KEY_WOW64_64KEY)) + access = space.c_uint_w(w_access) + sub_key = space.realunicode_w(w_sub_key) + hkey = hkey_w(w_key, space) + space.audit("winreg.DeleteKey", + [hkey_to_w_int(w_key, space), w_sub_key, w_access]) if not _RegDeleteKeyExW.check(): raise oefmt(space.w_NotImplementedError, "not implemented on this platform") else: - hkey = hkey_w(w_key, space) with rffi.scoped_unicode2wcharp(sub_key) as wide_subkey: c_subkey = rffi.cast(rffi.CWCHARP, wide_subkey) ret = _RegDeleteKeyExW.call(hkey, c_subkey, access, reserved) diff --git a/pypy/module/_winreg/test/apptest_audit.py b/pypy/module/_winreg/test/apptest_audit.py new file mode 100644 index 0000000000..2feacb72ef --- /dev/null +++ b/pypy/module/_winreg/test/apptest_audit.py @@ -0,0 +1,195 @@ +import sys +import __pypy__ + +class TestHook: + def __init__(self, raise_on_events=None, exc_type=RuntimeError): + self.raise_on_events = raise_on_events or () + self.exc_type = exc_type + self.seen = [] + self.closed = False + + def __enter__(self, *a): + sys.addaudithook(self) + return self + + def __exit__(self, *a): + self.close() + __pypy__._testing_clear_audithooks() + + def close(self): + self.closed = True + + @property + def seen_events(self): + return [i[0] for i in self.seen] + + def __call__(self, event, args): + if self.closed: + return + if not event.startswith("winreg."): + return + self.seen.append((event, args)) + if event in self.raise_on_events: + raise self.exc_type("saw event " + event) + +def test_ConnectRegistry(): + from winreg import ConnectRegistry, HKEY_LOCAL_MACHINE + machine = u"This is a long computer name that doesn't exist, hopefully" + with TestHook() as hook: + try: + ConnectRegistry(machine, HKEY_LOCAL_MACHINE) + except OSError: + pass + assert hook.seen[0] == ("winreg.ConnectRegistry", (machine, HKEY_LOCAL_MACHINE)) + +def test_CreateKey(): + from winreg import CreateKey, CreateKeyEx + from winreg import HKEY_CURRENT_USER, KEY_ALL_ACCESS, KEY_WRITE + with TestHook() as hook: + key = CreateKey(HKEY_CURRENT_USER, u"SOFTWARE") + sub_key = CreateKeyEx(key, u"Microsoft", 0, KEY_ALL_ACCESS) + assert hook.seen[0][0] == "winreg.CreateKey" + assert hook.seen[0][1] == (HKEY_CURRENT_USER, u"SOFTWARE", KEY_WRITE) + assert hook.seen[1][0] == "winreg.OpenKey/result" + assert hook.seen[1][1] == (key.handle, ) + assert hook.seen[2][0] == "winreg.CreateKey" + assert hook.seen[2][1] == (key.handle, u"Microsoft", KEY_ALL_ACCESS) + assert hook.seen[3][0] == "winreg.OpenKey/result" + assert hook.seen[3][1] == (sub_key.handle, ) + sub_key.Close() + key.Close() + +def test_ExpandEnvironmentStrings(): + from winreg import ExpandEnvironmentStrings + s = u"This is a test string" + with TestHook() as hook: + ExpandEnvironmentStrings(s) + assert hook.seen[0] == ("winreg.ExpandEnvironmentStrings", (s, )) + +def test_LoadKey(): + from winreg import LoadKey, HKEY_USERS + subkey = u"PyPy Test key - Delete me" + filename = u"This is a long filename that doesn't exist, hopefully" + with TestHook() as hook: + try: + LoadKey(HKEY_USERS, subkey, filename) + except OSError: + pass + assert hook.seen[0] == ("winreg.LoadKey", (HKEY_USERS, subkey, filename)) + +def test_OpenKey(): + from winreg import OpenKey, OpenKeyEx + from winreg import HKEY_CURRENT_USER, KEY_ALL_ACCESS, KEY_READ + with TestHook() as hook: + key = OpenKey(HKEY_CURRENT_USER, u"SOFTWARE") + sub_key = OpenKeyEx(key, u"Microsoft", 0, KEY_ALL_ACCESS) + assert hook.seen[0][0] == "winreg.OpenKey" + assert hook.seen[0][1] == (HKEY_CURRENT_USER, u"SOFTWARE", KEY_READ) + assert hook.seen[1][0] == "winreg.OpenKey/result" + assert hook.seen[1][1] == (key.handle, ) + assert hook.seen[2][0] == "winreg.OpenKey" + assert hook.seen[2][1] == (key.handle, u"Microsoft", KEY_ALL_ACCESS) + assert hook.seen[3][0] == "winreg.OpenKey/result" + assert hook.seen[3][1] == (sub_key.handle, ) + sub_key.Close() + key.Close() + +def test_PyHKEY_Detach(): + from winreg import OpenKey, CloseKey, HKEY_CURRENT_USER + with TestHook() as hook: + key = OpenKey(HKEY_CURRENT_USER, u"SOFTWARE") + handle = key.Detach() + CloseKey(handle) + assert hook.seen[-1] == ("winreg.PyHKEY.Detach", (handle, )) + +def test_QueryInfoKey(): + from winreg import QueryInfoKey, HKEY_CURRENT_USER + with TestHook() as hook: + QueryInfoKey(HKEY_CURRENT_USER) + assert hook.seen[0] == ("winreg.QueryInfoKey", (HKEY_CURRENT_USER, )) + +def test_QueryValue(): + from winreg import QueryValue, QueryValueEx, HKEY_CURRENT_USER + with TestHook() as hook: + QueryValue(HKEY_CURRENT_USER, u"SOFTWARE") + try: + QueryValueEx(HKEY_CURRENT_USER, u"Invalid") + except OSError: + pass + assert hook.seen[0] == ("winreg.QueryValue", (HKEY_CURRENT_USER, u"SOFTWARE", None)) + assert hook.seen[1] == ("winreg.QueryValue", (HKEY_CURRENT_USER, None, u"Invalid")) + +def test_SaveKey(): + from winreg import SaveKey, HKEY_CURRENT_USER + filename = u"this file should not be created, delete me" + with TestHook(raise_on_events="winreg.SaveKey") as hook: + try: + SaveKey(HKEY_CURRENT_USER, filename) + except RuntimeError as ex: + assert str(ex) == "saw event winreg.SaveKey" + else: + assert False + assert hook.seen[0] == ("winreg.SaveKey", (HKEY_CURRENT_USER, filename)) + +def test_set_and_delete(): + import os + from winreg import CreateKey, HKEY_CURRENT_USER, REG_SZ, KEY_WOW64_64KEY + from winreg import DeleteKey, DeleteKeyEx, DeleteValue, SetValue, SetValueEx + key_name = "SOFTWARE\\Pypy Test Key 2 - Delete Me [%d]" % os.getpid() + subkey_name = "Test SubKey" + subkey2_name = "Test SubKey 2" + value_name = "Test Value" + value = "hello world" + with CreateKey(HKEY_CURRENT_USER, key_name) as key: + handle = key.handle + with TestHook() as hook: + SetValue(key, subkey_name, REG_SZ, value) + SetValueEx(key, value_name, 0, REG_SZ, value) + DeleteValue(key, value_name) + try: + DeleteKeyEx(key, subkey2_name, KEY_WOW64_64KEY, 0) + except (NotImplementedError, OSError): + pass + DeleteKey(key, subkey_name) + DeleteKey(HKEY_CURRENT_USER, key_name) + assert hook.seen[0] == ("winreg.SetValue", (handle, subkey_name, REG_SZ, value)) + assert hook.seen[1] == ("winreg.SetValue", (handle, value_name, REG_SZ, value)) + assert hook.seen[2] == ("winreg.DeleteValue", (handle, value_name)) + assert hook.seen[3] == ("winreg.DeleteKey", (handle, subkey2_name, KEY_WOW64_64KEY)) + assert hook.seen[4] == ("winreg.DeleteKey", (handle, subkey_name, 0)) + assert hook.seen[5] == ("winreg.DeleteKey", (HKEY_CURRENT_USER, key_name, 0)) + +def test_enum(): + from winreg import EnumKey, EnumValue, HKEY_CURRENT_USER + functions = [ + (EnumKey, "winreg.EnumKey"), + (EnumValue, "winreg.EnumValue"), + ] + index = 42 + with TestHook() as hook: + for func, ev in functions: + try: + func(HKEY_CURRENT_USER, index) + except OSError: + pass + for i, (func, ev) in enumerate(functions): + assert hook.seen[i] == (ev, (HKEY_CURRENT_USER, index)) + +def test_reflection(): + from winreg import DisableReflectionKey, EnableReflectionKey, \ + QueryReflectionKey, OpenKey, HKEY_LOCAL_MACHINE + functions = [ + (DisableReflectionKey, "winreg.DisableReflectionKey"), + (EnableReflectionKey, "winreg.EnableReflectionKey"), + (QueryReflectionKey, "winreg.QueryReflectionKey"), + ] + # calling {Dis,En}ableReflectionKey on HKLM\Software has no effect in all OSes + with OpenKey(HKEY_LOCAL_MACHINE, "Software") as key: + with TestHook() as hook: + for func, ev in functions: + try: + func(key) + except NotImplementedError: + pass + for i, (func, ev) in enumerate(functions): + assert hook.seen[i] == (ev, (key.handle, )) -- GitLab From c1c205d4b36324af0f7e8b3c20d3c4103b1ed7c4 Mon Sep 17 00:00:00 2001 From: nulano Date: Sat, 27 Mar 2021 09:37:20 +0100 Subject: [PATCH 3/5] more mmap.has_madvise fixes on non-_POSIX platforms --HG-- branch : winreg-audithooks --- pypy/module/mmap/interp_mmap.py | 8 +++++--- pypy/module/mmap/test/test_mmap.py | 2 +- rpython/rlib/test/test_rmmap.py | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/pypy/module/mmap/interp_mmap.py b/pypy/module/mmap/interp_mmap.py index 5a91e6cd8c..5301070886 100644 --- a/pypy/module/mmap/interp_mmap.py +++ b/pypy/module/mmap/interp_mmap.py @@ -279,8 +279,13 @@ class W_MMap(W_Root): self.mmap.madvise(flags, start, length) +optional = {} + if rmmap._POSIX: + if rmmap.has_madvise: + optional['madvise'] = interp2app(W_MMap.descr_madvise) + @unwrap_spec(fileno=int, length=int, flags=int, prot=int, access=int, offset=OFF_T) def mmap(space, w_subtype, fileno, length, flags=rmmap.MAP_SHARED, @@ -314,9 +319,6 @@ elif rmmap._MS_WINDOWS: raise mmap_error(space, e) return self -optional = {} -if rmmap.has_madvise: - optional['madvise'] = interp2app(W_MMap.descr_madvise) W_MMap.typedef = TypeDef("mmap.mmap", None, None, 'read-write', __new__ = interp2app(mmap), diff --git a/pypy/module/mmap/test/test_mmap.py b/pypy/module/mmap/test/test_mmap.py index 6e14a21cb0..5143386a60 100644 --- a/pypy/module/mmap/test/test_mmap.py +++ b/pypy/module/mmap/test/test_mmap.py @@ -903,7 +903,7 @@ class AppTestMMap: m = mmap.mmap(-1, 1024) if not hasattr(m, "madvise"): m.close() - py.test.skip("no madvise") + skip("no madvise") m.madvise(mmap.MADV_NORMAL) m.close() diff --git a/rpython/rlib/test/test_rmmap.py b/rpython/rlib/test/test_rmmap.py index 8012840f36..712f85e396 100644 --- a/rpython/rlib/test/test_rmmap.py +++ b/rpython/rlib/test/test_rmmap.py @@ -485,7 +485,7 @@ class TestMMap: py.test.raises(RValueError, m.getitem, 0) m.close() - @py.test.mark.skipif("not mmap.has_madvise") + @py.test.mark.skipif("not mmap._POSIX or not mmap.has_madvise") def test_madvise(self): m = mmap.mmap(-1, 8096) m.madvise(mmap.MADV_NORMAL, 0, 8096) -- GitLab From d8eae7e047bfe1c3530ac9c44fb0e3b633cbf24c Mon Sep 17 00:00:00 2001 From: nulano Date: Sun, 25 Apr 2021 23:34:47 +0200 Subject: [PATCH 4/5] Backout changeset a4d822d4e5094f17a28060692d05a6a58e861808 --HG-- branch : winreg-audithooks --- pypy/module/mmap/interp_mmap.py | 8 +++----- pypy/module/mmap/test/test_mmap.py | 2 +- rpython/rlib/test/test_rmmap.py | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/pypy/module/mmap/interp_mmap.py b/pypy/module/mmap/interp_mmap.py index 5301070886..5a91e6cd8c 100644 --- a/pypy/module/mmap/interp_mmap.py +++ b/pypy/module/mmap/interp_mmap.py @@ -279,13 +279,8 @@ class W_MMap(W_Root): self.mmap.madvise(flags, start, length) -optional = {} - if rmmap._POSIX: - if rmmap.has_madvise: - optional['madvise'] = interp2app(W_MMap.descr_madvise) - @unwrap_spec(fileno=int, length=int, flags=int, prot=int, access=int, offset=OFF_T) def mmap(space, w_subtype, fileno, length, flags=rmmap.MAP_SHARED, @@ -319,6 +314,9 @@ elif rmmap._MS_WINDOWS: raise mmap_error(space, e) return self +optional = {} +if rmmap.has_madvise: + optional['madvise'] = interp2app(W_MMap.descr_madvise) W_MMap.typedef = TypeDef("mmap.mmap", None, None, 'read-write', __new__ = interp2app(mmap), diff --git a/pypy/module/mmap/test/test_mmap.py b/pypy/module/mmap/test/test_mmap.py index 5143386a60..6e14a21cb0 100644 --- a/pypy/module/mmap/test/test_mmap.py +++ b/pypy/module/mmap/test/test_mmap.py @@ -903,7 +903,7 @@ class AppTestMMap: m = mmap.mmap(-1, 1024) if not hasattr(m, "madvise"): m.close() - skip("no madvise") + py.test.skip("no madvise") m.madvise(mmap.MADV_NORMAL) m.close() diff --git a/rpython/rlib/test/test_rmmap.py b/rpython/rlib/test/test_rmmap.py index 712f85e396..8012840f36 100644 --- a/rpython/rlib/test/test_rmmap.py +++ b/rpython/rlib/test/test_rmmap.py @@ -485,7 +485,7 @@ class TestMMap: py.test.raises(RValueError, m.getitem, 0) m.close() - @py.test.mark.skipif("not mmap._POSIX or not mmap.has_madvise") + @py.test.mark.skipif("not mmap.has_madvise") def test_madvise(self): m = mmap.mmap(-1, 8096) m.madvise(mmap.MADV_NORMAL, 0, 8096) -- GitLab From 141bb9221f293ef36a3c4abcfef42c6d03c30f87 Mon Sep 17 00:00:00 2001 From: nulano Date: Sun, 25 Apr 2021 23:35:19 +0200 Subject: [PATCH 5/5] Backout changeset a4a370d5434010d6ffcb441fca5702cca4f4399b --HG-- branch : winreg-audithooks --- rpython/rlib/rmmap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py index 0008cc6e9a..f2e99ac292 100644 --- a/rpython/rlib/rmmap.py +++ b/rpython/rlib/rmmap.py @@ -654,7 +654,7 @@ class MMap(object): index += self.size self.data[index] = value[0] - if _POSIX and has_madvise: + if has_madvise: def madvise(self, flags, start, length): res = c_madvise_safe(rffi.cast(PTR, rffi.ptradd(self.data, + start)), rffi.cast(size_t, length), -- GitLab