@@ -221,6 +221,30 @@ void main() {
221221 expect (Utils .unescape ('%20%u0020' ), equals (' ' ));
222222 // An invalid escape sequence should remain unchanged.
223223 expect (Utils .unescape ('abc%g' ), equals ('abc%g' ));
224+
225+ // The input "%uZZZZ" is 6 characters long so it passes the length check.
226+ // However, "ZZZZ" is not valid hex so int.parse will throw a FormatException.
227+ // In that case, the catch block writes the literal '%' and increments i by 1.
228+ // The remainder of the string is then processed normally.
229+ // For input "%uZZZZ", the processing is:
230+ // - At i = 0, encounter '%', then since i+1 is 'u' and there are 6 characters, try block is entered.
231+ // - int.parse("ZZZZ", radix: 16) fails, so the catch writes '%' and i becomes 1.
232+ // - Then the rest of the string ("uZZZZ") is appended as literal.
233+ // The expected result is "%uZZZZ".
234+ expect (Utils .unescape ('%uZZZZ' ), equals ('%uZZZZ' ));
235+
236+ // Input "%u12" has only 4 characters.
237+ // For a valid %u escape we need 6 characters.
238+ // Thus, the branch "Not enough characters for a valid %u escape" is triggered,
239+ // which writes the literal '%' and increments i.
240+ // The remainder of the string ("u12") is then appended as literal.
241+ // Expected output is "%u12".
242+ expect (Utils .unescape ('%u12' ), equals ('%u12' ));
243+
244+ // When "%" is the last character of the string (with no following characters),
245+ // the code writes it as literal.
246+ // For example, "abc%" should remain "abc%".
247+ expect (Utils .unescape ('abc%' ), equals ('abc%' ));
224248 });
225249
226250 test ('unescape huge string' , () {
0 commit comments