From c14fedd5629cf45f4a7b64e6c87d87181432c42d Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Tue, 28 Apr 2020 00:26:00 +0100 Subject: [PATCH] LibJS: Add bounds check to Array.prototype.{find,findIndex} The number of iterations is limited to the initial array size, but we still need to check if the array did shrink since then before accessing each element. Fixes #1992. --- Libraries/LibJS/Runtime/ArrayPrototype.cpp | 6 +++++ .../Tests/array-shrink-during-find-crash.js | 25 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 Libraries/LibJS/Tests/array-shrink-during-find-crash.js diff --git a/Libraries/LibJS/Runtime/ArrayPrototype.cpp b/Libraries/LibJS/Runtime/ArrayPrototype.cpp index b3ac9b7928..0cd228cf6a 100644 --- a/Libraries/LibJS/Runtime/ArrayPrototype.cpp +++ b/Libraries/LibJS/Runtime/ArrayPrototype.cpp @@ -441,6 +441,9 @@ Value ArrayPrototype::find(Interpreter& interpreter) auto array_size = array->elements().size(); for (size_t i = 0; i < array_size; ++i) { + if (i >= array->elements().size()) + break; + auto value = array->elements().at(i); if (value.is_empty()) continue; @@ -475,6 +478,9 @@ Value ArrayPrototype::find_index(Interpreter& interpreter) auto array_size = array->elements().size(); for (size_t i = 0; i < array_size; ++i) { + if (i >= array->elements().size()) + break; + auto value = array->elements().at(i); if (value.is_empty()) continue; diff --git a/Libraries/LibJS/Tests/array-shrink-during-find-crash.js b/Libraries/LibJS/Tests/array-shrink-during-find-crash.js new file mode 100644 index 0000000000..656eab3e80 --- /dev/null +++ b/Libraries/LibJS/Tests/array-shrink-during-find-crash.js @@ -0,0 +1,25 @@ +load("test-common.js"); + +try { + var a, callbackCalled; + + callbackCalled = 0; + a = [1, 2, 3, 4, 5]; + a.find(() => { + callbackCalled++; + a.pop(); + }); + assert(callbackCalled === 3); + + callbackCalled = 0; + a = [1, 2, 3, 4, 5]; + a.findIndex(() => { + callbackCalled++; + a.pop(); + }); + assert(callbackCalled === 3); + + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +}