Author: mgrigorov
Date: Thu Apr 28 14:20:40 2011
New Revision: 1097472

URL: http://svn.apache.org/viewvc?rev=1097472&view=rev
Log:
WICKET-3648 AbstractMarkupParser.removeComment() goes in endless loop when the 
comment is multi line
WICKET-3500 Method AbstractMarkupParser.removeComment() causes an endless loop

Merge the fix from WICKET-3500 to 1.5. It fixes both the endless loop problem 
and the proper handling of multiple IE conditional comments.


Added:
    
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/IEConditionalCommentsPage.html
    
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/IEConditionalCommentsPage.java
Modified:
    
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/AbstractMarkupParser.java
    
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/parser/filter/StyleAndScriptIdentifier.java
    
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/MarkupParserTest.java

Modified: 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/AbstractMarkupParser.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/AbstractMarkupParser.java?rev=1097472&r1=1097471&r2=1097472&view=diff
==============================================================================
--- 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/AbstractMarkupParser.java
 (original)
+++ 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/AbstractMarkupParser.java
 Thu Apr 28 14:20:40 2011
@@ -16,12 +16,6 @@
  */
 package org.apache.wicket.markup;
 
-import java.io.IOException;
-import java.text.ParseException;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
 import org.apache.wicket.Application;
 import org.apache.wicket.markup.parser.IMarkupFilter;
 import org.apache.wicket.markup.parser.IXmlPullParser;
@@ -33,6 +27,12 @@ import org.apache.wicket.util.resource.S
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.IOException;
+import java.text.ParseException;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 /**
  * This is a base MarkupParser specifically for (X)HTML. It makes use of a 
streaming XML parser to
  * read the markup and IMarkupFilters to remove comments, identify Wicket 
relevant tags, apply html
@@ -53,8 +53,8 @@ public abstract class AbstractMarkupPars
        /** Log for reporting. */
        private static final Logger log = 
LoggerFactory.getLogger(AbstractMarkupParser.class);
 
-       /** Conditional comment section, which is NOT treated as a comment 
section */
-       private static final Pattern CONDITIONAL_COMMENT = 
Pattern.compile("\\[if .+\\]>((?s).*)<!\\[endif\\]");
+       /** Opening a conditional comment section, which is NOT treated as a 
comment section */
+       public static final Pattern CONDITIONAL_COMMENT_OPENING = 
Pattern.compile("(s?)^[^>]*?<!--\\[if.*?\\]>(-->)?(<!.*?-->)?");
 
        /** The XML parser to use */
        private final IXmlPullParser xmlParser;
@@ -413,45 +413,34 @@ public abstract class AbstractMarkupPars
                return sb.toString();
        }
 
+
        /**
         * Remove all comment sections (&lt;!-- .. --&gt;) from the raw markup.
         * 
         * @param rawMarkup
         * @return raw markup
         */
-       private String removeComment(String rawMarkup)
+       private static String removeComment(String rawMarkup)
        {
-               // For reasons I don't understand, the following regex 
<code>"<!--(.|\n|\r)*?-->"<code>
-               // causes a stack overflow in some circumstances (jdk 1.5)
-               // See 
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5050507
-               // See 
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6337993
                int pos1 = rawMarkup.indexOf("<!--");
                while (pos1 != -1)
                {
-                       int pos2 = rawMarkup.indexOf("-->", pos1 + 4);
-
                        final StringBuilder buf = new 
StringBuilder(rawMarkup.length());
-                       if (pos2 != -1)
+                       final String possibleComment = 
rawMarkup.substring(pos1);
+                       Matcher matcher = 
CONDITIONAL_COMMENT_OPENING.matcher(possibleComment);
+                       if (matcher.find())
                        {
-                               final String comment = rawMarkup.substring(pos1 
+ 4, pos2);
-
-                               // See wicket-2105 for an example where this 
rather simple regex throws an exception
-                               // CONDITIONAL_COMMENT = Pattern.compile("\\[if 
.+\\]>(.|\n|\r)*<!\\[endif\\]");
-                               // See 
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5050507
-                               // See 
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6337993
-                               if 
(CONDITIONAL_COMMENT.matcher(comment).matches() == false)
-                               {
-                                       buf.append(rawMarkup.substring(0, 
pos1));
-                                       if (rawMarkup.length() >= pos2 + 3)
-                                       {
-                                               
buf.append(rawMarkup.substring(pos2 + 3));
-                                       }
-                                       rawMarkup = buf.toString();
-                               }
-                               else
+                               pos1 = pos1 + matcher.end();
+                       }
+                       else
+                       {
+                               int pos2 = rawMarkup.indexOf("-->", pos1 + 4);
+                               buf.append(rawMarkup.substring(0, pos1));
+                               if (rawMarkup.length() >= pos2 + 3)
                                {
-                                       pos1 = pos2;
+                                       buf.append(rawMarkup.substring(pos2 + 
3));
                                }
+                               rawMarkup = buf.toString();
                        }
                        pos1 = rawMarkup.indexOf("<!--", pos1);
                }

