Skip to content

Commit 3eaea6c

Browse files
committed
Improve number conversions
- pass string length to `js_atof()` instead of end pointer - get string length from `bf_ftoa()` in `js_bigint_to_string1`
1 parent bb4878d commit 3eaea6c

File tree

1 file changed

+24
-21
lines changed

1 file changed

+24
-21
lines changed

quickjs.c

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10163,17 +10163,18 @@ static JSValue js_string_to_bigint(JSContext *ctx, const char *buf, int radix)
1016310163
return JS_CompactBigInt1(ctx, val);
1016410164
}
1016510165

10166-
/* `js_atof(ctx, p, end, pp, radix, flags)`
10166+
/* `js_atof(ctx, p, len, pp, radix, flags)`
10167+
Convert the string pointed to by `p` to a number value.
1016710168
Return an exception in case of memory error.
1016810169
Return `JS_NAN` if invalid syntax.
10169-
- `p` points to a null terminated UTF-8 encoded char array
10170-
- `end` points to the end of the array.
10171-
- `pp` if not null receives a pointer to the next character
10172-
- `radix` must be in range 2 to 36, else return `JS_NAN`
10173-
- `flags` is a combination of the flags below
10174-
There is a null byte at `*end`, but there might be embedded null bytes
10175-
between `p` and `end` which must produce `JS_NAN` if the
10176-
`ATOD_NO_TRAILING_CHARS` flag is not present.
10170+
- `p` points to a null terminated UTF-8 encoded char array,
10171+
- `len` the length of the array,
10172+
- `pp` if not null receives a pointer to the next character,
10173+
- `radix` must be in range 2 to 36, else return `JS_NAN`.
10174+
- `flags` is a combination of the flags below.
10175+
There is a null byte at `p[len]`, but there might be embedded null
10176+
bytes between `p[0]` and `p[len]` which must produce `JS_NAN` if
10177+
the `ATOD_NO_TRAILING_CHARS` flag is present.
1017710178
*/
1017810179

1017910180
#define ATOD_TRIM_SPACES (1 << 0) /* trim white space */
@@ -10188,14 +10189,15 @@ static JSValue js_string_to_bigint(JSContext *ctx, const char *buf, int radix)
1018810189
#define ATOD_DECIMAL_AFTER_SIGN (1 << 9) /* only accept decimal number after sign */
1018910190
#define ATOD_NO_TRAILING_CHARS (1 << 10) /* do not accept trailing characters */
1019010191

