From 4d1ecd2d50149c0dd182b2113c53e2bbf3bc780c Mon Sep 17 00:00:00 2001 From: pedrocarlo Date: Fri, 11 Apr 2025 01:36:36 -0300 Subject: [PATCH] better MalformedHexInteger --- cli/app.rs | 13 ++--- vendored/sqlite3-parser/src/lexer/scan.rs | 4 +- .../sqlite3-parser/src/lexer/sql/error.rs | 51 +++++++++++++++---- vendored/sqlite3-parser/src/lexer/sql/mod.rs | 21 ++++++-- 4 files changed, 65 insertions(+), 24 deletions(-) diff --git a/cli/app.rs b/cli/app.rs index 3f04ab9fe..bb9515660 100644 --- a/cli/app.rs +++ b/cli/app.rs @@ -789,10 +789,9 @@ impl<'a> Limbo<'a> { if let Some(ref mut stats) = statistics { stats.execute_time_elapsed_samples.push(start.elapsed()); } - let _ = self.write_fmt(format_args!( - "{:?}", - miette::Error::from(err).with_source_code(sql.to_owned()) - )); + let report = + miette::Error::from(err).with_source_code(sql.to_owned()); + let _ = self.write_fmt(format_args!("{:?}", report)); break; } } @@ -805,10 +804,8 @@ impl<'a> Limbo<'a> { }, Ok(None) => {} Err(err) => { - let _ = self.write_fmt(format_args!( - "{:?}", - miette::Error::from(err).with_source_code(sql.to_owned()) - )); + let report = miette::Error::from(err).with_source_code(sql.to_owned()); + let _ = self.write_fmt(format_args!("{:?}", report)); anyhow::bail!("We have to throw here, even if we printed error"); } } diff --git a/vendored/sqlite3-parser/src/lexer/scan.rs b/vendored/sqlite3-parser/src/lexer/scan.rs index e0d22cbd5..6c0085b29 100644 --- a/vendored/sqlite3-parser/src/lexer/scan.rs +++ b/vendored/sqlite3-parser/src/lexer/scan.rs @@ -9,7 +9,7 @@ use std::io; /// Error with position pub trait ScanError: Error + From + Sized { /// Update the position where the error occurs - fn position(&mut self, line: u64, column: usize); + fn position(&mut self, line: u64, column: usize, offset: usize); } /// The `(&[u8], TokenType)` is the token. @@ -126,7 +126,7 @@ impl Scanner { let data = &input[self.offset..]; match self.splitter.split(data) { Err(mut e) => { - e.position(self.line, self.column); + e.position(self.line, self.column, self.offset); return Err(e); } Ok((None, 0)) => { diff --git a/vendored/sqlite3-parser/src/lexer/sql/error.rs b/vendored/sqlite3-parser/src/lexer/sql/error.rs index d3e3ac345..fb6d6c32e 100644 --- a/vendored/sqlite3-parser/src/lexer/sql/error.rs +++ b/vendored/sqlite3-parser/src/lexer/sql/error.rs @@ -56,6 +56,8 @@ pub enum Error { MalformedHexInteger( Option<(u64, usize)>, #[label("here")] Option, + Option, + #[help] Option<&'static str>, ), /// Grammar error ParserError( @@ -87,7 +89,7 @@ impl fmt::Display for Error { Self::MalformedBlobLiteral(pos, _) => { write!(f, "malformed blob literal at {:?}", pos.unwrap()) } - Self::MalformedHexInteger(pos, _) => { + Self::MalformedHexInteger(pos, _, _, _) => { write!(f, "malformed hex integer at {:?}", pos.unwrap()) } Self::ParserError(ref msg, Some(pos), _) => write!(f, "{msg} at {pos:?}"), @@ -111,18 +113,45 @@ impl From for Error { } impl ScanError for Error { - fn position(&mut self, line: u64, column: usize) { + fn position(&mut self, line: u64, column: usize, offset: usize) { match *self { Self::Io(_) => {} - Self::UnrecognizedToken(ref mut pos, _) => *pos = Some((line, column)), - Self::UnterminatedLiteral(ref mut pos, _) => *pos = Some((line, column)), - Self::UnterminatedBracket(ref mut pos, _) => *pos = Some((line, column)), - Self::UnterminatedBlockComment(ref mut pos, _) => *pos = Some((line, column)), - Self::BadVariableName(ref mut pos, _) => *pos = Some((line, column)), - Self::BadNumber(ref mut pos, _) => *pos = Some((line, column)), - Self::ExpectedEqualsSign(ref mut pos, _) => *pos = Some((line, column)), - Self::MalformedBlobLiteral(ref mut pos, _) => *pos = Some((line, column)), - Self::MalformedHexInteger(ref mut pos, _) => *pos = Some((line, column)), + Self::UnrecognizedToken(ref mut pos, ref mut src) => { + *pos = Some((line, column)); + *src = Some((offset).into()); + } + Self::UnterminatedLiteral(ref mut pos, ref mut src) => { + *pos = Some((line, column)); + *src = Some((offset).into()); + } + Self::UnterminatedBracket(ref mut pos, ref mut src) => { + *pos = Some((line, column)); + *src = Some((offset).into()); + } + Self::UnterminatedBlockComment(ref mut pos, ref mut src) => { + *pos = Some((line, column)); + *src = Some((offset).into()); + } + Self::BadVariableName(ref mut pos, ref mut src) => { + *pos = Some((line, column)); + *src = Some((offset).into()); + } + Self::BadNumber(ref mut pos, ref mut src) => { + *pos = Some((line, column)); + *src = Some((offset).into()); + } + Self::ExpectedEqualsSign(ref mut pos, ref mut src) => { + *pos = Some((line, column)); + *src = Some((offset).into()); + } + Self::MalformedBlobLiteral(ref mut pos, ref mut src) => { + *pos = Some((line, column)); + *src = Some((offset).into()); + } + Self::MalformedHexInteger(ref mut pos, ref mut src, len, _) => { + *pos = Some((line, column)); + *src = Some((offset, len.unwrap_or(0)).into()); + } Self::ParserError(_, ref mut pos, _) => *pos = Some((line, column)), } } diff --git a/vendored/sqlite3-parser/src/lexer/sql/mod.rs b/vendored/sqlite3-parser/src/lexer/sql/mod.rs index fba3d72d1..ccb05bd01 100644 --- a/vendored/sqlite3-parser/src/lexer/sql/mod.rs +++ b/vendored/sqlite3-parser/src/lexer/sql/mod.rs @@ -172,7 +172,7 @@ macro_rules! try_with_position { Ok(val) => val, Err(err) => { let mut err = Error::from(err); - err.position($scanner.line(), $scanner.column()); + err.position($scanner.line(), $scanner.column(), $scanner.offset() - 1); return Err(err); } } @@ -610,13 +610,28 @@ fn hex_integer(data: &[u8]) -> Result<(Option>, usize), Error> { if let Some((i, b)) = find_end_of_number(data, 2, u8::is_ascii_hexdigit)? { // Must not be empty (Ox is invalid) if i == 2 || is_identifier_start(b) { - return Err(Error::MalformedHexInteger(None, None)); + let (len, help) = if i == 2 && !is_identifier_start(b) { + (i, "Did you forget to add digits after '0x' or '0X'?") + } else { + (i + 1, "There are some invalid digits after '0x' or '0X'") + }; + return Err(Error::MalformedHexInteger( + None, + None, + Some(len), // Length of the malformed hex + Some(help), // Help Message + )); } Ok((Some((&data[..i], TK_INTEGER)), i)) } else { // Must not be empty (Ox is invalid) if data.len() == 2 { - return Err(Error::MalformedHexInteger(None, None)); + return Err(Error::MalformedHexInteger( + None, + None, + Some(2), // Length of the malformed hex + Some("Did you forget to add digits after '0x' or '0X'?"), // Help Message + )); } Ok((Some((data, TK_INTEGER)), data.len())) }