@@ -311,6 +311,11 @@ where
311
311
}
312
312
}
313
313
314
+ fn is_valid_unicode_escape ( s : & str ) -> bool {
315
+ // Check if it is a valid Unicode escape sequence
316
+ s. len ( ) == 4 && s. chars ( ) . all ( |c| c. is_digit ( 16 ) )
317
+ }
318
+
314
319
impl < W > fmt:: Write for CssStringWriter < ' _ , W >
315
320
where
316
321
W : fmt:: Write ,
@@ -320,7 +325,36 @@ where
320
325
for ( i, b) in s. bytes ( ) . enumerate ( ) {
321
326
let escaped = match_byte ! { b,
322
327
b'"' => Some ( "\\ \" " ) ,
323
- b'\\' => Some ( "\\ \\ " ) ,
328
+ b'\\' => {
329
+ // Handle backslash
330
+ if i + 1 < s. len( ) {
331
+ match s. as_bytes( ) [ i + 1 ] {
332
+ b'0' ..=b'9' | b'a' ..=b'f' | b'A' ..=b'F' => {
333
+ // If the character following the backslash is part of a Unicode escape sequence, preserve the entire sequence
334
+ if i + 4 <= s. len( ) {
335
+ let next_4_chars = & s[ i + 1 ..i + 5 ] ;
336
+ if is_valid_unicode_escape( next_4_chars) {
337
+ // Preserve the entire Unicode escape sequence
338
+ Some ( "\\ " )
339
+ } else {
340
+ // If it is not a valid Unicode escape sequence, escape the backslash itself
341
+ Some ( "\\ \\ " )
342
+ }
343
+ } else {
344
+ // If there are fewer than 4 characters following, escape the backslash itself
345
+ Some ( "\\ \\ " )
346
+ }
347
+ }
348
+ _ => {
349
+ // If the character following the backslash is any other character, escape the backslash itself
350
+ Some ( "\\ \\ " )
351
+ }
352
+ }
353
+ } else {
354
+ // If the backslash is the last character, escape the backslash itself
355
+ Some ( "\\ \\ " )
356
+ }
357
+ } ,
324
358
b'\0' => Some ( "\u{FFFD} " ) ,
325
359
b'\x01' ..=b'\x1F' | b'\x7F' => None ,
326
360
_ => continue ,
0 commit comments