From 15d5c43adb804ba148bd311712b359d9da503e18 Mon Sep 17 00:00:00 2001 From: Tobie Morgan Hitchcock Date: Sun, 16 Oct 2022 15:20:41 +0100 Subject: [PATCH] Ensure SQL queries are parsed completely or fail Closes #1364 --- lib/src/err/mod.rs | 4 ++++ lib/src/sql/parser.rs | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/src/err/mod.rs b/lib/src/err/mod.rs index a71a2098..7e1faa7e 100644 --- a/lib/src/err/mod.rs +++ b/lib/src/err/mod.rs @@ -53,6 +53,10 @@ pub enum Error { #[error("Specify some SQL code to execute")] 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 #[error("Parse error on line {line} at character {char} when parsing '{sql}'")] InvalidQuery { diff --git a/lib/src/sql/parser.rs b/lib/src/sql/parser.rs index 91bfd6a8..e6cb0db8 100644 --- a/lib/src/sql/parser.rs +++ b/lib/src/sql/parser.rs @@ -20,13 +20,23 @@ pub fn json(input: &str) -> Result { } fn parse_impl(input: &str, parser: impl Fn(&str) -> IResult<&str, O>) -> Result { + // Check the length of the input match input.trim().len() { + // The input query was empty 0 => Err(Error::QueryEmpty), + // Continue parsing the query _ => 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 { + // There was a parsing error ParserError(e) => { + // Locate the parser position let (s, l, c) = locate(input, e); + // Return the parser error Err(Error::InvalidQuery { line: l, char: c,