Function expression failed with string paramater which contains \
lemanhtien opened this issue · comments
Here is the default test case, which the result is correct
func testCallAnyExpressionSymbolEvaluatorConstant() {
let expression = AnyExpression("foo('foo', 'bar')", constants: [
"foo": { ($0[0] as! String) + ($0[1] as! String) } as AnyExpression.SymbolEvaluator,
])
XCTAssertEqual(try expression.evaluate(), "foobar")
XCTAssertEqual(expression.symbols, [.function("foo", arity: 2)])
}
Modify the parameter value a bit, by adding "\", then the result is wrong
func testCallAnyExpressionSymbolEvaluatorConstant() {
let expression = AnyExpression("foo('foo\\s', 'bar')", constants: [
"foo": { ($0[0] as! String) + ($0[1] as! String) } as AnyExpression.SymbolEvaluator,
])
XCTAssertEqual(try expression.evaluate(), "foo\\sbar")
XCTAssertEqual(expression.symbols, [.function("foo", arity: 2)])
}
I tested several test case, and noticed that if the parameter is string, and it contains \\
, the result will be wrong.
Do you have any ideas to update this one? I think it relates to the function parseEscapedIdentifier
.
@lemanhtien sorry for the late reply. From what I can see, this is behaving correctly. What's confusing is the double escaping.
In Swift strings literals \ is an escaped slash, so you get a single \ in the output.
But when that swift string contains an expression, then that single \ is passed to the expression parser. "\s" is not a known escape sequence so the \ is silently dropped, resulting in "foobar" as the output. To include a literal \ in the value you would need to double-escape the slash, like this:
let expression = AnyExpression("foo('foo\\\\s', 'bar')", constants: [...])