Skip to content

Commit e43da5e

Browse files
committed
Immediately bail-out on empty strings
1 parent 8389d8a commit e43da5e

File tree

1 file changed

+13
-5
lines changed

1 file changed

+13
-5
lines changed

src/read.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ where
222222
{
223223
loop {
224224
let ch = tri!(next_or_eof(self));
225-
if !is_escape(ch) {
225+
if !is_escape(ch, true) {
226226
scratch.push(ch);
227227
continue;
228228
}
@@ -343,7 +343,7 @@ where
343343
fn ignore_str(&mut self) -> Result<()> {
344344
loop {
345345
let ch = tri!(next_or_eof(self));
346-
if !is_escape(ch) {
346+
if !is_escape(ch, true) {
347347
continue;
348348
}
349349
match ch {
@@ -427,6 +427,14 @@ impl<'a> SliceRead<'a> {
427427
}
428428

429429
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+
430438
let rest = &self.slice[self.index..];
431439

432440
if !forbid_control_characters {
@@ -472,7 +480,7 @@ impl<'a> SliceRead<'a> {
472480
#[cold]
473481
#[inline(never)]
474482
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) {
476484
self.index += 1;
477485
}
478486
}
@@ -825,8 +833,8 @@ pub trait Fused: private::Sealed {}
825833
impl<'a> Fused for SliceRead<'a> {}
826834
impl<'a> Fused for StrRead<'a> {}
827835

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)
830838
}
831839

832840
fn next_or_eof<'de, R>(read: &mut R) -> Result<u8>

0 commit comments

Comments
 (0)