Просмотр исходного кода

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.
Nico Weber 3 лет назад
Родитель
Сommit
1b944b4c41

+ 1 - 1
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);
 

+ 3 - 0
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");