fmt: scandigits rejects the i32-overflowing last digit (F-A)
The one-sided guard `v > 214748364` never fired for the last digit: at v==214748364 a next digit of '8'/'9' made `v*10+digit` overflow i32 and wrap negative, slipping past the signed args-index bound check at fmt.ww:703 -> OOB arg read -> SIGSEGV on any format directive carrying an over-i32 digit run (index, width or precision). Complete it to the canonical two-part pre-multiply Horner guard (MAX/10, MAX%10). Hand-rolled in signed i32, not Hare scan_sz's unsigned post-multiply wrap-check (ref/hare/strconv/stou.ha:60), which would be signed-overflow UB-class here; noted at the site. Table-driven subprocess test over all three scandigits call sites, 5 rows x both stages; reverting the guard reproduces exit=139.
This commit is contained in:
8
Makefile
8
Makefile
@@ -478,6 +478,7 @@ TESTS = $(BIN)/test_smoke $(BIN)/test_lex $(BIN)/test_parse $(BIN)/test_check \
|
||||
$(BIN)/test_memio_vstream_run \
|
||||
$(BIN)/test_fmt_handle_run \
|
||||
$(BIN)/test_fmt_mods_run \
|
||||
$(BIN)/test_fmt_scanoverflow_run \
|
||||
$(BIN)/test_fmt_compositions_run \
|
||||
$(BIN)/test_fmt_int_run \
|
||||
$(BIN)/test_fieldfn_leaf_collide_run \
|
||||
@@ -2034,6 +2035,13 @@ $(BIN)/test_fmt_mods_run: test/wcc/780_fmt_mods_run.c \
|
||||
$(LIB)/libwwrt.a | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
$(BIN)/test_fmt_scanoverflow_run: test/wcc/989_fmt_scanoverflow_run.c \
|
||||
$(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
||||
$(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww $(BIN)/w6l_ww \
|
||||
lib/fmt/fmt.ww \
|
||||
$(LIB)/libwwrt.a | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
$(BIN)/test_fmt_compositions_run: test/wcc/781_fmt_compositions_run.c \
|
||||
$(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
||||
$(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww $(BIN)/w6l_ww \
|
||||
|
||||
Reference in New Issue
Block a user