bpo-37483: fix reference leak in _PyCodec_Lookup (GH-14600)

This commit is contained in:
Jeroen Demeyer 2019-07-05 12:57:32 +02:00 committed by Inada Naoki
parent 1da4462765
commit 6e43d07324
1 changed files with 14 additions and 13 deletions

View File

@ -99,40 +99,38 @@ PyObject *normalizestring(const char *string)
PyObject *_PyCodec_Lookup(const char *encoding) PyObject *_PyCodec_Lookup(const char *encoding)
{ {
PyObject *result, *v;
Py_ssize_t i, len;
if (encoding == NULL) { if (encoding == NULL) {
PyErr_BadArgument(); PyErr_BadArgument();
goto onError; return NULL;
} }
PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) {
goto onError; return NULL;
}
/* Convert the encoding to a normalized Python string: all /* Convert the encoding to a normalized Python string: all
characters are converted to lower case, spaces and hyphens are characters are converted to lower case, spaces and hyphens are
replaced with underscores. */ replaced with underscores. */
v = normalizestring(encoding); PyObject *v = normalizestring(encoding);
if (v == NULL) if (v == NULL) {
goto onError; return NULL;
}
PyUnicode_InternInPlace(&v); PyUnicode_InternInPlace(&v);
/* First, try to lookup the name in the registry dictionary */ /* First, try to lookup the name in the registry dictionary */
result = PyDict_GetItemWithError(interp->codec_search_cache, v); PyObject *result = PyDict_GetItemWithError(interp->codec_search_cache, v);
if (result != NULL) { if (result != NULL) {
Py_INCREF(result); Py_INCREF(result);
Py_DECREF(v); Py_DECREF(v);
return result; return result;
} }
else if (PyErr_Occurred()) { else if (PyErr_Occurred()) {
Py_DECREF(v); goto onError;
return NULL;
} }
/* Next, scan the search functions in order of registration */ /* Next, scan the search functions in order of registration */
len = PyList_Size(interp->codec_search_path); const Py_ssize_t len = PyList_Size(interp->codec_search_path);
if (len < 0) if (len < 0)
goto onError; goto onError;
if (len == 0) { if (len == 0) {
@ -142,6 +140,7 @@ PyObject *_PyCodec_Lookup(const char *encoding)
goto onError; goto onError;
} }
Py_ssize_t i;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
PyObject *func; PyObject *func;
@ -175,9 +174,11 @@ PyObject *_PyCodec_Lookup(const char *encoding)
Py_DECREF(result); Py_DECREF(result);
goto onError; goto onError;
} }
Py_DECREF(v);
return result; return result;
onError: onError:
Py_DECREF(v);
return NULL; return NULL;
} }