From e223ba13d8d871ee58570dfca4e82a591189cc2f Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Mon, 9 Sep 2019 03:26:15 -0600 Subject: [PATCH] bpo-32587: Make winreg.REG_MULTI_SZ support zero-length strings (#13239) * bpo-32587: Make winreg.REG_MULTI_SZ support PendingFileRenameOperations * Address review comments. --- Lib/test/test_winreg.py | 1 + .../2019-05-10-15-25-44.bpo-32587.-0g2O3.rst | 1 + PC/winreg.c | 41 +++++++++++-------- 3 files changed, 27 insertions(+), 16 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2019-05-10-15-25-44.bpo-32587.-0g2O3.rst diff --git a/Lib/test/test_winreg.py b/Lib/test/test_winreg.py index 91a2bbc066b..5c25ec8f7ec 100644 --- a/Lib/test/test_winreg.py +++ b/Lib/test/test_winreg.py @@ -41,6 +41,7 @@ ("String Val", "A string value", REG_SZ), ("StringExpand", "The path is %path%", REG_EXPAND_SZ), ("Multi-string", ["Lots", "of", "string", "values"], REG_MULTI_SZ), + ("Multi-nul", ["", "", "", ""], REG_MULTI_SZ), ("Raw Data", b"binary\x00data", REG_BINARY), ("Big String", "x"*(2**14-1), REG_SZ), ("Big Binary", b"x"*(2**14), REG_BINARY), diff --git a/Misc/NEWS.d/next/Windows/2019-05-10-15-25-44.bpo-32587.-0g2O3.rst b/Misc/NEWS.d/next/Windows/2019-05-10-15-25-44.bpo-32587.-0g2O3.rst new file mode 100644 index 00000000000..41483aa8b74 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2019-05-10-15-25-44.bpo-32587.-0g2O3.rst @@ -0,0 +1 @@ +Make :data:`winreg.REG_MULTI_SZ` support zero-length strings. diff --git a/PC/winreg.c b/PC/winreg.c index d0df7ef0ad4..37bc2c72dcd 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -518,11 +518,18 @@ fixupMultiSZ(wchar_t **str, wchar_t *data, int len) int i; wchar_t *Q; - Q = data + len; - for (P = data, i = 0; P < Q && *P != '\0'; P++, i++) { + if (len > 0 && data[len - 1] == '\0') { + Q = data + len - 1; + } + else { + Q = data + len; + } + + for (P = data, i = 0; P < Q; P++, i++) { str[i] = P; - for (; P < Q && *P != '\0'; P++) + for (; P < Q && *P != '\0'; P++) { ; + } } } @@ -530,12 +537,20 @@ static int countStrings(wchar_t *data, int len) { int strings; - wchar_t *P; - wchar_t *Q = data + len; + wchar_t *P, *Q; - for (P = data, strings = 0; P < Q && *P != '\0'; P++, strings++) - for (; P < Q && *P != '\0'; P++) + if (len > 0 && data[len - 1] == '\0') { + Q = data + len - 1; + } + else { + Q = data + len; + } + + for (P = data, strings = 0; P < Q; P++, strings++) { + for (; P < Q && *P != '\0'; P++) { ; + } + } return strings; } @@ -749,21 +764,15 @@ Reg2Py(BYTE *retDataBuf, DWORD retDataSize, DWORD typ) } for (index = 0; index < s; index++) { - size_t len = wcslen(str[index]); - if (len > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "registry string is too long for a Python string"); - Py_DECREF(obData); - PyMem_Free(str); - return NULL; - } - PyObject *uni = PyUnicode_FromWideChar(str[index], len); + size_t slen = wcsnlen(str[index], len); + PyObject *uni = PyUnicode_FromWideChar(str[index], slen); if (uni == NULL) { Py_DECREF(obData); PyMem_Free(str); return NULL; } PyList_SET_ITEM(obData, index, uni); + len -= slen + 1; } PyMem_Free(str);