* 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;
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);
}
/**
* Attribute)*
*/
private void parsePageDirective(Node parent) throws JasperException {
- Attributes attrs = parseAttributes();
+ Attributes attrs = parseAttributes(true);
Node.PageDirective n = new Node.PageDirective(attrs, start, parent);
/*
*/
public class UniqueAttributesImpl extends AttributesImpl {
- private Set<String> qNames = new HashSet<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() {
public void setAttributes(Attributes atts) {
for (int i = 0; i < atts.getLength(); i++) {
if (!qNames.add(atts.getQName(i))) {
- handleDuplicate(atts.getQName(i));
+ handleDuplicate(atts.getQName(i), atts.getValue(i));
}
}
super.setAttributes(atts);
if (qNames.add(qName)) {
super.addAttribute(uri, localName, qName, type, value);
} else {
- handleDuplicate(qName);
+ handleDuplicate(qName, value);
}
}
if (qNames.add(qName)) {
super.setAttribute(index, uri, localName, qName, type, value);
} else {
- handleDuplicate(qName);
+ handleDuplicate(qName, value);
}
}
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));
}
}
assertEquals(500, sc);
}
+ public void testBug49297MultipleImport1() 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();
+
+ ByteChunk res = new ByteChunk();
+ int sc = getUrl("http://localhost:" + getPort() +
+ "/test/bug49nnn/bug49297MultipleImport1.jsp", res,
+ new HashMap<String,List<String>>());
+
+ assertEquals(200, sc);
+ assertEcho(res.toString(), "OK");
+ }
+
+ public void testBug49297MultipleImport2() 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();
+
+ ByteChunk res = new ByteChunk();
+ int sc = getUrl("http://localhost:" + getPort() +
+ "/test/bug49nnn/bug49297MultipleImport2.jsp", res,
+ new HashMap<String,List<String>>());
+
+ assertEquals(200, sc);
+ assertEcho(res.toString(), "OK");
+ }
+
+ public void testBug49297MultiplePageEncoding1() 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();
+
+ ByteChunk res = new ByteChunk();
+ int sc = getUrl("http://localhost:" + getPort() +
+ "/test/bug49nnn/bug49297MultiplePageEncoding1.jsp", res,
+ new HashMap<String,List<String>>());
+
+ assertEquals(500, sc);
+ }
+
+ public void testBug49297MultiplePageEncoding2() 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();
+
+ ByteChunk res = new ByteChunk();
+ int sc = getUrl("http://localhost:" + getPort() +
+ "/test/bug49nnn/bug49297MultiplePageEncoding2.jsp", res,
+ new HashMap<String,List<String>>());
+
+ assertEquals(500, sc);
+ }
+
+ public void testBug49297MultiplePageEncoding3() 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();
+
+ ByteChunk res = new ByteChunk();
+ int sc = getUrl("http://localhost:" + getPort() +
+ "/test/bug49nnn/bug49297MultiplePageEncoding3.jsp", res,
+ new HashMap<String,List<String>>());
+
+ assertEquals(500, sc);
+ }
+
+ public void testBug49297MultiplePageEncoding4() 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();
+
+ ByteChunk res = new ByteChunk();
+ int sc = getUrl("http://localhost:" + getPort() +
+ "/test/bug49nnn/bug49297MultiplePageEncoding4.jsp", res,
+ new HashMap<String,List<String>>());
+
+ assertEquals(500, sc);
+ }
+
/** Assertion for text printed by tags:echo */
private static void assertEcho(String result, String expected) {
assertTrue(result.indexOf("<p>" + expected + "</p>") > 0);
--- /dev/null
+<%--
+ 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.
+--%>
+<%@page import="java.util.List" import="java.util.ArrayList" %>
+<html>
+ <head><title>Bug 49297 multiple import test case</title></head>
+ <body>
+ <%
+ // Make sure the imports above do work
+ List<String> l = new ArrayList<String>();
+ l.add("OK");
+ %>
+ <p><%=l.get(0)%></p>
+ </body>
+</html>
\ No newline at end of file
--- /dev/null
+<%--
+ 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.
+--%>
+<%@page import="java.util.List" %>
+<%@page import="java.util.ArrayList" %>
+<html>
+ <head><title>Bug 49297 multiple import test case</title></head>
+ <body>
+ <%
+ // Make sure the imports above do work
+ List<String> l = new ArrayList<String>();
+ l.add("OK");
+ %>
+ <p><%=l.get(0)%></p>
+ </body>
+</html>
\ No newline at end of file
--- /dev/null
+<%--
+ 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.
+--%>
+<%@page pageEncoding="ISO-8859-1" %>
+<%@page pageEncoding="ISO-8859-1" %>
+<html>
+ <head><title>Bug 49297 multiple pageEncoding test case</title></head>
+ <body>
+ <p>Should fail</p>
+ </body>
+</html>
\ No newline at end of file
--- /dev/null
+<%--
+ 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.
+--%>
+<%@page pageEncoding="ISO-8859-1" pageEncoding="ISO-8859-1" %>
+<html>
+ <head><title>Bug 49297 multiple pageEncoding test case</title></head>
+ <body>
+ <p>Should fail</p>
+ </body>
+</html>
\ No newline at end of file
--- /dev/null
+<%--
+ 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.
+--%>
+<%@page pageEncoding="ISO-8859-1" %>
+<%@page pageEncoding="UTF-8" %>
+<html>
+ <head><title>Bug 49297 multiple pageEncoding test case</title></head>
+ <body>
+ <p>Should fail</p>
+ </body>
+</html>
\ No newline at end of file
--- /dev/null
+<%--
+ 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.
+--%>
+<%@page pageEncoding="ISO-8859-1" pageEncoding="UTF-8"%>
+<html>
+ <head><title>Bug 49297 multiple pageEncoding test case</title></head>
+ <body>
+ <p>Should fail</p>
+ </body>
+</html>
\ No newline at end of file
whitespace before the attribute name. The whitespace test can be
disabled by setting the system property
<code>org.apache.jasper.compiler.Parser.STRICT_WHITESPACE</code> to
- <code>false</code>. (markt)
+ <code>false</code>. Attributes of the page directive have slightly
+ different rules. The implementation of that part of the fix is based on
+ a patch by genspring. (markt)
</fix>
<fix>
<bug>50105</bug>: When processing composite EL expressions use