fix(svg): reject trailing decimal path numbers

This commit is contained in:
ldm0
2026-10-02 03:28:23 +08:00
parent e5cad522f8
commit f953b33d4e
+54 -1
View File
@@ -3,7 +3,7 @@ use svgtypes::{SimplePathSegment, SimplifyingPathParser};
pub(crate) fn path_geometry(raw: &str) -> Option<BezPath> {
let mut path = BezPath::new();
for segment in SimplifyingPathParser::from(raw) {
for segment in SimplifyingPathParser::from(path_data_before_invalid_number(raw)) {
let Ok(segment) = segment else {
break;
};
@@ -26,3 +26,56 @@ pub(crate) fn path_geometry(raw: &str) -> Option<BezPath> {
}
Some(path)
}
fn path_data_before_invalid_number(raw: &str) -> &str {
let bytes = raw.as_bytes();
let mut position = 0;
while let Some(&byte) = bytes.get(position) {
match byte {
b'\t' | b'\n' | b'\x0c' | b'\r' | b' ' | b',' | b'A' | b'C' | b'H' | b'L' | b'M'
| b'Q' | b'S' | b'T' | b'V' | b'Z' | b'a' | b'c' | b'h' | b'l' | b'm' | b'q' | b's'
| b't' | b'v' | b'z' => position += 1,
b'+' | b'-' | b'.' | b'0'..=b'9' => {
let number_start = position;
if matches!(bytes[position], b'+' | b'-') {
position += 1;
}
let integer_start = position;
while bytes.get(position).is_some_and(u8::is_ascii_digit) {
position += 1;
}
let has_integer = position != integer_start;
if bytes.get(position) == Some(&b'.') {
position += 1;
let fraction_start = position;
while bytes.get(position).is_some_and(u8::is_ascii_digit) {
position += 1;
}
if position == fraction_start {
return &raw[..number_start];
}
} else if !has_integer {
return &raw[..number_start];
}
if matches!(bytes.get(position), Some(b'e' | b'E')) {
position += 1;
if matches!(bytes.get(position), Some(b'+' | b'-')) {
position += 1;
}
let exponent_start = position;
while bytes.get(position).is_some_and(u8::is_ascii_digit) {
position += 1;
}
if position == exponent_start {
return &raw[..number_start];
}
}
}
_ => return raw,
}
}
raw
}