From 1b944b4c41321c1180b175a257674a9679a0b88a Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Thu, 13 Jan 2022 20:20:06 -0500 Subject: [PATCH] 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. --- Userland/Libraries/LibJS/Runtime/StringPrototype.cpp | 2 +- .../LibJS/Tests/builtins/String/String.prototype.substr.js | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) 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");