Skip to content

Commit bbf02da

Browse files
bpo-32587: Make winreg.REG_MULTI_SZ support zero-length strings (GH-13239)
* bpo-32587: Make winreg.REG_MULTI_SZ support PendingFileRenameOperations * Address review comments. (cherry picked from commit e223ba1) Co-authored-by: Zackery Spytz <[email protected]>
1 parent 1af2c0e commit bbf02da

File tree

3 files changed

+27
-16
lines changed

3 files changed

+27
-16
lines changed

Lib/test/test_winreg.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
("String Val", "A string value", REG_SZ),
4242
("StringExpand", "The path is %path%", REG_EXPAND_SZ),
4343
("Multi-string", ["Lots", "of", "string", "values"], REG_MULTI_SZ),
44+
("Multi-nul", ["", "", "", ""], REG_MULTI_SZ),
4445
("Raw Data", b"binary\x00data", REG_BINARY),
4546
("Big String", "x"*(2**14-1), REG_SZ),
4647
("Big Binary", b"x"*(2**14), REG_BINARY),
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Make :data:`winreg.REG_MULTI_SZ` support zero-length strings.

PC/winreg.c

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -517,24 +517,39 @@ fixupMultiSZ(wchar_t **str, wchar_t *data, int len)
517517
int i;
518518
wchar_t *Q;
519519

520-
Q = data + len;
521-
for (P = data, i = 0; P < Q && *P != '\0'; P++, i++) {
520+
if (len > 0 && data[len - 1] == '\0') {
521+
Q = data + len - 1;
522+
}
523+
else {
524+
Q = data + len;
525+
}
526+
527+
for (P = data, i = 0; P < Q; P++, i++) {
522528
str[i] = P;
523-
for (; P < Q && *P != '\0'; P++)
529+
for (; P < Q && *P != '\0'; P++) {
524530
;
531+
}
525532
}
526533
}
527534

528535
static int
529536
countStrings(wchar_t *data, int len)
530537
{
531538
int strings;
532-
wchar_t *P;
533-
wchar_t *Q = data + len;
539+
wchar_t *P, *Q;
540+
541+
if (len > 0 && data[len - 1] == '\0') {
542+
Q = data + len - 1;
543+
}
544+
else {
545+
Q = data + len;
546+
}
534547

535-
for (P = data, strings = 0; P < Q && *P != '\0'; P++, strings++)
536-
for (; P < Q && *P != '\0'; P++)
548+
for (P = data, strings = 0; P < Q; P++, strings++) {
549+
for (; P < Q && *P != '\0'; P++) {
537550
;
551+
}
552+
}
538553
return strings;
539554
}
540555

@@ -749,21 +764,15 @@ Reg2Py(BYTE *retDataBuf, DWORD retDataSize, DWORD typ)
749764
}
750765
for (index = 0; index < s; index++)
751766
{
752-
size_t len = wcslen(str[index]);
753-
if (len > INT_MAX) {
754-
PyErr_SetString(PyExc_OverflowError,
755-
"registry string is too long for a Python string");
756-
Py_DECREF(obData);
757-
PyMem_Free(str);
758-
return NULL;
759-
}
760-
PyObject *uni = PyUnicode_FromWideChar(str[index], len);
767+
size_t slen = wcsnlen(str[index], len);
768+
PyObject *uni = PyUnicode_FromWideChar(str[index], slen);
761769
if (uni == NULL) {
762770
Py_DECREF(obData);
763771
PyMem_Free(str);
764772
return NULL;
765773
}
766774
PyList_SET_ITEM(obData, index, uni);
775+
len -= slen + 1;
767776
}
768777
PyMem_Free(str);
769778

0 commit comments

Comments
 (0)