From c737fd28d24cbb4e8f8851768c8376e0f17f4492 Mon Sep 17 00:00:00 2001 From: Rynco Maekawa Date: Tue, 19 Mar 2024 16:48:01 +0800 Subject: [PATCH] Add proper escaping for String::escape_to --- string/string.mbt | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/string/string.mbt b/string/string.mbt index 30d410758..1f2041e78 100644 --- a/string/string.mbt +++ b/string/string.mbt @@ -18,19 +18,38 @@ /// This method only escapes characters below 0x20 and the following characters: /// `"`, `'`, `\`. pub fn escape_to(self : String, buf : Buffer) -> Unit { + fn write_escaped_ch(ch : Char) -> Unit { + buf.write_char('\\') + buf.write_char(ch) + } + + fn to_hex_digit(i : Int) -> Char { + if i < 10 { + Char::from_int('0'.to_int() + i) + } else { + Char::from_int('a'.to_int() + (i - 10)) + } + } + let mut ix = 0 while ix < self.length() { let ch = self[ix] match ch { - '"' | '\'' | '\\' => { - buf.write_char('\\') - buf.write_char(ch) - } - '\n' => { - buf.write_char('\\') - buf.write_char('n') - } - _ => buf.write_char(ch) + '"' | '\'' | '\\' => write_escaped_ch(ch) + '\n' => write_escaped_ch('n') + '\r' => write_escaped_ch('r') + '\b' => write_escaped_ch('b') + '\t' => write_escaped_ch('t') + _ => + if ch.to_int() < 0x20 { + buf.write_char('\\') + buf.write_char('x') + let ich = ch.to_int() + buf.write_char(to_hex_digit(ich / 16)) + buf.write_char(to_hex_digit(ich % 16)) + } else { + buf.write_char(ch) + } } ix += 1 }