You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 10:11:16 UTC

[sling-org-apache-sling-scripting-sightly-compiler] 03/31: SLING-6094 - HTL can generate invalid Java code by using user-supplied input

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.scripting.sightly.compiler.java-1.0.10
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-sightly-compiler.git

commit 8ba6830fc760ac329d373e77472a3132e5d00637
Author: Radu Cotescu <ra...@apache.org>
AuthorDate: Thu Oct 6 16:44:00 2016 +0000

    SLING-6094 - HTL can generate invalid Java code by using user-supplied input
    
    * made sure that generated variables, even if they contain user-input, are correctly
    and uniformly escaped
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/scripting/sightly/java-compiler@1763629 13f79535-47bb-0310-9956-ffa450edef68
---
 .../sightly/java/compiler/JavaEscapeUtils.java     | 159 +++++++++++++++++++++
 .../java/compiler/impl/VariableAnalyzer.java       |   8 +-
 .../java/compiler/impl/utils/JavaEscapeUtils.java  |  95 ------------
 .../sightly/java/compiler/package-info.java        |   2 +-
 4 files changed, 164 insertions(+), 100 deletions(-)

diff --git a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/JavaEscapeUtils.java b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/JavaEscapeUtils.java
new file mode 100644
index 0000000..3bc299c
--- /dev/null
+++ b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/JavaEscapeUtils.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * 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 org.apache.sling.scripting.sightly.java.compiler;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * The {@code JavaEscapeUtils} provides useful methods for escaping or transforming invalid Java tokens to valid ones that could be used in
+ * generated Java source code.
+ */
+public class JavaEscapeUtils {
+
+    private static final Set<String> javaKeywords = new HashSet<String>() {{
+        add("abstract");
+        add("assert");
+        add("boolean");
+        add("break");
+        add("byte");
+        add("case");
+        add("catch");
+        add("char");
+        add("class");
+        add("const");
+        add("continue");
+        add("default");
+        add("do");
+        add("double");
+        add("else");
+        add("enum");
+        add("extends");
+        add("final");
+        add("finally");
+        add("float");
+        add("for");
+        add("goto");
+        add("if");
+        add("implements");
+        add("import");
+        add("instanceof");
+        add("int");
+        add("interface");
+        add("long");
+        add("native");
+        add("new");
+        add("package");
+        add("private");
+        add("protected");
+        add("public");
+        add("return");
+        add("short");
+        add("static");
+        add("strictfp");
+        add("super");
+        add("switch");
+        add("synchronized");
+        add("this");
+        add("throw");
+        add("throws");
+        add("transient");
+        add("try");
+        add("void");
+        add("volatile");
+        add("while");
+    }};
+
+    /**
+     * Converts the given identifier to a legal Java identifier
+     *
+     * @param identifier the identifier to convert
+     * @return legal Java identifier corresponding to the given identifier
+     */
+    public static String makeJavaIdentifier(String identifier) {
+        StringBuilder modifiedIdentifier = new StringBuilder(identifier.length());
+        if (!Character.isJavaIdentifierStart(identifier.charAt(0))) {
+            modifiedIdentifier.append('_');
+        }
+        for (int i = 0; i < identifier.length(); i++) {
+            char ch = identifier.charAt(i);
+            if (Character.isJavaIdentifierPart(ch) && ch != '_') {
+                modifiedIdentifier.append(ch);
+            } else if (ch == '.') {
+                modifiedIdentifier.append('_');
+            } else {
+                modifiedIdentifier.append(mangleChar(ch));
+            }
+        }
+        if (isJavaKeyword(modifiedIdentifier.toString())) {
+            modifiedIdentifier.append('_');
+        }
+        return modifiedIdentifier.toString();
+    }
+
+    /**
+     * Mangle the specified character to create a legal Java class name.
+     *
+     * @param ch the character to mangle
+     * @return the mangled
+     */
+    public static String mangleChar(char ch) {
+        return String.format("__%04x__", (int) ch);
+    }
+
+    /**
+     * Provided a mangled string (obtained by calling {@link #mangleChar(char)}) it will will return the character that was mangled.
+     *
+     * @param mangled the mangled string
+     * @return the original character
+     */
+    public static char unmangle(String mangled) {
+        String toProcess = mangled.replaceAll("__", "");
+        return (char) Integer.parseInt(toProcess, 16);
+    }
+
+    /**
+     * Converts the given scriptName to a Java package or fully-qualified class name
+     *
+     * @param scriptName the scriptName to convert
+     * @return Java package corresponding to the given scriptName
+     */
+    public static String makeJavaPackage(String scriptName) {
+        String classNameComponents[] = StringUtils.split(scriptName, '/');
+        StringBuilder legalClassNames = new StringBuilder();
+        for (int i = 0; i < classNameComponents.length; i++) {
+            legalClassNames.append(makeJavaIdentifier(classNameComponents[i]));
+            if (i < classNameComponents.length - 1) {
+                legalClassNames.append('.');
+            }
+        }
+        return legalClassNames.toString();
+    }
+
+    /**
+     * Test whether the argument is a Java keyword.
+     *
+     * @param key the String to test
+     * @return {@code true} if the String is a Java keyword, {@code false} otherwise
+     */
+    public static boolean isJavaKeyword(String key) {
+        return javaKeywords.contains(key);
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/VariableAnalyzer.java b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/VariableAnalyzer.java
index 80aa5c7..b0fb3e3 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/VariableAnalyzer.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/VariableAnalyzer.java
@@ -23,7 +23,7 @@ import java.util.HashMap;
 import java.util.List;
 
 import org.apache.sling.scripting.sightly.java.compiler.SightlyJavaCompilerException;
-import org.apache.sling.scripting.sightly.java.compiler.impl.utils.JavaEscapeUtils;
+import org.apache.sling.scripting.sightly.java.compiler.JavaEscapeUtils;
 import org.apache.sling.scripting.sightly.compiler.util.VariableTracker;
 
 /**
@@ -140,16 +140,16 @@ public class VariableAnalyzer {
     }
 
     private String findDynamicName(String original) {
-        return DYNAMIC_PREFIX + JavaEscapeUtils.getEscapedToken(original);
+        return DYNAMIC_PREFIX + JavaEscapeUtils.makeJavaIdentifier(original);
     }
 
     private String findGlobalName(String original) {
-        return GLOBAL_PREFIX + JavaEscapeUtils.getEscapedToken(original);
+        return GLOBAL_PREFIX + JavaEscapeUtils.makeJavaIdentifier(original);
     }
 
     private String findSafeName(String original) {
         int occurrenceCount = tracker.getOccurrenceCount(original);
-        String syntaxSafe = JavaEscapeUtils.getEscapedToken(original);
+        String syntaxSafe = JavaEscapeUtils.makeJavaIdentifier(original);
         if (occurrenceCount == 0) {
             return syntaxSafe; //no other declarations in scope. Use this very name
         } else {
diff --git a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/utils/JavaEscapeUtils.java b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/utils/JavaEscapeUtils.java
deleted file mode 100644
index 91c10af..0000000
--- a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/utils/JavaEscapeUtils.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*******************************************************************************
- * 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 org.apache.sling.scripting.sightly.java.compiler.impl.utils;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * The {@code JavaEscapeUtils} provides useful methods for escaping or transforming invalid Java tokens to valid ones that could be used in
- * generated Java source code.
- */
-public class JavaEscapeUtils {
-
-    private static final Set<String> reservedKeywords = new HashSet<String>() {{
-        add("abstract");
-        add("assert");
-        add("boolean");
-        add("break");
-        add("byte");
-        add("case");
-        add("catch");
-        add("char");
-        add("class");
-        add("const");
-        add("continue");
-        add("default");
-        add("do");
-        add("double");
-        add("else");
-        add("enum");
-        add("extends");
-        add("final");
-        add("finally");
-        add("float");
-        add("for");
-        add("goto");
-        add("if");
-        add("implements");
-        add("import");
-        add("instanceof");
-        add("int");
-        add("interface");
-        add("long");
-        add("native");
-        add("new");
-        add("package");
-        add("private");
-        add("protected");
-        add("public");
-        add("return");
-        add("short");
-        add("static");
-        add("strictfp");
-        add("super");
-        add("switch");
-        add("synchronized");
-        add("this");
-        add("throw");
-        add("throws");
-        add("transient");
-        add("try");
-        add("void");
-        add("volatile");
-        add("while");
-    }};
-
-    /**
-     * Escapes and / or transforms an invalid token (in case the token represents a reserved Java keyword) to provide a valid token.
-     *
-     * @param token the token to be transformed
-     * @return a valid Java token
-     */
-    public static String getEscapedToken(String token) {
-        String result = token;
-        if (reservedKeywords.contains(result)) {
-            result = "_" + result;
-        }
-        return result.replaceAll("-", "_");
-    }
-
-}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/package-info.java b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/package-info.java
index 8179757..4502fd2 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/package-info.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/package-info.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  ******************************************************************************/
-@Version("1.0.0")
+@Version("1.1.0")
 package org.apache.sling.scripting.sightly.java.compiler;
 
 import org.osgi.annotation.versioning.Version;

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.