Decode JavaScript hex and control escapes in AF script strings

Found while testing crates/forms/src/af.rs:166 (Parser::string)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
NetterSilver
2026-10-20 09:25:47 +00:00
co-authored by Claude Haiku 5.5
parent ec0a965074
commit 1cd36bfcb2
+21
View File
@@ -196,6 +196,18 @@ impl Parser<'_> {
b'n' => out.push(b'\n'),
b'r' => out.push(b'\r'),
b't' => out.push(b'\t'),
b'b' => out.push(0x08),
b'f' => out.push(0x0C),
b'v' => out.push(0x0B),
b'0' => out.push(0),
b'x' => {
let digits = self.s.get(self.i..self.i.checked_add(2)?)?;
let code = hex4(&[b'0', b'0', digits[0], digits[1]])?;
self.i += 2;
let ch = char::from_u32(u32::from(code)).unwrap_or('\u{FFFD}');
let mut encoded = [0u8; 4];
out.extend_from_slice(ch.encode_utf8(&mut encoded).as_bytes());
}
b'u' => {
let code = hex4(self.s.get(self.i..self.i.checked_add(4)?)?)?;
self.i += 4;
@@ -1111,6 +1123,15 @@ pub fn calculate(c: &Calculate, values: &dyn Fn(&str) -> Vec<String>) -> Option<
mod tests {
use super::*;
#[test]
fn javascript_escapes_are_decoded() {
assert_eq!(
parse_format("AFNumber_Format(2, 0, 0, 0, \"\\x24\", true);"),
Some(Format::Number { decimals: 2, sep: 0, neg: 0, currency: "$".into(), prepend: true })
);
assert_eq!(parse_format("AFDate_FormatEx(\"\\b\\f\\v\\0\\q\");"), Some(Format::Date("\u{8}\u{c}\u{b}\0q".into())));
}
#[test]
fn scripts_are_recognised_and_written_back() {
assert_eq!(