SLING-11610 - Sling XSS API 2.3.0 does not work on Java 17
Use the reflection API in a way that is compatible with Java 17. This still requires
invokers to use "-add-opens", see the updates surefire config.
diff --git a/pom.xml b/pom.xml
index 3e37d9e..d9c9d19 100644
--- a/pom.xml
+++ b/pom.xml
@@ -377,5 +377,26 @@
<scope>test</scope>
</dependency>
</dependencies>
+
+ <profiles>
+ <profile>
+ <id>java12-or-higher</id>
+ <activation>
+ <!-- starting with Java 12 some reflective operations require add-opens instructions -->
+ <jdk>[12,)</jdk>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <argLine>--add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED</argLine>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
</project>
diff --git a/src/main/java/org/apache/sling/xss/impl/AntiSamyPolicyAdapter.java b/src/main/java/org/apache/sling/xss/impl/AntiSamyPolicyAdapter.java
index cb20842..20a8568 100644
--- a/src/main/java/org/apache/sling/xss/impl/AntiSamyPolicyAdapter.java
+++ b/src/main/java/org/apache/sling/xss/impl/AntiSamyPolicyAdapter.java
@@ -19,6 +19,7 @@
package org.apache.sling.xss.impl;
import java.lang.reflect.Field;
+import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
@@ -27,8 +28,8 @@
import java.util.regex.Pattern;
import org.apache.sling.xss.impl.style.CssValidator;
-import org.apache.sling.xss.impl.xml.Attribute;
import org.apache.sling.xss.impl.xml.AntiSamyPolicy;
+import org.apache.sling.xss.impl.xml.Attribute;
import org.apache.sling.xss.impl.xml.Tag;
import org.jetbrains.annotations.Nullable;
import org.owasp.html.AttributePolicy;
@@ -222,6 +223,7 @@
private static Predicate<String> matchesPatternsOrLiterals(List<Pattern> patternList, boolean ignoreCase, List<String> literalList) {
return new Predicate<String>() {
+ @Override
public boolean apply(String s) {
// check if the string matches to the pattern or one of the literal
s = ignoreCase ? s.toLowerCase() : s;
@@ -261,13 +263,28 @@
}
}
- private void letMeIn(Field field) throws ReflectiveOperationException {
- if (!field.isAccessible())
- field.setAccessible(true);
- if ((field.getModifiers() & Modifier.FINAL) != 0) {
- Field modifiersField = Field.class.getDeclaredField("modifiers");
+ private void letMeIn(Field inaccessible) throws ReflectiveOperationException {
+ if (!inaccessible.isAccessible())
+ inaccessible.setAccessible(true);
+ if ((inaccessible.getModifiers() & Modifier.FINAL) != 0) {
+ Field modifiersField = null;
+ try {
+ modifiersField = Field.class.getDeclaredField("modifiers");
+ } catch ( NoSuchFieldException e ) {
+ // fallback for Java 12+
+ Method getDeclaredFields = Class.class.getDeclaredMethod("getDeclaredFields0", boolean.class);
+ getDeclaredFields.setAccessible(true);
+ Field[] fields = (Field[]) getDeclaredFields.invoke(Field.class, false);
+ for ( Field field : fields ) {
+ if ( "modifiers".equals(field.getName()) ) {
+ modifiersField = field;
+ }
+ }
+ }
+ if ( modifiersField == null )
+ throw new IllegalAccessException("Unable to locate modifiers field " + Field.class.getName() + ", aborting setup");
modifiersField.setAccessible(true);
- modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
+ modifiersField.setInt(inaccessible, inaccessible.getModifiers() & ~Modifier.FINAL);
}
}
}
\ No newline at end of file