3636import org .xml .sax .InputSource ;
3737import org .xml .sax .SAXException ;
3838import org .xml .sax .SAXParseException ;
39- import org .xml .sax .XMLReader ;
4039
40+ import javax .xml .XMLConstants ;
4141import javax .xml .namespace .QName ;
4242import javax .xml .parsers .DocumentBuilder ;
4343import javax .xml .parsers .DocumentBuilderFactory ;
4444import javax .xml .parsers .ParserConfigurationException ;
4545import javax .xml .parsers .SAXParser ;
46- import javax .xml .parsers .SAXParserFactory ;
4746import javax .xml .stream .XMLStreamException ;
47+ import javax .xml .transform .TransformerConfigurationException ;
48+ import javax .xml .transform .TransformerFactory ;
4849import java .io .ByteArrayInputStream ;
4950import java .io .ByteArrayOutputStream ;
5051import java .io .IOException ;
5657import java .net .ProtocolException ;
5758import java .net .URL ;
5859import java .net .URLConnection ;
59- import java .util .Stack ;
6060
6161
6262public class XMLUtils {
6363 public static final String charEncoding = "ISO-8859-1" ;
64- private static final String saxParserFactoryProperty =
65- "javax.xml.parsers.SAXParserFactory" ;
6664
6765 private static DocumentBuilderFactory dbf = getDOMFactory ();
68- private static SAXParserFactory saxFactory ;
69- private static Stack saxParsers = new Stack ();
7066
7167 private static String empty = "" ;
7268 private static ByteArrayInputStream bais = new ByteArrayInputStream (empty .getBytes ());
7369
74- static {
75- // Initialize SAX Parser factory defaults
76- initSAXFactory (null , true , false );
77- }
78-
7970 /**
80- * Initializes the SAX parser factory.
71+ * Formerly configured a pooled SAX parser factory that nothing in Axis2 ever
72+ * handed out.
8173 *
82- * @param factoryClassName The (optional) class name of the desired
83- * SAXParserFactory implementation. Will be
84- * assigned to the system property
85- * <b>javax.xml.parsers.SAXParserFactory</b>
86- * unless this property is already set.
87- * If <code>null</code>, leaves current setting
88- * alone.
89- * @param namespaceAware true if we want a namespace-aware parser
90- * @param validating true if we want a validating parser
74+ * @deprecated has no effect; use a hardened parser at the point of use instead
9175 */
76+ @ Deprecated
9277 public static void initSAXFactory (String factoryClassName ,
9378 boolean namespaceAware ,
9479 boolean validating ) {
95- if (factoryClassName != null ) {
96- try {
97- saxFactory = (SAXParserFactory ) Loader .loadClass (factoryClassName ).
98- newInstance ();
99- /*
100- * Set the system property only if it is not already set to
101- * avoid corrupting environments in which Axis is embedded.
102- */
103- if (System .getProperty (saxParserFactoryProperty ) == null ) {
104- System .setProperty (saxParserFactoryProperty ,
105- factoryClassName );
106- }
107- } catch (Exception e ) {
108- saxFactory = SAXParserFactory .newInstance ();
109- }
110- } else {
111- saxFactory = SAXParserFactory .newInstance ();
112- }
113- saxFactory .setNamespaceAware (namespaceAware );
114- saxFactory .setValidating (validating );
115-
116- // Discard existing parsers
117- saxParsers .clear ();
11880 }
11981
12082 /**
@@ -142,6 +104,39 @@ public static DocumentBuilderFactory newSecureDocumentBuilderFactory()
142104 return dbf ;
143105 }
144106
107+ /**
108+ * A TransformerFactory that refuses external DTDs, external entities and
109+ * external stylesheets.
110+ * <p>
111+ * Use this for any transform whose Source may come from outside Axis2. An
112+ * identity transform parses a StreamSource, or a SAXSource without its own
113+ * XMLReader, with the transformer's internal parser, which ignores every
114+ * parser hardening applied elsewhere. Implementations that do not recognise
115+ * a restriction keep the rest rather than fail, since the JAXP 1.5 access
116+ * attributes are optional for third-party processors.
117+ *
118+ * @return a TransformerFactory with secure processing and no external access
119+ */
120+ public static TransformerFactory newSecureTransformerFactory () {
121+ TransformerFactory tf = TransformerFactory .newInstance ();
122+ try {
123+ tf .setFeature (XMLConstants .FEATURE_SECURE_PROCESSING , true );
124+ } catch (TransformerConfigurationException e ) {
125+ // Not supported by this processor; the access attributes still apply.
126+ }
127+ setAttributeIfSupported (tf , XMLConstants .ACCESS_EXTERNAL_DTD , "" );
128+ setAttributeIfSupported (tf , XMLConstants .ACCESS_EXTERNAL_STYLESHEET , "" );
129+ return tf ;
130+ }
131+
132+ private static void setAttributeIfSupported (TransformerFactory tf , String name , String value ) {
133+ try {
134+ tf .setAttribute (name , value );
135+ } catch (IllegalArgumentException e ) {
136+ // Not recognised by this processor.
137+ }
138+ }
139+
145140 private static DocumentBuilderFactory getDOMFactory () {
146141 DocumentBuilderFactory dbf ;
147142 try {
@@ -164,31 +159,14 @@ private static DocumentBuilderFactory getDOMFactory() {
164159 return (dbf );
165160 }
166161
167- private static boolean tryReset = true ;
168-
169162 /**
170- * Returns a SAX parser for reuse.
163+ * Formerly returned a parser to a pool that was never drawn from, so every
164+ * released parser was retained for the life of the class.
171165 *
172- * @param parser A SAX parser that is available for reuse
166+ * @deprecated has no effect
173167 */
168+ @ Deprecated
174169 public static void releaseSAXParser (SAXParser parser ) {
175- if (!tryReset ) {
176- return ;
177- }
178-
179- //Free up possible ref. held by past contenthandler.
180- try {
181- XMLReader xmlReader = parser .getXMLReader ();
182- if (null != xmlReader ) {
183- synchronized (XMLUtils .class ) {
184- saxParsers .push (parser );
185- }
186- } else {
187- tryReset = false ;
188- }
189- } catch (org .xml .sax .SAXException e ) {
190- tryReset = false ;
191- }
192170 }
193171
194172 /**
0 commit comments