Skip to content
Permalink
Browse files
Fix '@' escaping in smart strings
Pass literal `\` as literal `\\` to `__smart_string__`, so that `__smart_string__` can disambiguate between `"\@"` and `"\\@"`, rather than getting the same input for both.
As this function is an internal compiler function, and users that do use it would now have to pass double escaped `\` into the function to make it work properly, the function has also been renamed to `__smart_string__` to fit the other compiler functions.
Fixes #1229.
  • Loading branch information
Pieter12345 committed Aug 1, 2020
1 parent 566f8c7 commit 1dd871eea6d7e6ea6425a0a8dadd3ab9595384c8
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 6 deletions.
@@ -49,7 +49,7 @@
import com.laytonsmith.core.functions.Compiler.__autoconcat__;
import com.laytonsmith.core.functions.Compiler.__cbrace__;
import com.laytonsmith.core.functions.Compiler.p;
import com.laytonsmith.core.functions.Compiler.smart_string;
import com.laytonsmith.core.functions.Compiler.__smart_string__;
import com.laytonsmith.core.functions.Math.neg;
import com.laytonsmith.core.functions.ControlFlow;
import com.laytonsmith.core.functions.DataHandling;
@@ -708,6 +708,12 @@ public static TokenStream lex(String script, Environment env, File file,
// Handle an escape sign in a quote.
switch(c2) {
case '\\':
if(inSmartQuote) {
// Escaping of '@' and '\' is handled within __smart_string__.
buf.append('\\');
}
buf.append('\\');
break;
case '\'':
case '"':
buf.append(c2);
@@ -1467,7 +1473,7 @@ public static ParseTree compile(TokenStream stream, Environment environment,
if(t.type == TType.SMART_STRING) {
if(t.val().contains("@")) {
ParseTree function = new ParseTree(fileOptions);
function.setData(new CFunction(smart_string.NAME, t.target));
function.setData(new CFunction(__smart_string__.NAME, t.target));
ParseTree string = new ParseTree(fileOptions);
string.setData(new CString(t.value, t.target));
function.addChild(string);
@@ -667,9 +667,9 @@ public ParseTree optimizeDynamic(Target t, Environment env,
@api
@hide("This is more of a compiler feature, rather than a function, and so it is hidden from normal"
+ " documentation.")
public static class smart_string extends AbstractFunction {
public static class __smart_string__ extends AbstractFunction {

public static final String NAME = "smart_string";
public static final String NAME = "__smart_string__";

@Override
public String getName() {
@@ -734,11 +734,21 @@ public ParseTree postParseRewrite(ParseTree ast, Environment env,
for(int i = 0; i < value.length(); i++) {
char c = value.charAt(i);
char c2 = (i + 1 < value.length() ? value.charAt(i + 1) : '\0');
if(c == '\\' && c2 == '@') {
b.append("@");

// The parser passes '\' as '\\' and literal '@' as '\@' for disambiguation in parsing here.
if(c == '\\') {
if(c2 == '@') {
b.append('@');
} else if(c2 == '\\') {
b.append('\\');
} else {
throw new ConfigCompileException(
"Invalid unhandled escape sequence passed to " + this.getName() + ": \\" + c2, t);
}
i++;
continue;
}

if(c == '@') {
if(c2 == '{') {
//Start of a complex variable

0 comments on commit 1dd871e

Please sign in to comment.