Add error handling for objsequence and objstr index overflow

This commit is contained in:
Vladimir Karamyshev committed 2019-02-05 10:17:43 +03:00
1 parent f4a78d4148
commit ebbd3d9f22
3 files changed
+52 -17

No files matched your search

+26
View File
@@ -0,0 +1,26 @@
import sys
def expect_cannot_fit_index_error(s, index):
try:
s[index]
except IndexError:
pass
# TODO: Replace current except block with commented
# after solving https://github.com/RustPython/RustPython/issues/322
# except IndexError as error:
# assert str(error) == "cannot fit 'int' into an index-sized integer"
else:
assert False
MAX_INDEX = sys.maxsize + 1
MIN_INDEX = -(MAX_INDEX + 1)
test_str = "test"
expect_cannot_fit_index_error(test_str, MIN_INDEX)
expect_cannot_fit_index_error(test_str, MAX_INDEX)
test_list = [0, 1, 2, 3]
expect_cannot_fit_index_error(test_list, MIN_INDEX)
expect_cannot_fit_index_error(test_list, MAX_INDEX)
+13 -10
View File
@@ -76,17 +76,20 @@ pub fn get_item(
subscript: PyObjectRef,
) -> PyResult {
match &(subscript.borrow()).payload {
PyObjectPayload::Integer { value } => {
let value = value.to_i32().unwrap();
let pos_index = elements.to_vec().get_pos(value);
if pos_index < elements.len() {
let obj = elements[pos_index].clone();
Ok(obj)
} else {
let index_error = vm.context().exceptions.index_error.clone();
Err(vm.new_exception(index_error, "Index out of bounds!".to_string()))
PyObjectPayload::Integer { value } => match value.to_i32() {
Some(value) => {
let pos_index = elements.to_vec().get_pos(value);
if pos_index < elements.len() {
let obj = elements[pos_index].clone();
Ok(obj)
} else {
Err(vm.new_index_error("Index out of bounds!".to_string()))
}
}
}
None => {
Err(vm.new_index_error("cannot fit 'int' into an index-sized integer".to_string()))
}
},
PyObjectPayload::Slice {
start: _,
stop: _,
+13 -7
View File
@@ -1015,13 +1015,19 @@ fn to_graphemes<S: AsRef<str>>(value: S) -> Vec<String> {
pub fn subscript(vm: &mut VirtualMachine, value: &str, b: PyObjectRef) -> PyResult {
if objtype::isinstance(&b, &vm.ctx.int_type()) {
let pos = objint::get_value(&b).to_i32().unwrap();
let graphemes = to_graphemes(value);
let idx = graphemes.get_pos(pos);
graphemes
.get(idx)
.map(|c| vm.new_str(c.to_string()))
.ok_or(vm.new_index_error("string index out of range".to_string()))
match objint::get_value(&b).to_i32() {
Some(pos) => {
let graphemes = to_graphemes(value);
let idx = graphemes.get_pos(pos);
graphemes
.get(idx)
.map(|c| vm.new_str(c.to_string()))
.ok_or(vm.new_index_error("string index out of range".to_string()))
}
None => {
Err(vm.new_index_error("cannot fit 'int' into an index-sized integer".to_string()))
}
}
} else {
match &(*b.borrow()).payload {
&PyObjectPayload::Slice {