Forward ported from 2.3-gae: \= escape in string literals

Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/782eed0b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/782eed0b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/782eed0b

Branch: refs/heads/3
Commit: 782eed0b4ac12545715580cfe08dbda119ad9871
Parents: 8093cb6
Author: ddekany <ddek...@apache.org>
Authored: Sun Mar 18 19:08:22 2018 +0100
Committer: ddekany <ddek...@apache.org>
Committed: Sun Mar 18 19:08:22 2018 +0100

----------------------------------------------------------------------
 .../core/InterpolationSyntaxTest.java           |  4 +++
 .../core/util/TemplateLanguageUtilsTest.java    | 21 ++++++++++++++-
 .../core/util/TemplateLanguageUtils.java        | 27 ++++++++++++--------
 freemarker-core/src/main/javacc/FTL.jj          |  2 +-
 4 files changed, 42 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/782eed0b/freemarker-core-test/src/test/java/org/apache/freemarker/core/InterpolationSyntaxTest.java
----------------------------------------------------------------------
diff --git 
a/freemarker-core-test/src/test/java/org/apache/freemarker/core/InterpolationSyntaxTest.java
 
b/freemarker-core-test/src/test/java/org/apache/freemarker/core/InterpolationSyntaxTest.java
index d187bb5..e6b0eeb 100644
--- 
a/freemarker-core-test/src/test/java/org/apache/freemarker/core/InterpolationSyntaxTest.java
+++ 
b/freemarker-core-test/src/test/java/org/apache/freemarker/core/InterpolationSyntaxTest.java
@@ -91,6 +91,10 @@ public class InterpolationSyntaxTest extends TemplateTest {
         assertErrorContains("[=", "end of file");
         assertErrorContains("[=1", "unclosed \"[\"");
         
+        assertOutput("[='[\\=1]']", "[=1]");
+        assertOutput("[='[\\=1][=2]']", "12"); // Usual legacy interpolation 
escaping glitch...
+        assertOutput("[=r'[=1]']", "[=1]");        
+        
         StringWriter sw = new StringWriter();
         new Template(null, "[= 1 + '[= 2 ]' ]", getConfiguration()).dump(sw);
         assertEquals("[=1 + \"[=2]\"]", sw.toString());

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/782eed0b/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/TemplateLanguageUtilsTest.java
----------------------------------------------------------------------
diff --git 
a/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/TemplateLanguageUtilsTest.java
 
b/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/TemplateLanguageUtilsTest.java
index aae4699..1e6f171 100644
--- 
a/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/TemplateLanguageUtilsTest.java
+++ 
b/freemarker-core-test/src/test/java/org/apache/freemarker/core/util/TemplateLanguageUtilsTest.java
@@ -20,8 +20,11 @@ package org.apache.freemarker.core.util;
 
 import static junit.framework.TestCase.assertFalse;
 import static junit.framework.TestCase.assertNull;
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import org.junit.Test;
 
@@ -43,8 +46,10 @@ public class TemplateLanguageUtilsTest {
         assertEquals("a\\'c\"d", 
TemplateLanguageUtils.escapeStringLiteralPart("a'c\"d", '\''));
         assertEquals("\\n\\r\\t\\f\\x0002\\\\", 
TemplateLanguageUtils.escapeStringLiteralPart("\n\r\t\f\u0002\\"));
         assertEquals("\\l\\g\\a", 
TemplateLanguageUtils.escapeStringLiteralPart("<>&"));
+        assertEquals("=[\\=]=", 
TemplateLanguageUtils.escapeStringLiteralPart("=[=]="));
+        assertEquals("[\\=", 
TemplateLanguageUtils.escapeStringLiteralPart("[="));
     }
-
+    
     @Test
     public void testEscapeStringLiteralAll() {
         assertFTLEsc("", "", "", "", "\"\"");
@@ -79,6 +84,20 @@ public class TemplateLanguageUtilsTest {
         assertEquals(
                 "'\"\n\b\u0000c><&{\\",
                 
TemplateLanguageUtils.unescapeStringLiteralPart("\\'\\\"\\n\\b\\x0000c\\g\\l\\a\\{\\\\"));
+        
+        assertEquals("\nq", 
TemplateLanguageUtils.unescapeStringLiteralPart("\\x0Aq"));
+        assertEquals("\n\r1", 
TemplateLanguageUtils.unescapeStringLiteralPart("\\x0A\\x000D1"));
+        assertEquals("\n\r\t", 
TemplateLanguageUtils.unescapeStringLiteralPart("\\n\\r\\t"));
+        assertEquals("${1}#{2}[=3]", 
TemplateLanguageUtils.unescapeStringLiteralPart("$\\{1}#\\{2}[\\=3]"));
+        assertEquals("{=", 
TemplateLanguageUtils.unescapeStringLiteralPart("\\{\\="));
+        assertEquals("\\=", 
TemplateLanguageUtils.unescapeStringLiteralPart("\\\\="));
+           
+        try {
+            TemplateLanguageUtils.unescapeStringLiteralPart("\\[");
+            fail();
+        } catch (GenericParseException e) {
+            assertThat(e.getMessage(), containsString("\\["));
+        }
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/782eed0b/freemarker-core/src/main/java/org/apache/freemarker/core/util/TemplateLanguageUtils.java
----------------------------------------------------------------------
diff --git 
a/freemarker-core/src/main/java/org/apache/freemarker/core/util/TemplateLanguageUtils.java
 
b/freemarker-core/src/main/java/org/apache/freemarker/core/util/TemplateLanguageUtils.java
index e2e32e4..f06276b 100644
--- 
a/freemarker-core/src/main/java/org/apache/freemarker/core/util/TemplateLanguageUtils.java
+++ 
b/freemarker-core/src/main/java/org/apache/freemarker/core/util/TemplateLanguageUtils.java
@@ -53,6 +53,10 @@ import org.apache.freemarker.core.model.impl.JavaMethodModel;
 // TODO [FM3] This name won't be good if the template language isn't called 
"FTL"...
 public final class TemplateLanguageUtils {
 
+    /**
+     *  Used to look up if the chars with low code needs to be escaped, but 
note that it gives bad result for '=', as
+     *  there the it matters if it's after '['.
+     */
     private static final char[] ESCAPES = createEscapes();
 
     private TemplateLanguageUtils() {
@@ -68,6 +72,7 @@ public final class TemplateLanguageUtils {
         escapes['\''] = '\'';
         escapes['"'] = '"';
         escapes['<'] = 'l';
+        // As '=' is only escaped if it's after '[', we can't handle it here
         escapes['>'] = 'g';
         escapes['&'] = 'a';
         escapes['\b'] = 'b';
@@ -139,10 +144,16 @@ public final class TemplateLanguageUtils {
         StringBuilder buf = null;
         for (int i = 0; i < ln; i++) {
             char c = s.charAt(i);
-            char escape =
-                    c < escLn ? ESCAPES[c] :
-                            c == '{' && i > 0 && 
isInterpolationStart(s.charAt(i - 1)) ? '{' :
-                                    0;
+            char escape;
+            if (c == '=') {
+                escape = i > 0 && s.charAt(i - 1) == '[' ? '=' : 0;
+            } else if (c < escLn) {
+                escape = ESCAPES[c]; //
+            } else if (c == '{' && i > 0 && s.charAt(i - 1) == '$') {
+                escape = '{';
+            } else {
+                escape = 0;
+            }
             if (escape == 0 || escape == otherQuotation
                     || c == '&' && !escapeAmp || c == '<' && !escapeLT || c == 
'>' && !escapeGT) {
                 if (buf != null) {
@@ -181,11 +192,6 @@ public final class TemplateLanguageUtils {
         }
     }
 
-    private static boolean isInterpolationStart(char c) {
-        // Find related: [interpolation prefixes]
-        return c == '$';
-    }
-
     /**
      * Unescapes a string that was escaped to be part of an FTL string 
literal. The string to unescape must not include
      * the two quotation marks or two apostrophe-quotes that delimit the 
literal.
@@ -267,7 +273,8 @@ public final class TemplateLanguageUtils {
                     bidx = idx + 2;
                     break;
                 case '{':
-                    buf.append('{');
+                case '=':
+                    buf.append(c);
                     bidx = idx + 2;
                     break;
                 case 'x': {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/782eed0b/freemarker-core/src/main/javacc/FTL.jj
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/javacc/FTL.jj 
b/freemarker-core/src/main/javacc/FTL.jj
index 46782d6..531253e 100644
--- a/freemarker-core/src/main/javacc/FTL.jj
+++ b/freemarker-core/src/main/javacc/FTL.jj
@@ -985,7 +985,7 @@ TOKEN:
     <#ESCAPED_CHAR :
         "\\"
         (
-            ("n" | "t" | "r" | "f" | "b" | "g" | "l" | "a" | "\\" | "'" | "\"" 
| "$" | "{")
+            ("n" | "t" | "r" | "f" | "b" | "g" | "l" | "a" | "\\" | "'" | "\"" 
| "$" | "{" | "=")
             |
             ("x" ["0"-"9", "A"-"F", "a"-"f"])
         )

Reply via email to