diff options
| author | Jonas Maier <jonas@x77.dev> | 2026-03-10 10:32:25 +0100 |
|---|---|---|
| committer | Jonas Maier <jonas@x77.dev> | 2026-03-10 10:32:25 +0100 |
| commit | 961314b443849840e15d079ebd5724383489fd05 (patch) | |
| tree | fbc48d21902757a3d4e89d170a2d46bb93c5ae5d | |
| parent | 876721d83999d3682cd8f959768824beadfd1ad5 (diff) | |
| download | pish-961314b443849840e15d079ebd5724383489fd05.tar.gz | |
hex escape
| -rw-r--r-- | src/parse/mod.rs | 24 | ||||
| -rw-r--r-- | src/parse/test.rs | 10 |
2 files changed, 33 insertions, 1 deletions
diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 4c19c96..f08426e 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -454,7 +454,7 @@ impl Parse for ExpString { let mut delim = b.peek(); if delim == b'\'' || delim == b'"' { b.adv(); - } else if is_symbol(delim) && delim != b'$' { + } else if is_symbol(delim) && delim != b'$' && delim != b'\\' { return if already_parsed { Ok(Self { parts }) } else { @@ -475,10 +475,30 @@ impl Parse for ExpString { b'r' => b'\r', b't' => b'\t', b'e' => 0x1b, // escape + b'x' => { + // parse two hex digits + b.adv(); + if b.buf.len() < 2 { + Err(ParseError::Eof)?; + } + let x1 = b.peek(); + b.adv(); + let x2 = b.peek(); + + if !x1.is_ascii_hexdigit() || !x2.is_ascii_hexdigit() { + Err(ParseError::NotHexDigit)?; + } + + let x1 = (x1 as char).to_digit(16).unwrap_or(0); + let x2 = (x2 as char).to_digit(16).unwrap_or(0); + + ((x1 << 4) | x2) as u8 + } _ => x, }; add_char(p, x); escaping = false; + already_parsed = true; b.adv(); continue; } @@ -650,6 +670,8 @@ pub enum ParseError { NotAFunDecl, NotAVarAssign, + + NotHexDigit, } type Result<T> = std::result::Result<T, ParseError>; diff --git a/src/parse/test.rs b/src/parse/test.rs index 92124b0..4ae6341 100644 --- a/src/parse/test.rs +++ b/src/parse/test.rs @@ -109,3 +109,13 @@ fn escape_carriage_return() { fn escape_tab() { parse_test(parse(b"\"\\t\""), pipes([cmd([estr(b"\t")])])); } + +#[test] +fn escape_hex_1() { + parse_test(parse(b"\\x41"), pipes([cmd([estr(b"A")])])); +} + +#[test] +fn escape_hex_2() { + parse_test(parse(b"\\x0a"), pipes([cmd([estr(b"\n")])])); +} |
