From 991b74dd0d8dd5323a55c65dae50f408c88ac59b Mon Sep 17 00:00:00 2001 From: Rangi <35663410+Rangi42@users.noreply.github.com> Date: Tue, 8 Jul 2025 12:34:54 -0400 Subject: [PATCH] Fix segfault with invalid RGBLINK scramble spec (#1730) --- src/link/main.cpp | 15 +++++++++------ test/link/scramble-invalid/a.asm | 2 ++ test/link/scramble-invalid/out.err | 2 ++ test/link/test.sh | 8 ++++++++ 4 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 test/link/scramble-invalid/a.asm create mode 100644 test/link/scramble-invalid/out.err diff --git a/src/link/main.cpp b/src/link/main.cpp index 397352d1..56a9046a 100644 --- a/src/link/main.cpp +++ b/src/link/main.cpp @@ -102,6 +102,7 @@ void error(FileStackNode const *where, uint32_t lineNo, char const *fmt, ...) { } } +[[gnu::format(printf, 2, 3)]] void argErr(char flag, char const *fmt, ...) { va_list args; @@ -234,7 +235,13 @@ static void parseScrambleSpec(char const *spec) { // Find the next non-blank char after the region name's end spec += regionNameLen + strspn(&spec[regionNameLen], " \t"); if (*spec != '\0' && *spec != ',' && *spec != '=') { - argErr('S', "Unexpected '%c' after region name \"%.*s\"", regionNameFmtLen, regionName); + argErr( + 'S', + "Unexpected '%c' after region name \"%.*s\"", + *spec, + regionNameFmtLen, + regionName + ); // Skip to next ',' or '=' (or NUL) and keep parsing spec += 1 + strcspn(&spec[1], ",="); } @@ -378,11 +385,7 @@ int main(int argc, char *argv[]) { char *endptr; unsigned long value = strtoul(musl_optarg, &endptr, 0); - if (musl_optarg[0] == '\0' || *endptr != '\0') { - argErr('p', ""); - value = 0xFF; - } - if (value > 0xFF) { + if (musl_optarg[0] == '\0' || *endptr != '\0' || value > 0xFF) { argErr('p', "Argument for 'p' must be a byte (between 0 and 0xFF)"); value = 0xFF; } diff --git a/test/link/scramble-invalid/a.asm b/test/link/scramble-invalid/a.asm new file mode 100644 index 00000000..58cd5c5d --- /dev/null +++ b/test/link/scramble-invalid/a.asm @@ -0,0 +1,2 @@ +SECTION "test", ROM0 +db 1, 2, 3 diff --git a/test/link/scramble-invalid/out.err b/test/link/scramble-invalid/out.err new file mode 100644 index 00000000..9f30c714 --- /dev/null +++ b/test/link/scramble-invalid/out.err @@ -0,0 +1,2 @@ +error: Invalid argument for option 'S': Unexpected ':' after region name "romx" +Linking failed with 1 error diff --git a/test/link/test.sh b/test/link/test.sh index 0013ad69..6152f29c 100755 --- a/test/link/test.sh +++ b/test/link/test.sh @@ -252,6 +252,14 @@ rgblinkQuiet -o "$gbtemp" "$otemp" "$gbtemp2" 2>"$outtemp" tryDiff "$test"/out.err "$outtemp" evaluateTest +test="scramble-invalid" +startTest +"$RGBASM" -o "$otemp" "$test"/a.asm +continueTest +rgblinkQuiet -o "$gbtemp" -S "romx := 4" "$otemp" 2>"$outtemp" +tryDiff "$test"/out.err "$outtemp" +evaluateTest + test="scramble-romx" startTest "$RGBASM" -o "$otemp" "$test"/a.asm