[Python-checkins] bpo-32587: Make winreg.REG_MULTI_SZ support zero-length strings (#13239)

Steve Dower webhook-mailer at python.org
Mon Sep 9 05:26:19 EDT 2019


https://github.com/python/cpython/commit/e223ba13d8d871ee58570dfca4e82a591189cc2f
commit: e223ba13d8d871ee58570dfca4e82a591189cc2f
branch: master
author: Zackery Spytz <zspytz at gmail.com>
committer: Steve Dower <steve.dower at python.org>
date: 2019-09-09T02:26:15-07:00
summary:

bpo-32587: Make winreg.REG_MULTI_SZ support zero-length strings (#13239)

* bpo-32587: Make winreg.REG_MULTI_SZ support PendingFileRenameOperations

* Address review comments.

files:
A Misc/NEWS.d/next/Windows/2019-05-10-15-25-44.bpo-32587.-0g2O3.rst
M Lib/test/test_winreg.py
M PC/winreg.c

diff --git a/Lib/test/test_winreg.py b/Lib/test/test_winreg.py
index 91a2bbc066b1..5c25ec8f7ec6 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 000000000000..41483aa8b74a
--- /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 d0df7ef0ad47..37bc2c72dcde 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;
+
+    if (len > 0 && data[len - 1] == '\0') {
+        Q = data + len - 1;
+    }
+    else {
+        Q = data + len;
+    }
 
-    for (P = data, strings = 0; P < Q && *P != '\0'; P++, strings++)
-        for (; P < Q && *P != '\0'; P++)
+    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);
 



More information about the Python-checkins mailing list