amaury.forgeotdarc
2008-09-05 20:48:47 UTC
Author: amaury.forgeotdarc
Date: Fri Sep 5 22:48:47 2008
New Revision: 66234
Log:
#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.
Modified:
python/branches/py3k/Misc/NEWS
python/branches/py3k/Objects/unicodeobject.c
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Fri Sep 5 22:48:47 2008
@@ -12,10 +12,13 @@
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.
-- 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
PyTokenizer_FindEncoding().
Modified: python/branches/py3k/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k/Objects/unicodeobject.c (original)
+++ python/branches/py3k/Objects/unicodeobject.c Fri Sep 5 22:48:47 2008
@@ -1328,7 +1328,7 @@
if (!PyUnicode_Check(unicode)) {
PyErr_BadArgument();
- goto onError;
+ return NULL;
}
if (encoding == NULL)
@@ -1351,27 +1351,33 @@
/* Encode via the codec registry */
v = PyCodec_Encode(unicode, encoding, errors);
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)) {
char msg[100];
+ PyObject *b;
PyOS_snprintf(msg, sizeof(msg),
"encoder %s returned buffer instead of bytes",
encoding);
if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 1) < 0) {
- v = NULL;
- goto onError;
+ Py_DECREF(v);
+ return NULL;
}
- v = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(v), Py_SIZE(v));
- }
- else if (!PyBytes_Check(v)) {
- PyErr_Format(PyExc_TypeError,
- "encoder did not return a bytes object (type=%.400s)",
- Py_TYPE(v)->tp_name);
- v = NULL;
+
+ b = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(v), Py_SIZE(v));
+ Py_DECREF(v);
+ return b;
}
- return v;
- onError:
+ PyErr_Format(PyExc_TypeError,
+ "encoder did not return a bytes object (type=%.400s)",
+ Py_TYPE(v)->tp_name);
+ Py_DECREF(v);
return NULL;
}
Date: Fri Sep 5 22:48:47 2008
New Revision: 66234
Log:
#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.
Modified:
python/branches/py3k/Misc/NEWS
python/branches/py3k/Objects/unicodeobject.c
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Fri Sep 5 22:48:47 2008
@@ -12,10 +12,13 @@
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.
-- 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
PyTokenizer_FindEncoding().
Modified: python/branches/py3k/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k/Objects/unicodeobject.c (original)
+++ python/branches/py3k/Objects/unicodeobject.c Fri Sep 5 22:48:47 2008
@@ -1328,7 +1328,7 @@
if (!PyUnicode_Check(unicode)) {
PyErr_BadArgument();
- goto onError;
+ return NULL;
}
if (encoding == NULL)
@@ -1351,27 +1351,33 @@
/* Encode via the codec registry */
v = PyCodec_Encode(unicode, encoding, errors);
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)) {
char msg[100];
+ PyObject *b;
PyOS_snprintf(msg, sizeof(msg),
"encoder %s returned buffer instead of bytes",
encoding);
if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 1) < 0) {
- v = NULL;
- goto onError;
+ Py_DECREF(v);
+ return NULL;
}
- v = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(v), Py_SIZE(v));
- }
- else if (!PyBytes_Check(v)) {
- PyErr_Format(PyExc_TypeError,
- "encoder did not return a bytes object (type=%.400s)",
- Py_TYPE(v)->tp_name);
- v = NULL;
+
+ b = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(v), Py_SIZE(v));
+ Py_DECREF(v);
+ return b;
}
- return v;
- onError:
+ PyErr_Format(PyExc_TypeError,
+ "encoder did not return a bytes object (type=%.400s)",
+ Py_TYPE(v)->tp_name);
+ Py_DECREF(v);
return NULL;
}