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

Skip to content

Commit 55aede7

Browse files
[3.13] gh-122888: Fix crash on certain calls to str() (GH-122889) (#122947)
Fixes GH-122888 (cherry picked from commit 53ebb62) Co-authored-by: Jelle Zijlstra <[email protected]>
1 parent 8b64ce4 commit 55aede7

File tree

3 files changed

+44
-12
lines changed

3 files changed

+44
-12
lines changed

Lib/test/test_str.py

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,8 +1736,6 @@ def __str__(self):
17361736
'character buffers are decoded to unicode'
17371737
)
17381738

1739-
self.assertRaises(TypeError, str, 42, 42, 42)
1740-
17411739
def test_constructor_keyword_args(self):
17421740
"""Pass various keyword argument combinations to the constructor."""
17431741
# The object argument can be passed as a keyword.
@@ -2652,22 +2650,45 @@ def test_check_encoding_errors(self):
26522650
self.assertEqual(proc.rc, 10, proc)
26532651

26542652
def test_str_invalid_call(self):
2655-
check = lambda *a, **kw: self.assertRaises(TypeError, str, *a, **kw)
2656-
26572653
# too many args
2658-
check(1, "", "", 1)
2654+
with self.assertRaisesRegex(TypeError, r"str expected at most 3 arguments, got 4"):
2655+
str("too", "many", "argu", "ments")
2656+
with self.assertRaisesRegex(TypeError, r"str expected at most 3 arguments, got 4"):
2657+
str(1, "", "", 1)
26592658

26602659
# no such kw arg
2661-
check(test=1)
2660+
with self.assertRaisesRegex(TypeError, r"str\(\) got an unexpected keyword argument 'test'"):
2661+
str(test=1)
26622662

26632663
# 'encoding' must be str
2664-
check(1, encoding=1)
2665-
check(1, 1)
2664+
with self.assertRaisesRegex(TypeError, r"str\(\) argument 'encoding' must be str, not int"):
2665+
str(1, 1)
2666+
with self.assertRaisesRegex(TypeError, r"str\(\) argument 'encoding' must be str, not int"):
2667+
str(1, encoding=1)
2668+
with self.assertRaisesRegex(TypeError, r"str\(\) argument 'encoding' must be str, not bytes"):
2669+
str(b"x", b"ascii")
2670+
with self.assertRaisesRegex(TypeError, r"str\(\) argument 'encoding' must be str, not bytes"):
2671+
str(b"x", encoding=b"ascii")
26662672

26672673
# 'errors' must be str
2668-
check(1, errors=1)
2669-
check(1, "", errors=1)
2670-
check(1, 1, 1)
2674+
with self.assertRaisesRegex(TypeError, r"str\(\) argument 'encoding' must be str, not int"):
2675+
str(1, 1, 1)
2676+
with self.assertRaisesRegex(TypeError, r"str\(\) argument 'errors' must be str, not int"):
2677+
str(1, errors=1)
2678+
with self.assertRaisesRegex(TypeError, r"str\(\) argument 'errors' must be str, not int"):
2679+
str(1, "", errors=1)
2680+
with self.assertRaisesRegex(TypeError, r"str\(\) argument 'errors' must be str, not bytes"):
2681+
str(b"x", "ascii", b"strict")
2682+
with self.assertRaisesRegex(TypeError, r"str\(\) argument 'errors' must be str, not bytes"):
2683+
str(b"x", "ascii", errors=b"strict")
2684+
2685+
# both positional and kwarg
2686+
with self.assertRaisesRegex(TypeError, r"argument for str\(\) given by name \('encoding'\) and position \(2\)"):
2687+
str(b"x", "utf-8", encoding="ascii")
2688+
with self.assertRaisesRegex(TypeError, r"str\(\) takes at most 3 arguments \(4 given\)"):
2689+
str(b"x", "utf-8", "ignore", encoding="ascii")
2690+
with self.assertRaisesRegex(TypeError, r"str\(\) takes at most 3 arguments \(4 given\)"):
2691+
str(b"x", "utf-8", "strict", errors="ignore")
26712692

26722693

26732694
class StringModuleTest(unittest.TestCase):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix crash on certain calls to ``str()`` with positional arguments of the
2+
wrong type. Patch by Jelle Zijlstra.

Objects/unicodeobject.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14817,7 +14817,16 @@ unicode_vectorcall(PyObject *type, PyObject *const *args,
1481714817
return PyObject_Str(object);
1481814818
}
1481914819
const char *encoding = arg_as_utf8(args[1], "encoding");
14820-
const char *errors = (nargs == 3) ? arg_as_utf8(args[2], "errors") : NULL;
14820+
if (encoding == NULL) {
14821+
return NULL;
14822+
}
14823+
const char *errors = NULL;
14824+
if (nargs == 3) {
14825+
errors = arg_as_utf8(args[2], "errors");
14826+
if (errors == NULL) {
14827+
return NULL;
14828+
}
14829+
}
1482114830
return PyUnicode_FromEncodedObject(object, encoding, errors);
1482214831
}
1482314832

0 commit comments

Comments
 (0)