[pypy-svn] r10271 - pypy/dist/pypy/objspace/std
arigo at codespeak.net
arigo at codespeak.net
Sun Apr 3 20:09:06 CEST 2005
Author: arigo
Date: Sun Apr 3 20:09:06 2005
New Revision: 10271
Modified:
pypy/dist/pypy/objspace/std/listobject.py
Log:
An attempt at making W_ListObject safe against evil code that mutates the list
while it is being operated on.
Modified: pypy/dist/pypy/objspace/std/listobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/listobject.py (original)
+++ pypy/dist/pypy/objspace/std/listobject.py Sun Apr 3 20:09:06 2005
@@ -73,23 +73,22 @@
return W_IntObject(space, result)
def getitem__List_ANY(space, w_list, w_index):
- items = w_list.ob_item
idx = space.int_w(w_index)
if idx < 0:
idx += w_list.ob_size
if idx < 0 or idx >= w_list.ob_size:
raise OperationError(space.w_IndexError,
space.wrap("list index out of range"))
- w_item = items[idx]
+ w_item = w_list.ob_item[idx]
return w_item
def getitem__List_Slice(space, w_list, w_slice):
- items = w_list.ob_item
length = w_list.ob_size
start, stop, step, slicelength = slicetype.indices4(space, w_slice, length)
assert slicelength >= 0
w_res = W_ListObject(space, [])
_list_resize(w_res, slicelength)
+ items = w_list.ob_item
subitems = w_res.ob_item
for i in range(slicelength):
subitems[i] = items[start]
@@ -98,10 +97,12 @@
return w_res
def contains__List_ANY(space, w_list, w_obj):
- items = w_list.ob_item
- for i in range(w_list.ob_size):
- if space.eq_w(items[i], w_obj):
+ # needs to be safe against eq_w() mutating the w_list behind our back
+ i = 0
+ while i < w_list.ob_size:
+ if space.eq_w(w_list.ob_item[i], w_obj):
return space.w_True
+ i += 1
return space.w_False
def iter__List(space, w_list):
@@ -131,10 +132,10 @@
def mul_list_times(space, w_list, times):
w_res = W_ListObject(space, [])
- src = w_list.ob_item
size = w_list.ob_size
newlen = size * times # XXX check overflow
_list_resize(w_res, newlen)
+ src = w_list.ob_item
items = w_res.ob_item
p = 0
for _ in range(times):
@@ -168,14 +169,15 @@
return w_list
def eq__List_List(space, w_list1, w_list2):
- items1 = w_list1.ob_item
- items2 = w_list2.ob_item
+ # needs to be safe against eq_w() mutating the w_lists behind our back
if w_list1.ob_size != w_list2.ob_size:
return space.w_False
- for i in range(w_list1.ob_size):
- if not space.is_true(space.eq(items1[i], items2[i])):
+ i = 0
+ while i < w_list1.ob_size and i < w_list2.ob_size:
+ if not space.eq_w(w_list1.ob_item[i], w_list2.ob_item[i]):
return space.w_False
- return space.w_True
+ i += 1
+ return space.newbool(w_list1.ob_size == w_list2.ob_size)
def _min(a, b):
if a < b:
@@ -183,24 +185,28 @@
return b
def lt__List_List(space, w_list1, w_list2):
- items1 = w_list1.ob_item
- items2 = w_list2.ob_item
- ncmp = _min(w_list1.ob_size, w_list2.ob_size)
+ # needs to be safe against eq_w() mutating the w_lists behind our back
# Search for the first index where items are different
- for p in range(ncmp):
- if not space.is_true(space.eq(items1[p], items2[p])):
- return space.lt(items1[p], items2[p])
+ i = 0
+ while i < w_list1.ob_size and i < w_list2.ob_size:
+ w_item1 = w_list1.ob_item[i]
+ w_item2 = w_list2.ob_item[i]
+ if not space.eq_w(w_item1, w_item2):
+ return space.lt(w_item1, w_item2)
+ i += 1
# No more items to compare -- compare sizes
return space.newbool(w_list1.ob_size < w_list2.ob_size)
def gt__List_List(space, w_list1, w_list2):
- items1 = w_list1.ob_item
- items2 = w_list2.ob_item
- ncmp = _min(w_list1.ob_size, w_list2.ob_size)
+ # needs to be safe against eq_w() mutating the w_lists behind our back
# Search for the first index where items are different
- for p in range(ncmp):
- if not space.is_true(space.eq(items1[p], items2[p])):
- return space.gt(items1[p], items2[p])
+ i = 0
+ while i < w_list1.ob_size and i < w_list2.ob_size:
+ w_item1 = w_list1.ob_item[i]
+ w_item2 = w_list2.ob_item[i]
+ if not space.eq_w(w_item1, w_item2):
+ return space.gt(w_item1, w_item2)
+ i += 1
# No more items to compare -- compare sizes
return space.newbool(w_list1.ob_size > w_list2.ob_size)
@@ -237,14 +243,13 @@
return space.w_None
def setitem__List_ANY_ANY(space, w_list, w_index, w_any):
- items = w_list.ob_item
idx = space.int_w(w_index)
if idx < 0:
idx += w_list.ob_size
if idx < 0 or idx >= w_list.ob_size:
raise OperationError(space.w_IndexError,
space.wrap("list index out of range"))
- items[idx] = w_any
+ w_list.ob_item[idx] = w_any
return space.w_None
def setitem__List_Slice_List(space, w_list, w_slice, w_list2):
@@ -463,39 +468,38 @@
return w_res
def list_remove__List_ANY(space, w_list, w_any):
- eq = space.eq
- items = w_list.ob_item
- for i in range(w_list.ob_size):
- cmp = eq(items[i], w_any)
- if space.is_true(cmp):
+ # needs to be safe against eq_w() mutating the w_list behind our back
+ i = 0
+ while i < w_list.ob_size:
+ if space.eq_w(w_list.ob_item[i], w_any):
_del_slice(w_list, i, i+1)
return space.w_None
+ i += 1
raise OperationError(space.w_ValueError,
space.wrap("list.remove(x): x not in list"))
def list_index__List_ANY_ANY_ANY(space, w_list, w_any, w_start, w_stop):
- eq = space.eq
- items = w_list.ob_item
+ # needs to be safe against eq_w() mutating the w_list behind our back
size = w_list.ob_size
w_start = slicetype.adapt_bound(space, w_start, space.wrap(size))
w_stop = slicetype.adapt_bound(space, w_stop, space.wrap(size))
- start = space.int_w(w_start)
+ i = space.int_w(w_start)
stop = space.int_w(w_stop)
- for i in range(start,stop):
- cmp = eq(items[i], w_any)
- if space.is_true(cmp):
+ while i < stop and i < w_list.ob_size:
+ if space.eq_w(w_list.ob_item[i], w_any):
return space.wrap(i)
+ i += 1
raise OperationError(space.w_ValueError,
space.wrap("list.index(x): x not in list"))
def list_count__List_ANY(space, w_list, w_any):
- eq = space.eq
- items = w_list.ob_item
- count = r_int(0)
- for i in range(w_list.ob_size):
- cmp = eq(items[i], w_any)
- if space.is_true(cmp):
+ # needs to be safe against eq_w() mutating the w_list behind our back
+ count = 0
+ i = 0
+ while i < w_list.ob_size:
+ if space.eq_w(w_list.ob_item[i], w_any):
count += 1
+ i += 1
return space.wrap(count)
# Reverse a slice of a list in place, from lo up to (exclusive) hi.
More information about the Pypy-commit
mailing list