Don't allow invalid interpolations to occur (#1925)

Fixes #1921
This commit is contained in:
Rangi
2026-04-11 12:16:07 -04:00
committed by GitHub
parent 123201ecc6
commit df0b557638
9 changed files with 77 additions and 13 deletions
+10 -3
View File
@@ -1320,6 +1320,7 @@ static std::pair<Symbol const *, std::shared_ptr<std::string>> readInterpolation
std::string identifier; std::string identifier;
FormatSpec fmt{}; FormatSpec fmt{};
bool invalid = false;
for (;;) { for (;;) {
// Use `consumeChar()` since `peek()` might expand nested interpolations and recursively // Use `consumeChar()` since `peek()` might expand nested interpolations and recursively
@@ -1330,7 +1331,8 @@ static std::pair<Symbol const *, std::shared_ptr<std::string>> readInterpolation
} }
continue; // Restart, reading from the new buffer continue; // Restart, reading from the new buffer
} else if (int c = peek(); c == EOF || isNewline(c) || c == '"') { } else if (int c = peek(); c == EOF || isNewline(c) || c == '"') {
error("Missing '}'"); error("Unterminated interpolation");
invalid = true;
break; break;
} else if (c == '}') { } else if (c == '}') {
shiftChar(); shiftChar();
@@ -1339,15 +1341,20 @@ static std::pair<Symbol const *, std::shared_ptr<std::string>> readInterpolation
shiftChar(); shiftChar();
size_t n = fmt.parseSpec(identifier.c_str()); size_t n = fmt.parseSpec(identifier.c_str());
if (!fmt.isValid() || n != identifier.length()) { 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 { } else {
shiftChar(); shiftChar();
identifier += c; identifier += c;
} }
} }
if (invalid) {
return {nullptr, nullptr}; // Don't allow invalid interpolation to occur.
}
if (identifier.starts_with('#')) { if (identifier.starts_with('#')) {
// Skip a '#' raw symbol prefix, but after expanding any nested interpolations. // Skip a '#' raw symbol prefix, but after expanding any nested interpolations.
identifier.erase(0, 1); identifier.erase(0, 1);
+2 -2
View File
@@ -12,9 +12,9 @@ error: STRFMT: Invalid format spec for argument 2
at invalid-format.asm(5) at invalid-format.asm(5)
error: STRFMT: Invalid format spec for argument 3 error: STRFMT: Invalid format spec for argument 3
at invalid-format.asm(5) at invalid-format.asm(5)
error: Invalid format spec "5d5" error: Invalid interpolation format spec "5d5"
at invalid-format.asm(8) at invalid-format.asm(8)
error: Invalid format spec "xx" error: Invalid interpolation format spec "xx"
at invalid-format.asm(9) at invalid-format.asm(9)
error: Formatting string with sign flag '+' error: Formatting string with sign flag '+'
at invalid-format.asm(11) at invalid-format.asm(11)
+2 -2
View File
@@ -3,8 +3,8 @@ $2a %##x
42 %--4d 42 %--4d
42 %..f 42 %..f
42.00000 %q.16f %qq16f 42.00000 %q.16f %qq16f
42 42 42
2a 2a 2a
hello hello
hello hello
hello hello
+2 -4
View File
@@ -10,8 +10,6 @@ error: syntax error, unexpected label, expecting symbol
while expanding symbol `VAR_DEF` while expanding symbol `VAR_DEF`
error: syntax error, unexpected label, expecting symbol error: syntax error, unexpected label, expecting symbol
at label-macro-arg.asm::test_char(26) <- label-macro-arg.asm(39) 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) at label-macro-arg.asm::test_char(29) <- label-macro-arg.asm(39)
error: Interpolated symbol `something` does not exist Assembly aborted with 6 errors
at label-macro-arg.asm::test_char(29) <- label-macro-arg.asm(39)
Assembly aborted with 7 errors
+1 -1
View File
@@ -1,3 +1,3 @@
error: Missing '}' error: Unterminated interpolation
at nested-brackets.asm(5) at nested-brackets.asm(5)
Assembly aborted with 1 error Assembly aborted with 1 error
+1 -1
View File
@@ -1,2 +1,2 @@
OK OK
OK
+13
View File
@@ -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}", "?!"
+36
View File
@@ -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
+10
View File
@@ -0,0 +1,10 @@
!
?
$A
...
!
?
!?
?!