SLING-9613 - java.lang.StackOverflowError in XSSFilterImpl.filter for long URLs
* make sure the bundle's classloader is used every time a call to any
of the XML APIs is made internally (e.g. AntiSamy init, AntiSamy scan)
diff --git a/src/main/java/org/apache/sling/xss/impl/HtmlToHtmlContentContext.java b/src/main/java/org/apache/sling/xss/impl/HtmlToHtmlContentContext.java
index 7e0535a..d387033 100644
--- a/src/main/java/org/apache/sling/xss/impl/HtmlToHtmlContentContext.java
+++ b/src/main/java/org/apache/sling/xss/impl/HtmlToHtmlContentContext.java
@@ -64,7 +64,6 @@
@Override
public String filter(final PolicyHandler policyHandler, final String str) {
if (StringUtils.isNotEmpty(str)) {
- ClassLoader tccl = Thread.currentThread().getContextClassLoader();
try {
final CleanResults results = getCleanResults(policyHandler, str);
if (results != null) {
@@ -78,8 +77,6 @@
}
} catch (Exception e) {
logError(e, str);
- } finally {
- Thread.currentThread().setContextClassLoader(tccl);
}
}
return StringUtils.EMPTY;
@@ -95,12 +92,16 @@
private CleanResults getCleanResults(PolicyHandler handler, String input) throws ScanException, PolicyException {
CleanResults results;
+ ClassLoader tccl = Thread.currentThread().getContextClassLoader();
try {
+ Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
results = handler.getAntiSamy().scan(input);
} catch (StackOverflowError e) {
log.debug("Will perform a second attempt at filtering the following input due to a StackOverflowError:\n{}", input);
results = handler.getFallbackAntiSamy().scan(input);
log.debug("Second attempt was successful.");
+ } finally {
+ Thread.currentThread().setContextClassLoader(tccl);
}
return results;
}
diff --git a/src/main/java/org/apache/sling/xss/impl/PolicyHandler.java b/src/main/java/org/apache/sling/xss/impl/PolicyHandler.java
index 5caf40a..2e737c2 100644
--- a/src/main/java/org/apache/sling/xss/impl/PolicyHandler.java
+++ b/src/main/java/org/apache/sling/xss/impl/PolicyHandler.java
@@ -45,6 +45,7 @@
Thread currentThread = Thread.currentThread();
ClassLoader cl = currentThread.getContextClassLoader();
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
+ currentThread.setContextClassLoader(this.getClass().getClassLoader());
IOUtils.copy(policyStream, baos);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
currentThread.setContextClassLoader(this.getClass().getClassLoader());