]> git.kaiwu.me - quickjs.git/commitdiff
Fix member access on non-decimal numeric literals
authorbptato <nincsnevem662@gmail.com>
Tue, 24 Mar 2026 18:44:11 +0000 (19:44 +0100)
committerbptato <nincsnevem662@gmail.com>
Tue, 24 Mar 2026 18:44:11 +0000 (19:44 +0100)
In other engines, 0x0.toString() returns '0', but QJS would try to parse it
as a float and then throw.
Also removes remnants of hex float parsing which is no longer supported
anyway.

(Port of https://github.com/quickjs-ng/quickjs/pull/377)

quickjs.c
tests/test_language.js

index 0f681d9be40e8c080ffb02a3ba720a391e6e1a3d..9a1eb8771afaa7c968c982c6b21f9b2e65ef7e73 100644 (file)
--- a/quickjs.c
+++ b/quickjs.c
@@ -12436,7 +12436,7 @@ static JSValue js_atof(JSContext *ctx, const char *str, const char **pp,
                 to_digit((uint8_t)p[1]) < radix)) {
         p++;
     }
-    if (!(flags & ATOD_INT_ONLY)) {
+    if (!(flags & ATOD_INT_ONLY) && radix == 10) {
         if (*p == '.' && (p > p_start || to_digit((uint8_t)p[1]) < radix)) {
             is_float = TRUE;
             p++;
@@ -12446,9 +12446,7 @@ static JSValue js_atof(JSContext *ctx, const char *str, const char **pp,
                    (*p == sep && to_digit((uint8_t)p[1]) < radix))
                 p++;
         }
-        if (p > p_start &&
-            (((*p == 'e' || *p == 'E') && radix == 10) ||
-             ((*p == 'p' || *p == 'P') && (radix == 2 || radix == 8 || radix == 16)))) {
+        if (p > p_start && (*p == 'e' || *p == 'E')) {
             const char *p1 = p + 1;
             is_float = TRUE;
             if (*p1 == '+') {
@@ -12485,19 +12483,9 @@ static JSValue js_atof(JSContext *ctx, const char *str, const char **pp,
     }
     buf[j] = '\0';
 
-    if (flags & ATOD_ACCEPT_SUFFIX) {
-        if (*p == 'n') {
-            p++;
-            atod_type = ATOD_TYPE_BIG_INT;
-        } else {
-            if (is_float && radix != 10)
-                goto fail;
-        }
-    } else {
-        if (atod_type == ATOD_TYPE_FLOAT64) {
-            if (is_float && radix != 10)
-                goto fail;
-        }
+    if ((flags & ATOD_ACCEPT_SUFFIX) && *p == 'n') {
+        p++;
+        atod_type = ATOD_TYPE_BIG_INT;
     }
 
     switch(atod_type) {
index 5c51f0df52c947d1dc35691a4dd09413e34948c9..f658044789f34de1d3f7ba6ef91b22b2183f5765 100644 (file)
@@ -664,6 +664,16 @@ function test_global_var_opt()
     assert(gvar1, 5);
 }
 
+function test_number_literals()
+{
+    assert(0.1.a, undefined);
+    assert(0x1.a, undefined);
+    assert(0b1.a, undefined);
+    assert(01.a, undefined);
+    assert(0o1.a, undefined);
+    assert_throws(SyntaxError, () => eval('0.a'));
+}
+
 test_op1();
 test_cvt();
 test_eq();
@@ -690,3 +700,4 @@ test_optional_chaining();
 test_parse_arrow_function();
 test_unicode_ident();
 test_global_var_opt();
+test_number_literals();