Skip to content

Commit bd50cba

Browse files
committed
Fix 'PyList_New': did not properly ensure initial capacity.
1 parent f6e115c commit bd50cba

File tree

3 files changed

+33
-9
lines changed

3 files changed

+33
-9
lines changed

graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_list.py

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,14 @@ def _reference_getitem(args):
5656

5757

5858
def _reference_setitem(args):
59-
listObj = args[0]
59+
capacity = args[0]
6060
pos = args[1]
6161
newitem = args[2]
6262
if pos < 0:
6363
raise IndexError("list index out of range")
64+
listObj = [None] * capacity
6465
listObj[pos] = newitem
65-
return 0
66+
return listObj
6667

6768

6869
def _reference_SET_ITEM(args):
@@ -154,14 +155,27 @@ def compile_module(self, name):
154155
)
155156

156157
test_PyList_SetItem = CPyExtFunction(
157-
_wrap_list_fun(_reference_setitem),
158+
_reference_setitem,
158159
lambda: (
159-
([1,2,3,4], 0, 0),
160-
([1,2,3,4], 3, 5),
160+
(4, 0, 0),
161+
(4, 3, 5),
161162
),
162-
resultspec="i",
163-
argspec='OnO',
164-
arguments=["PyObject* op", "Py_ssize_t size", "PyObject* newitem"],
163+
code='''PyObject* wrap_PyList_SetItem(Py_ssize_t capacity, Py_ssize_t idx, PyObject* new_item) {
164+
PyObject *newList = PyList_New(capacity);
165+
for (Py_ssize_t i = 0; i < capacity; i++) {
166+
if (i == idx) {
167+
PyList_SetItem(newList, i, new_item);
168+
} else {
169+
PyList_SetItem(newList, i, Py_None);
170+
}
171+
}
172+
return newList;
173+
}
174+
''',
175+
resultspec="O",
176+
argspec='nnO',
177+
arguments=["Py_ssize_t capacity", "Py_ssize_t size", "PyObject* new_item"],
178+
callfunction="wrap_PyList_SetItem",
165179
cmpfunc=unhandled_error_compare
166180
)
167181

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/list/ListBuiltins.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,16 @@ PList doPListInt(PList left, int right,
914914
}
915915
}
916916

917+
@Specialization(rewriteOn = ArithmeticException.class)
918+
PList doPListBigInt(PList left, long right,
919+
@Cached("createClassProfile()") ValueProfile profile) {
920+
try {
921+
return doPListInt(left, PInt.intValueExact(right), profile);
922+
} catch (ArithmeticException e) {
923+
throw raise(OverflowError, "cannot fit 'int' into an index-sized integer");
924+
}
925+
}
926+
917927
@Specialization(rewriteOn = ArithmeticException.class)
918928
PList doPListBigInt(PList left, PInt right,
919929
@Cached("createClassProfile()") ValueProfile profile) {

graalpython/lib-graalpython/python_cext.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ def PyList_New(size, errormarker):
204204
try:
205205
if size < 0:
206206
_PyErr_BadInternalCall(None, None, None)
207-
return []
207+
return [None] * size
208208
except BaseException:
209209
typ, val, tb = sys.exc_info()
210210
PyErr_Restore(typ, val, tb)

0 commit comments

Comments
 (0)