gh-98783: Fix crashes when `str` subclasses are used in `_PyUnicode_E… · python/cpython@76f989d · GitHub
Skip to content

Commit 76f989d

Browse files
authored
gh-98783: Fix crashes when str subclasses are used in _PyUnicode_Equal (#98806)
1 parent 3ac8c0a commit 76f989d

5 files changed

Lines changed: 36 additions & 3 deletions

File tree

Include/cpython/unicodeobject.h

Lines changed: 1 addition & 1 deletion

Lib/test/test_descr.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,6 +1317,15 @@ class X(object):
13171317
with self.assertRaisesRegex(AttributeError, "'X' object has no attribute 'a'"):
13181318
X().a
13191319

1320+
# Test string subclass in `__slots__`, see gh-98783
1321+
class SubStr(str):
1322+
pass
1323+
class X(object):
1324+
__slots__ = (SubStr('x'),)
1325+
X().x = 1
1326+
with self.assertRaisesRegex(AttributeError, "'X' object has no attribute 'a'"):
1327+
X().a
1328+
13201329
def test_slots_special(self):
13211330
# Testing __dict__ and __weakref__ in __slots__...
13221331
class D(object):
@@ -3589,6 +3598,16 @@ def __repr__(self):
35893598
self.assertEqual(o.__str__(), '41')
35903599
self.assertEqual(o.__repr__(), 'A repr')
35913600

3601+
def test_repr_with_module_str_subclass(self):
3602+
# gh-98783
3603+
class StrSub(str):
3604+
pass
3605+
class Some:
3606+
pass
3607+
Some.__module__ = StrSub('example')
3608+
self.assertIsInstance(repr(Some), str) # should not crash
3609+
self.assertIsInstance(repr(Some()), str) # should not crash
3610+
35923611
def test_keyword_arguments(self):
35933612
# Testing keyword arguments to __init__, __call__...
35943613
def f(a): return a

Lib/test/test_long.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,6 +1334,12 @@ def equivalent_python(n, length, byteorder, signed=False):
13341334
b'\xff\xff\xff\xff\xff')
13351335
self.assertRaises(OverflowError, (1).to_bytes, 0, 'big')
13361336

1337+
# gh-98783
1338+
class SubStr(str):
1339+
pass
1340+
self.assertEqual((0).to_bytes(1, SubStr('big')), b'\x00')
1341+
self.assertEqual((0).to_bytes(0, SubStr('little')), b'')
1342+
13371343
def test_from_bytes(self):
13381344
def check(tests, byteorder, signed=False):
13391345
def equivalent_python(byte_array, byteorder, signed=False):
@@ -1534,6 +1540,12 @@ def __bytes__(self):
15341540
self.assertRaises(TypeError, int.from_bytes, MissingBytes())
15351541
self.assertRaises(ZeroDivisionError, int.from_bytes, RaisingBytes())
15361542

1543+
# gh-98783
1544+
class SubStr(str):
1545+
pass
1546+
self.assertEqual(int.from_bytes(b'', SubStr('big')), 0)
1547+
self.assertEqual(int.from_bytes(b'\x00', SubStr('little')), 0)
1548+
15371549
@support.cpython_only
15381550
def test_from_bytes_small(self):
15391551
# bpo-46361
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix multiple crashes in debug mode when ``str`` subclasses
2+
are used instead of ``str`` itself.

Objects/unicodeobject.c

Lines changed: 2 additions & 2 deletions

0 commit comments

Comments
 (0)