Skip to content

Commit cd778b4

Browse files
[3.12] gh-111495: Test C API functions with extreme sizes and indices (GH-111631) (GH-111731)
(cherry picked from commit a8e1f47)
1 parent 3b839cc commit cd778b4

File tree

4 files changed

+130
-41
lines changed

4 files changed

+130
-41
lines changed

Lib/test/test_capi/test_abstract.py

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import unittest
22
import sys
33
from collections import OrderedDict
4-
from test import support
54
from test.support import import_helper
6-
import _testcapi
75

6+
_testcapi = import_helper.import_module('_testcapi')
7+
from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX
88

99
NULL = None
1010

@@ -446,6 +446,8 @@ def test_sequence_getitem(self):
446446
self.assertEqual(getitem(lst, 1), 'b')
447447
self.assertEqual(getitem(lst, -1), 'c')
448448
self.assertRaises(IndexError, getitem, lst, 3)
449+
self.assertRaises(IndexError, getitem, lst, PY_SSIZE_T_MAX)
450+
self.assertRaises(IndexError, getitem, lst, PY_SSIZE_T_MIN)
449451

450452
self.assertRaises(TypeError, getitem, 42, 1)
451453
self.assertRaises(TypeError, getitem, {}, 1)
@@ -470,6 +472,9 @@ def test_sequence_repeat(self):
470472
self.assertEqual(repeat(('a', 'b'), 2), ('a', 'b', 'a', 'b'))
471473
self.assertEqual(repeat(['a', 'b'], 0), [])
472474
self.assertEqual(repeat(['a', 'b'], -1), [])
475+
self.assertEqual(repeat(['a', 'b'], PY_SSIZE_T_MIN), [])
476+
self.assertEqual(repeat([], PY_SSIZE_T_MAX), [])
477+
self.assertRaises(MemoryError, repeat, ['a', 'b'], PY_SSIZE_T_MAX)
473478

474479
self.assertRaises(TypeError, repeat, set(), 2)
475480
self.assertRaises(TypeError, repeat, 42, 2)
@@ -503,6 +508,9 @@ def test_sequence_inplacerepeat(self):
503508
self.assertEqual(inplacerepeat(('a', 'b'), 2), ('a', 'b', 'a', 'b'))
504509
self.assertEqual(inplacerepeat(['a', 'b'], 0), [])
505510
self.assertEqual(inplacerepeat(['a', 'b'], -1), [])
511+
self.assertEqual(inplacerepeat(['a', 'b'], PY_SSIZE_T_MIN), [])
512+
self.assertEqual(inplacerepeat([], PY_SSIZE_T_MAX), [])
513+
self.assertRaises(MemoryError, inplacerepeat, ['a', 'b'], PY_SSIZE_T_MAX)
506514

507515
self.assertRaises(TypeError, inplacerepeat, set(), 2)
508516
self.assertRaises(TypeError, inplacerepeat, 42, 2)
@@ -519,6 +527,8 @@ def test_sequence_setitem(self):
519527
setitem(lst, 0, NULL)
520528
self.assertEqual(lst, ['x', 'y'])
521529
self.assertRaises(IndexError, setitem, lst, 3, 'x')
530+
self.assertRaises(IndexError, setitem, lst, PY_SSIZE_T_MAX, 'x')
531+
self.assertRaises(IndexError, setitem, lst, PY_SSIZE_T_MIN, 'x')
522532

523533
self.assertRaises(TypeError, setitem, 42, 1, 'x')
524534
self.assertRaises(TypeError, setitem, {}, 1, 'x')
@@ -532,6 +542,8 @@ def test_sequence_delitem(self):
532542
delitem(lst, -1)
533543
self.assertEqual(lst, ['a'])
534544
self.assertRaises(IndexError, delitem, lst, 3)
545+
self.assertRaises(IndexError, delitem, lst, PY_SSIZE_T_MAX)
546+
self.assertRaises(IndexError, delitem, lst, PY_SSIZE_T_MIN)
535547

536548
self.assertRaises(TypeError, delitem, 42, 1)
537549
self.assertRaises(TypeError, delitem, {}, 1)
@@ -541,13 +553,19 @@ def test_sequence_setslice(self):
541553
setslice = _testcapi.sequence_setslice
542554

543555
# Correct case:
544-
data = [1, 2, 3, 4, 5]
545-
data_copy = data.copy()
546-
547-
setslice(data, 1, 3, [8, 9])
548-
data_copy[1:3] = [8, 9]
549-
self.assertEqual(data, data_copy)
550-
self.assertEqual(data, [1, 8, 9, 4, 5])
556+
for start in [*range(-6, 7), PY_SSIZE_T_MIN, PY_SSIZE_T_MAX]:
557+
for stop in [*range(-6, 7), PY_SSIZE_T_MIN, PY_SSIZE_T_MAX]:
558+
data = [1, 2, 3, 4, 5]
559+
data_copy = [1, 2, 3, 4, 5]
560+
setslice(data, start, stop, [8, 9])
561+
data_copy[start:stop] = [8, 9]
562+
self.assertEqual(data, data_copy)
563+
564+
data = [1, 2, 3, 4, 5]
565+
data_copy = [1, 2, 3, 4, 5]
566+
setslice(data, start, stop, NULL)
567+
del data_copy[start:stop]
568+
self.assertEqual(data, data_copy)
551569