Modified: 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/parser/filter/StyleAndScriptIdentifier.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/parser/filter/StyleAndScriptIdentifier.java?rev=1097472&r1=1097471&r2=1097472&view=diff
==============================================================================
--- 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/parser/filter/StyleAndScriptIdentifier.java
 (original)
+++ 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/parser/filter/StyleAndScriptIdentifier.java
 Thu Apr 28 14:20:40 2011
@@ -16,8 +16,6 @@
  */
 package org.apache.wicket.markup.parser.filter;
 
-import java.text.ParseException;
-
 import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.markup.Markup;
 import org.apache.wicket.markup.MarkupElement;
@@ -26,6 +24,8 @@ import org.apache.wicket.markup.parser.A
 import org.apache.wicket.markup.parser.XmlPullParser;
 import org.apache.wicket.util.string.JavaScriptUtils;
 
+import java.text.ParseException;
+
 
 /**
  * 
@@ -94,7 +94,8 @@ public final class StyleAndScriptIdentif
                                                        if (close.closes(open))
                                                        {
                                                                String text = 
body.toString().trim();
-                                                               if 
(!text.startsWith("<!--") && !text.startsWith("<![CDATA["))
+                                                               if 
(!text.startsWith("<!--") && !text.startsWith("<![CDATA[") &&
+                                                                       
!text.startsWith("/*<![CDATA[*/"))
                                                                {
                                                                        text = 
JavaScriptUtils.SCRIPT_CONTENT_PREFIX + body.toString() +
                                                                                
JavaScriptUtils.SCRIPT_CONTENT_SUFFIX;

Added: 
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/IEConditionalCommentsPage.html
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/IEConditionalCommentsPage.html?rev=1097472&view=auto
==============================================================================
--- 
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/IEConditionalCommentsPage.html
 (added)
+++ 
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/IEConditionalCommentsPage.html
 Thu Apr 28 14:20:40 2011
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<!--[if lt IE 7 ]> <html class="no-js ie6"> <![endif]-->
+<!--[if IE 7 ]>    <html class="no-js ie7"> <![endif]-->
+<!--[if IE 8 ]>    <html class="no-js ie8"> <![endif]-->
+<!--[if (gte IE 9)|!(IE)]><!--> <html class="no-js" 
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd";> 
<!--<![endif]-->
+
+<head>
+    <style>
+/*<![CDATA[*/
+
+        html {
+            font-family: Arial;
+        }
+    
+/*]]>*/
+    </style>
+</head>
+<body></body>
+
+<!--[if lt IE 7 ]> </html> <![endif]-->
+<!--[if IE 7 ]>    </html> <![endif]-->
+<!--[if IE 8 ]>    </html> <![endif]-->
+<!--[if (gte IE 9)|!(IE)]><!--> </html> <!--<![endif]-->

Added: 
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/IEConditionalCommentsPage.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/IEConditionalCommentsPage.java?rev=1097472&view=auto
==============================================================================
--- 
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/IEConditionalCommentsPage.java
 (added)
+++ 
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/IEConditionalCommentsPage.java
 Thu Apr 28 14:20:40 2011
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.markup;
+
+import org.apache.wicket.markup.html.WebPage;
+
+/**
+ * A page with just markup to test that IE conditional comments are properly 
preserved by
+ * MarkupParser
+ */
+public class IEConditionalCommentsPage extends WebPage
+{
+       private static final long serialVersionUID = 1L;
+}

Modified: 
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/MarkupParserTest.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/MarkupParserTest.java?rev=1097472&r1=1097471&r2=1097472&view=diff
==============================================================================
--- 
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/MarkupParserTest.java
 (original)
+++ 
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/MarkupParserTest.java
 Thu Apr 28 14:20:40 2011
@@ -21,6 +21,7 @@ import org.apache.wicket.markup.html.bor
 import org.apache.wicket.markup.html.pages.PageExpiredErrorPage;
 import org.apache.wicket.markup.parser.XmlTag.TagType;
 import org.apache.wicket.markup.parser.filter.WicketTagIdentifier;
+import org.apache.wicket.settings.IMarkupSettings;
 import org.apache.wicket.util.resource.IResourceStream;
 import org.apache.wicket.util.resource.ResourceStreamNotFoundException;
 import org.apache.wicket.util.resource.locator.IResourceStreamLocator;
@@ -32,6 +33,7 @@ import org.slf4j.LoggerFactory;
 import java.io.IOException;
 import java.text.ParseException;
 import java.util.Locale;
+import java.util.regex.Matcher;
 
 import junit.framework.Assert;
 
@@ -437,21 +439,22 @@ public final class MarkupParserTest exte
         * @throws IOException
         * @throws ResourceStreamNotFoundException
         */
-       public final void wicket3648testCommentsWithNestedElements() throws 
IOException,
+       public final void testCommentsWithNestedElements() throws IOException,
                ResourceStreamNotFoundException
        {
                
tester.getApplication().getMarkupSettings().setStripComments(true);
                final MarkupParser parser = new MarkupParser(
 // @formatter:off
                        "<span><!--[if lt IE 8 ]>\n"
-                       + "<script src='js/ie7.js'></script>\n" + 
+                       + "<script src=\"js/ie7.js\"></script>\n" + 
                        "<![endif]--></span>"
                        // @formatter:on
                );
                IMarkupFragment markup = parser.parse();
 
-               RawMarkup raw = (RawMarkup)markup.get(0);
-               assertEquals("<span></span>", raw.toString());
+               String parsedMarkup = markup.toString(true);
+               assertEquals("<span><!--[if lt IE 8 ]>\n" + "<script 
src=\"js/ie7.js\"></script>\n"
+                       + "<![endif]--></span>", parsedMarkup);
        }
 
        /**
@@ -593,4 +596,64 @@ public final class MarkupParserTest exte
                Markup markup = parser.parse();
                assertEquals(conditionalComment, markup.get(0).toString());
        }
+
+       /**
+        * @see <a 
href="https://issues.apache.org/jira/browse/WICKET-3500";>WICKET-3500</a>
+        */
+       public void testOpenConditionalCommentPattern()
+       {
+               
assertFalse(MarkupParser.CONDITIONAL_COMMENT_OPENING.matcher("<!--x--> <!--[if 
IE]>")
+                       .find());
+
+               String markup = " <!--[if IE]> <![endif]--><!--[if 
IE]>--><!--<![endif]--><!--[if IE]><!--><!--<![endif]--><!--[if IE]><! 
--><!--<![endif]-->";
+               Matcher m = 
MarkupParser.CONDITIONAL_COMMENT_OPENING.matcher(markup);
+               assertTrue(m.find());
+               assertEquals(" <!--[if IE]>", m.group());
+               assertFalse(m.find());
+
+               markup = " <!--[if IE]>--> <![endif]--><!--[if 
IE]>--><!--<![endif]--><!--[if IE]><!--><!--<![endif]--><!--[if IE]><! 
--><!--<![endif]-->";
+               m = MarkupParser.CONDITIONAL_COMMENT_OPENING.matcher(markup);
+               assertTrue(m.find());
+               assertEquals(" <!--[if IE]>-->", m.group());
+               assertFalse(m.find());
+
+               markup = " <!--[if IE]><!--> <![endif]--><!--[if 
IE]>--><!--<![endif]--><!--[if IE]><!--><!--<![endif]--><!--[if IE]><! 
--><!--<![endif]-->";
+               m = MarkupParser.CONDITIONAL_COMMENT_OPENING.matcher(markup);
+               assertTrue(m.find());
+               assertEquals(" <!--[if IE]><!-->", m.group());
+               assertFalse(m.find());
+
+               markup = " <!--[if IE]><! --> <![endif]--><!--[if 
IE]>--><!--<![endif]--><!--[if IE]><!--><!--<![endif]--><!--[if IE]><! 
--><!--<![endif]-->";
+               m = MarkupParser.CONDITIONAL_COMMENT_OPENING.matcher(markup);
+               assertTrue(m.find());
+               assertEquals(" <!--[if IE]><! -->", m.group());
+               assertFalse(m.find());
+
+       }
+
+       /**
+        * Tests that IE conditional comments are properly preserved when
+        * {@link IMarkupSettings#setStripComments(boolean)} is set to true
+        * 
+        * @see <a 
href="https://issues.apache.org/jira/browse/WICKET-3648";>WICKET-3648</a>
+        * 
+        * @throws Exception
+        */
+       public void testIEConditionalComments() throws Exception
+       {
+
+               boolean stripComments = 
tester.getApplication().getMarkupSettings().getStripComments();
+               try
+               {
+                       
tester.getApplication().getMarkupSettings().setStripComments(false);
+                       executeTest(IEConditionalCommentsPage.class, 
"IEConditionalCommentsPage.html");
+
+                       
tester.getApplication().getMarkupSettings().setStripComments(true);
+                       executeTest(IEConditionalCommentsPage.class, 
"IEConditionalCommentsPage.html");
+               }
+               finally
+               {
+                       
tester.getApplication().getMarkupSettings().setStripComments(stripComments);
+               }
+       }
 }


Reply via email to