throw errors from char_reader.rs and get_n_chars when reading bad UTF8 data (#2244)

This commit is contained in:
Mark
2023-12-26 12:30:46 -07:00
parent 2fa46e6b6c
commit 42d6749501
3 changed files with 40 additions and 29 deletions

View File

@@ -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;
} }

View File

@@ -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"),

View File

@@ -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]);
} }