mirror of
https://github.com/storytold/designcraft.git
synced 2026-10-31 07:39:17 +00:00
Skip signed hex codes in Tagged Text <0x…> tags
Found while testing crates/textimport/src/tagged.rs:~190 (the `n.starts_with("0x")` branch of import: `u32::from_str_radix(&n[2..], 16)`)
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:
1 parent
7da69c16ce
commit
ae7e87ddd0
1 file changed
+14
-1
@@ -176,7 +176,10 @@ pub fn import(bytes: &[u8]) -> Result<Imported, ImportError> {
|
||||
let (name, value) = tag.split_once(':').map_or((tag.as_str(), ""), |(a, b)| (a, b));
|
||||
match name {
|
||||
n if n.starts_with("0x") => {
|
||||
if let Ok(u) = u32::from_str_radix(&n[2..], 16)
|
||||
// `from_str_radix` accepts a leading '+', so check the digits first.
|
||||
if let Some(digits) = n.get(2..)
|
||||
&& digits.bytes().all(|b| b.is_ascii_hexdigit())
|
||||
&& let Ok(u) = u32::from_str_radix(digits, 16)
|
||||
&& let Some(ch) = units.push(u)
|
||||
{
|
||||
push(&mut paras, ch, &fmt);
|
||||
@@ -278,6 +281,16 @@ mod tests {
|
||||
assert_eq!(import("<ASCII-WIN>\r\n<ParaStyle:Body>A<0xD83D>B<0xDE00>C".as_bytes()).unwrap().story.text, "ABC");
|
||||
}
|
||||
|
||||
/// `from_str_radix` accepts a leading `+`, so `<0x+41>` inserted an 'A'. A signed or empty
|
||||
/// code is not a code point tag and is skipped.
|
||||
#[test]
|
||||
fn a_signed_hex_code_tag_is_skipped() {
|
||||
for t in ["<0x+41>", "<0x-41>", "<0x>", "<0xZZ>"] {
|
||||
let src = format!("<ASCII-WIN>\r\n<ParaStyle:Body>A{t}B");
|
||||
assert_eq!(import(src.as_bytes()).unwrap().story.text, "AB", "{t}");
|
||||
}
|
||||
}
|
||||
|
||||
/// A size does not have to be non-finite to be nonsense: a file can hold `1e300`, `0` or a
|
||||
/// negative, and tagged text took all three and set them on the text (#1593). They are now
|
||||
/// dropped, as RTF and DOCX already dropped them, so the text keeps its style's size.
|
||||
|
||||
Reference in new issue
Block a user