throw errors from char_reader.rs and get_n_chars when reading bad UTF8 data (#2244)
This commit is contained in:
@@ -3492,6 +3492,12 @@ impl Machine {
|
|||||||
Some(Ok(c)) => {
|
Some(Ok(c)) => {
|
||||||
string.push(c);
|
string.push(c);
|
||||||
}
|
}
|
||||||
|
Some(Err(e)) => {
|
||||||
|
let stub = functor_stub(atom!("$get_n_chars"), 3);
|
||||||
|
let err = self.machine_st.session_error(SessionError::from(e));
|
||||||
|
|
||||||
|
return Err(self.machine_st.error_form(err, stub));
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -417,6 +417,9 @@ impl ParserError {
|
|||||||
ParserError::IO(e) if e.kind() == ErrorKind::UnexpectedEof => {
|
ParserError::IO(e) if e.kind() == ErrorKind::UnexpectedEof => {
|
||||||
atom!("unexpected_end_of_file")
|
atom!("unexpected_end_of_file")
|
||||||
}
|
}
|
||||||
|
ParserError::IO(e) if e.kind() == ErrorKind::InvalidData => {
|
||||||
|
atom!("invalid_data")
|
||||||
|
}
|
||||||
ParserError::IO(_) => atom!("input_output_error"),
|
ParserError::IO(_) => atom!("input_output_error"),
|
||||||
ParserError::LexicalError(_) => atom!("lexical_error"),
|
ParserError::LexicalError(_) => atom!("lexical_error"),
|
||||||
ParserError::MissingQuote(..) => atom!("missing_quote"),
|
ParserError::MissingQuote(..) => atom!("missing_quote"),
|
||||||
|
|||||||
@@ -144,21 +144,7 @@ impl<R: Read> CharRead for CharReader<R> {
|
|||||||
Err(e) => return Some(Err(e)),
|
Err(e) => return Some(Err(e)),
|
||||||
}
|
}
|
||||||
|
|
||||||
loop {
|
let bad_bytes_error = |buf: &[u8]| {
|
||||||
let buf = &self.buf[self.pos..];
|
|
||||||
|
|
||||||
if !buf.is_empty() {
|
|
||||||
let e = match str::from_utf8(buf) {
|
|
||||||
Ok(s) => {
|
|
||||||
let mut chars = s.chars();
|
|
||||||
let c = chars.next().unwrap();
|
|
||||||
|
|
||||||
return Some(Ok(c));
|
|
||||||
}
|
|
||||||
Err(e) => e,
|
|
||||||
};
|
|
||||||
|
|
||||||
if buf.len() - e.valid_up_to() >= 4 {
|
|
||||||
// If we have 4 bytes that still don't make up
|
// If we have 4 bytes that still don't make up
|
||||||
// a valid code point, then we have garbage.
|
// a valid code point, then we have garbage.
|
||||||
|
|
||||||
@@ -184,10 +170,25 @@ impl<R: Read> CharRead for CharReader<R> {
|
|||||||
// the buffer, it will be returned on the next
|
// the buffer, it will be returned on the next
|
||||||
// loop.
|
// loop.
|
||||||
|
|
||||||
return Some(Err(io::Error::new(
|
io::Error::new(io::ErrorKind::InvalidData, BadUtf8Error { bytes: badbytes })
|
||||||
io::ErrorKind::InvalidData,
|
};
|
||||||
BadUtf8Error { bytes: badbytes },
|
|
||||||
)));
|
loop {
|
||||||
|
let buf = &self.buf[self.pos..];
|
||||||
|
|
||||||
|
if !buf.is_empty() {
|
||||||
|
let e = match str::from_utf8(buf) {
|
||||||
|
Ok(s) => {
|
||||||
|
let mut chars = s.chars();
|
||||||
|
let c = chars.next().unwrap();
|
||||||
|
|
||||||
|
return Some(Ok(c));
|
||||||
|
}
|
||||||
|
Err(e) => e,
|
||||||
|
};
|
||||||
|
|
||||||
|
if buf.len() - e.valid_up_to() >= 4 {
|
||||||
|
return Some(Err(bad_bytes_error(buf)));
|
||||||
} else if self.pos >= self.buf.len() {
|
} else if self.pos >= self.buf.len() {
|
||||||
return None;
|
return None;
|
||||||
} else if self.buf.len() - self.pos >= 4 {
|
} else if self.buf.len() - self.pos >= 4 {
|
||||||
@@ -223,6 +224,7 @@ impl<R: Read> CharRead for CharReader<R> {
|
|||||||
|
|
||||||
match self.inner.read(word_slice) {
|
match self.inner.read(word_slice) {
|
||||||
Err(e) => return Some(Err(e)),
|
Err(e) => return Some(Err(e)),
|
||||||
|
Ok(nread) if nread == 0 => return Some(Err(bad_bytes_error(&self.buf))),
|
||||||
Ok(nread) => {
|
Ok(nread) => {
|
||||||
self.buf.extend_from_slice(&word_slice[0..nread]);
|
self.buf.extend_from_slice(&word_slice[0..nread]);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user