diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8835538 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/jakarta-taglibs-standard-1.1.2-src.tar.gz diff --git a/.jakarta-taglibs-standard.metadata b/.jakarta-taglibs-standard.metadata new file mode 100644 index 0000000..4a140e0 --- /dev/null +++ b/.jakarta-taglibs-standard.metadata @@ -0,0 +1 @@ +1d24c9e5019b57f298a40a77bac3f863ecf8a033 SOURCES/jakarta-taglibs-standard-1.1.2-src.tar.gz diff --git a/SOURCES/CVE-2015-0254.patch b/SOURCES/CVE-2015-0254.patch new file mode 100644 index 0000000..b722824 --- /dev/null +++ b/SOURCES/CVE-2015-0254.patch @@ -0,0 +1,699 @@ +diff --git a/standard/src/javax/servlet/jsp/jstl/tlv/PageParser.java b/standard/src/javax/servlet/jsp/jstl/tlv/PageParser.java +new file mode 100644 +index 0000000..29d5f17 +--- /dev/null ++++ b/standard/src/javax/servlet/jsp/jstl/tlv/PageParser.java +@@ -0,0 +1,45 @@ ++package javax.servlet.jsp.jstl.tlv; ++ ++import java.io.IOException; ++import java.io.InputStream; ++ ++import javax.servlet.jsp.tagext.PageData; ++import javax.xml.XMLConstants; ++import javax.xml.parsers.ParserConfigurationException; ++import javax.xml.parsers.SAXParser; ++import javax.xml.parsers.SAXParserFactory; ++ ++import org.xml.sax.SAXException; ++import org.xml.sax.SAXNotRecognizedException; ++import org.xml.sax.SAXNotSupportedException; ++import org.xml.sax.helpers.DefaultHandler; ++ ++class PageParser { ++ private final SAXParserFactory parserFactory; ++ ++ PageParser(boolean namespaceAware) throws SAXNotRecognizedException, SAXNotSupportedException, ParserConfigurationException { ++ parserFactory = SAXParserFactory.newInstance(); ++ ++ parserFactory.setNamespaceAware(namespaceAware); ++ parserFactory.setValidating(false); ++ try { ++ parserFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); ++ } catch (SAXNotSupportedException e) { ++ // FSP is not supported, GCJ? ++ } ++ } ++ ++ void parse(PageData pageData, DefaultHandler handler) throws ParserConfigurationException, SAXException, IOException { ++ SAXParser parser = parserFactory.newSAXParser(); ++ InputStream is = pageData.getInputStream(); ++ try { ++ parser.parse(is, handler); ++ } finally { ++ try { ++ is.close(); ++ } catch (IOException e) { ++ // Suppress. ++ } ++ } ++ } ++} +diff --git a/standard/src/javax/servlet/jsp/jstl/tlv/PermittedTaglibsTLV.java b/standard/src/javax/servlet/jsp/jstl/tlv/PermittedTaglibsTLV.java +index 4ba23d1..8e42449 100644 +--- a/standard/src/javax/servlet/jsp/jstl/tlv/PermittedTaglibsTLV.java ++++ b/standard/src/javax/servlet/jsp/jstl/tlv/PermittedTaglibsTLV.java +@@ -25,8 +25,6 @@ import javax.servlet.jsp.tagext.PageData; + import javax.servlet.jsp.tagext.TagLibraryValidator; + import javax.servlet.jsp.tagext.ValidationMessage; + import javax.xml.parsers.ParserConfigurationException; +-import javax.xml.parsers.SAXParser; +-import javax.xml.parsers.SAXParserFactory; + + import org.xml.sax.Attributes; + import org.xml.sax.SAXException; +@@ -104,10 +102,8 @@ public class PermittedTaglibsTLV extends TagLibraryValidator { + DefaultHandler h = new PermittedTaglibsHandler(); + + // parse the page +- SAXParserFactory f = SAXParserFactory.newInstance(); +- f.setValidating(true); +- SAXParser p = f.newSAXParser(); +- p.parse(page.getInputStream(), h); ++ PageParser p = new PageParser(false); ++ p.parse(page, h); + + if (failed) + return vmFromString( +diff --git a/standard/src/javax/servlet/jsp/jstl/tlv/ScriptFreeTLV.java b/standard/src/javax/servlet/jsp/jstl/tlv/ScriptFreeTLV.java +index d82b5c1..0bc4c11 100644 +--- a/standard/src/javax/servlet/jsp/jstl/tlv/ScriptFreeTLV.java ++++ b/standard/src/javax/servlet/jsp/jstl/tlv/ScriptFreeTLV.java +@@ -17,15 +17,12 @@ + package javax.servlet.jsp.jstl.tlv; + + import java.io.IOException; +-import java.io.InputStream; + import java.util.Map; + + import javax.servlet.jsp.tagext.PageData; + import javax.servlet.jsp.tagext.TagLibraryValidator; + import javax.servlet.jsp.tagext.ValidationMessage; + import javax.xml.parsers.ParserConfigurationException; +-import javax.xml.parsers.SAXParser; +-import javax.xml.parsers.SAXParserFactory; + + import org.xml.sax.Attributes; + import org.xml.sax.SAXException; +@@ -58,17 +55,12 @@ public class ScriptFreeTLV extends TagLibraryValidator { + private boolean allowScriptlets = false; + private boolean allowExpressions = false; + private boolean allowRTExpressions = false; +- private SAXParserFactory factory; ++ private PageParser parser; + + /** + * Constructs a new validator instance. +- * Initializes the parser factory to create non-validating, namespace-aware +- * SAX parsers. + */ + public ScriptFreeTLV () { +- factory = SAXParserFactory.newInstance(); +- factory.setValidating(false); +- factory.setNamespaceAware(true); + } + + /** +@@ -102,15 +94,12 @@ public class ScriptFreeTLV extends TagLibraryValidator { + */ + public ValidationMessage[] validate + (String prefix, String uri, PageData page) { +- InputStream in = null; +- SAXParser parser; + MyContentHandler handler = new MyContentHandler(); + try { +- synchronized (factory) { +- parser = factory.newSAXParser(); +- } +- in = page.getInputStream(); +- parser.parse(in, handler); ++ // Initializes the parser factory to create non-validating, namespace-aware ++ // SAX parsers. ++ parser = new PageParser(true); ++ parser.parse(page, handler); + } + catch (ParserConfigurationException e) { + return vmFromString(e.toString()); +@@ -121,9 +110,7 @@ public class ScriptFreeTLV extends TagLibraryValidator { + catch (IOException e) { + return vmFromString(e.toString()); + } +- finally { +- if (in != null) try { in.close(); } catch (IOException e) {} +- } ++ + return handler.reportResults(); + } + +diff --git a/standard/src/org/apache/taglibs/standard/extra/spath/SPathFilter.java b/standard/src/org/apache/taglibs/standard/extra/spath/SPathFilter.java +index bead698..c654ca9 100644 +--- a/standard/src/org/apache/taglibs/standard/extra/spath/SPathFilter.java ++++ b/standard/src/org/apache/taglibs/standard/extra/spath/SPathFilter.java +@@ -20,6 +20,9 @@ import java.io.IOException; + import java.util.List; + import java.util.Stack; + ++import javax.xml.parsers.ParserConfigurationException; ++ ++import org.apache.taglibs.standard.util.XmlUtil; + import org.apache.xalan.serialize.Serializer; + import org.apache.xalan.serialize.SerializerFactory; + import org.apache.xalan.templates.OutputProperties; +@@ -29,7 +32,6 @@ import org.xml.sax.SAXException; + import org.xml.sax.XMLFilter; + import org.xml.sax.XMLReader; + import org.xml.sax.helpers.XMLFilterImpl; +-import org.xml.sax.helpers.XMLReaderFactory; + + /** + *
Filters a SAX stream based on a single supplied SPath +@@ -70,7 +72,12 @@ System.setProperty("org.xml.sax.driver", "org.apache.xerces.parsers.SAXParser"); + + // construct the appropriate SAX chain + // (reader -> us -> serializer) +- XMLReader r = XMLReaderFactory.createXMLReader(); ++ XMLReader r; ++ try { ++ r = XmlUtil.newSAXParser().getXMLReader(); ++ } catch (ParserConfigurationException e) { ++ throw new SAXException(e); ++ } + XMLFilter f1 = new SPathFilter(p); + XMLFilter f2 = new XMLFilterImpl(); + f1.setParent(r); +diff --git a/standard/src/org/apache/taglibs/standard/tag/common/xml/ParseSupport.java b/standard/src/org/apache/taglibs/standard/tag/common/xml/ParseSupport.java +index 3bc8a54..7118919 100644 +--- a/standard/src/org/apache/taglibs/standard/tag/common/xml/ParseSupport.java ++++ b/standard/src/org/apache/taglibs/standard/tag/common/xml/ParseSupport.java +@@ -28,24 +28,21 @@ import javax.servlet.jsp.JspTagException; + import javax.servlet.jsp.PageContext; + import javax.servlet.jsp.tagext.BodyTagSupport; + import javax.xml.parsers.DocumentBuilder; +-import javax.xml.parsers.DocumentBuilderFactory; + import javax.xml.parsers.ParserConfigurationException; + import javax.xml.transform.TransformerConfigurationException; +-import javax.xml.transform.TransformerFactory; + import javax.xml.transform.dom.DOMResult; +-import javax.xml.transform.sax.SAXTransformerFactory; + import javax.xml.transform.sax.TransformerHandler; + + import org.apache.taglibs.standard.resources.Resources; + import org.apache.taglibs.standard.tag.common.core.ImportSupport; + import org.apache.taglibs.standard.tag.common.core.Util; ++import org.apache.taglibs.standard.util.XmlUtil; + import org.w3c.dom.Document; + import org.xml.sax.EntityResolver; + import org.xml.sax.InputSource; + import org.xml.sax.SAXException; + import org.xml.sax.XMLFilter; + import org.xml.sax.XMLReader; +-import org.xml.sax.helpers.XMLReaderFactory; + + /** + *
Support for tag handlers for <parse>, the XML parsing tag.
+@@ -70,9 +67,7 @@ public abstract class ParseSupport extends BodyTagSupport { + private int scopeDom; // processed 'scopeDom' attr + + // state in support of XML parsing... +- private DocumentBuilderFactory dbf; + private DocumentBuilder db; +- private TransformerFactory tf; + private TransformerHandler th; + + +@@ -89,9 +84,7 @@ public abstract class ParseSupport extends BodyTagSupport { + xml = null; + systemId = null; + filter = null; +- dbf = null; + db = null; +- tf = null; + th = null; + scope = PageContext.PAGE_SCOPE; + scopeDom = PageContext.PAGE_SCOPE; +@@ -106,22 +99,13 @@ public abstract class ParseSupport extends BodyTagSupport { + try { + + // set up our DocumentBuilder +- if (dbf == null) { +- dbf = DocumentBuilderFactory.newInstance(); +- dbf.setNamespaceAware(true); +- dbf.setValidating(false); ++ if (db == null) { ++ db = XmlUtil.newDocumentBuilder(); + } +- db = dbf.newDocumentBuilder(); + + // if we've gotten a filter, set up a transformer to support it + if (filter != null) { +- if (tf == null) +- tf = TransformerFactory.newInstance(); +- if (!tf.getFeature(SAXTransformerFactory.FEATURE)) +- throw new JspTagException( +- Resources.getMessage("PARSE_NO_SAXTRANSFORMER")); +- SAXTransformerFactory stf = (SAXTransformerFactory) tf; +- th = stf.newTransformerHandler(); ++ th = XmlUtil.newTransformerHandler(); + } + + // produce a Document by parsing whatever the attributes tell us to use +@@ -172,15 +156,14 @@ public abstract class ParseSupport extends BodyTagSupport { + + /** Parses the given InputSource after, applying the given XMLFilter. */ + private Document parseInputSourceWithFilter(InputSource s, XMLFilter f) +- throws SAXException, IOException { ++ throws SAXException, IOException, ParserConfigurationException { + if (f != null) { + // prepare an output Document + Document o = db.newDocument(); + + // use TrAX to adapt SAX events to a Document object + th.setResult(new DOMResult(o)); +- XMLReader xr = XMLReaderFactory.createXMLReader(); +- xr.setEntityResolver(new JstlEntityResolver(pageContext)); ++ XMLReader xr = XmlUtil.newXMLReader(new JstlEntityResolver(pageContext)); + // (note that we overwrite the filter's parent. this seems + // to be expected usage. we could cache and reset the old + // parent, but you can't setParent(null), so this wouldn't +@@ -195,20 +178,20 @@ public abstract class ParseSupport extends BodyTagSupport { + + /** Parses the given Reader after applying the given XMLFilter. */ + private Document parseReaderWithFilter(Reader r, XMLFilter f) +- throws SAXException, IOException { ++ throws SAXException, IOException, ParserConfigurationException { + return parseInputSourceWithFilter(new InputSource(r), f); + } + + /** Parses the given String after applying the given XMLFilter. */ + private Document parseStringWithFilter(String s, XMLFilter f) +- throws SAXException, IOException { ++ throws SAXException, IOException, ParserConfigurationException { + StringReader r = new StringReader(s); + return parseReaderWithFilter(r, f); + } + + /** Parses the given Reader after applying the given XMLFilter. */ + private Document parseURLWithFilter(String url, XMLFilter f) +- throws SAXException, IOException { ++ throws SAXException, IOException, ParserConfigurationException { + return parseInputSourceWithFilter(new InputSource(url), f); + } + +@@ -264,8 +247,10 @@ public abstract class ParseSupport extends BodyTagSupport { + systemId = systemId.substring(5); + + // we're only concerned with relative URLs +- if (ImportSupport.isAbsoluteUrl(systemId)) +- return null; ++ if (ImportSupport.isAbsoluteUrl(systemId)) { ++ XmlUtil.checkProtocol(XmlUtil.ALLOWED_PROTOCOLS, systemId); ++ return null; ++ } + + // for relative URLs, load and wrap the resource. + // don't bother checking for 'null' since we specifically want +diff --git a/standard/src/org/apache/taglibs/standard/tag/common/xml/TransformSupport.java b/standard/src/org/apache/taglibs/standard/tag/common/xml/TransformSupport.java +index 65d56f5..4751887 100644 +--- a/standard/src/org/apache/taglibs/standard/tag/common/xml/TransformSupport.java ++++ b/standard/src/org/apache/taglibs/standard/tag/common/xml/TransformSupport.java +@@ -29,14 +29,12 @@ import javax.servlet.jsp.JspTagException; + import javax.servlet.jsp.PageContext; + import javax.servlet.jsp.tagext.BodyTagSupport; + import javax.xml.parsers.DocumentBuilder; +-import javax.xml.parsers.DocumentBuilderFactory; + import javax.xml.parsers.ParserConfigurationException; + import javax.xml.transform.Result; + import javax.xml.transform.Source; + import javax.xml.transform.Transformer; + import javax.xml.transform.TransformerConfigurationException; + import javax.xml.transform.TransformerException; +-import javax.xml.transform.TransformerFactory; + import javax.xml.transform.URIResolver; + import javax.xml.transform.dom.DOMResult; + import javax.xml.transform.dom.DOMSource; +@@ -47,12 +45,12 @@ import javax.xml.transform.stream.StreamSource; + import org.apache.taglibs.standard.resources.Resources; + import org.apache.taglibs.standard.tag.common.core.ImportSupport; + import org.apache.taglibs.standard.tag.common.core.Util; ++import org.apache.taglibs.standard.util.XmlUtil; + import org.w3c.dom.Document; + import org.w3c.dom.Node; + import org.xml.sax.InputSource; + import org.xml.sax.SAXException; + import org.xml.sax.XMLReader; +-import org.xml.sax.helpers.XMLReaderFactory; + + /** + *Support for tag handlers for <transform>, the XML transformation
+@@ -77,9 +75,7 @@ public abstract class TransformSupport extends BodyTagSupport {
+ private String var; // 'var' attribute
+ private int scope; // processed 'scope' attr
+ private Transformer t; // actual Transformer
+- private TransformerFactory tf; // reusable factory
+ private DocumentBuilder db; // reusable factory
+- private DocumentBuilderFactory dbf; // reusable factory
+
+
+ //*********************************************************************
+@@ -95,7 +91,6 @@ public abstract class TransformSupport extends BodyTagSupport {
+ xmlSystemId = xsltSystemId = null;
+ var = null;
+ result = null;
+- tf = null;
+ scope = PageContext.PAGE_SCOPE;
+ }
+
+@@ -114,18 +109,8 @@ public abstract class TransformSupport extends BodyTagSupport {
+ //************************************
+ // Initialize
+
+- // set up our DocumentBuilderFactory if necessary
+- if (dbf == null) {
+- dbf = DocumentBuilderFactory.newInstance();
+- dbf.setNamespaceAware(true);
+- dbf.setValidating(false);
+- }
+ if (db == null)
+- db = dbf.newDocumentBuilder();
+-
+- // set up the TransformerFactory if necessary
+- if (tf == null)
+- tf = TransformerFactory.newInstance();
++ db = XmlUtil.newDocumentBuilder();
+
+ //************************************
+ // Produce transformer
+@@ -141,8 +126,8 @@ public abstract class TransformSupport extends BodyTagSupport {
+ throw new JspTagException(
+ Resources.getMessage("TRANSFORM_NO_TRANSFORMER"));
+ }
+- tf.setURIResolver(new JstlUriResolver(pageContext));
+- t = tf.newTransformer(s);
++ t = XmlUtil.newTransformer(s);
++ t.setURIResolver(new JstlUriResolver(pageContext));
+
+ return EVAL_BODY_BUFFERED;
+
+@@ -257,9 +242,7 @@ public abstract class TransformSupport extends BodyTagSupport {
+ } else if (o instanceof Reader) {
+ // explicitly go through SAX to maintain control
+ // over how relative external entities resolve
+- XMLReader xr = XMLReaderFactory.createXMLReader();
+- xr.setEntityResolver(
+- new ParseSupport.JstlEntityResolver(pageContext));
++ XMLReader xr = XmlUtil.newXMLReader(new ParseSupport.JstlEntityResolver(pageContext));
+ InputSource s = new InputSource((Reader) o);
+ s.setSystemId(wrapSystemId(systemId));
+ Source result = new SAXSource(xr, s);
+@@ -340,8 +323,10 @@ public abstract class TransformSupport extends BodyTagSupport {
+
+ // we're only concerned with relative URLs
+ if (ImportSupport.isAbsoluteUrl(href)
+- || (base != null && ImportSupport.isAbsoluteUrl(base)))
++ || (base != null && ImportSupport.isAbsoluteUrl(base))) {
++ XmlUtil.checkProtocol(XmlUtil.ALLOWED_PROTOCOLS, base);
+ return null;
++ }
+
+ // base is relative; remove everything after trailing '/'
+ if (base == null || base.lastIndexOf("/") == -1)
+diff --git a/standard/src/org/apache/taglibs/standard/tag/common/xml/XPathUtil.java b/standard/src/org/apache/taglibs/standard/tag/common/xml/XPathUtil.java
+index 9b66d73..20a8c0b 100644
+--- a/standard/src/org/apache/taglibs/standard/tag/common/xml/XPathUtil.java
++++ b/standard/src/org/apache/taglibs/standard/tag/common/xml/XPathUtil.java
+@@ -28,10 +28,10 @@ import javax.servlet.jsp.PageContext;
+ import javax.servlet.jsp.tagext.Tag;
+ import javax.servlet.jsp.tagext.TagSupport;
+ import javax.xml.parsers.DocumentBuilder;
+-import javax.xml.parsers.DocumentBuilderFactory;
+ import javax.xml.transform.TransformerException;
+
+ import org.apache.taglibs.standard.resources.Resources;
++import org.apache.taglibs.standard.util.XmlUtil;
+ import org.apache.xml.utils.QName;
+ import org.apache.xpath.VariableStack;
+ import org.apache.xpath.XPathContext;
+@@ -394,18 +394,14 @@ public class XPathUtil {
+ }
+ }
+
+- static DocumentBuilderFactory dbf = null;
+ static DocumentBuilder db = null;
+ static Document d = null;
+
+ static Document getDummyDocument( ) {
+ try {
+- if ( dbf == null ) {
+- dbf = DocumentBuilderFactory.newInstance();
+- dbf.setNamespaceAware( true );
+- dbf.setValidating( false );
++ if ( db == null ) {
++ db = XmlUtil.newDocumentBuilder();
+ }
+- db = dbf.newDocumentBuilder();
+
+ DOMImplementation dim = db.getDOMImplementation();
+ d = dim.createDocument("http://java.sun.com/jstl", "dummyroot", null);
+@@ -419,12 +415,9 @@ public class XPathUtil {
+
+ static Document getDummyDocumentWithoutRoot( ) {
+ try {
+- if ( dbf == null ) {
+- dbf = DocumentBuilderFactory.newInstance();
+- dbf.setNamespaceAware( true );
+- dbf.setValidating( false );
++ if ( db == null ) {
++ db = XmlUtil.newDocumentBuilder();
+ }
+- db = dbf.newDocumentBuilder();
+
+ d = db.newDocument();
+ return d;
+diff --git a/standard/src/org/apache/taglibs/standard/tlv/JstlBaseTLV.java b/standard/src/org/apache/taglibs/standard/tlv/JstlBaseTLV.java
+index e2d6092..6f81f89 100644
+--- a/standard/src/org/apache/taglibs/standard/tlv/JstlBaseTLV.java
++++ b/standard/src/org/apache/taglibs/standard/tlv/JstlBaseTLV.java
+@@ -17,6 +17,7 @@
+ package org.apache.taglibs.standard.tlv;
+
+ import java.io.IOException;
++import java.io.InputStream;
+ import java.util.HashMap;
+ import java.util.HashSet;
+ import java.util.Map;
+@@ -31,14 +32,15 @@ import javax.servlet.jsp.tagext.TagData;
+ import javax.servlet.jsp.tagext.TagLibraryValidator;
+ import javax.servlet.jsp.tagext.ValidationMessage;
+ import javax.xml.parsers.ParserConfigurationException;
+-import javax.xml.parsers.SAXParser;
+-import javax.xml.parsers.SAXParserFactory;
+
+ import org.apache.taglibs.standard.lang.support.ExpressionEvaluator;
+ import org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager;
+ import org.apache.taglibs.standard.resources.Resources;
++import org.apache.taglibs.standard.util.XmlUtil;
+ import org.xml.sax.Attributes;
++import org.xml.sax.InputSource;
+ import org.xml.sax.SAXException;
++import org.xml.sax.XMLReader;
+ import org.xml.sax.helpers.DefaultHandler;
+
+ /**
+@@ -149,11 +151,18 @@ public abstract class JstlBaseTLV extends TagLibraryValidator {
+ DefaultHandler h = getHandler();
+
+ // parse the page
+- SAXParserFactory f = SAXParserFactory.newInstance();
+- f.setValidating(false);
+- f.setNamespaceAware(true);
+- SAXParser p = f.newSAXParser();
+- p.parse(page.getInputStream(), h);
++ XMLReader xmlReader = XmlUtil.newXMLReader(null);
++ xmlReader.setContentHandler(h);
++ InputStream inputStream = page.getInputStream();
++ try {
++ xmlReader.parse(new InputSource(inputStream));
++ } finally {
++ try {
++ inputStream.close();
++ } catch (IOException e) {
++ // Suppressed.
++ }
++ }
+
+ if (messageVector.size() == 0)
+ return null;
+diff --git a/standard/src/org/apache/taglibs/standard/util/XmlUtil.java b/standard/src/org/apache/taglibs/standard/util/XmlUtil.java
+new file mode 100644
+index 0000000..13ec790
+--- /dev/null
++++ b/standard/src/org/apache/taglibs/standard/util/XmlUtil.java
+@@ -0,0 +1,168 @@
++package org.apache.taglibs.standard.util;
++
++import java.security.AccessControlException;
++import java.security.AccessController;
++import java.security.PrivilegedAction;
++
++import javax.xml.XMLConstants;
++import javax.xml.parsers.DocumentBuilder;
++import javax.xml.parsers.DocumentBuilderFactory;
++import javax.xml.parsers.ParserConfigurationException;
++import javax.xml.parsers.SAXParser;
++import javax.xml.parsers.SAXParserFactory;
++import javax.xml.transform.Source;
++import javax.xml.transform.Transformer;
++import javax.xml.transform.TransformerConfigurationException;
++import javax.xml.transform.TransformerFactory;
++import javax.xml.transform.sax.SAXTransformerFactory;
++import javax.xml.transform.sax.TransformerHandler;
++
++import org.apache.taglibs.standard.tag.common.xml.ParseSupport.JstlEntityResolver;
++import org.xml.sax.SAXException;
++import org.xml.sax.SAXNotSupportedException;
++import org.xml.sax.XMLReader;
++
++/**
++ * Utilities for working with JAXP and SAX.
++ */
++public class XmlUtil {
++
++ /**
++ * Create a new DocumentBuilder configured for namespaces but not validating.
++ *
++ * @return a new, configured DocumentBuilder
++ * @throws ParserConfigurationException
++ */
++ public static DocumentBuilder newDocumentBuilder() throws ParserConfigurationException {
++ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
++
++ dbf.setNamespaceAware(true);
++ dbf.setValidating(false);
++ try {
++ dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
++ } catch (ParserConfigurationException e) {
++ // FSP is not supported, GCJ?
++ }
++ return dbf.newDocumentBuilder();
++ }
++
++ private static SAXTransformerFactory newTransformerFactory() throws TransformerConfigurationException {
++ TransformerFactory tf = TransformerFactory.newInstance();
++ if (!(tf instanceof SAXTransformerFactory)) {
++ throw new TransformerConfigurationException("TransformerFactory does not support SAX");
++ }
++ try {
++ tf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
++ } catch (TransformerConfigurationException e) {
++ // FSP is not supported, GCJ?
++ }
++ return (SAXTransformerFactory) tf;
++ }
++
++ /**
++ * Create a new TransformerHandler.
++ * @return a new TransformerHandler
++ */
++ public static TransformerHandler newTransformerHandler() throws TransformerConfigurationException {
++ return newTransformerFactory().newTransformerHandler();
++ }
++
++ /**
++ * Create a new Transformer from an XSLT.
++ * @param source the source of the XSLT.
++ * @return a new Transformer
++ * @throws TransformerConfigurationException if there was a problem creating the Transformer from the XSLT
++ */
++ public static Transformer newTransformer(Source source) throws TransformerConfigurationException {
++ Transformer transformer = newTransformerFactory().newTransformer(source);
++ // Although newTansformer() is not allowed to return null, Xalan does.
++ // Trap that here by throwing the expected TransformerConfigurationException.
++ if (transformer == null) {
++ throw new TransformerConfigurationException("newTransformer returned null. XSLT may be invalid.");
++ }
++ return transformer;
++ }
++
++ /**
++ * Create an XMLReader that resolves entities using JSTL semantics.
++ * @param entityResolver for resolving using JSTL semantics
++ * @return a new XMLReader
++ * @throws ParserConfigurationException if there was a configuration problem creating the reader
++ * @throws SAXException if there was a problem creating the reader
++ */
++ public static XMLReader newXMLReader(JstlEntityResolver entityResolver)
++ throws ParserConfigurationException, SAXException {
++
++ XMLReader xmlReader = newSAXParser().getXMLReader();
++ xmlReader.setEntityResolver(entityResolver);
++ return xmlReader;
++ }
++
++ /**
++ * Create a new SAXParser.
++ * @return a new SAXParser
++ * @throws ParserConfigurationException if there was a configuration problem creating the reader
++ * @throws SAXException if there was a problem creating the reader
++ */
++ public static SAXParser newSAXParser() throws ParserConfigurationException, SAXException {
++ SAXParserFactory spf = SAXParserFactory.newInstance();
++
++ spf.setNamespaceAware(true);
++ try {
++ spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
++ } catch (SAXNotSupportedException e) {
++ // FSP is not supported, GCJ?
++ }
++ return spf.newSAXParser();
++ }
++
++ private static final String SP_ALLOWED_PROTOCOLS = "org.apache.taglibs.standard.xml.accessExternalEntity";
++ public static final String ALLOWED_PROTOCOLS = initAllowedProtocols();
++
++ private static String initAllowedProtocols() {
++ if (System.getSecurityManager() == null) {
++ return System.getProperty(SP_ALLOWED_PROTOCOLS, "all");
++ } else {
++ final String defaultProtocols = "";
++ try {
++ return (String) AccessController.doPrivileged(new PrivilegedAction() {
++ public Object run() {
++ return System.getProperty(SP_ALLOWED_PROTOCOLS, defaultProtocols);
++ }
++ });
++ } catch (AccessControlException e) {
++ // Fall back to the default i.e. none.
++ return defaultProtocols;
++ }
++ }
++ }
++
++ public static void checkProtocol(String allowedProtocols, String uri) {
++ if ("all".equalsIgnoreCase(allowedProtocols)) {
++ return;
++ }
++ String protocol = getScheme(uri);
++ String[] allowed = allowedProtocols.split(",");
++ for (int i = 0; i < allowed.length; i++) {
++ if (allowed[i].trim().equalsIgnoreCase(protocol)) {
++ return;
++ }
++ }
++ throw new AccessControlException("Access to external URI not allowed: " + uri);
++ }
++
++ private static String getScheme(CharSequence url) {
++ StringBuilder scheme = new StringBuilder();
++ for (int i = 0; i < url.length(); i++) {
++ char ch = url.charAt(i);
++ if (ch == ':') {
++ String result = scheme.toString();
++ if (!"jar".equals(result)) {
++ return result;
++ }
++ }
++ scheme.append(ch);
++ }
++ throw new IllegalArgumentException("No scheme found: " + url);
++ }
++}
diff --git a/SOURCES/fix-1.6.0-build.patch b/SOURCES/fix-1.6.0-build.patch
new file mode 100644
index 0000000..7befacc
--- /dev/null
+++ b/SOURCES/fix-1.6.0-build.patch
@@ -0,0 +1,14 @@
+--- standard/src/org/apache/taglibs/standard/tag/common/sql/DataSourceWrapper.java.sav 2004-07-20 00:06:07.000000000 +0300
++++ standard/src/org/apache/taglibs/standard/tag/common/sql/DataSourceWrapper.java 2011-07-19 14:19:40.689712335 +0300
+@@ -111,5 +111,11 @@ public class DataSourceWrapper implement
+ throw new SQLException(Resources.getMessage("NOT_SUPPORTED"));
+ }
+
++ public boolean isWrapperFor(Class iface) throws SQLException {
++ throw new SQLException(Resources.getMessage("NOT_SUPPORTED"));
++ }
++ public Object unwrap(Class iface) throws SQLException {
++ throw new SQLException(Resources.getMessage("NOT_SUPPORTED"));
++ }
+
+ }
diff --git a/SOURCES/jakarta-taglibs-standard-1.1.1-build.patch b/SOURCES/jakarta-taglibs-standard-1.1.1-build.patch
new file mode 100644
index 0000000..d0637b6
--- /dev/null
+++ b/SOURCES/jakarta-taglibs-standard-1.1.1-build.patch
@@ -0,0 +1,35 @@
+--- standard/build.xml.orig 2004-07-19 17:06:08.000000000 -0400
++++ standard/build.xml 2007-04-16 17:56:48.000000000 -0400
+@@ -164,18 +164,16 @@
+
+ A simple DataSource
wrapper for the standard
+@@ -118,4 +120,7 @@ public class DataSourceWrapper implement
+ throw new SQLException(Resources.getMessage("NOT_SUPPORTED"));
+ }
+
++ public Logger getParentLogger() throws SQLFeatureNotSupportedException {
++ throw new SQLFeatureNotSupportedException(Resources.getMessage("NOT_SUPPORTED"));
++ }
+ }
diff --git a/SOURCES/jstl-1.1.2.pom b/SOURCES/jstl-1.1.2.pom
new file mode 100644
index 0000000..bc4c983
--- /dev/null
+++ b/SOURCES/jstl-1.1.2.pom
@@ -0,0 +1,19 @@
+