SLING-6787 : HTMLRendererServlet shoud properly encode output

git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1792724 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/pom.xml b/pom.xml
index 426f657..85bce3c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -85,6 +85,12 @@
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.xss</artifactId>
+            <version>1.0.6</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.api</artifactId>
             <version>2.7.0</version>
             <scope>provided</scope>
diff --git a/src/main/java/org/apache/sling/servlets/get/impl/DefaultGetServlet.java b/src/main/java/org/apache/sling/servlets/get/impl/DefaultGetServlet.java
index 7f1d1cb..1f69132 100644
--- a/src/main/java/org/apache/sling/servlets/get/impl/DefaultGetServlet.java
+++ b/src/main/java/org/apache/sling/servlets/get/impl/DefaultGetServlet.java
@@ -37,9 +37,12 @@
 import org.apache.sling.servlets.get.impl.helpers.PlainTextRendererServlet;
 import org.apache.sling.servlets.get.impl.helpers.StreamRendererServlet;
 import org.apache.sling.servlets.get.impl.helpers.XMLRendererServlet;
+import org.apache.sling.xss.XSSAPI;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
 import org.osgi.service.metatype.annotations.AttributeDefinition;
 import org.osgi.service.metatype.annotations.Designate;
 import org.osgi.service.metatype.annotations.ObjectClassDefinition;
@@ -151,6 +154,9 @@
 
     private boolean enableXml;
 
