mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-24 18:32:28 -05:00
LibJS: Prevent stack overflow in flatten_into_array()
The check for stack space in VM from push_execution_context has been moved to a method on VM called did_reach_stack_space_limit. This allows us to check the stack size in other places besides push_execution_context. We can now verify that we have enough space on the stack before calling flatten_into_array to ensure that we don't cause a stack overflow error when calling the function with a large depth.
This commit is contained in:
parent
da51b8f39d
commit
e26cfd313e
3 changed files with 22 additions and 2 deletions
|
@ -1945,6 +1945,11 @@ static size_t flatten_into_array(GlobalObject& global_object, Object& new_array,
|
|||
}
|
||||
|
||||
if (depth > 0 && value.is_array(global_object)) {
|
||||
if (vm.did_reach_stack_space_limit()) {
|
||||
vm.throw_exception<Error>(global_object, "Call stack size limit exceeded");
|
||||
return {};
|
||||
}
|
||||
|
||||
auto length = length_of_array_like(global_object, value.as_object());
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
|
|
@ -105,12 +105,17 @@ public:
|
|||
return *m_single_ascii_character_strings[character];
|
||||
}
|
||||
|
||||
bool did_reach_stack_space_limit() const
|
||||
{
|
||||
// Note: the 32 kiB used to be 16 kiB, but that turned out to not be enough with ASAN enabled.
|
||||
return m_stack_info.size_free() < 32 * KiB;
|
||||
}
|
||||
|
||||
void push_execution_context(ExecutionContext& context, GlobalObject& global_object)
|
||||
{
|
||||
VERIFY(!exception());
|
||||
// Ensure we got some stack space left, so the next function call doesn't kill us.
|
||||
// Note: the 32 kiB used to be 16 kiB, but that turned out to not be enough with ASAN enabled.
|
||||
if (m_stack_info.size_free() < 32 * KiB)
|
||||
if (did_reach_stack_space_limit())
|
||||
throw_exception<Error>(global_object, "Call stack size limit exceeded");
|
||||
else
|
||||
m_execution_context_stack.append(&context);
|
||||
|
|
|
@ -2,6 +2,16 @@ test("length is 0", () => {
|
|||
expect(Array.prototype.flat).toHaveLength(0);
|
||||
});
|
||||
|
||||
describe("error", () => {
|
||||
test("Issue #9317, stack overflow in flatten_into_array from flat call", () => {
|
||||
var a = [];
|
||||
a[0] = a;
|
||||
expect(() => {
|
||||
a.flat(3893232121);
|
||||
}).toThrowWithMessage(Error, "Call stack size limit exceeded");
|
||||
});
|
||||
});
|
||||
|
||||
describe("normal behavior", () => {
|
||||
test("basic functionality", () => {
|
||||
var array1 = [1, 2, [3, 4]];
|
||||
|
|
Loading…
Add table
Reference in a new issue