Author: johnh
Date: Thu Aug 21 13:17:25 2008
New Revision: 687849

URL: http://svn.apache.org/viewvc?rev=687849&view=rev
Log:
Special handling of script and style blocks -- text contained therein is not 
escaped. Comments in code provide more context.


Modified:
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/GadgetHtmlNode.java
    
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/parse/GadgetHtmlNodeTest.java

Modified: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/GadgetHtmlNode.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/GadgetHtmlNode.java?rev=687849&r1=687848&r2=687849&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/GadgetHtmlNode.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/GadgetHtmlNode.java
 Thu Aug 21 13:17:25 2008
@@ -300,33 +300,7 @@
    */
   public void render(Writer w) throws IOException {
     if (isText()) {
-      String rawText = getText();
-      int commentStart = 0;
-      int curPos = 0;
-      while ((commentStart = rawText.indexOf("<!--", curPos)) >= 0) {
-        // Comment found. By definition there must be an end-comment marker
-        // since if there wasn't, the comment would subsume all further text.
-        
-        // First append up to the current point, with proper escaping.
-        w.append(StringEscapeUtils.escapeHtml(rawText.substring(curPos, 
commentStart)));
-        
-        // Then append the comment verbatim.
-        int commentEnd = rawText.indexOf("-->", commentStart);
-        if (commentEnd == -1) {
-          // Should never happen, per above comment. But we know that the 
comment
-          // has begun, so just append the rest of the string verbatim to be 
safe.
-          w.append(rawText.substring(commentStart));
-          return;
-        }
-        int endPos = commentEnd + "-->".length();
-        w.append(rawText.substring(commentStart, endPos));
-        
-        // Then set current position
-        curPos = endPos;
-      }
-      
-      // Append remaining (all, if no comment) text, escaped.
-      w.append(StringEscapeUtils.escapeHtml(rawText.substring(curPos)));
+      renderText(w);
     } else {
       w.append('<').append(tagName);
       for (String attrKey : getAttributeKeys()) {
@@ -350,6 +324,50 @@
     }
   }
   
+  // Helper that renders text content
+  private void renderText(Writer w) throws IOException {
+    String rawText = getText();
+    String parentTag = getParentNode() != null ? getParentNode().getTagName() 
: null;
+    if (parentTag != null &&
+        (parentTag.equalsIgnoreCase("script") ||
+         parentTag.equalsIgnoreCase("style"))) {
+      // Special dispensation for script and style blocks: don't escape
+      // them at all. The caller is always some server code, so must be
+      // trusted to render content appropriately, not trust user input
+      // verbatim where appropriate, etc. Escaping is avoided in order
+      // to preserve proper interpretation semantics.
+      w.append(rawText);
+      return;
+    }
+    
+    int commentStart = 0;
+    int curPos = 0;
+    while ((commentStart = rawText.indexOf("<!--", curPos)) >= 0) {
+      // Comment found. By definition there must be an end-comment marker
+      // since if there wasn't, the comment would subsume all further text.
+      
+      // First append up to the current point, with proper escaping.
+      w.append(StringEscapeUtils.escapeHtml(rawText.substring(curPos, 
commentStart)));
+      
+      // Then append the comment verbatim.
+      int commentEnd = rawText.indexOf("-->", commentStart);
+      if (commentEnd == -1) {
+        // Should never happen, per above comment. But we know that the comment
+        // has begun, so just append the rest of the string verbatim to be 
safe.
+        w.append(rawText.substring(commentStart));
+        return;
+      }
+      int endPos = commentEnd + "-->".length();
+      w.append(rawText.substring(commentStart, endPos));
+      
+      // Then set current position
+      curPos = endPos;
+    }
+    
+    // Append remaining (all, if no comment) text, escaped.
+    w.append(StringEscapeUtils.escapeHtml(rawText.substring(curPos)));
+  }
+  
   // Helper that cleans up and validates an attribute key
   private String validateAttributeKey(String key) {
     if (key == null) {

Modified: 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/parse/GadgetHtmlNodeTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/parse/GadgetHtmlNodeTest.java?rev=687849&r1=687848&r2=687849&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/parse/GadgetHtmlNodeTest.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/parse/GadgetHtmlNodeTest.java
 Thu Aug 21 13:17:25 2008
@@ -485,6 +485,24 @@
                  renderNode(escapedTextNode));
   }
   
+  public void testRenderEscapedTextContentInDiv() {
+    GadgetHtmlNode divNode = new GadgetHtmlNode("div", null);
+    divNode.appendChild(new GadgetHtmlNode("<script&\"data'>"));
+    assertEquals("<div>&lt;script&amp;&quot;data'&gt;</div>", 
renderNode(divNode));
+  }
+  
+  public void testRenderNoEscapingInScript() {
+    GadgetHtmlNode divNode = new GadgetHtmlNode("script", null);
+    divNode.appendChild(new GadgetHtmlNode("<script&\"data'>"));
+    assertEquals("<script><script&\"data'></script>", renderNode(divNode));
+  }
+  
+  public void testRenderNoEscapingInStyle() {
+    GadgetHtmlNode divNode = new GadgetHtmlNode("stYle", null);
+    divNode.appendChild(new GadgetHtmlNode("<script&\"data'>"));
+    assertEquals("<stYle><script&\"data'></stYle>", renderNode(divNode));
+  }
+  
   public void testRenderAdjacentStringsInTag() {
     GadgetHtmlNode container = new GadgetHtmlNode("div", null);
     container.appendChild(new GadgetHtmlNode("one"));


Reply via email to