summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNico Weber <thakis@chromium.org>2022-01-13 20:20:06 -0500
committerLinus Groh <mail@linusgroh.de>2022-01-14 11:12:24 +0100
commit1b944b4c41321c1180b175a257674a9679a0b88a (patch)
treef20bb1ffc77960b0ad50844086ea081f4b47651f
parent23cde7685cf9efa229f3cab05eeca2dbf5f79886 (diff)
downloadserenity-1b944b4c41321c1180b175a257674a9679a0b88a.zip
LibJS: Fix substr() with negative arguments larger than string length
length_in_code_units() returns a size_t, which is 64-bit unsigned in i686 builds. `size + (i32)int_length` hence produced a 64-bit unsigned result, so a negative value would wrap around and become a very large number. As fix, just omit the cast -- we assign the result of max() to a double anyways. With this, all test262 tests in annexB/built-ins/String/prototype pass.
-rw-r--r--Userland/Libraries/LibJS/Runtime/StringPrototype.cpp2
-rw-r--r--Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.substr.js3
2 files changed, 4 insertions, 1 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp
index 756a3311e8..fbf917f126 100644
--- a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp
@@ -518,7 +518,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::substr)
if (Value(int_start).is_negative_infinity())
int_start = 0;
if (int_start < 0)
- int_start = max(size + (i32)int_start, 0);
+ int_start = max(size + int_start, 0);
auto length = vm.argument(1);
diff --git a/Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.substr.js b/Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.substr.js
index d452643295..9c0273f762 100644
--- a/Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.substr.js
+++ b/Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.substr.js
@@ -4,6 +4,9 @@ test("basic functionality", () => {
expect("".substr(1)).toBe("");
expect("".substr()).toBe("");
expect("".substr(-1)).toBe("");
+ expect("a".substr(-1)).toBe("a");
+ expect("a".substr(-2)).toBe("a");
+ expect("a".substr(-3)).toBe("a");
expect("hello friends".substr()).toBe("hello friends");
expect("hello friends".substr(1)).toBe("ello friends");
expect("hello friends".substr(0, 5)).toBe("hello");