diff --git a/vm/src/sequence.rs b/vm/src/sequence.rs index 7f47874dda..3f2d1e94d2 100644 --- a/vm/src/sequence.rs +++ b/vm/src/sequence.rs @@ -1,6 +1,10 @@ use crate::{ - builtins::PyIntRef, function::OptionalArg, sliceable::SequenceIndexOp, types::PyComparisonOp, - vm::VirtualMachine, AsObject, PyObject, PyObjectRef, PyResult, + builtins::PyIntRef, + function::OptionalArg, + sliceable::SequenceIndexOp, + types::PyComparisonOp, + vm::{VirtualMachine, MAX_MEMORY_SIZE}, + AsObject, PyObject, PyObjectRef, PyResult, }; use optional::Optioned; use std::ops::{Deref, Range}; @@ -95,6 +99,11 @@ where { fn mul(&self, vm: &VirtualMachine, n: isize) -> PyResult> { let n = vm.check_repeat_or_overflow_error(self.as_ref().len(), n)?; + + if n > 1 && std::mem::size_of_val(self.as_ref()) >= MAX_MEMORY_SIZE / n { + return Err(vm.new_memory_error("".to_owned())); + } + let mut v = Vec::with_capacity(n * self.as_ref().len()); for _ in 0..n { v.extend_from_slice(self.as_ref()); diff --git a/vm/src/vm/mod.rs b/vm/src/vm/mod.rs index 579d5e6d3c..1a5f40e767 100644 --- a/vm/src/vm/mod.rs +++ b/vm/src/vm/mod.rs @@ -53,6 +53,8 @@ pub use interpreter::Interpreter; pub(crate) use method::PyMethod; pub use setting::Settings; +pub const MAX_MEMORY_SIZE: usize = isize::MAX as usize; + // Objects are live when they are on stack, or referenced by a name (for now) /// Top level container of a python virtual machine. In theory you could