Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0d92c4f

Browse files
committed
Issue #16416: Fix error handling in _Py_wchar2char() _Py_char2wchar() functions
1 parent fc93ec5 commit 0d92c4f

2 files changed

Lines changed: 21 additions & 15 deletions

File tree

Objects/unicodeobject.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4691,7 +4691,10 @@ PyUnicode_DecodeUTF8Stateful(const char *s,
46914691
#ifdef __APPLE__
46924692

46934693
/* Simplified UTF-8 decoder using surrogateescape error handler,
4694-
used to decode the command line arguments on Mac OS X. */
4694+
used to decode the command line arguments on Mac OS X.
4695+
4696+
Return a pointer to a newly allocated wide character string (use
4697+
PyMem_Free() to free the memory), or NULL on memory allocation error. */
46954698

46964699
wchar_t*
46974700
_Py_DecodeUTF8_surrogateescape(const char *s, Py_ssize_t size)
@@ -4702,10 +4705,8 @@ _Py_DecodeUTF8_surrogateescape(const char *s, Py_ssize_t size)
47024705

47034706
/* Note: size will always be longer than the resulting Unicode
47044707
character count */
4705-
if (PY_SSIZE_T_MAX / sizeof(wchar_t) < (size + 1)) {
4706-
PyErr_NoMemory();
4708+
if (PY_SSIZE_T_MAX / sizeof(wchar_t) < (size + 1))
47074709
return NULL;
4708-
}
47094710
unicode = PyMem_Malloc((size + 1) * sizeof(wchar_t));
47104711
if (!unicode)
47114712
return NULL;

Python/fileutils.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,12 @@ _Py_char2wchar(const char* arg, size_t *size)
6767
#ifdef __APPLE__
6868
wchar_t *wstr;
6969
wstr = _Py_DecodeUTF8_surrogateescape(arg, strlen(arg));
70-
if (wstr == NULL)
71-
return NULL;
72-
if (size != NULL)
73-
*size = wcslen(wstr);
70+
if (size != NULL) {
71+
if (wstr != NULL)
72+
*size = wcslen(wstr);
73+
else
74+
*size = (size_t)-1;
75+
}
7476
return wstr;
7577
#else
7678
wchar_t *res;
@@ -204,22 +206,25 @@ _Py_wchar2char(const wchar_t *text, size_t *error_pos)
204206
char *cpath;
205207

206208
unicode = PyUnicode_FromWideChar(text, wcslen(text));
207-
if (unicode == NULL) {
208-
Py_DECREF(unicode);
209+
if (unicode == NULL)
209210
return NULL;
210-
}
211211

212212
bytes = _PyUnicode_AsUTF8String(unicode, "surrogateescape");
213213
Py_DECREF(unicode);
214214
if (bytes == NULL) {
215215
PyErr_Clear();
216+
if (error_pos != NULL)
217+
*error_pos = (size_t)-1;
216218
return NULL;
217219
}
218220

219221
len = PyBytes_GET_SIZE(bytes);
220222
cpath = PyMem_Malloc(len+1);
221223
if (cpath == NULL) {
224+
PyErr_Clear();
222225
Py_DECREF(bytes);
226+
if (error_pos != NULL)
227+
*error_pos = (size_t)-1;
223228
return NULL;
224229
}
225230
memcpy(cpath, PyBytes_AsString(bytes), len + 1);
@@ -231,9 +236,6 @@ _Py_wchar2char(const wchar_t *text, size_t *error_pos)
231236
size_t i, size, converted;
232237
wchar_t c, buf[2];
233238

234-
if (error_pos != NULL)
235-
*error_pos = (size_t)-1;
236-
237239
/* The function works in two steps:
238240
1. compute the length of the output buffer in bytes (size)
239241
2. outputs the bytes */
@@ -280,8 +282,11 @@ _Py_wchar2char(const wchar_t *text, size_t *error_pos)
280282

281283
size += 1; /* nul byte at the end */
282284
result = PyMem_Malloc(size);
283-
if (result == NULL)
285+
if (result == NULL) {
286+
if (error_pos != NULL)
287+
*error_pos = (size_t)-1;
284288
return NULL;
289+
}
285290
bytes = result;
286291
}
287292
return result;

0 commit comments

Comments
 (0)