[Jython-checkins] jython: Fix index out of range in slice deletion from sequences.
jeff.allen
jython-checkins at python.org
Sun Jul 8 15:22:55 CEST 2012
http://hg.python.org/jython/rev/cdf3485e1ba6
changeset: 6787:cdf3485e1ba6
parent: 6781:bf3a1d3eae8c
user: Jeff Allen <ja...py at farowl.co.uk>
date: Sun Jul 08 14:00:01 2012 +0100
summary:
Fix index out of range in slice deletion from sequences.
The loop in SequenceIndexDelegate.delSlice generated an invalid index for size approaching MAXINT. Fixes a failure in test_bytes.py and removes a skip from list_tests.py .
files:
Lib/test/list_tests.py | 8 +-
src/org/python/core/SequenceIndexDelegate.java | 37 +++++----
2 files changed, 25 insertions(+), 20 deletions(-)
diff --git a/Lib/test/list_tests.py b/Lib/test/list_tests.py
--- a/Lib/test/list_tests.py
+++ b/Lib/test/list_tests.py
@@ -529,11 +529,9 @@
a[::2] = tuple(range(5))
self.assertEqual(a, self.type2test([0, 1, 1, 3, 2, 5, 3, 7, 4, 9]))
- #FIXME: not working on Jython
- if not test_support.is_jython:
- # test issue7788
- a = self.type2test(range(10))
- del a[9::1<<333]
+ # test issue7788
+ a = self.type2test(range(10))
+ del a[9::1<<333]
# XXX: CPython specific, PyList doesn't len() during init
def _test_constructor_exception_handling(self):
diff --git a/src/org/python/core/SequenceIndexDelegate.java b/src/org/python/core/SequenceIndexDelegate.java
--- a/src/org/python/core/SequenceIndexDelegate.java
+++ b/src/org/python/core/SequenceIndexDelegate.java
@@ -50,8 +50,8 @@
if (idx.isIndex()) {
delItem(checkIdx(idx.asIndex(Py.IndexError)));
} else if (idx instanceof PySlice) {
- int[] indices = ((PySlice)idx).indicesEx(len());
- delSlice(indices[0], indices[1], indices[2]);
+ PySlice slice = (PySlice) idx;
+ delSlice(slice.indicesEx(len()));
} else {
throw Py.TypeError(getTypeName() + " indices must be integers");
}
@@ -109,21 +109,28 @@
}
}
- private void delSlice(int start, int stop, int step) {
- if(step == 1) {
- if (stop > start) {
- delItems(start, stop);
+ private void delSlice(int[] indices) {
+ int p = indices[0], step = indices[2], count = indices[3];
+ if (step > 1) {
+ /*
+ * Key observation: each deletion causes material to the right (not yet visited) to move
+ * one place left, so the deletion pointer moves by step-1 not by step as might be
+ * expected.
+ */
+ step = step - 1;
+ for (; count > 0; --count, p += step) {
+ delItem(p);
}
- } else if(step > 1) {
- for(int i = start; i < stop; i += step) {
- delItem(i);
- i--;
- stop--;
+ } else if (step < 1) {
+ // Deletion pointer moves leftwards, and moving data is to the right
+ for (; count > 0; --count, p += step) {
+ delItem(p);
}
- } else if(step < 0) {
- for(int i = start; i >= 0 && i > stop; i += step) {
- delItem(i);
+ } else { // step == 1, since it is never == 0
+ // Slice is contiguous: use range delete
+ if (count > 0) {
+ delItems(p, p + count);
}
}
}
-}
\ No newline at end of file
+}
--
Repository URL: http://hg.python.org/jython
More information about the Jython-checkins
mailing list