Repository: groovy
Updated Branches:
  refs/heads/GROOVY_2_6_X 104b2babf -> c2cd68047


GROOVY-4585: backslash can not be escaped by `SimpleTemplateEngine`
(closes #681)

(cherry picked from commit 49aaa28)


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/c2cd6804
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/c2cd6804
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/c2cd6804

Branch: refs/heads/GROOVY_2_6_X
Commit: c2cd68047e31c2666d8de6d6c1ae6c007bfb3d71
Parents: 104b2ba
Author: Daniel Sun <realblue...@hotmail.com>
Authored: Fri Apr 6 21:44:49 2018 +0800
Committer: danielsun1106 <realblue...@hotmail.com>
Committed: Fri Apr 6 22:25:38 2018 +0800

----------------------------------------------------------------------
 .../groovy/bugs/groovy4585/groovy4585.xml       | 12 +++++++
 .../groovy/bugs/groovy4585/Groovy4585Bug.groovy | 33 +++++++++++++++++
 .../groovy/text/SimpleTemplateEngine.java       | 38 ++++++++++++++++++--
 3 files changed, 81 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/c2cd6804/src/test-resources/groovy/bugs/groovy4585/groovy4585.xml
----------------------------------------------------------------------
diff --git a/src/test-resources/groovy/bugs/groovy4585/groovy4585.xml 
b/src/test-resources/groovy/bugs/groovy4585/groovy4585.xml
new file mode 100644
index 0000000..5d8e83c
--- /dev/null
+++ b/src/test-resources/groovy/bugs/groovy4585/groovy4585.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="GB2312"?>
+<project name="projBuild" default="projBuild" basedir=".">
+    <property name="drive" value="d:\" />
+
+    <target name="projBuild">
+        <%for (int i = 0; i < names.size(); i++) {%>
+            <exec dir="\${drive}" executable="echo">
+                  <arg line="${names[i]}"/>
+            </exec>
+        <%}%>
+    </target>
+</project>

http://git-wip-us.apache.org/repos/asf/groovy/blob/c2cd6804/src/test/groovy/bugs/groovy4585/Groovy4585Bug.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/bugs/groovy4585/Groovy4585Bug.groovy 
b/src/test/groovy/bugs/groovy4585/Groovy4585Bug.groovy
new file mode 100644
index 0000000..fed604e
--- /dev/null
+++ b/src/test/groovy/bugs/groovy4585/Groovy4585Bug.groovy
@@ -0,0 +1,33 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.bugs.groovy4585
+
+class Groovy4585Bug extends GroovyTestCase {
+    void test() {
+        assertScript '''
+            package groovy.bugs.groovy4585
+            def engineForBuildXml = new 
groovy.text.SimpleTemplateEngine(false, true)
+            def templateForBuildXml = 
engineForBuildXml.createTemplate(this.getClass().getResource("/groovy/bugs/groovy4585/groovy4585.xml").text)
+            String buildXmlContent = templateForBuildXml.make([names:['a', 
'b', 'c']]).toString()
+    
+            assert buildXmlContent.contains('<property name="drive" 
value="d:\\\\" />')
+            assert buildXmlContent.contains('<exec dir="${drive}" 
executable="echo">')
+        '''
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/c2cd6804/subprojects/groovy-templates/src/main/groovy/groovy/text/SimpleTemplateEngine.java
----------------------------------------------------------------------
diff --git 
a/subprojects/groovy-templates/src/main/groovy/groovy/text/SimpleTemplateEngine.java
 
b/subprojects/groovy-templates/src/main/groovy/groovy/text/SimpleTemplateEngine.java
index e4776ab..2c541f0 100644
--- 
a/subprojects/groovy-templates/src/main/groovy/groovy/text/SimpleTemplateEngine.java
+++ 
b/subprojects/groovy-templates/src/main/groovy/groovy/text/SimpleTemplateEngine.java
@@ -97,16 +97,21 @@ import java.util.Map;
 public class SimpleTemplateEngine extends TemplateEngine {
     private boolean verbose;
     private static int counter = 1;
-
     private GroovyShell groovyShell;
+    private boolean escapeBackslash;
 
     public SimpleTemplateEngine() {
         this(GroovyShell.class.getClassLoader());
     }
 
     public SimpleTemplateEngine(boolean verbose) {
+        this(verbose, false);
+    }
+
+    public SimpleTemplateEngine(boolean verbose, boolean escapeBackslash) {
         this(GroovyShell.class.getClassLoader());
         setVerbose(verbose);
+        this.escapeBackslash = escapeBackslash;
     }
 
     public SimpleTemplateEngine(ClassLoader parentLoader) {
@@ -118,7 +123,7 @@ public class SimpleTemplateEngine extends TemplateEngine {
     }
 
     public Template createTemplate(Reader reader) throws 
CompilationFailedException, IOException {
-        SimpleTemplate template = new SimpleTemplate();
+        SimpleTemplate template = new SimpleTemplate(escapeBackslash);
         String script = template.parse(reader);
         if (verbose) {
             System.out.println("\n-- script source --");
@@ -147,6 +152,16 @@ public class SimpleTemplateEngine extends TemplateEngine {
     private static class SimpleTemplate implements Template {
 
         protected Script script;
+        private boolean escapeBackslash;
+
+        public SimpleTemplate() {
+            this(false);
+        }
+
+        public SimpleTemplate(boolean escapeBackslash) {
+            this.escapeBackslash = escapeBackslash;
+        }
+
 
         public Writable make() {
             return make(null);
@@ -236,6 +251,25 @@ public class SimpleTemplateEngine extends TemplateEngine {
                 if (c == '\"') {
                     sw.write('\\');
                 }
+
+                /*
+                 *  GROOVY-4585
+                 *  Handle backslash characters.
+                 */
+                if (escapeBackslash) {
+                    if (c == '\\') {
+                        reader.mark(1);
+                        c = reader.read();
+                        if (c != '$') {
+                            sw.write("\\\\");
+                            reader.reset();
+                        } else {
+                            sw.write("\\$");
+                        }
+
+                        continue;
+                    }
+                }
                 /*
                  * Handle raw new line characters.
                  */

Reply via email to