552570
# Custom class:
553571
class Custom:
@@ -573,21 +591,17 @@ def __setitem__(self, index, value):
573591
self.assertRaises(TypeError, setslice, object(), 1, 3, 'xy')
574592
self.assertRaises(SystemError, setslice, NULL, 1, 3, 'xy')
575593

576-
data_copy = data.copy()
577-
setslice(data_copy, 1, 3, NULL)
578-
self.assertEqual(data_copy, [1, 4, 5])
579-
580594
def test_sequence_delslice(self):
581595
delslice = _testcapi.sequence_delslice
582596

583597
# Correct case:
584-
data = [1, 2, 3, 4, 5]
585-
data_copy = data.copy()
586-
587-
delslice(data, 1, 3)
588-
del data_copy[1:3]
589-
self.assertEqual(data, data_copy)
590-
self.assertEqual(data, [1, 4, 5])
598+
for start in [*range(-6, 7), PY_SSIZE_T_MIN, PY_SSIZE_T_MAX]:
599+
for stop in [*range(-6, 7), PY_SSIZE_T_MIN, PY_SSIZE_T_MAX]:
600+
data = [1, 2, 3, 4, 5]
601+
data_copy = [1, 2, 3, 4, 5]
602+
delslice(data, start, stop)
603+
del data_copy[start:stop]
604+
self.assertEqual(data, data_copy)
591605

592606
# Custom class:
593607
class Custom:

Lib/test/test_capi/test_bytearray.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import unittest
2-
import sys
32
from test.support import import_helper
43

54
_testcapi = import_helper.import_module('_testcapi')
5+
from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX
66

77
NULL = None
88

@@ -53,10 +53,12 @@ def test_fromstringandsize(self):
5353
self.assertEqual(fromstringandsize(b'', 0), bytearray())
5454
self.assertEqual(fromstringandsize(NULL, 0), bytearray())
5555
self.assertEqual(len(fromstringandsize(NULL, 3)), 3)
56-
self.assertRaises(MemoryError, fromstringandsize, NULL, sys.maxsize)
56+
self.assertRaises(MemoryError, fromstringandsize, NULL, PY_SSIZE_T_MAX)
5757

5858
self.assertRaises(SystemError, fromstringandsize, b'abc', -1)
59+
self.assertRaises(SystemError, fromstringandsize, b'abc', PY_SSIZE_T_MIN)
5960
self.assertRaises(SystemError, fromstringandsize, NULL, -1)
61+
self.assertRaises(SystemError, fromstringandsize, NULL, PY_SSIZE_T_MIN)
6062

6163
def test_fromobject(self):
6264
# Test PyByteArray_FromObject()
@@ -149,8 +151,8 @@ def test_resize(self):
149151
self.assertEqual(resize(ba, 3), 0)
150152
self.assertEqual(ba, bytearray(b'abc'))
151153

152-
self.assertRaises(MemoryError, resize, bytearray(), sys.maxsize)
153-
self.assertRaises(MemoryError, resize, bytearray(1000), sys.maxsize)
154+
self.assertRaises(MemoryError, resize, bytearray(), PY_SSIZE_T_MAX)
155+
self.assertRaises(MemoryError, resize, bytearray(1000), PY_SSIZE_T_MAX)
154156

155157
# CRASHES resize(bytearray(b'abc'), -1)
156158
# CRASHES resize(b'abc', 0)

Lib/test/test_capi/test_bytes.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import unittest
2-
import sys
32
from test.support import import_helper
43

54
_testcapi = import_helper.import_module('_testcapi')
5+
from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX
66

77
NULL = None
88

@@ -55,10 +55,13 @@ def test_fromstringandsize(self):
5555
self.assertEqual(fromstringandsize(b'', 0), b'')
5656
self.assertEqual(fromstringandsize(NULL, 0), b'')
5757
self.assertEqual(len(fromstringandsize(NULL, 3)), 3)
58-
self.assertRaises((MemoryError, OverflowError), fromstringandsize, NULL, sys.maxsize)
58+
self.assertRaises((MemoryError, OverflowError),
59+
fromstringandsize, NULL, PY_SSIZE_T_MAX)
5960

6061
self.assertRaises(SystemError, fromstringandsize, b'abc', -1)
62+
self.assertRaises(SystemError, fromstringandsize, b'abc', PY_SSIZE_T_MIN)
6163
self.assertRaises(SystemError, fromstringandsize, NULL, -1)
64+
self.assertRaises(SystemError, fromstringandsize, NULL, PY_SSIZE_T_MIN)
6265

6366
def test_fromstring(self):
6467
# Test PyBytes_FromString()
@@ -208,7 +211,10 @@ def test_decodeescape(self):
208211
self.assertEqual(decodeescape(br'x\xa\xy', 'ignore'), b'xy')
209212
self.assertRaises(ValueError, decodeescape, b'\\', 'spam')
210213
self.assertEqual(decodeescape(NULL), b'')
214+
self.assertRaises(OverflowError, decodeescape, b'abc', NULL, PY_SSIZE_T_MAX)
215+
self.assertRaises(OverflowError, decodeescape, NULL, NULL, PY_SSIZE_T_MAX)
211216

217+
# CRASHES decodeescape(b'abc', NULL, -1)
212218
# CRASHES decodeescape(NULL, NULL, 1)
213219

214220

0 commit comments

Comments
 (0)