From c3ca9acf78552b5d748a8ba02a9dff74edb02cfb Mon Sep 17 00:00:00 2001 From: sobolevn Date: Fri, 28 Oct 2022 14:53:25 +0300 Subject: [PATCH 1/4] gh-98783: Fix crashes when `str` subclasses where used in `_PyUnicode_Equal` --- Include/cpython/unicodeobject.h | 2 +- Lib/test/test_descr.py | 19 +++++++++++++++++++ Lib/test/test_long.py | 12 ++++++++++++ ...2-10-28-14-52-55.gh-issue-98783.iG0kMs.rst | 2 ++ Objects/unicodeobject.c | 4 ++-- 5 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-10-28-14-52-55.gh-issue-98783.iG0kMs.rst diff --git a/Include/cpython/unicodeobject.h b/Include/cpython/unicodeobject.h index 3ca6ace24c5f74..8444507ade1b31 100644 --- a/Include/cpython/unicodeobject.h +++ b/Include/cpython/unicodeobject.h @@ -945,7 +945,7 @@ PyAPI_FUNC(PyObject*) _PyUnicode_FromId(_Py_Identifier*); and where the hash values are equal (i.e. a very probable match) */ PyAPI_FUNC(int) _PyUnicode_EQ(PyObject *, PyObject *); -/* Equality check. Returns -1 on failure. */ +/* Equality check. */ PyAPI_FUNC(int) _PyUnicode_Equal(PyObject *, PyObject *); PyAPI_FUNC(int) _PyUnicode_WideCharString_Converter(PyObject *, void *); diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 037c859e97d41b..4ba9d8c517f6cb 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -1317,6 +1317,15 @@ class X(object): with self.assertRaisesRegex(AttributeError, "'X' object has no attribute 'a'"): X().a + # Test string subclass in `__slots__`, see gh-98783 + class SubStr(str): + pass + class X(object): + __slots__ = (SubStr('x'),) + X().x = 1 + with self.assertRaisesRegex(AttributeError, "'X' object has no attribute 'a'"): + X().a + def test_slots_special(self): # Testing __dict__ and __weakref__ in __slots__... class D(object): @@ -3589,6 +3598,16 @@ def __repr__(self): self.assertEqual(o.__str__(), '41') self.assertEqual(o.__repr__(), 'A repr') + def test_repr_with_module_str_subclass(self): + # gh-98783 + class StrSub(str): + pass + class Some: + pass + Some.__module__ = StrSub('example') + self.assertEqual(repr(Some), type.__repr__(Some)) # should not crash + self.assertEqual(repr(Some()), Some().__repr__()) # should not crash + def test_keyword_arguments(self): # Testing keyword arguments to __init__, __call__... def f(a): return a diff --git a/Lib/test/test_long.py b/Lib/test/test_long.py index b6407b5a7c881e..77b37ca1fa4afe 100644 --- a/Lib/test/test_long.py +++ b/Lib/test/test_long.py @@ -1334,6 +1334,12 @@ def equivalent_python(n, length, byteorder, signed=False): b'\xff\xff\xff\xff\xff') self.assertRaises(OverflowError, (1).to_bytes, 0, 'big') + # gh-98783 + class SubStr(str): + pass + self.assertEqual((0).to_bytes(1, SubStr('big')), b'\x00') + self.assertEqual((0).to_bytes(0, SubStr('little')), b'') + def test_from_bytes(self): def check(tests, byteorder, signed=False): def equivalent_python(byte_array, byteorder, signed=False): @@ -1534,6 +1540,12 @@ def __bytes__(self): self.assertRaises(TypeError, int.from_bytes, MissingBytes()) self.assertRaises(ZeroDivisionError, int.from_bytes, RaisingBytes()) + # gh-98783 + class SubStr(str): + pass + self.assertEqual(int.from_bytes(b'', SubStr('big')), 0) + self.assertEqual(int.from_bytes(b'\x00', SubStr('little')), 0) + @support.cpython_only def test_from_bytes_small(self): # bpo-46361 diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-10-28-14-52-55.gh-issue-98783.iG0kMs.rst b/Misc/NEWS.d/next/Core and Builtins/2022-10-28-14-52-55.gh-issue-98783.iG0kMs.rst new file mode 100644 index 00000000000000..ad1a01ab8437b3 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-10-28-14-52-55.gh-issue-98783.iG0kMs.rst @@ -0,0 +1,2 @@ +Fix multiple crashes when ``str`` subclasses where used instead of ``str`` +itself. diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index d090915146f804..9dd0c42a0acda2 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -10444,8 +10444,8 @@ unicode_compare_eq(PyObject *str1, PyObject *str2) int _PyUnicode_Equal(PyObject *str1, PyObject *str2) { - assert(PyUnicode_CheckExact(str1)); - assert(PyUnicode_CheckExact(str2)); + assert(PyUnicode_Check(str1)); + assert(PyUnicode_Check(str2)); if (str1 == str2) { return 1; } From 401bc15969b8d0261f8e4a64645e7275a8fa10e1 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Fri, 28 Oct 2022 15:43:42 +0300 Subject: [PATCH 2/4] Fix CI --- Lib/test/test_descr.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 4ba9d8c517f6cb..40cf81ff0b33f5 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -3605,8 +3605,8 @@ class StrSub(str): class Some: pass Some.__module__ = StrSub('example') - self.assertEqual(repr(Some), type.__repr__(Some)) # should not crash - self.assertEqual(repr(Some()), Some().__repr__()) # should not crash + self.assertIsInstance(repr(Some), str) # should not crash + self.assertIsInstance(repr(Some()), str) # should not crash def test_keyword_arguments(self): # Testing keyword arguments to __init__, __call__... From d74bd3d32a24d5777d185da116ba6159bcb03be3 Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Fri, 28 Oct 2022 21:29:44 +0300 Subject: [PATCH 3/4] Update 2022-10-28-14-52-55.gh-issue-98783.iG0kMs.rst --- .../2022-10-28-14-52-55.gh-issue-98783.iG0kMs.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-10-28-14-52-55.gh-issue-98783.iG0kMs.rst b/Misc/NEWS.d/next/Core and Builtins/2022-10-28-14-52-55.gh-issue-98783.iG0kMs.rst index ad1a01ab8437b3..4a78335e2de05f 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2022-10-28-14-52-55.gh-issue-98783.iG0kMs.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2022-10-28-14-52-55.gh-issue-98783.iG0kMs.rst @@ -1,2 +1,2 @@ -Fix multiple crashes when ``str`` subclasses where used instead of ``str`` -itself. +Fix multiple crashes in debug mode when ``str`` subclasses +where used instead of ``str`` itself. From f9e8ea8f96ea28dd13f588623feea850629ead44 Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Sun, 30 Oct 2022 02:28:55 +0300 Subject: [PATCH 4/4] Update Misc/NEWS.d/next/Core and Builtins/2022-10-28-14-52-55.gh-issue-98783.iG0kMs.rst Co-authored-by: Dennis Sweeney <36520290+sweeneyde@users.noreply.github.com> --- .../2022-10-28-14-52-55.gh-issue-98783.iG0kMs.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-10-28-14-52-55.gh-issue-98783.iG0kMs.rst b/Misc/NEWS.d/next/Core and Builtins/2022-10-28-14-52-55.gh-issue-98783.iG0kMs.rst index 4a78335e2de05f..da1e61ea850472 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2022-10-28-14-52-55.gh-issue-98783.iG0kMs.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2022-10-28-14-52-55.gh-issue-98783.iG0kMs.rst @@ -1,2 +1,2 @@ Fix multiple crashes in debug mode when ``str`` subclasses -where used instead of ``str`` itself. +are used instead of ``str`` itself.