Skip to content

Commit e1336a5

Browse files
committed
serializer: Fix handling of backslashes and Unicode escape sequences in CSS content
1 parent fa6f5eb commit e1336a5

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

src/serializer.rs

+31-1
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,36 @@ where
311311
}
312312
}
313313

314+
fn handle_backslash(s: &str, i: usize) -> Option<&'static str> {
315+
let bytes = s.as_bytes();
316+
if i + 1 < s.len() {
317+
match bytes[i + 1] {
318+
b'0'..=b'9' | b'a'..=b'f' | b'A'..=b'F' => {
319+
// If the character following the backslash is part of a Unicode escape sequence, preserve the entire sequence
320+
let mut j = i + 1;
321+
while j < s.len() && bytes[j].is_ascii_hexdigit() && j - i < 6 {
322+
j += 1;
323+
}
324+
if j - i > 1 {
325+
// Preserve the entire Unicode escape sequence
326+
Some("\\")
327+
} else {
328+
// If it is not a valid Unicode escape sequence, escape the backslash itself
329+
Some("\\\\")
330+
}
331+
}
332+
_ => {
333+
// If the character following the backslash is any other character, escape the backslash itself
334+
Some("\\\\")
335+
}
336+
}
337+
} else {
338+
// If the backslash is the last character, escape the backslash itself
339+
Some("\\\\")
340+
}
341+
}
342+
343+
314344
impl<W> fmt::Write for CssStringWriter<'_, W>
315345
where
316346
W: fmt::Write,
@@ -320,7 +350,7 @@ where
320350
for (i, b) in s.bytes().enumerate() {
321351
let escaped = match_byte! { b,
322352
b'"' => Some("\\\""),
323-
b'\\' => Some("\\\\"),
353+
b'\\' => handle_backslash(s, i),
324354
b'\0' => Some("\u{FFFD}"),
325355
b'\x01'..=b'\x1F' | b'\x7F' => None,
326356
_ => continue,

0 commit comments

Comments
 (0)