@@ -170,28 +170,44 @@ impl Helper for CliHelper {}
170170///
171171/// The data read from stdio will be escaped, so we need to unescape the input before executing the input
172172pub fn unescape_input ( input : & str ) -> datafusion:: error:: Result < String > {
173- let mut chars = input. chars ( ) ;
174-
173+ let mut chars = input. chars ( ) . peekable ( ) ;
175174 let mut result = String :: with_capacity ( input. len ( ) ) ;
176- while let Some ( char) = chars. next ( ) {
177- if char == '\\' {
178- if let Some ( next_char) = chars. next ( ) {
179- // https://static.rust-lang.org/doc/master/reference.html#literals
180- result. push ( match next_char {
181- '0' => '\0' ,
182- 'n' => '\n' ,
183- 'r' => '\r' ,
184- 't' => '\t' ,
185- '\\' => '\\' ,
175+
176+ while let Some ( ch) = chars. next ( ) {
177+ if ch == '\\' {
178+ if let Some ( & next) = chars. peek ( ) {
179+ match next {
180+ '0' => {
181+ chars. next ( ) ;
182+ result. push ( '\0' ) ;
183+ }
184+ 'n' => {
185+ chars. next ( ) ;
186+ result. push ( '\n' ) ;
187+ }
188+ 'r' => {
189+ chars. next ( ) ;
190+ result. push ( '\r' ) ;
191+ }
192+ 't' => {
193+ chars. next ( ) ;
194+ result. push ( '\t' ) ;
195+ }
196+ '\\' | '\'' => result. push ( '\\' ) ,
186197 _ => {
187- return Err ( sql_datafusion_err ! ( ParserError :: TokenizerError (
188- format!( "unsupported escape char: '\\ {}'" , next_char)
198+ return Err ( DataFusionError :: Execution ( format ! (
199+ "Invalid escape sequence: \\ {}" ,
200+ next
189201 ) ) )
190202 }
191- } ) ;
203+ }
204+ } else {
205+ return Err ( sql_datafusion_err ! ( ParserError :: TokenizerError (
206+ "incomplete escape sequence: trailing backslash" . to_string( )
207+ ) ) ) ;
192208 }
193209 } else {
194- result. push ( char ) ;
210+ result. push ( ch ) ;
195211 }
196212 }
197213
@@ -319,6 +335,14 @@ mod tests {
319335 ) ?;
320336 assert ! ( matches!( result, ValidationResult :: Invalid ( Some ( _) ) ) ) ;
321337
338+ let result = readline_direct (
339+ Cursor :: new (
340+ r"select '\', '\\', '\\\\\', 'dsdsds\\\\', '\t', '\0', '\n';" . as_bytes ( ) ,
341+ ) ,
342+ & validator,
343+ ) ?;
344+ assert ! ( matches!( result, ValidationResult :: Valid ( None ) ) ) ;
345+
322346 Ok ( ( ) )
323347 }
324348
0 commit comments