+    @Reference(policyOption = ReferencePolicyOption.GREEDY)
+    private XSSAPI xssApi;
+
     @Activate
     protected void activate(Config cfg) {
         this.aliases = cfg.aliases();
@@ -179,7 +185,7 @@
         if ( StreamRendererServlet.EXT_RES.equals(type) ) {
             servlet = new StreamRendererServlet(index, indexFiles);
         } else if ( HtmlRendererServlet.EXT_HTML.equals(type) ) {
-            servlet = new HtmlRendererServlet();
+            servlet = new HtmlRendererServlet(xssApi);
         } else if ( PlainTextRendererServlet.EXT_TXT.equals(type) ) {
             servlet = new PlainTextRendererServlet();
         } else if (JsonRendererServlet.EXT_JSON.equals(type) ) {
diff --git a/src/main/java/org/apache/sling/servlets/get/impl/helpers/HtmlRendererServlet.java b/src/main/java/org/apache/sling/servlets/get/impl/helpers/HtmlRendererServlet.java
index 7b5a35d..c018427 100644
--- a/src/main/java/org/apache/sling/servlets/get/impl/helpers/HtmlRendererServlet.java
+++ b/src/main/java/org/apache/sling/servlets/get/impl/helpers/HtmlRendererServlet.java
@@ -18,13 +18,11 @@
 
 import java.io.IOException;
 import java.io.PrintWriter;
-import java.util.Iterator;
 import java.util.Map;
 
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletResponse;
 
-import org.apache.commons.lang3.StringEscapeUtils;
 import org.apache.sling.api.SlingConstants;
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.SlingHttpServletResponse;
@@ -32,6 +30,7 @@
 import org.apache.sling.api.resource.ResourceNotFoundException;
 import org.apache.sling.api.resource.ResourceUtil;
 import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
+import org.apache.sling.xss.XSSAPI;
 
 /**
  * The <code>HtmlRendererServlet</code> renders the current resource in HTML
@@ -43,9 +42,16 @@
 
     public static final String EXT_HTML = "html";
 
+    private final XSSAPI xssApi;
+
+    public HtmlRendererServlet(final XSSAPI xssApi) {
+        this.xssApi = xssApi;
+    }
+
     @Override
-    protected void doGet(SlingHttpServletRequest req,
-            SlingHttpServletResponse resp) throws ServletException, IOException {
+    protected void doGet(final SlingHttpServletRequest req,
+            final SlingHttpServletResponse resp)
+    throws ServletException, IOException {
         final Resource r = req.getResource();
 
         if (ResourceUtil.isNonExistingResource(r)) {
@@ -59,7 +65,7 @@
 
         final boolean isIncluded = req.getAttribute(SlingConstants.ATTR_REQUEST_SERVLET) != null;
 
-        @SuppressWarnings("unchecked")
+        @SuppressWarnings({ "rawtypes" })
         final Map map = r.adaptTo(Map.class);
         if ( map != null ) {
             printProlog(pw, isIncluded);
@@ -83,7 +89,7 @@
         }
     }
 
-    private void printProlog(PrintWriter pw, boolean isIncluded) {
+    private void printProlog(final PrintWriter pw, final boolean isIncluded) {
         if ( !isIncluded ) {
             pw.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
             pw.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"");
@@ -94,55 +100,63 @@
         }
     }
 
-    private void printEpilog(PrintWriter pw, boolean isIncluded) {
+    private void printEpilog(final PrintWriter pw, final boolean isIncluded) {
         if ( !isIncluded ) {
             pw.println("</body></html>");
         }
     }
 
-    private void printResourceInfo(PrintWriter pw, Resource r) {
-        pw.println("<h1>Resource dumped by " + getClass().getSimpleName() + "</h1>");
-        pw.println("<p>Resource path: <b>" + r.getPath() + "</b></p>");
-        pw.println("<p>Resource metadata: <b>"
-            + StringEscapeUtils.escapeHtml4(String.valueOf(r.getResourceMetadata()))
-            + "</b></p>");
+    private void printResourceInfo(final PrintWriter pw, final Resource r) {
+        pw.print("<h1>Resource dumped by ");
+        pw.print(xssApi.encodeForHTML(getClass().getSimpleName()));
+        pw.println("</h1>");
 
-        pw.println("<p>Resource type: <b>" + r.getResourceType() + "</b></p>");
+        pw.print("<p>Resource path: <b>");
+        pw.print(xssApi.encodeForHTML(r.getPath()));
+        pw.println("</b></p>");
 
-        String resourceSuperType = ResourceUtil.findResourceSuperType(r);
+        pw.print("<p>Resource metadata: <b>");
+        pw.print(xssApi.encodeForHTML(String.valueOf(r.getResourceMetadata())));
+        pw.println("</b></p>");
+
+        pw.print("<p>Resource type: <b>");
+        pw.print(xssApi.encodeForHTML(r.getResourceType()));
+        pw.println("</b></p>");
+
+        String resourceSuperType = r.getResourceResolver().getParentResourceType(r);
         if (resourceSuperType == null) {
             resourceSuperType = "-";
         }
-        pw.println("<p>Resource super type: <b>" + resourceSuperType
-            + "</b></p>");
+        pw.print("<p>Resource super type: <b>");
+        pw.print(xssApi.encodeForHTML(resourceSuperType));
+        pw.println("</b></p>");
     }
 
-    @SuppressWarnings("unchecked")
-    private void render(PrintWriter pw, Resource r, Map map) {
+    @SuppressWarnings({"rawtypes"})
+    private void render(final PrintWriter pw, final Resource r, final Map<?, ?> map) {
         pw.println("<h2>Resource properties</h2>");
         pw.println("<p>");
-        final Iterator<Map.Entry> pi = map.entrySet().iterator();
-        while ( pi.hasNext() ) {
-            final Map.Entry p = pi.next();
+        for(final Map.Entry p : map.entrySet()) {
             printPropertyValue(pw, p.getKey().toString(), p.getValue());
             pw.println();
         }
         pw.println("</p>");
     }
 
-    private void render(PrintWriter pw, Resource r, String value) {
+    private void render(final PrintWriter pw, final Resource r, final String value) {
         printPropertyValue(pw, "Resource Value", value);
     }
 
-    private void render(PrintWriter pw, Resource r, String[] values) {
-        for (String value : values) {
+    private void render(final PrintWriter pw, final Resource r, final String[] values) {
+        for (final String value : values) {
             printPropertyValue(pw, "Resource Value", value);
         }
     }
 
-    private void printPropertyValue(PrintWriter pw, String name, Object value) {
+    private void printPropertyValue(final PrintWriter pw, final String name, final Object value) {
 
-        pw.print(name + ": <b>");
+        pw.print(xssApi.encodeForHTML(name));
+        pw.print(": <b>");
 
         if ( value.getClass().isArray() ) {
             Object[] values = (Object[])value;
@@ -151,11 +165,11 @@
                 if (i > 0) {
                     pw.print(", ");
                 }
-                pw.print(values[i].toString());
+                pw.print(xssApi.encodeForHTML(values[i].toString()));
             }
             pw.print(']');
         } else {
-            pw.print(value.toString());
+            pw.print(xssApi.encodeForHTML(value.toString()));
         }
 
         pw.print("</b><br />");