gh-111495: Test C API functions with extreme sizes and indices (GH-111631)

diff --git a/Lib/test/test_capi/test_abstract.py b/Lib/test/test_capi/test_abstract.py
index 687ce1e..5b5dfb3 100644
--- a/Lib/test/test_capi/test_abstract.py
+++ b/Lib/test/test_capi/test_abstract.py
@@ -1,7 +1,9 @@
 import unittest
 from collections import OrderedDict
-import _testcapi
+from test.support import import_helper
 
+_testcapi = import_helper.import_module('_testcapi')
+from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX
 
 NULL = None
 
@@ -574,6 +576,8 @@ def test_sequence_getitem(self):
         self.assertEqual(getitem(lst, 1), 'b')
         self.assertEqual(getitem(lst, -1), 'c')
         self.assertRaises(IndexError, getitem, lst, 3)
+        self.assertRaises(IndexError, getitem, lst, PY_SSIZE_T_MAX)
+        self.assertRaises(IndexError, getitem, lst, PY_SSIZE_T_MIN)
 
         self.assertRaises(TypeError, getitem, 42, 1)
         self.assertRaises(TypeError, getitem, {}, 1)
@@ -598,6 +602,9 @@ def test_sequence_repeat(self):
         self.assertEqual(repeat(('a', 'b'), 2), ('a', 'b', 'a', 'b'))
         self.assertEqual(repeat(['a', 'b'], 0), [])
         self.assertEqual(repeat(['a', 'b'], -1), [])
+        self.assertEqual(repeat(['a', 'b'], PY_SSIZE_T_MIN), [])
+        self.assertEqual(repeat([], PY_SSIZE_T_MAX), [])
+        self.assertRaises(MemoryError, repeat, ['a', 'b'], PY_SSIZE_T_MAX)
 
         self.assertRaises(TypeError, repeat, set(), 2)
         self.assertRaises(TypeError, repeat, 42, 2)
@@ -631,6 +638,9 @@ def test_sequence_inplacerepeat(self):
         self.assertEqual(inplacerepeat(('a', 'b'), 2), ('a', 'b', 'a', 'b'))
         self.assertEqual(inplacerepeat(['a', 'b'], 0), [])
         self.assertEqual(inplacerepeat(['a', 'b'], -1), [])
+        self.assertEqual(inplacerepeat(['a', 'b'], PY_SSIZE_T_MIN), [])
+        self.assertEqual(inplacerepeat([], PY_SSIZE_T_MAX), [])
+        self.assertRaises(MemoryError, inplacerepeat, ['a', 'b'], PY_SSIZE_T_MAX)
 
         self.assertRaises(TypeError, inplacerepeat, set(), 2)
         self.assertRaises(TypeError, inplacerepeat, 42, 2)
@@ -647,6 +657,8 @@ def test_sequence_setitem(self):
         setitem(lst, 0, NULL)
         self.assertEqual(lst, ['x', 'y'])
         self.assertRaises(IndexError, setitem, lst, 3, 'x')
+        self.assertRaises(IndexError, setitem, lst, PY_SSIZE_T_MAX, 'x')
+        self.assertRaises(IndexError, setitem, lst, PY_SSIZE_T_MIN, 'x')
 
         self.assertRaises(TypeError, setitem, 42, 1, 'x')
         self.assertRaises(TypeError, setitem, {}, 1, 'x')
@@ -660,6 +672,8 @@ def test_sequence_delitem(self):
         delitem(lst, -1)
         self.assertEqual(lst, ['a'])
         self.assertRaises(IndexError, delitem, lst, 3)
+        self.assertRaises(IndexError, delitem, lst, PY_SSIZE_T_MAX)
+        self.assertRaises(IndexError, delitem, lst, PY_SSIZE_T_MIN)
 
         self.assertRaises(TypeError, delitem, 42, 1)
         self.assertRaises(TypeError, delitem, {}, 1)
@@ -669,13 +683,19 @@ def test_sequence_setslice(self):
         setslice = _testcapi.sequence_setslice
 
         # Correct case:
