ソースを参照

LibJS: Make string to integer parsing for properties more strict

This does break two TypedArray test262 test but those really were not
  correct because hasProperty was not implemented
davidot 4 年 前
コミット
f7e2994f35

+ 13 - 0
Userland/Libraries/LibJS/Runtime/PropertyName.h

@@ -113,6 +113,19 @@ public:
     bool try_coerce_into_number()
     {
         VERIFY(m_string_may_be_number);
+        if (m_string.is_empty()) {
+            m_string_may_be_number = false;
+            return false;
+        }
+
+        if (char first = m_string.characters()[0]; first < '0' || first > '9') {
+            m_string_may_be_number = false;
+            return false;
+        } else if (m_string.length() > 1 && first == '0') {
+            m_string_may_be_number = false;
+            return false;
+        }
+
         i32 property_index = m_string.to_int(TrimWhitespace::No).value_or(-1);
         if (property_index < 0) {
             m_string_may_be_number = false;

+ 49 - 0
Userland/Libraries/LibJS/Tests/builtins/Array/array-index-from-string.js

@@ -0,0 +1,49 @@
+describe("normal behavior", () => {
+    var arr = [3, 4, 5];
+
+    test("basic", () => {
+        expect(arr["0"]).toBe(3);
+        expect(arr["1"]).toBe(4);
+        expect(arr["2"]).toBe(5);
+    });
+
+    test("above length", () => {
+        expect(arr["3"]).toBeUndefined();
+    });
+});
+
+describe("strings with extra characters", () => {
+    var arr = [3, 4, 5];
+
+    test("whitespace", () => {
+        expect(arr[" 0"]).toBeUndefined();
+        expect(arr["0 "]).toBeUndefined();
+        expect(arr["  0"]).toBeUndefined();
+        expect(arr["  0  "]).toBeUndefined();
+        expect(arr["  3  "]).toBeUndefined();
+    });
+
+    test("leading 0", () => {
+        expect(arr["00"]).toBeUndefined();
+        expect(arr["01"]).toBeUndefined();
+        expect(arr["02"]).toBeUndefined();
+        expect(arr["03"]).toBeUndefined();
+    });
+
+    test("leading +/-", () => {
+        ["+", "-"].forEach(op => {
+            expect(arr[op + "0"]).toBeUndefined();
+            expect(arr[op + "1"]).toBeUndefined();
+
+            expect(arr[op + "-0"]).toBeUndefined();
+            expect(arr[op + "+0"]).toBeUndefined();
+        });
+    });
+
+    test("combined", () => {
+        expect(arr["+00"]).toBeUndefined();
+        expect(arr[" +0"]).toBeUndefined();
+        expect(arr["  +0 "]).toBeUndefined();
+        expect(arr["  00 "]).toBeUndefined();
+    });
+});

+ 0 - 7
Userland/Libraries/LibJS/Tests/builtins/Array/array-index-number-whitespace.js

@@ -1,7 +0,0 @@
-test("indexing the array doesn't strip whitespace if it's a number", () => {
-    var a = [];
-    a[1] = 1;
-
-    expect(a["1"]).toBe(1);
-    expect(a[" 1 "]).toBeUndefined();
-});