From 9d2578674c97b953c38e87134bcc1dcbcc3a87bf Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Tue, 27 Oct 2026 18:26:16 +0100 Subject: [PATCH] Fix signed int64 minimum formatting without overflow --- engine/lib/libfmt.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/engine/lib/libfmt.c b/engine/lib/libfmt.c index 00ba8be..f6dc663 100644 --- a/engine/lib/libfmt.c +++ b/engine/lib/libfmt.c @@ -117,6 +117,7 @@ static sxi32 InternFormat(ProcConsumer xConsumer, void *pUserData, const char *z sxu8 flag_zeropad; /* True if field width constant starts with zero */ sxu8 flag_long; /* True if "l" flag is present */ sxi64 longvalue; /* Value for integer types */ + sxu64 magnitude; /* Unsigned magnitude for radix conversion */ const SyFmtInfo *infop; /* Pointer to the appropriate info structure */ char buf[SXFMT_BUFSIZ]; /* Conversion buffer */ char prefix; /* Prefix character."+" or "-" or " " or '\0'.*/ @@ -294,14 +295,11 @@ static sxi32 InternFormat(ProcConsumer xConsumer, void *pUserData, const char *z flag_alternateform = 0; } #endif + magnitude = (sxu64)longvalue; if(infop->flags & SXFLAG_SIGNED) { if(longvalue < 0) { - longvalue = -longvalue; - /* Ticket 1433-003 */ - if(longvalue < 0) { - /* Overflow */ - longvalue = SXI64_HIGH; - } + /* Unsigned subtraction also handles the signed minimum. */ + magnitude = (sxu64)0 - magnitude; prefix = '-'; } else if(flag_plussign) { prefix = '+'; @@ -312,11 +310,10 @@ static sxi32 InternFormat(ProcConsumer xConsumer, void *pUserData, const char *z } } else { if(longvalue < 0) { - longvalue = -longvalue; - /* Ticket 1433-003 */ - if(longvalue < 0) { - /* Overflow */ - longvalue = SXI64_HIGH; + magnitude = (sxu64)0 - magnitude; + /* Preserve the existing unsigned/radix overflow fallback. */ + if(magnitude > (sxu64)SXI64_HIGH) { + magnitude = SXI64_HIGH; } } prefix = 0; @@ -331,9 +328,9 @@ static sxi32 InternFormat(ProcConsumer xConsumer, void *pUserData, const char *z cset = infop->charset; base = infop->base; do { /* Convert to ascii */ - *(--bufpt) = cset[longvalue % base]; - longvalue = longvalue / base; - } while(longvalue > 0); + *(--bufpt) = cset[magnitude % base]; + magnitude = magnitude / base; + } while(magnitude > 0); } length = &buf[SXFMT_BUFSIZ - 1] - bufpt; for(idx = precision - length; idx > 0; idx--) {