From: Fabrice Bellard Date: Mon, 26 Oct 2026 10:19:52 +0000 (+0100) Subject: intl: removed use after free - removed buffer overflow - fixed invalid use of isalnum() X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=4490e58b3a105bbad2fd034c45e68df1e891e3cc;p=quickjs.git intl: removed use after free - removed buffer overflow - fixed invalid use of isalnum() --- diff --git a/intl/displaynames.c b/intl/displaynames.c index 5dccaa2..aad243e 100644 --- a/intl/displaynames.c +++ b/intl/displaynames.c @@ -364,17 +364,15 @@ static JSValue js_displaynames_of(JSContext *ctx, JSValueConst this_val, } if (!name) { + JSValue v; if (!strcmp(s->fallback, "none")) { JS_FreeCString(ctx, code); return JS_UNDEFINED; } /* fallback "code": return the code itself */ - if (!strcmp(s->type, "currency")) { - JS_FreeCString(ctx, code); - return JS_NewString(ctx, code); - } + v = JS_NewString(ctx, code); JS_FreeCString(ctx, code); - return JS_NewString(ctx, code); + return v; } JS_FreeCString(ctx, code); diff --git a/intl/listformat.c b/intl/listformat.c index 23354a5..69e5577 100644 --- a/intl/listformat.c +++ b/intl/listformat.c @@ -137,7 +137,7 @@ static JSValue string_list_from_iterable(JSContext *ctx, JSValueConst iterable) JSValue iter = JS_UNDEFINED; JSValue next_method = JS_UNDEFINED; JSValue r = JS_UNDEFINED; - JSValue v = JS_UNDEFINED; + JSValue v; BOOL done; int64_t k; @@ -157,9 +157,11 @@ static JSValue string_list_from_iterable(JSContext *ctx, JSValueConst iterable) for (k = 0;; k++) { v = JS_IteratorNext(ctx, iter, next_method, &done); if (JS_IsException(v)) - goto exception_close; - if (done) + goto exception; + if (done) { + JS_FreeValue(ctx, v); break; + } if (!JS_IsString(v)) { JS_FreeValue(ctx, v); JS_ThrowTypeError(ctx, "iterable yielded non-string value"); @@ -178,7 +180,6 @@ static JSValue string_list_from_iterable(JSContext *ctx, JSValueConst iterable) exception: JS_FreeValue(ctx, r); r = JS_EXCEPTION; - JS_FreeValue(ctx, v); goto done; } @@ -416,7 +417,7 @@ static JSValue js_listformat_format(JSContext *ctx, JSValueConst this_val, if (!s) return JS_EXCEPTION; - arr = string_list_from_iterable(ctx, argc > 0 ? argv[0] : JS_UNDEFINED); + arr = string_list_from_iterable(ctx, argv[0]); if (JS_IsException(arr)) return JS_EXCEPTION; @@ -493,7 +494,7 @@ static JSValue js_listformat_formatToParts(JSContext *ctx, JSValueConst this_val if (!s) return JS_EXCEPTION; - arr = string_list_from_iterable(ctx, argc > 0 ? argv[0] : JS_UNDEFINED); + arr = string_list_from_iterable(ctx, argv[0]); if (JS_IsException(arr)) return JS_EXCEPTION; diff --git a/intl/numberformat.c b/intl/numberformat.c index fac43a1..60ef2f1 100644 --- a/intl/numberformat.c +++ b/intl/numberformat.c @@ -786,6 +786,7 @@ static int intl_mv_round_fraction(JSContext *ctx, IntlMV *mv, int maxFD, int min /* For scale < 0, drop last k zeros (result is multiple of 10^k) */ if (k > 0) { scaled_len -= k; + scaled_len = max_int(scaled_len, 0); /* XXX: fail safe */ scaled_digits[scaled_len] = '\0'; } @@ -1133,6 +1134,7 @@ static int intl_mv_round_significant(JSContext *ctx, IntlMV *mv, int maxSD, int /* Drop the last 'drop' zeros */ scaled_len -= drop; + scaled_len = max_int(scaled_len, 0); /* XXX: fail safe */ scaled_digits[scaled_len] = '\0'; js_free(ctx, mv->digits); @@ -1974,6 +1976,8 @@ static void add_grouping(DynBuf *db, const char *digits, int len, const char *gr remaining -= first; while (remaining > 0) { int g = remaining > gs2 ? gs2 : remaining; + if (num_groups >= countof(groups)) + break; /* XXX: return an error or dynamic groups alloc ? */ groups[num_groups++] = g; remaining -= g; } @@ -2046,6 +2050,8 @@ static void nf_add_grouped_integer_parts(JSContext *ctx, JSValue parts, const ch remaining -= first; while (remaining > 0) { int g = remaining > gs2 ? gs2 : remaining; + if (num_groups >= countof(groups)) + break; /* XXX: return an error or dynamic groups alloc ? */ groups[num_groups++] = g; remaining -= g; } diff --git a/intl/segmenter.c b/intl/segmenter.c index 7035405..3c4bd9d 100644 --- a/intl/segmenter.c +++ b/intl/segmenter.c @@ -233,7 +233,7 @@ static JSValue create_segment_data(JSContext *ctx, JSValueConst str_val, /* Returns 1 if c is "word-like" (letter, digit, non-ASCII, or some punct) */ static int is_word_char(int c) { - return isalnum(c) || c > 127 || + return c > 127 || isalnum(c) || c == '.' || c == '-' || c == '+' || c == '%' || c == '$' || c == '_' || c == '\''; }