@@ -222,7 +222,7 @@ where
222
222
{
223
223
loop {
224
224
let ch = tri ! ( next_or_eof( self ) ) ;
225
- if !is_escape ( ch) {
225
+ if !is_escape ( ch, true ) {
226
226
scratch. push ( ch) ;
227
227
continue ;
228
228
}
@@ -343,7 +343,7 @@ where
343
343
fn ignore_str ( & mut self ) -> Result < ( ) > {
344
344
loop {
345
345
let ch = tri ! ( next_or_eof( self ) ) ;
346
- if !is_escape ( ch) {
346
+ if !is_escape ( ch, true ) {
347
347
continue ;
348
348
}
349
349
match ch {
@@ -427,6 +427,14 @@ impl<'a> SliceRead<'a> {
427
427
}
428
428
429
429
fn skip_to_escape ( & mut self , forbid_control_characters : bool ) {
430
+ // Immediately bail-out on empty strings and consecutive escapes (e.g. \u041b\u0435)
431
+ if self . index == self . slice . len ( )
432
+ || is_escape ( self . slice [ self . index ] , forbid_control_characters)
433
+ {
434
+ return ;
435
+ }
436
+ self . index += 1 ;
437
+
430
438
let rest = & self . slice [ self . index ..] ;
431
439
432
440
if !forbid_control_characters {
@@ -472,7 +480,7 @@ impl<'a> SliceRead<'a> {
472
480
#[ cold]
473
481
#[ inline( never) ]
474
482
fn skip_to_escape_slow ( & mut self ) {
475
- while self . index < self . slice . len ( ) && !is_escape ( self . slice [ self . index ] ) {
483
+ while self . index < self . slice . len ( ) && !is_escape ( self . slice [ self . index ] , true ) {
476
484
self . index += 1 ;
477
485
}
478
486
}
@@ -825,8 +833,8 @@ pub trait Fused: private::Sealed {}
825
833
impl < ' a > Fused for SliceRead < ' a > { }
826
834
impl < ' a > Fused for StrRead < ' a > { }
827
835
828
- fn is_escape ( ch : u8 ) -> bool {
829
- ch == b'"' || ch == b'\\' || ch < 0x20
836
+ fn is_escape ( ch : u8 , including_control_characters : bool ) -> bool {
837
+ ch == b'"' || ch == b'\\' || ( including_control_characters && ch < 0x20 )
830
838
}
831
839
832
840
fn next_or_eof < ' de , R > ( read : & mut R ) -> Result < u8 >
0 commit comments