diff --git a/tests/snippets/strings.py b/tests/snippets/strings.py index 2abd35da7..786622e9f 100644 --- a/tests/snippets/strings.py +++ b/tests/snippets/strings.py @@ -37,6 +37,8 @@ assert 3 * "xy" == "xyxyxy" assert 0 * "x" == "" assert -1 * "x" == "" +assert_raises(OverflowError, lambda: 'xy' * 234234234234234234234234234234) + a = 'Hallo' assert a.lower() == 'hallo' assert a.upper() == 'HALLO' diff --git a/vm/src/obj/objstr.rs b/vm/src/obj/objstr.rs index 44542a970..6545c9985 100644 --- a/vm/src/obj/objstr.rs +++ b/vm/src/obj/objstr.rs @@ -183,22 +183,17 @@ impl PyString { #[pymethod(name = "__mul__")] fn mul(&self, val: PyObjectRef, vm: &VirtualMachine) -> PyResult { - if objtype::isinstance(&val, &vm.ctx.int_type()) { - let value = &self.value; - let multiplier = objint::get_value(&val).to_i32().unwrap(); - let capacity = if multiplier > 0 { - multiplier.to_usize().unwrap() * value.len() - } else { - 0 - }; - let mut result = String::with_capacity(capacity); - for _x in 0..multiplier { - result.push_str(value.as_str()); - } - Ok(result) - } else { - Err(vm.new_type_error(format!("Cannot multiply {} and {}", self, val))) + if !objtype::isinstance(&val, &vm.ctx.int_type()) { + return Err(vm.new_type_error(format!("Cannot multiply {} and {}", self, val))); } + objint::get_value(&val) + .to_isize() + .map(|multiplier| multiplier.max(0)) + .and_then(|multiplier| multiplier.to_usize()) + .map(|multiplier| self.value.repeat(multiplier)) + .ok_or_else(|| { + vm.new_overflow_error("cannot fit 'int' into an index-sized integer".to_string()) + }) } #[pymethod(name = "__rmul__")]