From df0b55763847e8fbb9e9cc3cce37776de74d6f68 Mon Sep 17 00:00:00 2001 From: Rangi <35663410+Rangi42@users.noreply.github.com> Date: Sat, 11 Apr 2026 12:16:07 -0400 Subject: [PATCH] Don't allow invalid interpolations to occur (#1925) Fixes #1921 --- src/asm/lexer.cpp | 13 ++++++--- test/asm/invalid-format.err | 4 +-- test/asm/invalid-format.out | 4 +-- test/asm/label-macro-arg.err | 6 ++--- test/asm/nested-brackets.err | 2 +- test/asm/nested-brackets.out | 2 +- test/asm/unterminated-interpolation.asm | 13 +++++++++ test/asm/unterminated-interpolation.err | 36 +++++++++++++++++++++++++ test/asm/unterminated-interpolation.out | 10 +++++++ 9 files changed, 77 insertions(+), 13 deletions(-) create mode 100644 test/asm/unterminated-interpolation.asm create mode 100644 test/asm/unterminated-interpolation.err create mode 100644 test/asm/unterminated-interpolation.out diff --git a/src/asm/lexer.cpp b/src/asm/lexer.cpp index 92b1aade..6739e90a 100644 --- a/src/asm/lexer.cpp +++ b/src/asm/lexer.cpp @@ -1320,6 +1320,7 @@ static std::pair> readInterpolation std::string identifier; FormatSpec fmt{}; + bool invalid = false; for (;;) { // Use `consumeChar()` since `peek()` might expand nested interpolations and recursively @@ -1330,7 +1331,8 @@ static std::pair> readInterpolation } continue; // Restart, reading from the new buffer } else if (int c = peek(); c == EOF || isNewline(c) || c == '"') { - error("Missing '}'"); + error("Unterminated interpolation"); + invalid = true; break; } else if (c == '}') { shiftChar(); @@ -1339,15 +1341,20 @@ static std::pair> readInterpolation shiftChar(); size_t n = fmt.parseSpec(identifier.c_str()); if (!fmt.isValid() || n != identifier.length()) { - error("Invalid format spec \"%s\"", identifier.c_str()); + error("Invalid interpolation format spec \"%s\"", identifier.c_str()); + invalid = true; } - identifier.clear(); // Now that format has been set, restart at beginning of string + identifier.clear(); // Now that format has been set, restart at beginning of string. } else { shiftChar(); identifier += c; } } + if (invalid) { + return {nullptr, nullptr}; // Don't allow invalid interpolation to occur. + } + if (identifier.starts_with('#')) { // Skip a '#' raw symbol prefix, but after expanding any nested interpolations. identifier.erase(0, 1); diff --git a/test/asm/invalid-format.err b/test/asm/invalid-format.err index b62c621b..808b8c13 100644 --- a/test/asm/invalid-format.err +++ b/test/asm/invalid-format.err @@ -12,9 +12,9 @@ error: STRFMT: Invalid format spec for argument 2 at invalid-format.asm(5) error: STRFMT: Invalid format spec for argument 3 at invalid-format.asm(5) -error: Invalid format spec "5d5" +error: Invalid interpolation format spec "5d5" at invalid-format.asm(8) -error: Invalid format spec "xx" +error: Invalid interpolation format spec "xx" at invalid-format.asm(9) error: Formatting string with sign flag '+' at invalid-format.asm(11) diff --git a/test/asm/invalid-format.out b/test/asm/invalid-format.out index 633d8403..a14b199a 100644 --- a/test/asm/invalid-format.out +++ b/test/asm/invalid-format.out @@ -3,8 +3,8 @@ $2a %##x 42 %--4d 42 %..f 42.00000 %q.16f %qq16f - 42 42 -2a 2a + 42 +2a hello hello hello diff --git a/test/asm/label-macro-arg.err b/test/asm/label-macro-arg.err index 1ad79c46..bae97dfe 100644 --- a/test/asm/label-macro-arg.err +++ b/test/asm/label-macro-arg.err @@ -10,8 +10,6 @@ error: syntax error, unexpected label, expecting symbol while expanding symbol `VAR_DEF` error: syntax error, unexpected label, expecting symbol at label-macro-arg.asm::test_char(26) <- label-macro-arg.asm(39) -error: Invalid format spec "sizeof_" +error: Invalid interpolation format spec "sizeof_" at label-macro-arg.asm::test_char(29) <- label-macro-arg.asm(39) -error: Interpolated symbol `something` does not exist - at label-macro-arg.asm::test_char(29) <- label-macro-arg.asm(39) -Assembly aborted with 7 errors +Assembly aborted with 6 errors diff --git a/test/asm/nested-brackets.err b/test/asm/nested-brackets.err index b5fbc276..19f809e2 100644 --- a/test/asm/nested-brackets.err +++ b/test/asm/nested-brackets.err @@ -1,3 +1,3 @@ -error: Missing '}' +error: Unterminated interpolation at nested-brackets.asm(5) Assembly aborted with 1 error diff --git a/test/asm/nested-brackets.out b/test/asm/nested-brackets.out index 2c94e483..885fd66b 100644 --- a/test/asm/nested-brackets.out +++ b/test/asm/nested-brackets.out @@ -1,2 +1,2 @@ OK -OK + diff --git a/test/asm/unterminated-interpolation.asm b/test/asm/unterminated-interpolation.asm new file mode 100644 index 00000000..b73a681a --- /dev/null +++ b/test/asm/unterminated-interpolation.asm @@ -0,0 +1,13 @@ +def x = 10 +println "{d:x", "!" +println "{v:x", "?" +println x, {d:x + +def name equs "x" +println "{{name", "..." +println "{v:{name}}!" +println "{v:{name}?" +println "{v:{name}", "?" +println "{d:{v:name}}!?" +println "{d:{v:name}?!" +println "{d:{v:name}", "?!" diff --git a/test/asm/unterminated-interpolation.err b/test/asm/unterminated-interpolation.err new file mode 100644 index 00000000..ab2f5f8f --- /dev/null +++ b/test/asm/unterminated-interpolation.err @@ -0,0 +1,36 @@ +error: Unterminated interpolation + at unterminated-interpolation.asm(2) +error: Invalid interpolation format spec "v" + at unterminated-interpolation.asm(3) +error: Unterminated interpolation + at unterminated-interpolation.asm(3) +error: Unterminated interpolation + at unterminated-interpolation.asm(4) +error: Unterminated interpolation + at unterminated-interpolation.asm(7) +error: Unterminated interpolation + at unterminated-interpolation.asm(7) +error: Invalid interpolation format spec "v" + at unterminated-interpolation.asm(8) +error: Invalid interpolation format spec "v" + at unterminated-interpolation.asm(9) +error: Unterminated interpolation + at unterminated-interpolation.asm(9) +error: Invalid interpolation format spec "v" + at unterminated-interpolation.asm(10) +error: Unterminated interpolation + at unterminated-interpolation.asm(10) + while expanding symbol `name` +error: Invalid interpolation format spec "v" + at unterminated-interpolation.asm(11) +error: Interpolated symbol `` does not exist + at unterminated-interpolation.asm(11) +error: Invalid interpolation format spec "v" + at unterminated-interpolation.asm(12) +error: Unterminated interpolation + at unterminated-interpolation.asm(12) +error: Invalid interpolation format spec "v" + at unterminated-interpolation.asm(13) +error: Unterminated interpolation + at unterminated-interpolation.asm(13) +Assembly aborted with 17 errors diff --git a/test/asm/unterminated-interpolation.out b/test/asm/unterminated-interpolation.out new file mode 100644 index 00000000..17d0d3e8 --- /dev/null +++ b/test/asm/unterminated-interpolation.out @@ -0,0 +1,10 @@ +! +? +$A +... +! + +? +!? + +?!