This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-sightly-compiler-java.git
commit c988fec676719adf40783d57a4816295b3c6d1ee Author: Radu Cotescu <[email protected]> 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@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 "[email protected]" <[email protected]>.
