From a4cd010976c1d19e06a1f481200efb7fc9ef669b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 10 Nov 2010 11:48:20 +0800 Subject: [PATCH] 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. --- .../apache/jasper/util/UniqueAttributesImpl.java | 86 ++++++++++++++++---- test/org/apache/jasper/compiler/TestParser.java | 34 ++++++++ test/webapp-3.0/bug49297DuplicateAttr_import.jsp | 24 ++++++ .../webapp-3.0/bug49297DuplicateAttr_samevalue.jsp | 23 +++++ 4 files changed, 150 insertions(+), 17 deletions(-) create mode 100644 test/webapp-3.0/bug49297DuplicateAttr_import.jsp create mode 100644 test/webapp-3.0/bug49297DuplicateAttr_samevalue.jsp diff --git a/java/org/apache/jasper/util/UniqueAttributesImpl.java b/java/org/apache/jasper/util/UniqueAttributesImpl.java index ce38099..c0c3e28 100644 --- a/java/org/apache/jasper/util/UniqueAttributesImpl.java +++ b/java/org/apache/jasper/util/UniqueAttributesImpl.java @@ -16,8 +16,8 @@ */ package org.apache.jasper.util; -import java.util.HashSet; -import java.util.Set; +import java.util.HashMap; +import java.util.Map; import org.apache.jasper.compiler.Localizer; import org.xml.sax.Attributes; @@ -29,54 +29,106 @@ import org.xml.sax.helpers.AttributesImpl; */ public class UniqueAttributesImpl extends AttributesImpl { - private Set qNames = new HashSet(); + private Map attributes = new HashMap(); @Override public void clear() { - qNames.clear(); + attributes.clear(); super.clear(); } @Override public void setAttributes(Attributes atts) { + for (int i = 0; i < atts.getLength(); i++) { - if (!qNames.add(atts.getQName(i))) { - handleDuplicate(atts.getQName(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); } + } + super.setAttributes(atts); } @Override public void addAttribute(String uri, String localName, String qName, String type, String value) { - if (qNames.add(qName)) { - super.addAttribute(uri, localName, qName, type, 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 on how to handle multiple pageEncoding attributes. + + } else if (!attributes.get(qName).equals(value)) { + + handleDuplicate(qName); + } + } else { - handleDuplicate(qName); + attributes.put(qName, value); + super.addAttribute(uri, localName, qName, type, value); } + } @Override public void setAttribute(int index, String uri, String localName, String qName, String type, String value) { - qNames.remove(super.getQName(index)); - if (qNames.add(qName)) { - super.setAttribute(index, uri, localName, qName, type, value); - } else { - handleDuplicate(qName); - } + + attributes.remove(super.getQName(index)); + attributes.put(qName, value); + super.setAttribute(index, uri, localName, qName, type, value); + } @Override public void removeAttribute(int index) { - qNames.remove(super.getQName(index)); + attributes.remove(super.getQName(index)); super.removeAttribute(index); } @Override public void setQName(int index, String qName) { - qNames.remove(super.getQName(index)); + attributes.remove(super.getQName(index)); super.setQName(index, qName); } diff --git a/test/org/apache/jasper/compiler/TestParser.java b/test/org/apache/jasper/compiler/TestParser.java index 145c260..8616f7b 100644 --- a/test/org/apache/jasper/compiler/TestParser.java +++ b/test/org/apache/jasper/compiler/TestParser.java @@ -144,6 +144,40 @@ public class TestParser extends TomcatBaseTest { assertEquals(500, sc); } + public void testBug49297DuplicateAttr_samevalue() throws Exception { + Tomcat tomcat = getTomcatInstance(); + + File appDir = new File("test/webapp-3.0"); + // app dir is relative to server home + tomcat.addWebapp(null, "/test", appDir.getAbsolutePath()); + + tomcat.start(); + + int sc = getUrl("http://localhost:" + getPort() + + "/test/bug49297DuplicateAttr_samevalue.jsp", new ByteChunk(), + new HashMap>()); + + assertEquals(200, sc); + } + + public void testBug49297DuplicateAttr_import() throws Exception { + Tomcat tomcat = getTomcatInstance(); + + File appDir = new File("test/webapp-3.0"); + // app dir is relative to server home + tomcat.addWebapp(null, "/test", appDir.getAbsolutePath()); + + tomcat.start(); + + int sc = getUrl("http://localhost:" + getPort() + + "/test/bug49297DuplicateAttr_import.jsp", new ByteChunk(), + new HashMap>()); + + assertEquals(200, sc); + } + + + /** Assertion for text printed by tags:echo */ private static void assertEcho(String result, String expected) { assertTrue(result.indexOf("

" + expected + "

") > 0); diff --git a/test/webapp-3.0/bug49297DuplicateAttr_import.jsp b/test/webapp-3.0/bug49297DuplicateAttr_import.jsp new file mode 100644 index 0000000..9429815 --- /dev/null +++ b/test/webapp-3.0/bug49297DuplicateAttr_import.jsp @@ -0,0 +1,24 @@ +<%-- + 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. +--%> +<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %> +<%@page import="java.util.List" import="java.util.ArrayList" %> + + Bug 49297 duplicate attribute test case - for import directives + + + + \ No newline at end of file diff --git a/test/webapp-3.0/bug49297DuplicateAttr_samevalue.jsp b/test/webapp-3.0/bug49297DuplicateAttr_samevalue.jsp new file mode 100644 index 0000000..917c740 --- /dev/null +++ b/test/webapp-3.0/bug49297DuplicateAttr_samevalue.jsp @@ -0,0 +1,23 @@ +<%-- + 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. +--%> +<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %> + + Bug 49297 duplicate attribute test case + + + + \ No newline at end of file -- 1.7.3.1.msysgit.0