You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ra...@apache.org on 2019/05/24 13:38:23 UTC
[sling-org-apache-sling-scripting-sightly-compiler] branch
issue/SLING-6779 updated: SLING-6779 - The HTL compiler and Maven Plugin
should warn when using potentially invalid options
This is an automated email from the ASF dual-hosted git repository.
radu pushed a commit to branch issue/SLING-6779
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-sightly-compiler.git
The following commit(s) were added to refs/heads/issue/SLING-6779 by this push:
new 7e38340 SLING-6779 - The HTL compiler and Maven Plugin should warn when using potentially invalid options
7e38340 is described below
commit 7e383407b96a03c63fc54c7e201e8cbbee5fa258
Author: Radu Cotescu <ra...@apache.org>
AuthorDate: Fri May 24 15:38:12 2019 +0200
SLING-6779 - The HTL compiler and Maven Plugin should warn when using potentially invalid options
* collected known options from filters
* added a warn message in the compiler if a certain expression option is not handled by
any of the filters and the expression context doesn't allow arbitrary options
---
bnd.bnd | 2 +
pom.xml | 93 ++++++++++++----------
.../impl/compiler/frontend/CompilerContext.java | 5 +-
.../impl/compiler/frontend/ExpressionWrapper.java | 25 +++++-
.../sightly/impl/filter/AbstractFilter.java | 27 ++++---
.../scripting/sightly/impl/filter/Filter.java | 20 +++++
.../sightly/impl/filter/FormatFilter.java | 39 ++++-----
.../scripting/sightly/impl/filter/I18nFilter.java | 26 ++++--
.../scripting/sightly/impl/filter/JoinFilter.java | 33 +++++---
.../sightly/impl/filter/URIManipulationFilter.java | 43 +++++-----
.../scripting/sightly/impl/filter/XSSFilter.java | 16 ++--
.../sightly/impl/html/dom/MarkupHandler.java | 2 +-
.../sightly/impl/compiler/SightlyCompilerTest.java | 21 +++--
.../impl/frontend/ExpressionWrapperTest.java | 9 ++-
14 files changed, 218 insertions(+), 143 deletions(-)
diff --git a/bnd.bnd b/bnd.bnd
new file mode 100644
index 0000000..b036455
--- /dev/null
+++ b/bnd.bnd
@@ -0,0 +1,2 @@
+Provide-Capability: io.sightly.compiler; version:Version="1.0", io.sightly.compiler; version:Version="1.1", io.sightly.compiler; version:Version="1.2", io.sightly.compiler; version:Version="1.3", io.sightly.compiler; version:Version="1.3.1", io.sightly.compiler; version:Version="1.4",
+Require-Capability: io.sightly.runtime; filter:="(&(version>=1.0)(!(version>=2.0)))"
diff --git a/pom.xml b/pom.xml
index 8797fb0..5a9d563 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,8 +24,8 @@
<!-- ======================================================================= -->
<parent>
<groupId>org.apache.sling</groupId>
- <artifactId>sling</artifactId>
- <version>34</version>
+ <artifactId>sling-bundle-parent</artifactId>
+ <version>35</version>
<relativePath />
</parent>
@@ -38,7 +38,6 @@
releasing to only increase the first part, unless the module provides support for a newer version of the HTL specification.
-->
<version>1.1.3-1.4.0-SNAPSHOT</version>
- <packaging>bundle</packaging>
<name>Apache Sling Scripting HTL Compiler</name>
@@ -64,35 +63,35 @@
<!-- ======================================================================= -->
<build>
<plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <executions>
- <execution>
- <id>scr-metadata</id>
- <goals>
- <goal>manifest</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <exportScr>true</exportScr>
- <instructions>
- <Provide-Capability>
- io.sightly.compiler; version:Version=1.0,
- io.sightly.compiler; version:Version=1.1,
- io.sightly.compiler; version:Version=1.2,
- io.sightly.compiler; version:Version=1.3,
- io.sightly.compiler; version:Version=1.3.1,
- io.sightly.compiler; version:Version=1.4
- </Provide-Capability>
- <Require-Capability>
- io.sightly.runtime; filter:="(&(version>=1.0)(!(version>=2.0)))"
- </Require-Capability>
- </instructions>
- </configuration>
- </plugin>
+<!-- <plugin>-->
+<!-- <groupId>org.apache.felix</groupId>-->
+<!-- <artifactId>maven-bundle-plugin</artifactId>-->
+<!-- <extensions>true</extensions>-->
+<!-- <executions>-->
+<!-- <execution>-->
+<!-- <id>scr-metadata</id>-->
+<!-- <goals>-->
+<!-- <goal>manifest</goal>-->
+<!-- </goals>-->
+<!-- </execution>-->
+<!-- </executions>-->
+<!-- <configuration>-->
+<!-- <exportScr>true</exportScr>-->
+<!-- <instructions>-->
+<!-- <Provide-Capability>-->
+<!-- io.sightly.compiler; version:Version=1.0,-->
+<!-- io.sightly.compiler; version:Version=1.1,-->
+<!-- io.sightly.compiler; version:Version=1.2,-->
+<!-- io.sightly.compiler; version:Version=1.3,-->
+<!-- io.sightly.compiler; version:Version=1.3.1,-->
+<!-- io.sightly.compiler; version:Version=1.4-->
+<!-- </Provide-Capability>-->
+<!-- <Require-Capability>-->
+<!-- io.sightly.runtime; filter:="(&(version>=1.0)(!(version>=2.0)))"-->
+<!-- </Require-Capability>-->
+<!-- </instructions>-->
+<!-- </configuration>-->
+<!-- </plugin>-->
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
@@ -126,9 +125,9 @@
</executions>
</plugin>
<plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>findbugs-maven-plugin</artifactId>
- <version>3.0.5</version>
+ <groupId>com.github.spotbugs</groupId>
+ <artifactId>spotbugs-maven-plugin</artifactId>
+ <version>3.1.11</version>
<configuration>
<effort>Max</effort>
<xmlOutput>true</xmlOutput>
@@ -257,22 +256,28 @@
</dependency>
<dependency>
<groupId>org.powermock</groupId>
- <artifactId>powermock-reflect</artifactId>
- <version>1.6.5</version>
+ <artifactId>powermock-api-mockito2</artifactId>
+ <version>2.0.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
- <version>1.6.5</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.powermock</groupId>
- <artifactId>powermock-api-mockito</artifactId>
- <version>1.6.5</version>
+ <version>2.0.2</version>
<scope>test</scope>
</dependency>
+<!-- <dependency>-->
+<!-- <groupId>org.powermock</groupId>-->
+<!-- <artifactId>powermock-module-junit4</artifactId>-->
+<!-- <version>2.0.2</version>-->
+<!-- <scope>test</scope>-->
+<!-- </dependency>-->
+<!-- <dependency>-->
+<!-- <groupId>org.powermock</groupId>-->
+<!-- <artifactId>powermock-api-mockito</artifactId>-->
+<!-- <version>2.0.2</version>-->
+<!-- <scope>test</scope>-->
+<!-- </dependency>-->
</dependencies>
</project>
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/CompilerContext.java b/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/CompilerContext.java
index 60b4247..3e8cf0b 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/CompilerContext.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/CompilerContext.java
@@ -47,10 +47,7 @@ public class CompilerContext {
}
public Expression adjustToContext(Expression expression, MarkupContext context, ExpressionContext expressionContext) {
- if (!expression.getOptions().containsKey(Syntax.CONTEXT_OPTION)) {
- return expressionWrapper.adjustToContext(expression, context, expressionContext);
- }
- return expression;
+ return expressionWrapper.adjustToContext(expression, context, expressionContext);
}
public PushStream getPushStream() {
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ExpressionWrapper.java b/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ExpressionWrapper.java
index cf26b1c..53d1024 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ExpressionWrapper.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ExpressionWrapper.java
@@ -19,15 +19,20 @@
package org.apache.sling.scripting.sightly.impl.compiler.frontend;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import org.apache.sling.scripting.sightly.compiler.expression.Expression;
import org.apache.sling.scripting.sightly.compiler.expression.ExpressionNode;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.BinaryOperation;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.BinaryOperator;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.StringConstant;
+import org.apache.sling.scripting.sightly.impl.compiler.PushStream;
import org.apache.sling.scripting.sightly.impl.compiler.Syntax;
+import org.apache.sling.scripting.sightly.impl.filter.AbstractFilter;
import org.apache.sling.scripting.sightly.impl.filter.ExpressionContext;
import org.apache.sling.scripting.sightly.impl.filter.Filter;
import org.apache.sling.scripting.sightly.compiler.expression.MarkupContext;
@@ -38,9 +43,18 @@ import org.apache.sling.scripting.sightly.compiler.expression.MarkupContext;
public class ExpressionWrapper {
private final List<Filter> filters;
+ private final Set<String> knownOptions;
+ private final PushStream stream;
- public ExpressionWrapper(List<Filter> filters) {
+ public ExpressionWrapper(PushStream stream, List<Filter> filters) {
+ this.stream = stream;
this.filters = filters;
+ Set<String> options = new HashSet<>();
+ for (Filter filter : filters) {
+ options.addAll(filter.getOptions());
+ }
+ options.add(Syntax.CONTEXT_OPTION);
+ knownOptions = Collections.unmodifiableSet(options);
}
public Expression transform(Interpolation interpolation, MarkupContext markupContext, ExpressionContext expressionContext) {
@@ -51,13 +65,20 @@ public class ExpressionWrapper {
nodes.add(new StringConstant(fragment.getText()));
} else {
Expression expression = fragment.getExpression();
+ if (AbstractFilter.NON_PARAMETRIZABLE_CONTEXTS.contains(expressionContext)) {
+ for (String option : expression.getOptions().keySet()) {
+ if (!knownOptions.contains(option)) {
+ stream.warn(new PushStream.StreamMessage(String.format("Unknown option '%s'.", option), expression.getRawText()));
+ }
+ }
+ }
Expression transformed = adjustToContext(expression, markupContext, expressionContext);
nodes.add(transformed.getRoot());
options.putAll(transformed.getOptions());
}
}
ExpressionNode root = join(nodes);
- if (interpolation.size() > 1 && options.containsKey(Syntax.CONTEXT_OPTION)) {
+ if (interpolation.size() > 1) {
//context must not be calculated by merging
options.remove(Syntax.CONTEXT_OPTION);
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/AbstractFilter.java b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/AbstractFilter.java
index 9f2f931..53ee22c 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/AbstractFilter.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/AbstractFilter.java
@@ -18,11 +18,12 @@
******************************************************************************/
package org.apache.sling.scripting.sightly.impl.filter;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import java.util.function.Function;
-import java.util.function.Supplier;
import org.apache.sling.scripting.sightly.compiler.expression.Expression;
import org.apache.sling.scripting.sightly.compiler.expression.ExpressionNode;
@@ -30,6 +31,14 @@ import org.apache.sling.scripting.sightly.compiler.expression.ExpressionNode;
public abstract class AbstractFilter implements Filter {
protected int priority = 100;
+ public static final Set<ExpressionContext> NON_PARAMETRIZABLE_CONTEXTS;
+ static {
+ Set<ExpressionContext> contexts = new HashSet<>(Arrays.asList(ExpressionContext.values()));
+ contexts.remove(ExpressionContext.PLUGIN_DATA_SLY_USE);
+ contexts.remove(ExpressionContext.PLUGIN_DATA_SLY_TEMPLATE);
+ contexts.remove(ExpressionContext.PLUGIN_DATA_SLY_CALL);
+ NON_PARAMETRIZABLE_CONTEXTS = Collections.unmodifiableSet(contexts);
+ }
@Override
public int priority() {
@@ -48,19 +57,15 @@ public abstract class AbstractFilter implements Filter {
@Override
public Expression apply(Expression expression, ExpressionContext expressionContext) {
- boolean filter = false;
- for (String option : getOptions()) {
- if (expression.containsOption(option)) {
- filter = true;
- break;
- }
- }
- if (filter) {
+ Set<String> expressionOptions = expression.getOptions().keySet();
+ if (getApplicableContexts().contains(expressionContext) && expressionOptions.containsAll(getRequiredOptions())) {
return apply(expression, getFilterOptions(expression, getOptions()));
}
return expression;
}
+ protected abstract Expression apply(Expression expression, Map<String, ExpressionNode> options);
+
/**
* Collects the options passed in the {@code options} array into a new map while removing them from the original expression.
*
@@ -79,8 +84,6 @@ public abstract class AbstractFilter implements Filter {
return collector;
}
- protected abstract Expression apply(Expression expression, Map<String, ExpressionNode> options);
-
@Override
public int hashCode() {
return super.hashCode();
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/Filter.java b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/Filter.java
index 44d7288..4607df1 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/Filter.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/Filter.java
@@ -18,7 +18,9 @@
******************************************************************************/
package org.apache.sling.scripting.sightly.impl.filter;
+import java.util.Arrays;
import java.util.Collections;
+import java.util.HashSet;
import java.util.Set;
import org.apache.sling.scripting.sightly.compiler.expression.Expression;
@@ -57,4 +59,22 @@ public interface Filter extends Comparable<Filter> {
return Collections.emptySet();
}
+ /**
+ * Provides the option names that will trigger a filter's execution.
+ *
+ * @return the required options from an expression in order to trigger the filter
+ */
+ default Set<String> getRequiredOptions() {
+ return Collections.emptySet();
+ }
+
+ /**
+ * Provides the applicable contexts for this filter.
+ *
+ * @return the applicable contexts for this filter
+ */
+ default Set<ExpressionContext> getApplicableContexts() {
+ return new HashSet<>(Arrays.asList(ExpressionContext.values()));
+ }
+
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/FormatFilter.java b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/FormatFilter.java
index 0af52dd..349e13e 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/FormatFilter.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/FormatFilter.java
@@ -19,8 +19,9 @@
package org.apache.sling.scripting.sightly.impl.filter;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashSet;
-import java.util.Optional;
+import java.util.Map;
import java.util.Set;
import org.apache.sling.scripting.sightly.compiler.expression.Expression;
@@ -38,8 +39,8 @@ public class FormatFilter extends AbstractFilter {
public static final String FORMAT_LOCALE_OPTION = "formatLocale";
public static final String TIMEZONE_OPTION = "timezone";
- private static final Set<String> OPTIONS =
- new HashSet<>(Arrays.asList(FORMAT_OPTION, TYPE_OPTION, FORMAT_LOCALE_OPTION, TIMEZONE_OPTION));
+ private static final Set<String> OPTIONS = new HashSet<>(Arrays.asList(FORMAT_OPTION, TYPE_OPTION, FORMAT_LOCALE_OPTION, TIMEZONE_OPTION));
+ private static final Set<String> REQUIRED_OPTIONS = Collections.singleton(FORMAT_OPTION);
private static final class FormatFilterLoader {
private static final FormatFilter INSTANCE = new FormatFilter();
@@ -53,27 +54,9 @@ public class FormatFilter extends AbstractFilter {
}
@Override
- public Expression apply(Expression expression, ExpressionContext expressionContext) {
- //todo: if the expression is a string constant, we can produce the transformation at
- //compile time, with no need of a runtime function
- boolean filter = false;
- for (String option : OPTIONS) {
- if (expression.containsOption(option)) {
- filter = true;
- break;
- }
- }
- if (!filter) {
- return expression;
- }
+ protected Expression apply(Expression expression, Map<String, ExpressionNode> options) {
ExpressionNode translation =
- new RuntimeCall(RuntimeCall.FORMAT, expression.getRoot(),
- new MapLiteral(getFilterOptions(expression,
- FORMAT_OPTION,
- TYPE_OPTION,
- I18nFilter.LOCALE_OPTION,
- FORMAT_LOCALE_OPTION,
- TIMEZONE_OPTION)));
+ new RuntimeCall(RuntimeCall.FORMAT, expression.getRoot(), new MapLiteral(getFilterOptions(expression, getOptions())));
return expression.withNode(translation);
}
@@ -81,4 +64,14 @@ public class FormatFilter extends AbstractFilter {
public Set<String> getOptions() {
return OPTIONS;
}
+
+ @Override
+ public Set<String> getRequiredOptions() {
+ return REQUIRED_OPTIONS;
+ }
+
+ @Override
+ public Set<ExpressionContext> getApplicableContexts() {
+ return NON_PARAMETRIZABLE_CONTEXTS;
+ }
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/I18nFilter.java b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/I18nFilter.java
index 16b9228..94353f0 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/I18nFilter.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/I18nFilter.java
@@ -19,6 +19,7 @@
package org.apache.sling.scripting.sightly.impl.filter;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@@ -39,15 +40,13 @@ public final class I18nFilter extends AbstractFilter {
public static final String BASENAME_OPTION = "basename";
private static final Set<String> OPTIONS = new HashSet<>(Arrays.asList(I18N_OPTION, HINT_OPTION, LOCALE_OPTION, BASENAME_OPTION));
+ private static final Set<String> REQUIRED_OPTIONS = Collections.singleton(I18N_OPTION);
private static final class I18nFilterLoader {
private static final I18nFilter INSTANCE = new I18nFilter();
}
private I18nFilter() {
- if (I18nFilterLoader.INSTANCE != null) {
- throw new IllegalStateException("INSTANCE was already defined.");
- }
priority = 90;
}
@@ -57,14 +56,27 @@ public final class I18nFilter extends AbstractFilter {
@Override
protected Expression apply(Expression expression, Map<String, ExpressionNode> options) {
- ExpressionNode translation = new RuntimeCall(RuntimeCall.I18N, expression.getRoot(), new MapLiteral(options));
- expression.removeOption(I18N_OPTION);
- expression.getOptions().put(FormatFilter.FORMAT_LOCALE_OPTION, options.get(LOCALE_OPTION));
- return expression.withNode(translation);
+ if (options.containsKey(I18N_OPTION)) {
+ ExpressionNode translation = new RuntimeCall(RuntimeCall.I18N, expression.getRoot(), new MapLiteral(options));
+ expression.removeOption(I18N_OPTION);
+ expression.getOptions().put(FormatFilter.FORMAT_LOCALE_OPTION, options.get(LOCALE_OPTION));
+ return expression.withNode(translation);
+ }
+ return expression;
}
@Override
public Set<String> getOptions() {
return OPTIONS;
}
+
+ @Override
+ public Set<String> getRequiredOptions() {
+ return REQUIRED_OPTIONS;
+ }
+
+ @Override
+ public Set<ExpressionContext> getApplicableContexts() {
+ return NON_PARAMETRIZABLE_CONTEXTS;
+ }
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/JoinFilter.java b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/JoinFilter.java
index 113b3f5..73cdc62 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/JoinFilter.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/JoinFilter.java
@@ -18,6 +18,10 @@
******************************************************************************/
package org.apache.sling.scripting.sightly.impl.filter;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
import org.apache.sling.scripting.sightly.compiler.expression.Expression;
import org.apache.sling.scripting.sightly.compiler.expression.ExpressionNode;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.RuntimeCall;
@@ -28,29 +32,38 @@ import org.apache.sling.scripting.sightly.compiler.expression.nodes.RuntimeCall;
public class JoinFilter extends AbstractFilter {
public static final String JOIN_OPTION = "join";
+ private static final Set<String> OPTIONS = Collections.singleton(JOIN_OPTION);
private static final class JoinFilterLoader {
private static final JoinFilter INSTANCE = new JoinFilter();
}
- private JoinFilter() {
- if (JoinFilterLoader.INSTANCE != null) {
- throw new IllegalStateException("INSTANCE was already defined.");
- }
- }
+ private JoinFilter() {}
public static JoinFilter getInstance() {
return JoinFilterLoader.INSTANCE;
}
@Override
- public Expression apply(Expression expression, ExpressionContext expressionContext) {
- if (!expression.containsOption(JOIN_OPTION) || expressionContext == ExpressionContext.PLUGIN_DATA_SLY_USE || expressionContext
- == ExpressionContext.PLUGIN_DATA_SLY_TEMPLATE || expressionContext == ExpressionContext.PLUGIN_DATA_SLY_CALL) {
- return expression;
- }
+ protected Expression apply(Expression expression, Map<String, ExpressionNode> options) {
ExpressionNode translation =
new RuntimeCall(RuntimeCall.JOIN, expression.getRoot(), expression.removeOption(JOIN_OPTION));
return expression.withNode(translation);
}
+
+ @Override
+ public Set<String> getOptions() {
+ return OPTIONS;
+ }
+
+ @Override
+ public Set<String> getRequiredOptions() {
+ return OPTIONS;
+ }
+
+ @Override
+ public Set<ExpressionContext> getApplicableContexts() {
+ return NON_PARAMETRIZABLE_CONTEXTS;
+ }
+
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/URIManipulationFilter.java b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/URIManipulationFilter.java
index 8ba4b22..40ba54b 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/URIManipulationFilter.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/URIManipulationFilter.java
@@ -18,7 +18,10 @@
******************************************************************************/
package org.apache.sling.scripting.sightly.impl.filter;
+import java.util.Arrays;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
import org.apache.sling.scripting.sightly.compiler.expression.Expression;
import org.apache.sling.scripting.sightly.compiler.expression.ExpressionNode;
@@ -48,43 +51,37 @@ public class URIManipulationFilter extends AbstractFilter {
public static final String ADD_QUERY = "addQuery";
public static final String REMOVE_QUERY = "removeQuery";
+ private static final Set<String> OPTIONS = new HashSet<>(Arrays.asList(SCHEME, DOMAIN, PATH, APPEND_PATH, PREPEND_PATH, SELECTORS,
+ ADD_SELECTORS, REMOVE_SELECTORS, EXTENSION, SUFFIX, PREPEND_SUFFIX, APPEND_SUFFIX, FRAGMENT, QUERY, ADD_QUERY, REMOVE_QUERY));
+
private static final class URIManipulationFilterLoader {
private static final URIManipulationFilter INSTANCE = new URIManipulationFilter();
}
- private URIManipulationFilter() {
- if (URIManipulationFilterLoader.INSTANCE != null) {
- throw new IllegalStateException("INSTANCE was already defined.");
- }
- }
+ private URIManipulationFilter() {}
public static URIManipulationFilter getInstance() {
return URIManipulationFilterLoader.INSTANCE;
}
@Override
- public Expression apply(Expression expression, ExpressionContext expressionContext) {
- if ((expression.containsOption(SCHEME) || expression.containsOption(DOMAIN) || expression.containsOption(PATH) || expression
- .containsOption(APPEND_PATH) || expression.containsOption(PREPEND_PATH) || expression.containsOption(SELECTORS) ||
- expression.containsOption(ADD_SELECTORS) || expression.containsOption(REMOVE_SELECTORS) || expression.containsOption
- (EXTENSION) || expression.containsOption(SUFFIX) || expression.containsOption(PREPEND_SUFFIX) || expression
- .containsOption(APPEND_SUFFIX) || expression.containsOption(FRAGMENT) || expression.containsOption(QUERY) || expression
- .containsOption(ADD_QUERY) || expression.containsOption(REMOVE_QUERY)) && expressionContext != ExpressionContext
- .PLUGIN_DATA_SLY_USE && expressionContext
- != ExpressionContext.PLUGIN_DATA_SLY_TEMPLATE && expressionContext != ExpressionContext.PLUGIN_DATA_SLY_CALL &&
- expressionContext != ExpressionContext.PLUGIN_DATA_SLY_RESOURCE) {
- Map<String, ExpressionNode> uriOptions = getFilterOptions(expression, SCHEME, DOMAIN, PATH, APPEND_PATH, PREPEND_PATH,
- SELECTORS, ADD_SELECTORS, REMOVE_SELECTORS, EXTENSION, SUFFIX, PREPEND_SUFFIX, APPEND_SUFFIX, FRAGMENT, QUERY,
- ADD_QUERY, REMOVE_QUERY);
- if (uriOptions.size() > 0) {
- ExpressionNode translation =
- new RuntimeCall(RuntimeCall.URI_MANIPULATION, expression.getRoot(), new MapLiteral(uriOptions));
- return expression.withNode(translation);
- }
+ protected Expression apply(Expression expression, Map<String, ExpressionNode> options) {
+ if (options.size() > 0) {
+ ExpressionNode translation =
+ new RuntimeCall(RuntimeCall.URI_MANIPULATION, expression.getRoot(), new MapLiteral(options));
+ return expression.withNode(translation);
}
return expression;
}
+ @Override
+ public Set<String> getOptions() {
+ return OPTIONS;
+ }
+ @Override
+ public Set<ExpressionContext> getApplicableContexts() {
+ return NON_PARAMETRIZABLE_CONTEXTS;
+ }
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/XSSFilter.java b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/XSSFilter.java
index f693102..2451d90 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/XSSFilter.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/XSSFilter.java
@@ -18,6 +18,9 @@
******************************************************************************/
package org.apache.sling.scripting.sightly.impl.filter;
+import java.util.Map;
+import java.util.Set;
+
import org.apache.sling.scripting.sightly.compiler.expression.Expression;
import org.apache.sling.scripting.sightly.compiler.expression.ExpressionNode;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.RuntimeCall;
@@ -33,9 +36,6 @@ public class XSSFilter extends AbstractFilter {
}
private XSSFilter() {
- if (XSSFilterLoader.INSTANCE != null) {
- throw new IllegalStateException("INSTANCE was already defined.");
- }
priority = 110;
}
@@ -44,11 +44,7 @@ public class XSSFilter extends AbstractFilter {
}
@Override
- public Expression apply(Expression expression, ExpressionContext expressionContext) {
- if (expressionContext == ExpressionContext.PLUGIN_DATA_SLY_USE || expressionContext == ExpressionContext.PLUGIN_DATA_SLY_TEMPLATE
- || expressionContext == ExpressionContext.PLUGIN_DATA_SLY_CALL) {
- return expression;
- }
+ protected Expression apply(Expression expression, Map<String, ExpressionNode> options) {
ExpressionNode context = expression.removeOption(Syntax.CONTEXT_OPTION);
if (context != null) {
return expression.withNode(new RuntimeCall(RuntimeCall.XSS, expression.getRoot(), context));
@@ -56,4 +52,8 @@ public class XSSFilter extends AbstractFilter {
return expression;
}
+ @Override
+ public Set<ExpressionContext> getApplicableContexts() {
+ return NON_PARAMETRIZABLE_CONTEXTS;
+ }
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/html/dom/MarkupHandler.java b/src/main/java/org/apache/sling/scripting/sightly/impl/html/dom/MarkupHandler.java
index c8c4966..314b29a 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/html/dom/MarkupHandler.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/html/dom/MarkupHandler.java
@@ -78,7 +78,7 @@ public class MarkupHandler {
public MarkupHandler(PushStream stream, Map<String, Plugin> pluginRegistry, List<Filter> filters) {
this.stream = stream;
this.pluginRegistry = pluginRegistry;
- this.expressionWrapper = new ExpressionWrapper(filters);
+ this.expressionWrapper = new ExpressionWrapper(stream, filters);
this.compilerContext = new CompilerContext(symbolGenerator, expressionWrapper, stream);
}
diff --git a/src/test/java/org/apache/sling/scripting/sightly/impl/compiler/SightlyCompilerTest.java b/src/test/java/org/apache/sling/scripting/sightly/impl/compiler/SightlyCompilerTest.java
index 7d95e1d..044561e 100644
--- a/src/test/java/org/apache/sling/scripting/sightly/impl/compiler/SightlyCompilerTest.java
+++ b/src/test/java/org/apache/sling/scripting/sightly/impl/compiler/SightlyCompilerTest.java
@@ -51,7 +51,7 @@ public class SightlyCompilerTest {
@Test
public void testMissingExplicitContext() {
- for (String s : new String[] {"", "-win", "-mac"}) {
+ for (String s : new String[]{"", "-win", "-mac"}) {
String script = "/missing-explicit-context" + s + ".html";
testMissingExplicitContext(script);
}
@@ -74,7 +74,7 @@ public class SightlyCompilerTest {
PowerMockito.mockStatic(System.class);
PowerMockito.when(System.lineSeparator()).thenReturn("\r\n");
- for (String s : new String[] {"", "-win", "-mac"}) {
+ for (String s : new String[]{"", "-win", "-mac"}) {
String script = "/missing-explicit-context" + s + ".html";
testMissingExplicitContext(script);
}
@@ -85,7 +85,7 @@ public class SightlyCompilerTest {
PowerMockito.mockStatic(System.class);
PowerMockito.when(System.lineSeparator()).thenReturn("\r");
- for (String s : new String[] {"", "-win", "-mac"}) {
+ for (String s : new String[]{"", "-win", "-mac"}) {
String script = "/missing-explicit-context" + s + ".html";
testMissingExplicitContext(script);
}
@@ -129,8 +129,8 @@ public class SightlyCompilerTest {
}
// doubles
- double doubleTestRange = 20.00;
- for (double i = -1.00 * doubleTestRange; i < doubleTestRange; i+= 0.1) {
+ double doubleTestRange = 20.00;
+ for (double i = -1.00 * doubleTestRange; i < doubleTestRange; i += 0.1) {
assertEquals(0, compileSource("${" + i + "}").getErrors().size());
}
@@ -150,6 +150,17 @@ public class SightlyCompilerTest {
assertEquals(0, compileSource("${1e+2}").getErrors().size());
}
+ @Test
+ public void testUnknownExpressionOptions() {
+ assertEquals(0, compileSource("<sly data-sly-use.a=\"${com.example.Pojo @ param1=1, param2=2}\"></sly>").getWarnings().size());
+ assertEquals(0, compileSource("<sly data-sly-call=\"${myTemplate @ param1=1, param2=2}\"></sly>").getWarnings().size());
+ assertEquals(0, compileSource("<template data-sly-template.myTemplate=\"${@ param1, param2}\"></template>").getWarnings().size());
+ assertEquals(1, compileSource("${currentPage.title @ contex = 'scriptString'}").getWarnings().size());
+ assertEquals(1, compileSource("${a @ unknownOption}").getWarnings().size());
+ assertEquals(2, compileSource("${a @ unknownOption1, unknownOption2}").getWarnings().size());
+ assertEquals(1, compileSource("<div data-sly-text='${\"text\" @ i18nn}'>Replaced</div>").getWarnings().size());
+ }
+
private CompilationResult compileFile(final String file) {
InputStream stream = this.getClass().getResourceAsStream(file);
final Reader reader = new InputStreamReader(stream);
diff --git a/src/test/java/org/apache/sling/scripting/sightly/impl/frontend/ExpressionWrapperTest.java b/src/test/java/org/apache/sling/scripting/sightly/impl/frontend/ExpressionWrapperTest.java
index 4eea958..a713265 100644
--- a/src/test/java/org/apache/sling/scripting/sightly/impl/frontend/ExpressionWrapperTest.java
+++ b/src/test/java/org/apache/sling/scripting/sightly/impl/frontend/ExpressionWrapperTest.java
@@ -33,6 +33,7 @@ import org.apache.sling.scripting.sightly.compiler.expression.nodes.NullLiteral;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.NumericConstant;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.RuntimeCall;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.StringConstant;
+import org.apache.sling.scripting.sightly.impl.compiler.PushStream;
import org.apache.sling.scripting.sightly.impl.compiler.frontend.ExpressionWrapper;
import org.apache.sling.scripting.sightly.impl.compiler.frontend.Interpolation;
import org.apache.sling.scripting.sightly.impl.filter.ExpressionContext;
@@ -70,7 +71,7 @@ public class ExpressionWrapperTest {
options.put(I18nFilter.LOCALE_OPTION, new StringConstant("de"));
options.put(I18nFilter.I18N_OPTION, NullLiteral.INSTANCE);
interpolation.addExpression(new Expression(new StringConstant("hello"), options));
- ExpressionWrapper wrapper = new ExpressionWrapper(filters);
+ ExpressionWrapper wrapper = new ExpressionWrapper(new PushStream(), filters);
Expression result = wrapper.transform(interpolation, MarkupContext.TEXT, ExpressionContext.TEXT);
List<ExpressionNode> xssArguments = runOptionsAndXSSAssertions(result, 1);
RuntimeCall i18n = (RuntimeCall) xssArguments.get(0);
@@ -86,7 +87,7 @@ public class ExpressionWrapperTest {
formatArray.add(new StringConstant("Doe"));
options.put(FormatFilter.FORMAT_OPTION, new ArrayLiteral(formatArray));
interpolation.addExpression(new Expression(new StringConstant("Hello {0} {1}"), options));
- ExpressionWrapper wrapper = new ExpressionWrapper(filters);
+ ExpressionWrapper wrapper = new ExpressionWrapper(new PushStream(), filters);
Expression result = wrapper.transform(interpolation, MarkupContext.TEXT, ExpressionContext.TEXT);
List<ExpressionNode> xssArguments = runOptionsAndXSSAssertions(result, 0);
RuntimeCall format = (RuntimeCall) xssArguments.get(0);
@@ -102,7 +103,7 @@ public class ExpressionWrapperTest {
array.add(new NumericConstant(0));
array.add(new NumericConstant(1));
interpolation.addExpression(new Expression(new ArrayLiteral(array), options));
- ExpressionWrapper wrapper = new ExpressionWrapper(filters);
+ ExpressionWrapper wrapper = new ExpressionWrapper(new PushStream(), filters);
Expression result = wrapper.transform(interpolation, MarkupContext.TEXT, ExpressionContext.TEXT);
List<ExpressionNode> xssArguments = runOptionsAndXSSAssertions(result, 0);
RuntimeCall join = (RuntimeCall) xssArguments.get(0);
@@ -138,7 +139,7 @@ public class ExpressionWrapperTest {
interpolation.addExpression(
new Expression(new StringConstant("http://www.example.com/resource.selector.extension/suffix#fragment?param=value"),
options));
- ExpressionWrapper wrapper = new ExpressionWrapper(filters);
+ ExpressionWrapper wrapper = new ExpressionWrapper(new PushStream(), filters);
Expression result = wrapper.transform(interpolation, MarkupContext.TEXT, ExpressionContext.TEXT);
List<ExpressionNode> xssArguments = runOptionsAndXSSAssertions(result, 0);
RuntimeCall join = (RuntimeCall) xssArguments.get(0);