fixed buffer overflow in js_bigint_from_string()

This commit is contained in:
Fabrice Bellard 2025-08-25 14:24:06 +02:00
parent c942978927
commit e1c18befb8

View File

@ -11745,6 +11745,7 @@ static JSBigInt *js_bigint_from_string(JSContext *ctx,
const char *str, int radix) const char *str, int radix)
{ {
const char *p = str; const char *p = str;
size_t n_digits1;
int is_neg, n_digits, n_limbs, len, log2_radix, n_bits, i; int is_neg, n_digits, n_limbs, len, log2_radix, n_bits, i;
JSBigInt *r; JSBigInt *r;
js_limb_t v, c, h; js_limb_t v, c, h;
@ -11756,10 +11757,16 @@ static JSBigInt *js_bigint_from_string(JSContext *ctx,
} }
while (*p == '0') while (*p == '0')
p++; p++;
n_digits = strlen(p); n_digits1 = strlen(p);
/* the real check for overflox is done js_bigint_new(). Here
we just avoid integer overflow */
if (n_digits1 > JS_BIGINT_MAX_SIZE * JS_LIMB_BITS) {
JS_ThrowRangeError(ctx, "BigInt is too large to allocate");
return NULL;
}
n_digits = n_digits1;
log2_radix = 32 - clz32(radix - 1); /* ceil(log2(radix)) */ log2_radix = 32 - clz32(radix - 1); /* ceil(log2(radix)) */
/* compute the maximum number of limbs */ /* compute the maximum number of limbs */
/* XXX: overflow */
if (radix == 10) { if (radix == 10) {
n_bits = (n_digits * 27 + 7) / 8; /* >= ceil(n_digits * log2(10)) */ n_bits = (n_digits * 27 + 7) / 8; /* >= ceil(n_digits * log2(10)) */
} else { } else {
@ -12207,8 +12214,10 @@ static JSValue js_atof(JSContext *ctx, const char *str, const char **pp,
if (has_legacy_octal || is_float) if (has_legacy_octal || is_float)
goto fail; goto fail;
r = js_bigint_from_string(ctx, buf, radix); r = js_bigint_from_string(ctx, buf, radix);
if (!r) if (!r) {
goto mem_error; val = JS_EXCEPTION;
goto done;
}
val = JS_CompactBigInt(ctx, r); val = JS_CompactBigInt(ctx, r);
} }
break; break;