10191-
static JSValue js_atof(JSContext *ctx, const char *p, const char *end,
10192+
static JSValue js_atof(JSContext *ctx, const char *p, size_t len,
1019210193
const char **pp, int radix, int flags)
1019310194
{
1019410195
const char *p_start;
10196+
const char *end = p + len;
1019510197
int sep;
1019610198
BOOL is_float;
1019710199
char buf1[64], *buf = buf1;
10198-
size_t i, j, len;
10200+
size_t i, j;
1019910201
JSValue val = JS_NAN;
1020010202
double d;
1020110203
char sign;
@@ -10377,7 +10379,7 @@ static JSValue JS_ToNumberHintFree(JSContext *ctx, JSValue val,
1037710379
ATOD_ACCEPT_FLOAT | ATOD_ACCEPT_INFINITY |
1037810380
ATOD_ACCEPT_HEX_PREFIX | ATOD_ACCEPT_BIN_OCT |
1037910381
ATOD_DECIMAL_AFTER_SIGN | ATOD_NO_TRAILING_CHARS;
10380-
ret = js_atof(ctx, str, str + len, NULL, 10, flags);
10382+
ret = js_atof(ctx, str, len, NULL, 10, flags);
1038110383
JS_FreeCString(ctx, str);
1038210384
}
1038310385
break;
@@ -10961,21 +10963,21 @@ static JSValue js_bigint_to_string1(JSContext *ctx, JSValue val, int radix)
1096110963
bf_t a_s, *a;
1096210964
char *str;
1096310965
int saved_sign;
10966+
size_t len;
1096410967

1096510968
a = JS_ToBigInt(ctx, &a_s, val);
1096610969
if (!a)
1096710970
return JS_EXCEPTION;
1096810971
saved_sign = a->sign;
1096910972
if (a->expn == BF_EXP_ZERO)
1097010973
a->sign = 0;
10971-
// TODO(chqrlie) bf_ftoa should return the string length to the caller
10972-
str = bf_ftoa(NULL, a, radix, 0, BF_RNDZ | BF_FTOA_FORMAT_FRAC |
10974+
str = bf_ftoa(&len, a, radix, 0, BF_RNDZ | BF_FTOA_FORMAT_FRAC |
1097310975
BF_FTOA_JS_QUIRKS);
1097410976
a->sign = saved_sign;
1097510977
JS_FreeBigInt(ctx, a, &a_s);
1097610978
if (!str)
1097710979
return JS_ThrowOutOfMemory(ctx);
10978-
ret = js_new_string8(ctx, str);
10980+
ret = js_new_string8_len(ctx, str, len);
1097910981
bf_free(ctx->bf_ctx, str);
1098010982
return ret;
1098110983
}
@@ -11903,7 +11905,7 @@ static JSValue JS_StringToBigInt(JSContext *ctx, JSValue val)
1190311905
ATOD_TRIM_SPACES | ATOD_ACCEPT_EMPTY |
1190411906
ATOD_ACCEPT_HEX_PREFIX | ATOD_ACCEPT_BIN_OCT |
1190511907
ATOD_DECIMAL_AFTER_SIGN | ATOD_NO_TRAILING_CHARS;
11906-
val = js_atof(ctx, str, str + len, NULL, 10, flags);
11908+
val = js_atof(ctx, str, len, NULL, 10, flags);
1190711909
JS_FreeCString(ctx, str);
1190811910
return val;
1190911911
}
@@ -19342,13 +19344,14 @@ static __exception int next_token(JSParseState *s)
1934219344
/* number */
1934319345
{
1934419346
JSValue ret;
19345-
const uint8_t *p1;
19347+
const char *p1;
1934619348

1934719349
flags = ATOD_ACCEPT_FLOAT | ATOD_ACCEPT_UNDERSCORES | ATOD_ACCEPT_SUFFIX;
1934819350
radix = 10;
1934919351
parse_number:
19350-
ret = js_atof(s->ctx, (const char *)p, (const char *)s->buf_end,
19351-
(const char **)&p, radix, flags);
19352+
p1 = (const char *)p;
19353+
ret = js_atof(s->ctx, p1, s->buf_end - p, &p1, radix, flags);
19354+
p = (const uint8_t *)p1;
1935219355
if (JS_IsException(ret))
1935319356
goto fail;
1935419357
/* reject `10instanceof Number` */
@@ -39217,7 +39220,7 @@ static JSValue js_parseInt(JSContext *ctx, JSValue this_val,
3921739220
flags |= ATOD_ACCEPT_HEX_PREFIX; // Only 0x and 0X are supported
3921839221
radix = 10;
3921939222
}
39220-
ret = js_atof(ctx, str, str + len, NULL, radix, flags);
39223+
ret = js_atof(ctx, str, len, NULL, radix, flags);
3922139224
JS_FreeCString(ctx, str);
3922239225
return ret;
3922339226
}
@@ -39234,7 +39237,7 @@ static JSValue js_parseFloat(JSContext *ctx, JSValue this_val,
3923439237
if (!str)
3923539238
return JS_EXCEPTION;
3923639239
flags = ATOD_TRIM_SPACES | ATOD_ACCEPT_FLOAT | ATOD_ACCEPT_INFINITY;
39237-
ret = js_atof(ctx, str, str + len, NULL, 10, flags);
39240+
ret = js_atof(ctx, str, len, NULL, 10, flags);
3923839241
JS_FreeCString(ctx, str);
3923939242
return ret;
3924039243
}

0 commit comments

Comments
 (0)