Skip to content

Commit 66afb72

Browse files
committed
Fix member access on non-decimal numeric literals
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 quickjs-ng/quickjs#377)
1 parent a31dcef commit 66afb72

2 files changed

Lines changed: 16 additions & 17 deletions

File tree

quickjs.c

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12436,7 +12436,7 @@ static JSValue js_atof(JSContext *ctx, const char *str, const char **pp,
1243612436
to_digit((uint8_t)p[1]) < radix)) {
1243712437
p++;
1243812438
}
12439-
if (!(flags & ATOD_INT_ONLY)) {
12439+
if (!(flags & ATOD_INT_ONLY) && radix == 10) {
1244012440
if (*p == '.' && (p > p_start || to_digit((uint8_t)p[1]) < radix)) {
1244112441
is_float = TRUE;
1244212442
p++;
@@ -12446,9 +12446,7 @@ static JSValue js_atof(JSContext *ctx, const char *str, const char **pp,
1244612446
(*p == sep && to_digit((uint8_t)p[1]) < radix))
1244712447
p++;
1244812448
}
12449-
if (p > p_start &&
12450-
(((*p == 'e' || *p == 'E') && radix == 10) ||
12451-
((*p == 'p' || *p == 'P') && (radix == 2 || radix == 8 || radix == 16)))) {
12449+
if (p > p_start && (*p == 'e' || *p == 'E')) {
1245212450
const char *p1 = p + 1;
1245312451
is_float = TRUE;
1245412452
if (*p1 == '+') {
@@ -12485,19 +12483,9 @@ static JSValue js_atof(JSContext *ctx, const char *str, const char **pp,
1248512483
}
1248612484
buf[j] = '\0';
1248712485

12488-
if (flags & ATOD_ACCEPT_SUFFIX) {
12489-
if (*p == 'n') {
12490-
p++;
12491-
atod_type = ATOD_TYPE_BIG_INT;
12492-
} else {
12493-
if (is_float && radix != 10)
12494-
goto fail;
12495-
}
12496-
} else {
12497-
if (atod_type == ATOD_TYPE_FLOAT64) {
12498-
if (is_float && radix != 10)
12499-
goto fail;
12500-
}
12486+
if ((flags & ATOD_ACCEPT_SUFFIX) && *p == 'n') {
12487+
p++;
12488+
atod_type = ATOD_TYPE_BIG_INT;
1250112489
}
1250212490

1250312491
switch(atod_type) {

tests/test_language.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,16 @@ function test_global_var_opt()
664664
assert(gvar1, 5);
665665
}
666666

667+
function test_number_literals()
668+
{
669+
assert(0.1.a, undefined);
670+
assert(0x1.a, undefined);
671+
assert(0b1.a, undefined);
672+
assert(01.a, undefined);
673+
assert(0o1.a, undefined);
674+
assert_throws(SyntaxError, () => eval('0.a'));
675+
}
676+
667677
test_op1();
668678
test_cvt();
669679
test_eq();
@@ -690,3 +700,4 @@ test_optional_chaining();
690700
test_parse_arrow_function();
691701
test_unicode_ident();
692702
test_global_var_opt();
703+
test_number_literals();

0 commit comments

Comments
 (0)