-        data = [1, 2, 3, 4, 5]
-        data_copy = data.copy()
+        for start in [*range(-6, 7), PY_SSIZE_T_MIN, PY_SSIZE_T_MAX]:
+            for stop in [*range(-6, 7), PY_SSIZE_T_MIN, PY_SSIZE_T_MAX]:
+                data = [1, 2, 3, 4, 5]
+                data_copy = [1, 2, 3, 4, 5]
+                setslice(data, start, stop, [8, 9])
+                data_copy[start:stop] = [8, 9]
+                self.assertEqual(data, data_copy)
 
-        setslice(data, 1, 3, [8, 9])
-        data_copy[1:3] = [8, 9]
-        self.assertEqual(data, data_copy)
-        self.assertEqual(data, [1, 8, 9, 4, 5])
+                data = [1, 2, 3, 4, 5]
+                data_copy = [1, 2, 3, 4, 5]
+                setslice(data, start, stop, NULL)
+                del data_copy[start:stop]
+                self.assertEqual(data, data_copy)
 
         # Custom class:
         class Custom:
@@ -701,21 +721,17 @@ def __setitem__(self, index, value):
         self.assertRaises(TypeError, setslice, object(), 1, 3, 'xy')
         self.assertRaises(SystemError, setslice, NULL, 1, 3, 'xy')
 
-        data_copy = data.copy()
-        setslice(data_copy, 1, 3, NULL)
-        self.assertEqual(data_copy, [1, 4, 5])
-
     def test_sequence_delslice(self):
         delslice = _testcapi.sequence_delslice
 
         # Correct case:
-        data = [1, 2, 3, 4, 5]
-        data_copy = data.copy()
-
-        delslice(data, 1, 3)
-        del data_copy[1:3]
-        self.assertEqual(data, data_copy)
-        self.assertEqual(data, [1, 4, 5])
+        for start in [*range(-6, 7), PY_SSIZE_T_MIN, PY_SSIZE_T_MAX]:
+            for stop in [*range(-6, 7), PY_SSIZE_T_MIN, PY_SSIZE_T_MAX]:
+                data = [1, 2, 3, 4, 5]
+                data_copy = [1, 2, 3, 4, 5]
+                delslice(data, start, stop)
+                del data_copy[start:stop]
+                self.assertEqual(data, data_copy)
 
         # Custom class:
         class Custom:
diff --git a/Lib/test/test_capi/test_bytearray.py b/Lib/test/test_capi/test_bytearray.py
index 6a0f313..833122c 100644
--- a/Lib/test/test_capi/test_bytearray.py
+++ b/Lib/test/test_capi/test_bytearray.py
@@ -1,8 +1,8 @@
 import unittest
-import sys
 from test.support import import_helper
 
 _testcapi = import_helper.import_module('_testcapi')
+from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX
 
 NULL = None
 
@@ -53,10 +53,12 @@ def test_fromstringandsize(self):
         self.assertEqual(fromstringandsize(b'', 0), bytearray())
         self.assertEqual(fromstringandsize(NULL, 0), bytearray())
         self.assertEqual(len(fromstringandsize(NULL, 3)), 3)
-        self.assertRaises(MemoryError, fromstringandsize, NULL, sys.maxsize)
+        self.assertRaises(MemoryError, fromstringandsize, NULL, PY_SSIZE_T_MAX)
 
         self.assertRaises(SystemError, fromstringandsize, b'abc', -1)
+        self.assertRaises(SystemError, fromstringandsize, b'abc', PY_SSIZE_T_MIN)
         self.assertRaises(SystemError, fromstringandsize, NULL, -1)
+        self.assertRaises(SystemError, fromstringandsize, NULL, PY_SSIZE_T_MIN)
 
     def test_fromobject(self):
         # Test PyByteArray_FromObject()
@@ -149,8 +151,8 @@ def test_resize(self):
         self.assertEqual(resize(ba, 3), 0)
         self.assertEqual(ba, bytearray(b'abc'))
 
-        self.assertRaises(MemoryError, resize, bytearray(), sys.maxsize)
-        self.assertRaises(MemoryError, resize, bytearray(1000), sys.maxsize)
+        self.assertRaises(MemoryError, resize, bytearray(), PY_SSIZE_T_MAX)
+        self.assertRaises(MemoryError, resize, bytearray(1000), PY_SSIZE_T_MAX)
 
         # CRASHES resize(bytearray(b'abc'), -1)
         # CRASHES resize(b'abc', 0)
diff --git a/Lib/test/test_capi/test_bytes.py b/Lib/test/test_capi/test_bytes.py
index e366578..bb5d724 100644
--- a/Lib/test/test_capi/test_bytes.py
+++ b/Lib/test/test_capi/test_bytes.py
@@ -1,8 +1,8 @@
 import unittest
-import sys
 from test.support import import_helper
 
 _testcapi = import_helper.import_module('_testcapi')
+from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX
 
 NULL = None
 
@@ -55,10 +55,13 @@ def test_fromstringandsize(self):
         self.assertEqual(fromstringandsize(b'', 0), b'')
         self.assertEqual(fromstringandsize(NULL, 0), b'')
         self.assertEqual(len(fromstringandsize(NULL, 3)), 3)
-        self.assertRaises((MemoryError, OverflowError), fromstringandsize, NULL, sys.maxsize)
+        self.assertRaises((MemoryError, OverflowError),
+                          fromstringandsize, NULL, PY_SSIZE_T_MAX)
 
         self.assertRaises(SystemError, fromstringandsize, b'abc', -1)
+        self.assertRaises(SystemError, fromstringandsize, b'abc', PY_SSIZE_T_MIN)
         self.assertRaises(SystemError, fromstringandsize, NULL, -1)
+        self.assertRaises(SystemError, fromstringandsize, NULL, PY_SSIZE_T_MIN)
 
     def test_fromstring(self):
         # Test PyBytes_FromString()
@@ -208,7 +211,10 @@ def test_decodeescape(self):
         self.assertEqual(decodeescape(br'x\xa\xy', 'ignore'), b'xy')
         self.assertRaises(ValueError, decodeescape, b'\\', 'spam')
         self.assertEqual(decodeescape(NULL), b'')
+        self.assertRaises(OverflowError, decodeescape, b'abc', NULL, PY_SSIZE_T_MAX)
+        self.assertRaises(OverflowError, decodeescape, NULL, NULL, PY_SSIZE_T_MAX)
 
+        # CRASHES decodeescape(b'abc', NULL, -1)
         # CRASHES decodeescape(NULL, NULL, 1)
 
 
diff --git a/Lib/test/test_capi/test_unicode.py b/Lib/test/test_capi/test_unicode.py
index 63e51eb..d853724 100644
--- a/Lib/test/test_capi/test_unicode.py
+++ b/Lib/test/test_capi/test_unicode.py
@@ -5,6 +5,7 @@
 
 try:
     import _testcapi
+    from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX
 except ImportError:
     _testcapi = None
 try:
@@ -30,9 +31,17 @@ def test_new(self):
         for maxchar in 0, 0x61, 0xa1, 0x4f60, 0x1f600, 0x10ffff:
             self.assertEqual(new(0, maxchar), '')
             self.assertEqual(new(5, maxchar), chr(maxchar)*5)
+            self.assertRaises(MemoryError, new, PY_SSIZE_T_MAX, maxchar)
         self.assertEqual(new(0, 0x110000), '')
+        self.assertRaises(MemoryError, new, PY_SSIZE_T_MAX//2, 0x4f60)
+        self.assertRaises(MemoryError, new, PY_SSIZE_T_MAX//2+1, 0x4f60)
+        self.assertRaises(MemoryError, new, PY_SSIZE_T_MAX//2, 0x1f600)
+        self.assertRaises(MemoryError, new, PY_SSIZE_T_MAX//2+1, 0x1f600)
+        self.assertRaises(MemoryError, new, PY_SSIZE_T_MAX//4, 0x1f600)
+        self.assertRaises(MemoryError, new, PY_SSIZE_T_MAX//4+1, 0x1f600)
         self.assertRaises(SystemError, new, 5, 0x110000)
         self.assertRaises(SystemError, new, -1, 0)
+        self.assertRaises(SystemError, new, PY_SSIZE_T_MIN, 0)
 
     @support.cpython_only
     @unittest.skipIf(_testcapi is None, 'need _testcapi module')
@@ -53,8 +62,8 @@ def test_fill(self):
             for to in strings[:idx]:
                 self.assertRaises(ValueError, fill, to, 0, 0, fill_char)
             for to in strings[idx:]:
-                for start in range(7):
-                    for length in range(-1, 7 - start):
+                for start in [*range(7), PY_SSIZE_T_MAX]:
+                    for length in [*range(-1, 7 - start), PY_SSIZE_T_MIN, PY_SSIZE_T_MAX]:
                         filled = max(min(length, 5 - start), 0)
                         if filled == 5 and to != strings[idx]:
                             # narrow -> wide
@@ -66,6 +75,7 @@ def test_fill(self):
 
         s = strings[0]
         self.assertRaises(IndexError, fill, s, -1, 0, 0x78)
+        self.assertRaises(IndexError, fill, s, PY_SSIZE_T_MIN, 0, 0x78)
         self.assertRaises(ValueError, fill, s, 0, 0, 0x110000)
         self.assertRaises(SystemError, fill, b'abc', 0, 0, 0x78)
         self.assertRaises(SystemError, fill, [], 0, 0, 0x78)
@@ -76,7 +86,7 @@ def test_fill(self):
     @support.cpython_only
     @unittest.skipIf(_testcapi is None, 'need _testcapi module')
     def test_writechar(self):
-        """Test PyUnicode_ReadChar()"""
+        """Test PyUnicode_WriteChar()"""
         from _testcapi import unicode_writechar as writechar
 
         strings = [
@@ -96,10 +106,12 @@ def test_writechar(self):
 
         self.assertRaises(IndexError, writechar, 'abc', 3, 0x78)
         self.assertRaises(IndexError, writechar, 'abc', -1, 0x78)
+        self.assertRaises(IndexError, writechar, 'abc', PY_SSIZE_T_MAX, 0x78)
+        self.assertRaises(IndexError, writechar, 'abc', PY_SSIZE_T_MIN, 0x78)
         self.assertRaises(TypeError, writechar, b'abc', 0, 0x78)
         self.assertRaises(TypeError, writechar, [], 0, 0x78)
         # CRASHES writechar(NULL, 0, 0x78)
-        # TODO: Test PyUnicode_CopyCharacters() with non-modifiable and legacy
+        # TODO: Test PyUnicode_WriteChar() with non-modifiable and legacy
         # unicode.
 
     @support.cpython_only
@@ -117,7 +129,11 @@ def test_resize(self):
             self.assertEqual(resize(s, 3), (s, 0))
             self.assertEqual(resize(s, 2), (s[:2], 0))
             self.assertEqual(resize(s, 4), (s + '\0', 0))
+            self.assertEqual(resize(s, 10), (s + '\0'*7, 0))
             self.assertEqual(resize(s, 0), ('', 0))
+            self.assertRaises(MemoryError, resize, s, PY_SSIZE_T_MAX)
+            self.assertRaises(SystemError, resize, s, -1)
+            self.assertRaises(SystemError, resize, s, PY_SSIZE_T_MIN)
         self.assertRaises(SystemError, resize, b'abc', 0)
         self.assertRaises(SystemError, resize, [], 0)
         self.assertRaises(SystemError, resize, NULL, 0)
@@ -196,10 +212,13 @@ def test_fromstringandsize(self):
         self.assertEqual(fromstringandsize(b'', 0), '')
         self.assertEqual(fromstringandsize(NULL, 0), '')
 
+        self.assertRaises(MemoryError, fromstringandsize, b'abc', PY_SSIZE_T_MAX)
         self.assertRaises(SystemError, fromstringandsize, b'abc', -1)
+        self.assertRaises(SystemError, fromstringandsize, b'abc', PY_SSIZE_T_MIN)
         self.assertRaises(SystemError, fromstringandsize, NULL, -1)
+        self.assertRaises(SystemError, fromstringandsize, NULL, PY_SSIZE_T_MIN)
         self.assertRaises(SystemError, fromstringandsize, NULL, 3)
-        self.assertRaises(SystemError, fromstringandsize, NULL, sys.maxsize)
+        self.assertRaises(SystemError, fromstringandsize, NULL, PY_SSIZE_T_MAX)
 
     @support.cpython_only
     @unittest.skipIf(_testcapi is None, 'need _testcapi module')
@@ -247,7 +266,9 @@ def test_fromkindanddata(self):
         for kind in -1, 0, 3, 5, 8:
             self.assertRaises(SystemError, fromkindanddata, kind, b'')
         self.assertRaises(ValueError, fromkindanddata, 1, b'abc', -1)
+        self.assertRaises(ValueError, fromkindanddata, 1, b'abc', PY_SSIZE_T_MIN)
         self.assertRaises(ValueError, fromkindanddata, 1, NULL, -1)
+        self.assertRaises(ValueError, fromkindanddata, 1, NULL, PY_SSIZE_T_MIN)
         # CRASHES fromkindanddata(1, NULL, 1)
         # CRASHES fromkindanddata(4, b'\xff\xff\xff\xff')
 
@@ -263,12 +284,14 @@ def test_substring(self):
             'ab\xa1\xa2\u4f60\u597d\U0001f600\U0001f601'
         ]
         for s in strings:
-            for start in range(0, len(s) + 2):
-                for end in range(max(start-1, 0), len(s) + 2):
+            for start in [*range(0, len(s) + 2), PY_SSIZE_T_MAX]:
+                for end in [*range(max(start-1, 0), len(s) + 2), PY_SSIZE_T_MAX]:
                     self.assertEqual(substring(s, start, end), s[start:end])
 
         self.assertRaises(IndexError, substring, 'abc', -1, 0)
+        self.assertRaises(IndexError, substring, 'abc', PY_SSIZE_T_MIN, 0)
         self.assertRaises(IndexError, substring, 'abc', 0, -1)
+        self.assertRaises(IndexError, substring, 'abc', 0, PY_SSIZE_T_MIN)
         # CRASHES substring(b'abc', 0, 0)
         # CRASHES substring([], 0, 0)
         # CRASHES substring(NULL, 0, 0)
@@ -298,7 +321,9 @@ def test_readchar(self):
             for i, c in enumerate(s):
                 self.assertEqual(readchar(s, i), ord(c))
             self.assertRaises(IndexError, readchar, s, len(s))
+            self.assertRaises(IndexError, readchar, s, PY_SSIZE_T_MAX)
             self.assertRaises(IndexError, readchar, s, -1)
+            self.assertRaises(IndexError, readchar, s, PY_SSIZE_T_MIN)
 
         self.assertRaises(TypeError, readchar, b'abc', 0)
         self.assertRaises(TypeError, readchar, [], 0)
@@ -733,10 +758,15 @@ def test_fromwidechar(self):
         if SIZEOF_WCHAR_T == 2:
             self.assertEqual(fromwidechar('a\U0001f600'.encode(encoding), 2), 'a\ud83d')
 
+        self.assertRaises(MemoryError, fromwidechar, b'', PY_SSIZE_T_MAX)
         self.assertRaises(SystemError, fromwidechar, b'\0'*SIZEOF_WCHAR_T, -2)
+        self.assertRaises(SystemError, fromwidechar, b'\0'*SIZEOF_WCHAR_T, PY_SSIZE_T_MIN)
         self.assertEqual(fromwidechar(NULL, 0), '')
         self.assertRaises(SystemError, fromwidechar, NULL, 1)
+        self.assertRaises(SystemError, fromwidechar, NULL, PY_SSIZE_T_MAX)
         self.assertRaises(SystemError, fromwidechar, NULL, -1)
+        self.assertRaises(SystemError, fromwidechar, NULL, -2)
+        self.assertRaises(SystemError, fromwidechar, NULL, PY_SSIZE_T_MIN)
 
     @support.cpython_only
     @unittest.skipIf(_testcapi is None, 'need _testcapi module')
@@ -974,6 +1004,11 @@ def test_split(self):
 
         self.assertEqual(split('a|b|c|d', '|'), ['a', 'b', 'c', 'd'])
         self.assertEqual(split('a|b|c|d', '|', 2), ['a', 'b', 'c|d'])
+        self.assertEqual(split('a|b|c|d', '|', PY_SSIZE_T_MAX),
+                         ['a', 'b', 'c', 'd'])
+        self.assertEqual(split('a|b|c|d', '|', -1), ['a', 'b', 'c', 'd'])
+        self.assertEqual(split('a|b|c|d', '|', PY_SSIZE_T_MIN),
+                         ['a', 'b', 'c', 'd'])
         self.assertEqual(split('a|b|c|d', '\u20ac'), ['a|b|c|d'])
         self.assertEqual(split('a||b|c||d', '||'), ['a', 'b|c', 'd'])
         self.assertEqual(split('а|б|в|г', '|'), ['а', 'б', 'в', 'г'])
@@ -997,6 +1032,11 @@ def test_rsplit(self):
 
         self.assertEqual(rsplit('a|b|c|d', '|'), ['a', 'b', 'c', 'd'])
         self.assertEqual(rsplit('a|b|c|d', '|', 2), ['a|b', 'c', 'd'])
+        self.assertEqual(rsplit('a|b|c|d', '|', PY_SSIZE_T_MAX),
+                         ['a', 'b', 'c', 'd'])
+        self.assertEqual(rsplit('a|b|c|d', '|', -1), ['a', 'b', 'c', 'd'])
+        self.assertEqual(rsplit('a|b|c|d', '|', PY_SSIZE_T_MIN),
+                         ['a', 'b', 'c', 'd'])
         self.assertEqual(rsplit('a|b|c|d', '\u20ac'), ['a|b|c|d'])
         self.assertEqual(rsplit('a||b|c||d', '||'), ['a', 'b|c', 'd'])
         self.assertEqual(rsplit('а|б|в|г', '|'), ['а', 'б', 'в', 'г'])
@@ -1129,11 +1169,14 @@ def test_count(self):
         self.assertEqual(unicode_count(str, '', 0, len(str)), len(str)+1)
         # start < end
         self.assertEqual(unicode_count(str, '!', 1, len(str)+1), 1)
+        self.assertEqual(unicode_count(str, '!', 1, PY_SSIZE_T_MAX), 1)
         # start >= end
         self.assertEqual(unicode_count(str, '!', 0, 0), 0)
         self.assertEqual(unicode_count(str, '!', len(str), 0), 0)
         # negative
         self.assertEqual(unicode_count(str, '!', -len(str), -1), 1)
+        self.assertEqual(unicode_count(str, '!', -len(str)-1, -1), 1)
+        self.assertEqual(unicode_count(str, '!', PY_SSIZE_T_MIN, -1), 1)
         # bad arguments
         self.assertRaises(TypeError, unicode_count, str, b'!', 0, len(str))
         self.assertRaises(TypeError, unicode_count, b"!>_<!", '!', 0, len(str))
@@ -1152,11 +1195,11 @@ def test_tailmatch(self):
         self.assertEqual(tailmatch(str, 'aba', 0, len(str), -1), 1)
         self.assertEqual(tailmatch(str, 'aha', 0, len(str), 1), 1)
 
-        self.assertEqual(tailmatch(str, 'aba', 0, sys.maxsize, -1), 1)
-        self.assertEqual(tailmatch(str, 'aba', -len(str), sys.maxsize, -1), 1)
-        self.assertEqual(tailmatch(str, 'aba', -sys.maxsize-1, len(str), -1), 1)
-        self.assertEqual(tailmatch(str, 'aha', 0, sys.maxsize, 1), 1)
-        self.assertEqual(tailmatch(str, 'aha', -sys.maxsize-1, len(str), 1), 1)
+        self.assertEqual(tailmatch(str, 'aba', 0, PY_SSIZE_T_MAX, -1), 1)
+        self.assertEqual(tailmatch(str, 'aba', -len(str), PY_SSIZE_T_MAX, -1), 1)
+        self.assertEqual(tailmatch(str, 'aba', PY_SSIZE_T_MIN, len(str), -1), 1)
+        self.assertEqual(tailmatch(str, 'aha', 0, PY_SSIZE_T_MAX, 1), 1)
+        self.assertEqual(tailmatch(str, 'aha', PY_SSIZE_T_MIN, len(str), 1), 1)
 
         self.assertEqual(tailmatch(str, 'z', 0, len(str), 1), 0)
         self.assertEqual(tailmatch(str, 'z', 0, len(str), -1), 0)
@@ -1195,13 +1238,21 @@ def test_find(self):
         self.assertEqual(find(str, '', 0, len(str), -1), len(str))
         # start < end
         self.assertEqual(find(str, '!', 1, len(str)+1, 1), 4)
-        self.assertEqual(find(str, '!', 1, len(str)+1, -1), 4)
+        self.assertEqual(find(str, '!', 1, PY_SSIZE_T_MAX, 1), 4)
+        self.assertEqual(find(str, '!', 0, len(str)+1, -1), 4)
+        self.assertEqual(find(str, '!', 0, PY_SSIZE_T_MAX, -1), 4)
         # start >= end
         self.assertEqual(find(str, '!', 0, 0, 1), -1)
+        self.assertEqual(find(str, '!', 0, 0, -1), -1)
         self.assertEqual(find(str, '!', len(str), 0, 1), -1)
+        self.assertEqual(find(str, '!', len(str), 0, -1), -1)
         # negative
         self.assertEqual(find(str, '!', -len(str), -1, 1), 0)
         self.assertEqual(find(str, '!', -len(str), -1, -1), 0)
+        self.assertEqual(find(str, '!', PY_SSIZE_T_MIN, -1, 1), 0)
+        self.assertEqual(find(str, '!', PY_SSIZE_T_MIN, -1, -1), 0)
+        self.assertEqual(find(str, '!', PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, 1), 0)
+        self.assertEqual(find(str, '!', PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, -1), 4)
         # bad arguments
         self.assertRaises(TypeError, find, str, b'!', 0, len(str), 1)
         self.assertRaises(TypeError, find, b"!>_<!", '!', 0, len(str), 1)
@@ -1226,13 +1277,21 @@ def test_findchar(self):
         self.assertEqual(unicode_findchar(str, 0x110000, 0, len(str), -1), -1)
         # start < end
         self.assertEqual(unicode_findchar(str, ord('!'), 1, len(str)+1, 1), 4)
-        self.assertEqual(unicode_findchar(str, ord('!'), 1, len(str)+1, -1), 4)
+        self.assertEqual(unicode_findchar(str, ord('!'), 1, PY_SSIZE_T_MAX, 1), 4)
+        self.assertEqual(unicode_findchar(str, ord('!'), 0, len(str)+1, -1), 4)
+        self.assertEqual(unicode_findchar(str, ord('!'), 0, PY_SSIZE_T_MAX, -1), 4)
         # start >= end
         self.assertEqual(unicode_findchar(str, ord('!'), 0, 0, 1), -1)
+        self.assertEqual(unicode_findchar(str, ord('!'), 0, 0, -1), -1)
         self.assertEqual(unicode_findchar(str, ord('!'), len(str), 0, 1), -1)
+        self.assertEqual(unicode_findchar(str, ord('!'), len(str), 0, -1), -1)
         # negative
         self.assertEqual(unicode_findchar(str, ord('!'), -len(str), -1, 1), 0)
         self.assertEqual(unicode_findchar(str, ord('!'), -len(str), -1, -1), 0)
+        self.assertEqual(unicode_findchar(str, ord('!'), PY_SSIZE_T_MIN, -1, 1), 0)
+        self.assertEqual(unicode_findchar(str, ord('!'), PY_SSIZE_T_MIN, -1, -1), 0)
+        self.assertEqual(unicode_findchar(str, ord('!'), PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, 1), 0)
+        self.assertEqual(unicode_findchar(str, ord('!'), PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, -1), 4)
         # bad arguments
         # CRASHES unicode_findchar(b"!>_<!", ord('!'), 0, len(str), 1)
         # CRASHES unicode_findchar([], ord('!'), 0, len(str), 1)
@@ -1250,7 +1309,9 @@ def test_replace(self):
         self.assertEqual(replace(str, 'abra', '='), '=cad=')
         self.assertEqual(replace(str, 'a', '=', 2), '=br=cadabra')
         self.assertEqual(replace(str, 'a', '=', 0), str)
-        self.assertEqual(replace(str, 'a', '=', sys.maxsize), '=br=c=d=br=')
+        self.assertEqual(replace(str, 'a', '=', PY_SSIZE_T_MAX), '=br=c=d=br=')
+        self.assertEqual(replace(str, 'a', '=', -1), '=br=c=d=br=')
+        self.assertEqual(replace(str, 'a', '=', PY_SSIZE_T_MIN), '=br=c=d=br=')
         self.assertEqual(replace(str, 'z', '='), str)
         self.assertEqual(replace(str, '', '='), '=a=b=r=a=c=a=d=a=b=r=a=')
         self.assertEqual(replace(str, 'a', 'ж'), 'жbrжcжdжbrж')
@@ -1386,6 +1447,9 @@ def test_equaltoutf8andsize(self):
             self.assertEqual(equaltoutf8andsize(s2, b + b'x', len(b)), 1)
             self.assertEqual(equaltoutf8andsize(s + '\0', b + b'\0x', len(b) + 1), 1)
             self.assertEqual(equaltoutf8andsize(s2, b, len(b) - 1), 0)
+            self.assertEqual(equaltoutf8andsize(s, b, -1), 0)
+            self.assertEqual(equaltoutf8andsize(s, b, PY_SSIZE_T_MAX), 0)
+            self.assertEqual(equaltoutf8andsize(s, b, PY_SSIZE_T_MIN), 0)
 
         self.assertEqual(equaltoutf8andsize('', b''), 1)
         self.assertEqual(equaltoutf8andsize('', b'\0'), 0)
@@ -1541,11 +1605,17 @@ def test_copycharacters(self):
 
         s = strings[0]
         self.assertRaises(IndexError, unicode_copycharacters, s, 6, s, 0, 5)
+        self.assertRaises(IndexError, unicode_copycharacters, s, PY_SSIZE_T_MAX, s, 0, 5)
         self.assertRaises(IndexError, unicode_copycharacters, s, -1, s, 0, 5)
+        self.assertRaises(IndexError, unicode_copycharacters, s, PY_SSIZE_T_MIN, s, 0, 5)
         self.assertRaises(IndexError, unicode_copycharacters, s, 0, s, 6, 5)
+        self.assertRaises(IndexError, unicode_copycharacters, s, 0, s, PY_SSIZE_T_MAX, 5)
         self.assertRaises(IndexError, unicode_copycharacters, s, 0, s, -1, 5)
+        self.assertRaises(IndexError, unicode_copycharacters, s, 0, s, PY_SSIZE_T_MIN, 5)
         self.assertRaises(SystemError, unicode_copycharacters, s, 1, s, 0, 5)
+        self.assertRaises(SystemError, unicode_copycharacters, s, 1, s, 0, PY_SSIZE_T_MAX)
         self.assertRaises(SystemError, unicode_copycharacters, s, 0, s, 0, -1)
+        self.assertRaises(SystemError, unicode_copycharacters, s, 0, s, 0, PY_SSIZE_T_MIN)
         self.assertRaises(SystemError, unicode_copycharacters, s, 0, b'', 0, 0)
         self.assertRaises(SystemError, unicode_copycharacters, s, 0, [], 0, 0)
         # CRASHES unicode_copycharacters(s, 0, NULL, 0, 0)