Bugfix #2175 - Allow escape characters in scripts (#2253)

This commit is contained in:
Finn Bear 2023-07-13 01:06:12 -07:00 committed by GitHub
parent 1d68fd5622
commit ce9430d1ac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 11 additions and 13 deletions

View file

@ -2,14 +2,10 @@ use crate::sql::comment::{block, slash};
use crate::sql::error::IResult; use crate::sql::error::IResult;
use crate::sql::strand::no_nul_bytes; use crate::sql::strand::no_nul_bytes;
use nom::branch::alt; use nom::branch::alt;
use nom::bytes::complete::escaped; use nom::bytes::complete::{escaped, is_not, tag};
use nom::bytes::complete::is_not; use nom::character::complete::{anychar, char, multispace0};
use nom::bytes::complete::tag;
use nom::character::complete::char;
use nom::character::complete::multispace0;
use nom::combinator::recognize; use nom::combinator::recognize;
use nom::multi::many0; use nom::multi::{many0, many1};
use nom::multi::many1;
use nom::sequence::delimited; use nom::sequence::delimited;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt::{self, Display, Formatter}; use std::fmt::{self, Display, Formatter};
@ -101,19 +97,19 @@ fn script_string(i: &str) -> IResult<&str, &str> {
}, },
|i| { |i| {
let (i, _) = char(SINGLE)(i)?; let (i, _) = char(SINGLE)(i)?;
let (i, v) = escaped(is_not(SINGLE_ESC_NUL), '\\', char(SINGLE))(i)?; let (i, v) = escaped(is_not(SINGLE_ESC_NUL), '\\', anychar)(i)?;
let (i, _) = char(SINGLE)(i)?; let (i, _) = char(SINGLE)(i)?;
Ok((i, v)) Ok((i, v))
}, },
|i| { |i| {
let (i, _) = char(DOUBLE)(i)?; let (i, _) = char(DOUBLE)(i)?;
let (i, v) = escaped(is_not(DOUBLE_ESC_NUL), '\\', char(DOUBLE))(i)?; let (i, v) = escaped(is_not(DOUBLE_ESC_NUL), '\\', anychar)(i)?;
let (i, _) = char(DOUBLE)(i)?; let (i, _) = char(DOUBLE)(i)?;
Ok((i, v)) Ok((i, v))
}, },
|i| { |i| {
let (i, _) = char(BACKTICK)(i)?; let (i, _) = char(BACKTICK)(i)?;
let (i, v) = escaped(is_not(BACKTICK_ESC_NUL), '\\', char(BACKTICK))(i)?; let (i, v) = escaped(is_not(BACKTICK_ESC_NUL), '\\', anychar)(i)?;
let (i, _) = char(BACKTICK)(i)?; let (i, _) = char(BACKTICK)(i)?;
Ok((i, v)) Ok((i, v))
}, },

View file

@ -39,18 +39,20 @@ async fn script_function_error() -> Result<(), Error> {
#[tokio::test] #[tokio::test]
async fn script_function_simple() -> Result<(), Error> { async fn script_function_simple() -> Result<(), Error> {
let sql = " let sql = r#"
CREATE person:test SET scores = function() { CREATE person:test SET scores = function() {
return [6.6, 8.4, 7.3].map(v => v * 10); return [6.6, 8.4, 7.3].map(v => v * 10);
}, bio = function() {
return "Line 1\nLine 2";
}; };
"; "#;
let dbs = Datastore::new("memory").await?; let dbs = Datastore::new("memory").await?;
let ses = Session::for_kv().with_ns("test").with_db("test"); let ses = Session::for_kv().with_ns("test").with_db("test");
let res = &mut dbs.execute(sql, &ses, None).await?; let res = &mut dbs.execute(sql, &ses, None).await?;
assert_eq!(res.len(), 1); assert_eq!(res.len(), 1);
// //
let tmp = res.remove(0).result?; let tmp = res.remove(0).result?;
let val = Value::parse("[{ id: person:test, scores: [66, 84, 73] }]"); let val = Value::parse(r#"[{ bio: "Line 1\nLine 2", id: person:test, scores: [66, 84, 73] }]"#);
assert_eq!(tmp, val); assert_eq!(tmp, val);
// //
Ok(()) Ok(())