diff options
author | Jelle Zijlstra <jelle.zijlstra@gmail.com> | 2024-08-12 16:20:09 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-12 16:20:09 (GMT) |
commit | 53ebb6232a8ebc03827cf2251bfc67f1886ffd70 (patch) | |
tree | dfe8046ed40d8ece6473caeb0d28b3b649f2e71e | |
parent | 7c22ab5b38a1350c976ef35453d9b3ab7a294812 (diff) | |
download | cpython-53ebb6232a8ebc03827cf2251bfc67f1886ffd70.zip cpython-53ebb6232a8ebc03827cf2251bfc67f1886ffd70.tar.gz cpython-53ebb6232a8ebc03827cf2251bfc67f1886ffd70.tar.bz2 |
gh-122888: Fix crash on certain calls to str() (#122889)
Fixes #122888
-rw-r--r-- | Lib/test/test_str.py | 43 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core_and_Builtins/2024-08-10-12-44-03.gh-issue-122888.TUyu9r.rst | 2 | ||||
-rw-r--r-- | Objects/unicodeobject.c | 11 |
3 files changed, 44 insertions, 12 deletions
diff --git a/Lib/test/test_str.py b/Lib/test/test_str.py index 7bdd288..b9ab137 100644 --- a/Lib/test/test_str.py +++ b/Lib/test/test_str.py @@ -1736,8 +1736,6 @@ class StrTest(string_tests.StringLikeTest, 'character buffers are decoded to unicode' ) - self.assertRaises(TypeError, str, 42, 42, 42) - def test_constructor_keyword_args(self): """Pass various keyword argument combinations to the constructor.""" # The object argument can be passed as a keyword. @@ -2652,22 +2650,45 @@ class StrTest(string_tests.StringLikeTest, self.assertEqual(proc.rc, 10, proc) def test_str_invalid_call(self): - check = lambda *a, **kw: self.assertRaises(TypeError, str, *a, **kw) - # too many args - check(1, "", "", 1) + with self.assertRaisesRegex(TypeError, r"str expected at most 3 arguments, got 4"): + str("too", "many", "argu", "ments") + with self.assertRaisesRegex(TypeError, r"str expected at most 3 arguments, got 4"): + str(1, "", "", 1) # no such kw arg - check(test=1) + with self.assertRaisesRegex(TypeError, r"str\(\) got an unexpected keyword argument 'test'"): + str(test=1) # 'encoding' must be str - check(1, encoding=1) - check(1, 1) + with self.assertRaisesRegex(TypeError, r"str\(\) argument 'encoding' must be str, not int"): + str(1, 1) + with self.assertRaisesRegex(TypeError, r"str\(\) argument 'encoding' must be str, not int"): + str(1, encoding=1) + with self.assertRaisesRegex(TypeError, r"str\(\) argument 'encoding' must be str, not bytes"): + str(b"x", b"ascii") + with self.assertRaisesRegex(TypeError, r"str\(\) argument 'encoding' must be str, not bytes"): + str(b"x", encoding=b"ascii") # 'errors' must be str - check(1, errors=1) - check(1, "", errors=1) - check(1, 1, 1) + with self.assertRaisesRegex(TypeError, r"str\(\) argument 'encoding' must be str, not int"): + str(1, 1, 1) + with self.assertRaisesRegex(TypeError, r"str\(\) argument 'errors' must be str, not int"): + str(1, errors=1) + with self.assertRaisesRegex(TypeError, r"str\(\) argument 'errors' must be str, not int"): + str(1, "", errors=1) + with self.assertRaisesRegex(TypeError, r"str\(\) argument 'errors' must be str, not bytes"): + str(b"x", "ascii", b"strict") + with self.assertRaisesRegex(TypeError, r"str\(\) argument 'errors' must be str, not bytes"): + str(b"x", "ascii", errors=b"strict") + + # both positional and kwarg + with self.assertRaisesRegex(TypeError, r"argument for str\(\) given by name \('encoding'\) and position \(2\)"): + str(b"x", "utf-8", encoding="ascii") + with self.assertRaisesRegex(TypeError, r"str\(\) takes at most 3 arguments \(4 given\)"): + str(b"x", "utf-8", "ignore", encoding="ascii") + with self.assertRaisesRegex(TypeError, r"str\(\) takes at most 3 arguments \(4 given\)"): + str(b"x", "utf-8", "strict", errors="ignore") class StringModuleTest(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-10-12-44-03.gh-issue-122888.TUyu9r.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-08-10-12-44-03.gh-issue-122888.TUyu9r.rst new file mode 100644 index 0000000..9317136 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-08-10-12-44-03.gh-issue-122888.TUyu9r.rst @@ -0,0 +1,2 @@ +Fix crash on certain calls to ``str()`` with positional arguments of the +wrong type. Patch by Jelle Zijlstra. diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 1257881..da9c585 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -15121,7 +15121,16 @@ unicode_vectorcall(PyObject *type, PyObject *const *args, return PyObject_Str(object); } const char *encoding = arg_as_utf8(args[1], "encoding"); - const char *errors = (nargs == 3) ? arg_as_utf8(args[2], "errors") : NULL; + if (encoding == NULL) { + return NULL; + } + const char *errors = NULL; + if (nargs == 3) { + errors = arg_as_utf8(args[2], "errors"); + if (errors == NULL) { + return NULL; + } + } return PyUnicode_FromEncodedObject(object, encoding, errors); } |