Vydáno ve v2026.10.17, 21. 10. 2026 Oprava chyby v upstreamu mise
mise: neukončený řetězec v aqua šabloně zacyklil lexer
Náš skener upozornil, že mise, správce verzí vývojářských nástrojů, se mohl při čtení šablony z položky aqua registry donekonečna zacyklit. Poslali jsme pull request s opravou a regresním testem. Správce Jeff Dickey přidal další testy a týž den ho začlenil. Oprava vyšla v mise v2026.10.17.
Co bylo špatně
mise instaluje řadu nástrojů přes backend aqua. Položky registry popisují URL ke stažení a názvy souborů malými šablonami ve stylu Go a mise je parsuje vlastním lexerem v crates/aqua-registry/src/template.rs.
Když token začínal znakem ", lex() hledal uzavírací uvozovku. Pokud žádná nebyla, nebo byly všechny kandidátní uvozovky escapované, vstup se neposunul a vnější smyčka while !code.is_empty() vstupovala pořád do stejné větve. Vadná šablona jako {{"abc}} tak mise zasekla místo toho, aby ohlásil chybu.
Kontrola escapování měla ještě druhou vadu: bajtový offset z match_indices používala jako index znaku (code.chars().nth(end)) a nerozlišovala \" od \\".
Šablony pocházejí ze zabudované registry nebo z registry, které si nastaví sám uživatel. Jde tedy o zaseknutí na vadné položce registry, ne o vzdálený útok. Upstream to popisuje stejně.
Jak to bylo opraveno
Lexer teď před každou kandidátní uvozovkou spočítá zpětná lomítka po bajtech, za uzavírací ji považuje jen při sudém počtu, a když uzavírací uvozovku nenajde, skončí chybou:
for (end, _) in code[1..].match_indices('"') {
- if code.chars().nth(end) != Some('\\') {
- tokens.push(Token::String(&code[1..end + 1]));
+ let slash_count = code[1..=end]
+ .bytes()
+ .rev()
+ .take_while(|&b| b == b'\\')
+ .count();
+ if slash_count % 2 == 0 {
+ tokens.push(Token::String(&code[1..=end]));
code = &code[end + 2..];
+ found = true;
break;
}
}
+ if !found {
+ bail!("unterminated string literal");
+ }
Náš pull request přidal regresní test test_render_unterminated_string_fails. Jeff Dickey (jdx) pak doplnil commity, které ověřují přesné znění chyby „unterminated string literal“ a pokrývají prázdný řetězec, a pull request začlenil. Poznámky k vydání mise v2026.10.17 změnu popisují takto:
“An aqua registry template with an unterminated string literal now fails with an "unterminated string literal" error instead of hanging. Escaped quotes after backslashes are also detected correctly.”
Časová osa
- Říjen 2026. Sken stromu mise upozornil na nekonečnou smyčku v
lex(); triáž (model qwen3.8-27b) nález potvrdila a zaseknutí šlo zopakovat na malém vstupu. - 20. 10. Otevřeli jsme pull request #14752 s opravou a regresním testem. Jeff Dickey přidal tři commity s formátováním a dalšími testy a týž den ho začlenil jako b915325.
- 21. 10. Oprava vyšla v mise v2026.10.17.
Jak to číst
Triáž skeneru počítala se škodlivou registry nebo útočníkem uprostřed spojení. Ve skutečnosti šablony pocházejí z registry, kterou mise dodává, nebo z registry, kterou si zvolil uživatel. Poctivý popis je tedy zaseknutí na vadné šabloně a stejně to popisuje i upstream. Nálezy jsou podněty pro lidi, ne rozsudky.