Ensure SQL queries are parsed completely or fail

Closes #1364
This commit is contained in:
Tobie Morgan Hitchcock 2022-10-16 15:20:41 +01:00
parent 264f208379
commit 15d5c43adb
2 changed files with 15 additions and 1 deletions

View file

@ -53,6 +53,10 @@ pub enum Error {
#[error("Specify some SQL code to execute")] #[error("Specify some SQL code to execute")]
QueryEmpty, QueryEmpty,
/// There was an error with the SQL query
#[error("The SQL query was not parsed fully")]
QueryRemaining,
/// There was an error with the SQL query /// There was an error with the SQL query
#[error("Parse error on line {line} at character {char} when parsing '{sql}'")] #[error("Parse error on line {line} at character {char} when parsing '{sql}'")]
InvalidQuery { InvalidQuery {

View file

@ -20,13 +20,23 @@ pub fn json(input: &str) -> Result<Value, Error> {
} }
fn parse_impl<O>(input: &str, parser: impl Fn(&str) -> IResult<&str, O>) -> Result<O, Error> { fn parse_impl<O>(input: &str, parser: impl Fn(&str) -> IResult<&str, O>) -> Result<O, Error> {
// Check the length of the input
match input.trim().len() { match input.trim().len() {
// The input query was empty
0 => Err(Error::QueryEmpty), 0 => Err(Error::QueryEmpty),
// Continue parsing the query
_ => match parser(input) { _ => match parser(input) {
Ok((_, parsed)) => Ok(parsed), // The query was parsed successfully
Ok((v, parsed)) if v.len() == 0 => Ok(parsed),
// There was unparsed SQL remaining
Ok((_, _)) => Err(Error::QueryRemaining),
// There was an error when parsing the query
Err(Err::Error(e)) | Err(Err::Failure(e)) => match e { Err(Err::Error(e)) | Err(Err::Failure(e)) => match e {
// There was a parsing error
ParserError(e) => { ParserError(e) => {
// Locate the parser position
let (s, l, c) = locate(input, e); let (s, l, c) = locate(input, e);
// Return the parser error
Err(Error::InvalidQuery { Err(Error::InvalidQuery {
line: l, line: l,
char: c, char: c,