Commit f0481114 authored by Amaury Forgeot d'Arc's avatar Amaury Forgeot d'Arc

#3660: Correct a reference leak in PyUnicode_AsEncodedString when

the encoder does not return a bytes object.

Now test_unicode passes without leaking.

Reviewer: Antoine Pitrou.
parent f9b99a0b
...@@ -12,10 +12,13 @@ What's New in Python 3.0 release candidate 1 ...@@ -12,10 +12,13 @@ What's New in Python 3.0 release candidate 1
Core and Builtins Core and Builtins
----------------- -----------------
- Issue 3774: Added a few more checks in PyTokenizer_FindEncoding to handle - Issue #3660: Corrected a reference leak in str.encode() when the encoder
does not return a bytes object.
- Issue #3774: Added a few more checks in PyTokenizer_FindEncoding to handle
error conditions. error conditions.
- Issue 3594: Fix Parser/tokenizer.c:fp_setreadl() to open the file being - Issue #3594: Fix Parser/tokenizer.c:fp_setreadl() to open the file being
tokenized by either a file path or file pointer for the benefit of tokenized by either a file path or file pointer for the benefit of
PyTokenizer_FindEncoding(). PyTokenizer_FindEncoding().
......
...@@ -1328,7 +1328,7 @@ PyObject *PyUnicode_AsEncodedString(PyObject *unicode, ...@@ -1328,7 +1328,7 @@ PyObject *PyUnicode_AsEncodedString(PyObject *unicode,
if (!PyUnicode_Check(unicode)) { if (!PyUnicode_Check(unicode)) {
PyErr_BadArgument(); PyErr_BadArgument();
goto onError; return NULL;
} }
if (encoding == NULL) if (encoding == NULL)
...@@ -1351,27 +1351,33 @@ PyObject *PyUnicode_AsEncodedString(PyObject *unicode, ...@@ -1351,27 +1351,33 @@ PyObject *PyUnicode_AsEncodedString(PyObject *unicode,
/* Encode via the codec registry */ /* Encode via the codec registry */
v = PyCodec_Encode(unicode, encoding, errors); v = PyCodec_Encode(unicode, encoding, errors);
if (v == NULL) if (v == NULL)
goto onError; return NULL;
/* The normal path */
if (PyBytes_Check(v))
return v;
/* If the codec returns a buffer, raise a warning and convert to bytes */
if (PyByteArray_Check(v)) { if (PyByteArray_Check(v)) {
char msg[100]; char msg[100];
PyObject *b;
PyOS_snprintf(msg, sizeof(msg), PyOS_snprintf(msg, sizeof(msg),
"encoder %s returned buffer instead of bytes", "encoder %s returned buffer instead of bytes",
encoding); encoding);
if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 1) < 0) { if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 1) < 0) {
v = NULL; Py_DECREF(v);
goto onError; return NULL;
} }
v = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(v), Py_SIZE(v));
b = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(v), Py_SIZE(v));
Py_DECREF(v);
return b;
} }
else if (!PyBytes_Check(v)) {
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"encoder did not return a bytes object (type=%.400s)", "encoder did not return a bytes object (type=%.400s)",
Py_TYPE(v)->tp_name); Py_TYPE(v)->tp_name);
v = NULL; Py_DECREF(v);
}
return v;
onError:
return NULL; return NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment