Skip to content

Commit 24dd20d

Browse files
committed
gh-153002: Guard specialized list-int subscript indices
1 parent 8b1dbb1 commit 24dd20d

5 files changed

Lines changed: 52 additions & 0 deletions

File tree

Lib/test/test_opcache.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,6 +1879,17 @@ def binary_subscr_list_int():
18791879
"BINARY_OP_SUBSCR_LIST_INT")
18801880
self.assert_no_opcode(binary_subscr_list_int, "BINARY_OP")
18811881

1882+
def binary_subscr_list_int_noncompact(index):
1883+
a = [1, 2, 3]
1884+
return a[index]
1885+
1886+
for _ in range(_testinternalcapi.SPECIALIZATION_THRESHOLD):
1887+
self.assertEqual(binary_subscr_list_int_noncompact(0), 1)
1888+
self.assert_specialized(binary_subscr_list_int_noncompact,
1889+
"BINARY_OP_SUBSCR_LIST_INT")
1890+
with self.assertRaises(IndexError):
1891+
binary_subscr_list_int_noncompact(1 << 64)
1892+
18821893
def binary_subscr_tuple_int():
18831894
for _ in range(_testinternalcapi.SPECIALIZATION_THRESHOLD):
18841895
a = (1, 2, 3)
@@ -1995,6 +2006,17 @@ def __getitem__(self, item):
19952006
@cpython_only
19962007
@requires_specialization
19972008
def test_store_subscr(self):
2009+
def store_subscr_list_int(index):
2010+
a = [None]
2011+
a[index] = 1
2012+
return a
2013+
2014+
for _ in range(_testinternalcapi.SPECIALIZATION_THRESHOLD):
2015+
self.assertEqual(store_subscr_list_int(0), [1])
2016+
self.assert_specialized(store_subscr_list_int, "STORE_SUBSCR_LIST_INT")
2017+
with self.assertRaises(IndexError):
2018+
store_subscr_list_int(1 << 64)
2019+
19982020
def store_subscr_dict():
19992021
for _ in range(_testinternalcapi.SPECIALIZATION_THRESHOLD):
20002022
a = {1: 2, 2: 3}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix specialized list subscript and store-subscript paths so they fall back for
2+
non-compact ``int`` indices instead of passing them to
3+
``_PyLong_CompactValue()``.

Python/bytecodes.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,6 +1142,7 @@ dummy_func(
11421142

11431143
assert(PyLong_CheckExact(sub));
11441144
assert(PyList_CheckExact(list));
1145+
EXIT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub));
11451146

11461147
Py_ssize_t index = _PyLong_CompactValue((PyLongObject *)sub);
11471148
if (index < 0) {
@@ -1420,6 +1421,7 @@ dummy_func(
14201421

14211422
assert(PyLong_CheckExact(sub));
14221423
assert(PyList_CheckExact(list));
1424+
DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub));
14231425

14241426
Py_ssize_t index = _PyLong_CompactValue((PyLongObject *)sub);
14251427
DEOPT_IF(!LOCK_OBJECT(list));

Python/executor_cases.c.h

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/generated_cases.c.h

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)