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

Skip to content

Commit f048111

Browse files
committed
#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.
1 parent f9b99a0 commit f048111

2 files changed

Lines changed: 24 additions & 15 deletions

File tree

Misc/NEWS

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@ What's New in Python 3.0 release candidate 1
1212
Core and Builtins
1313
-----------------
1414

15-
- Issue 3774: Added a few more checks in PyTokenizer_FindEncoding to handle
15+
- Issue #3660: Corrected a reference leak in str.encode() when the encoder
16+
does not return a bytes object.
17+
18+
- Issue #3774: Added a few more checks in PyTokenizer_FindEncoding to handle
1619
error conditions.
1720

18-
- Issue 3594: Fix Parser/tokenizer.c:fp_setreadl() to open the file being
21+
- Issue #3594: Fix Parser/tokenizer.c:fp_setreadl() to open the file being
1922
tokenized by either a file path or file pointer for the benefit of
2023
PyTokenizer_FindEncoding().
2124

Objects/unicodeobject.c

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,7 +1328,7 @@ PyObject *PyUnicode_AsEncodedString(PyObject *unicode,
13281328

13291329
if (!PyUnicode_Check(unicode)) {
13301330
PyErr_BadArgument();
1331-
goto onError;
1331+
return NULL;
13321332
}
13331333

13341334
if (encoding == NULL)
@@ -1351,27 +1351,33 @@ PyObject *PyUnicode_AsEncodedString(PyObject *unicode,
13511351
/* Encode via the codec registry */
13521352
v = PyCodec_Encode(unicode, encoding, errors);
13531353
if (v == NULL)
1354-
goto onError;
1354+
return NULL;
1355+
1356+
/* The normal path */
1357+
if (PyBytes_Check(v))
1358+
return v;
1359+
1360+
/* If the codec returns a buffer, raise a warning and convert to bytes */
13551361
if (PyByteArray_Check(v)) {
13561362
char msg[100];
1363+
PyObject *b;
13571364
PyOS_snprintf(msg, sizeof(msg),
13581365
"encoder %s returned buffer instead of bytes",
13591366
encoding);
13601367
if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 1) < 0) {
1361-
v = NULL;
1362-
goto onError;
1368+
Py_DECREF(v);
1369+
return NULL;
13631370
}
1364-
v = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(v), Py_SIZE(v));
1365-
}
1366-
else if (!PyBytes_Check(v)) {
1367-
PyErr_Format(PyExc_TypeError,
1368-
"encoder did not return a bytes object (type=%.400s)",
1369-
Py_TYPE(v)->tp_name);
1370-
v = NULL;
1371+
1372+
b = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(v), Py_SIZE(v));
1373+
Py_DECREF(v);
1374+
return b;
13711375
}
1372-
return v;
13731376

1374-
onError:
1377+
PyErr_Format(PyExc_TypeError,
1378+
"encoder did not return a bytes object (type=%.400s)",
1379+
Py_TYPE(v)->tp_name);
1380+
Py_DECREF(v);
13751381
return NULL;
13761382
}
13771383

0 commit comments

Comments
 (0)