Reject numeric literals longer than DEC_MAX_DIGITS (999999999)

A signed-int overflow in decNumber's D2U macro lets huge literals
write attacker-controlled bytes past a stack buffer. Cap the length
before calling decNumberFromString, and pre-slice long strings in
jv_dump_string_trunc so the resulting error message doesn't itself
allocate a multi-GiB buffer.

Fixes CVE-2026-43894.
This commit is contained in:
itchyny committed 2026-05-06 19:45:24 +09:00
1 parent 532ccea608
commit 9761ceb7d6
2 files changed
+8 -1

No files matched your search

+4 -1
View File
@@ -570,7 +570,10 @@ static jvp_literal_number* jvp_literal_number_alloc(unsigned literal_length) {
}
static jv jvp_literal_number_new(const char * literal) {
jvp_literal_number* n = jvp_literal_number_alloc(strlen(literal));
size_t len = strlen(literal);
if (len > DEC_MAX_DIGITS)
return JV_INVALID;
jvp_literal_number* n = jvp_literal_number_alloc(len);
decContext *ctx = DEC_CONTEXT();
decContextClearStatus(ctx, DEC_Conversion_syntax);
+4
View File
@@ -410,6 +410,10 @@ jv jv_dump_string(jv x, int flags) {
char *jv_dump_string_trunc(jv x, char *outbuf, size_t bufsize) {
assert(bufsize > 0);
if (jv_get_kind(x) == JV_KIND_STRING &&
(size_t)jv_string_length_bytes(jv_copy(x)) > bufsize) {
x = jv_string_slice(x, 0, bufsize);
}
x = jv_dump_string(x, 0);
const char *str = jv_string_value(x);
const size_t len = strlen(str);