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

Skip to content

Commit 4a72a7b

Browse files
committed
Issue #25270: Prevent codecs.escape_encode() from raising SystemError when an empty bytestring is passed
1 parent a4961e5 commit 4a72a7b

4 files changed

Lines changed: 38 additions & 6 deletions

File tree

Doc/c-api/bytes.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,5 +198,5 @@ called with a non-bytes parameter.
198198
desired. On success, *\*bytes* holds the resized bytes object and ``0`` is
199199
returned; the address in *\*bytes* may differ from its input value. If the
200200
reallocation fails, the original bytes object at *\*bytes* is deallocated,
201-
*\*bytes* is set to *NULL*, a memory exception is set, and ``-1`` is
201+
*\*bytes* is set to *NULL*, :exc:`MemoryError` is set, and ``-1`` is
202202
returned.

Lib/test/test_codecs.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2501,6 +2501,26 @@ def test_decode_errors(self):
25012501
self.assertEqual(decode(br"\U00110000", "replace"), ("\ufffd", 10))
25022502

25032503

2504+
class EscapeEncodeTest(unittest.TestCase):
2505+
2506+
def test_escape_encode(self):
2507+
tests = [
2508+
(b'', (b'', 0)),
2509+
(b'foobar', (b'foobar', 6)),
2510+
(b'spam\0eggs', (b'spam\\x00eggs', 9)),
2511+
(b'a\'b', (b"a\\'b", 3)),
2512+
(b'b\\c', (b'b\\\\c', 3)),
2513+
(b'c\nd', (b'c\\nd', 3)),
2514+
(b'd\re', (b'd\\re', 3)),
2515+
(b'f\x7fg', (b'f\\x7fg', 3)),
2516+
]
2517+
for data, output in tests:
2518+
with self.subTest(data=data):
2519+
self.assertEqual(codecs.escape_encode(data), output)
2520+
self.assertRaises(TypeError, codecs.escape_encode, 'spam')
2521+
self.assertRaises(TypeError, codecs.escape_encode, bytearray(b'spam'))
2522+
2523+
25042524
class SurrogateEscapeTest(unittest.TestCase):
25052525

25062526
def test_utf8(self):

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ Core and Builtins
7171
Library
7272
-------
7373

74+
- Issue #25270: Prevent codecs.escape_encode() from raising SystemError when
75+
an empty bytestring is passed.
76+
7477
- Issue #28181: Get antigravity over HTTPS. Patch by Kaartic Sivaraam.
7578

7679
- Issue #25895: Enable WebSocket URL schemes in urllib.parse.urljoin.

Objects/bytesobject.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3550,11 +3550,15 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize)
35503550
PyObject *v;
35513551
PyBytesObject *sv;
35523552
v = *pv;
3553-
if (!PyBytes_Check(v) || Py_REFCNT(v) != 1 || newsize < 0) {
3554-
*pv = 0;
3555-
Py_DECREF(v);
3556-
PyErr_BadInternalCall();
3557-
return -1;
3553+
if (!PyBytes_Check(v) || newsize < 0) {
3554+
goto error;
3555+
}
3556+
if (Py_SIZE(v) == newsize) {
3557+
/* return early if newsize equals to v->ob_size */
3558+
return 0;
3559+
}
3560+
if (Py_REFCNT(v) != 1) {
3561+
goto error;
35583562
}
35593563
/* XXX UNREF/NEWREF interface should be more symmetrical */
35603564
_Py_DEC_REFTOTAL;
@@ -3572,6 +3576,11 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize)
35723576
sv->ob_sval[newsize] = '\0';
35733577
sv->ob_shash = -1; /* invalidate cached hash value */
35743578
return 0;
3579+
error:
3580+
*pv = 0;
3581+
Py_DECREF(v);
3582+
PyErr_BadInternalCall();
3583+
return -1;
35753584
}
35763585

35773586
void

0 commit comments

Comments
 (0)