You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by ge...@apache.org on 2010/11/13 02:42:13 UTC

svn commit: r1034622 - in /geronimo/external/trunk/tomcat-parent-7.0.0/jasper/src/main/java/org/apache/jasper: compiler/Parser.java util/UniqueAttributesImpl.java

Author: genspring
Date: Sat Nov 13 01:42:13 2010
New Revision: 1034622

URL: http://svn.apache.org/viewvc?rev=1034622&view=rev
Log:
pull the acceptted fix for https://issues.apache.org/bugzilla/show_bug.cgi?id=49297

Modified:
    geronimo/external/trunk/tomcat-parent-7.0.0/jasper/src/main/java/org/apache/jasper/compiler/Parser.java
    geronimo/external/trunk/tomcat-parent-7.0.0/jasper/src/main/java/org/apache/jasper/util/UniqueAttributesImpl.java

Modified: geronimo/external/trunk/tomcat-parent-7.0.0/jasper/src/main/java/org/apache/jasper/compiler/Parser.java
URL: http://svn.apache.org/viewvc/geronimo/external/trunk/tomcat-parent-7.0.0/jasper/src/main/java/org/apache/jasper/compiler/Parser.java?rev=1034622&r1=1034621&r2=1034622&view=diff
==============================================================================
--- geronimo/external/trunk/tomcat-parent-7.0.0/jasper/src/main/java/org/apache/jasper/compiler/Parser.java (original)
+++ geronimo/external/trunk/tomcat-parent-7.0.0/jasper/src/main/java/org/apache/jasper/compiler/Parser.java Sat Nov 13 01:42:13 2010
@@ -150,7 +150,10 @@ class Parser implements TagConstants {
      * Attributes ::= (S Attribute)* S?
      */
     Attributes parseAttributes() throws JasperException {
-        UniqueAttributesImpl attrs = new UniqueAttributesImpl();
+        return parseAttributes(false);
+    }
+    Attributes parseAttributes(boolean pageDirective) throws JasperException {
+        UniqueAttributesImpl attrs = new UniqueAttributesImpl(pageDirective);
 
         reader.skipSpaces();
         int ws = 1;
@@ -177,7 +180,7 @@ class Parser implements TagConstants {
     public static Attributes parseAttributes(ParserController pc,
             JspReader reader) throws JasperException {
         Parser tmpParser = new Parser(pc, reader, false, false, null);
-        return tmpParser.parseAttributes();
+        return tmpParser.parseAttributes(true);
     }
 
     /**
@@ -327,7 +330,7 @@ class Parser implements TagConstants {
      * Attribute)*
      */
     private void parsePageDirective(Node parent) throws JasperException {
-        Attributes attrs = parseAttributes();
+        Attributes attrs = parseAttributes(true);
         Node.PageDirective n = new Node.PageDirective(attrs, start, parent);
 
         /*

Modified: geronimo/external/trunk/tomcat-parent-7.0.0/jasper/src/main/java/org/apache/jasper/util/UniqueAttributesImpl.java
URL: http://svn.apache.org/viewvc/geronimo/external/trunk/tomcat-parent-7.0.0/jasper/src/main/java/org/apache/jasper/util/UniqueAttributesImpl.java?rev=1034622&r1=1034621&r2=1034622&view=diff
==============================================================================
--- geronimo/external/trunk/tomcat-parent-7.0.0/jasper/src/main/java/org/apache/jasper/util/UniqueAttributesImpl.java (original)
+++ geronimo/external/trunk/tomcat-parent-7.0.0/jasper/src/main/java/org/apache/jasper/util/UniqueAttributesImpl.java Sat Nov 13 01:42:13 2010
@@ -16,8 +16,8 @@
  */
 package org.apache.jasper.util;
 
-import java.util.HashMap;
-import java.util.Map;
+import java.util.HashSet;
+import java.util.Set;
 
 import org.apache.jasper.compiler.Localizer;
 import org.xml.sax.Attributes;
@@ -29,110 +29,92 @@ import org.xml.sax.helpers.AttributesImp
  */
 public class UniqueAttributesImpl extends AttributesImpl {
 
-    private Map<String,String> attributes = new HashMap<String,String>();
+    private static final String IMPORT = "import";
+    private static final String PAGE_ENCODING = "pageEncoding";
+    
+    private final boolean pageDirective;
+    private final Set<String> qNames = new HashSet<String>();
+
+    public UniqueAttributesImpl() {
+        this.pageDirective = false;
+    }
+
+    public UniqueAttributesImpl(boolean pageDirective) {
+        this.pageDirective = pageDirective;
+    }
 
     @Override
     public void clear() {
-        attributes.clear();
+        qNames.clear();
         super.clear();
     }
 
     @Override
     public void setAttributes(Attributes atts) {
-        
         for (int i = 0; i < atts.getLength(); i++) {
-            
-            String qName = atts.getQName(i);
-            String value = atts.getValue(i);
-
-            /*
-             * A translation error will occur if the page directive defines duplicate attribute/values within a given
-             * translation unit, unless the values for the duplicate attributes are identical for all occurrences. The
-             * import and pageEncoding attributes are exempt from this rule and can appear multiple times.
-             */
-            if (attributes.keySet().contains(qName)) {
-
-                if (qName.equals("import")) {
-
-                    StringBuffer sb = new StringBuffer(3);
-                    sb.append(attributes.get(qName));
-                    sb.append(",");
-                    sb.append(value);
-                    attributes.put(qName, sb.toString());
-
-                } /*else if (qName.equals("pageEncoding")) {
-
-                    // It's not clear in the spec how would we handle multiple pageEncoding attributes.
-                    
-                } */else if (!attributes.get(qName).equals(value)) {
-
-                    handleDuplicate(qName);
-                } 
-
-            } else {
-                attributes.put(qName, value);
+            if (!qNames.add(atts.getQName(i))) {
+                handleDuplicate(atts.getQName(i), atts.getValue(i));
             }
-            
         }
-        
         super.setAttributes(atts);
     }
 
     @Override
     public void addAttribute(String uri, String localName, String qName,
             String type, String value) {
-        
-        if (attributes.keySet().contains(qName)) {
-
-            if (qName.equals("import")) {
-
-                StringBuffer sb = new StringBuffer(3);
-                sb.append(attributes.get(qName));
-                sb.append(",");
-                sb.append(value);
-                attributes.put(qName, sb.toString());
-                super.addAttribute(uri, localName, qName, type, sb.toString());
-
-                } /*else if (qName.equals("pageEncoding")) {
-
-                    // It's not clear in the spec how would we handle multiple pageEncoding attributes.
-                    
-                } */else if (!attributes.get(qName).equals(value)) {
-
-                handleDuplicate(qName);
-            } 
-
-        } else {
-            attributes.put(qName, value);
+        if (qNames.add(qName)) {
             super.addAttribute(uri, localName, qName, type, value);
+        } else {
+            handleDuplicate(qName, value);
         }
-       
     }
 
     @Override
     public void setAttribute(int index, String uri, String localName,
             String qName, String type, String value) {
-        
-        attributes.remove(super.getQName(index));
-        attributes.put(qName, value);
-        super.setAttribute(index, uri, localName, qName, type, value);
-
+        qNames.remove(super.getQName(index));
+        if (qNames.add(qName)) {
+            super.setAttribute(index, uri, localName, qName, type, value);
+        } else {
+            handleDuplicate(qName, value);
+        }
     }
 
     @Override
     public void removeAttribute(int index) {
-        attributes.remove(super.getQName(index));
+        qNames.remove(super.getQName(index));
         super.removeAttribute(index);
     }
 
     @Override
     public void setQName(int index, String qName) {
-        attributes.remove(super.getQName(index));
+        qNames.remove(super.getQName(index));
         super.setQName(index, qName);
     }
 
-    private void handleDuplicate(String qName) {
+    private void handleDuplicate(String qName, String value) {
+        if (pageDirective) {
+            if (IMPORT.equalsIgnoreCase(qName)) {
+                // Always merge imports
+                int i = super.getIndex(IMPORT);
+                String v = super.getValue(i);
+                super.setValue(i, v + "," + value);
+                return;
+            } else if (PAGE_ENCODING.equalsIgnoreCase(qName)) {
+                // Page encoding can only occur once per file so a second
+                // attribute - even one with a duplicate value - is an error
+            } else {
+                // Other attributes can be repeated if and only if the values
+                // are identical
+                String v = super.getValue(qName);
+                if (v.equals(value)) {
+                    return;
+                }
+            }
+        }
+
+        // Ordinary tag attributes can't be repeated, even with identical values
         throw new IllegalArgumentException(
-                Localizer.getMessage("jsp.error.duplicateqname", qName));
+                    Localizer.getMessage("jsp.error.duplicateqname", qName));
     }
 }