Skip to content

Commit 7d06d94

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

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

src/serializer.rs

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

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

0 commit comments

Comments
 (0)