summaryrefslogtreecommitdiffstats
path: root/PC/winreg.c
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2020-07-10 20:26:06 (GMT)
committerGitHub <noreply@github.com>2020-07-10 20:26:06 (GMT)
commit4c8f09d7cef8c7aa07d5b5232b5b64f63819a743 (patch)
tree2d90e13b6dc939f019a6cafc45ea604cbb90f584 /PC/winreg.c
parent9650fe0197779b4dfded94be111e39c5810f098f (diff)
downloadcpython-4c8f09d7cef8c7aa07d5b5232b5b64f63819a743.zip
cpython-4c8f09d7cef8c7aa07d5b5232b5b64f63819a743.tar.gz
cpython-4c8f09d7cef8c7aa07d5b5232b5b64f63819a743.tar.bz2
bpo-36346: Make using the legacy Unicode C API optional (GH-21437)
Add compile time option USE_UNICODE_WCHAR_CACHE. Setting it to 0 makes the interpreter not using the wchar_t cache and the legacy Unicode C API.
Diffstat (limited to 'PC/winreg.c')
-rw-r--r--PC/winreg.c61
1 files changed, 46 insertions, 15 deletions
diff --git a/PC/winreg.c b/PC/winreg.c
index b2725b8..a24d784 100644
--- a/PC/winreg.c
+++ b/PC/winreg.c
@@ -640,16 +640,25 @@ Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize)
for (j = 0; j < i; j++)
{
PyObject *t;
- wchar_t *wstr;
Py_ssize_t len;
t = PyList_GET_ITEM(value, j);
if (!PyUnicode_Check(t))
return FALSE;
- wstr = PyUnicode_AsUnicodeAndSize(t, &len);
- if (wstr == NULL)
+#if USE_UNICODE_WCHAR_CACHE
+_Py_COMP_DIAG_PUSH
+_Py_COMP_DIAG_IGNORE_DEPR_DECLS
+ len = PyUnicode_GetSize(t);
+ if (len < 0)
return FALSE;
- size += Py_SAFE_DOWNCAST((len + 1) * sizeof(wchar_t),
+ len++;
+_Py_COMP_DIAG_POP
+#else /* USE_UNICODE_WCHAR_CACHE */
+ len = PyUnicode_AsWideChar(t, NULL, 0);
+ if (len < 0)
+ return FALSE;
+#endif /* USE_UNICODE_WCHAR_CACHE */
+ size += Py_SAFE_DOWNCAST(len * sizeof(wchar_t),
size_t, DWORD);
}
@@ -665,17 +674,18 @@ Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize)
for (j = 0; j < i; j++)
{
PyObject *t;
- wchar_t *wstr;
Py_ssize_t len;
t = PyList_GET_ITEM(value, j);
- wstr = PyUnicode_AsUnicodeAndSize(t, &len);
- assert(wstr);
- wcscpy(P, wstr);
- P += (len + 1);
+ assert(size > 0);
+ len = PyUnicode_AsWideChar(t, P, size);
+ assert(len >= 0);
+ assert(len < size);
+ size -= (DWORD)len + 1;
+ P += len + 1;
}
/* And doubly-terminate the list... */
- *P = '\0';
+ *P = L'\0';
break;
}
case REG_BINARY:
@@ -1669,7 +1679,7 @@ winreg.SetValue
type: DWORD
An integer that specifies the type of the data. Currently this must
be REG_SZ, meaning only strings are supported.
- value: Py_UNICODE(zeroes=True)
+ value as value_obj: unicode
A string that specifies the new value.
/
@@ -1688,30 +1698,51 @@ KEY_SET_VALUE access.
static PyObject *
winreg_SetValue_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key,
- DWORD type, const Py_UNICODE *value,
- Py_ssize_clean_t value_length)
-/*[clinic end generated code: output=686bedb1cbb4367b input=2cd2adab79339c53]*/
+ DWORD type, PyObject *value_obj)
+/*[clinic end generated code: output=d4773dc9c372311a input=bf088494ae2d24fd]*/
{
+ Py_ssize_t value_length;
long rc;
if (type != REG_SZ) {
PyErr_SetString(PyExc_TypeError, "type must be winreg.REG_SZ");
return NULL;
}
- if ((size_t)value_length >= PY_DWORD_MAX) {
+
+#if USE_UNICODE_WCHAR_CACHE
+_Py_COMP_DIAG_PUSH
+_Py_COMP_DIAG_IGNORE_DEPR_DECLS
+ const wchar_t *value = PyUnicode_AsUnicodeAndSize(value_obj, &value_length);
+_Py_COMP_DIAG_POP
+#else /* USE_UNICODE_WCHAR_CACHE */
+ wchar_t *value = PyUnicode_AsWideCharString(value_obj, &value_length);
+#endif /* USE_UNICODE_WCHAR_CACHE */
+ if (value == NULL) {
+ return NULL;
+ }
+ if ((Py_ssize_t)(DWORD)value_length != value_length) {
PyErr_SetString(PyExc_OverflowError, "value is too long");
+#if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free(value);
+#endif /* USE_UNICODE_WCHAR_CACHE */
return NULL;
}
if (PySys_Audit("winreg.SetValue", "nunu#",
(Py_ssize_t)key, sub_key, (Py_ssize_t)type,
value, value_length) < 0) {
+#if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free(value);
+#endif /* USE_UNICODE_WCHAR_CACHE */
return NULL;
}
Py_BEGIN_ALLOW_THREADS
rc = RegSetValueW(key, sub_key, REG_SZ, value, (DWORD)(value_length + 1));
Py_END_ALLOW_THREADS
+#if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free(value);
+#endif /* USE_UNICODE_WCHAR_CACHE */
if (rc != ERROR_SUCCESS)
return PyErr_SetFromWindowsErrWithFunction(rc, "RegSetValue");
Py_RETURN_NONE;