Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP2:GA
xmlbeans
xmlbeans-CVE-2021-23926.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xmlbeans-CVE-2021-23926.patch of Package xmlbeans
Index: xmlbeans-2.6.0/src/common/org/apache/xmlbeans/impl/common/LoadSaveUtils.java =================================================================== --- xmlbeans-2.6.0.orig/src/common/org/apache/xmlbeans/impl/common/LoadSaveUtils.java +++ xmlbeans-2.6.0/src/common/org/apache/xmlbeans/impl/common/LoadSaveUtils.java @@ -22,7 +22,6 @@ package org.apache.xmlbeans.impl.common; import org.w3c.dom.Document; import org.xml.sax.SAXException; -import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.SAXParser; import javax.xml.parsers.ParserConfigurationException; import javax.xml.stream.XMLStreamWriter; @@ -40,10 +39,7 @@ public class LoadSaveUtils public static Document xmlText2GenericDom(InputStream is, Document emptyDoc) throws SAXException, ParserConfigurationException, IOException { - SAXParserFactory factory = SAXParserFactory.newInstance(); - factory.setNamespaceAware(true); - - SAXParser parser = factory.newSAXParser(); + SAXParser parser = SAXHelper.saxFactory.newSAXParser(); Sax2Dom handler = new Sax2Dom(emptyDoc); Index: xmlbeans-2.6.0/src/common/org/apache/xmlbeans/impl/common/Sax2Dom.java =================================================================== --- xmlbeans-2.6.0.orig/src/common/org/apache/xmlbeans/impl/common/Sax2Dom.java +++ xmlbeans-2.6.0/src/common/org/apache/xmlbeans/impl/common/Sax2Dom.java @@ -28,7 +28,6 @@ import org.xml.sax.helpers.DefaultHandle import org.xml.sax.ext.LexicalHandler; import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.DocumentBuilderFactory; import java.util.Stack; import java.util.Vector; @@ -49,9 +48,7 @@ public class Sax2Dom public Sax2Dom() throws ParserConfigurationException { - final DocumentBuilderFactory factory = - DocumentBuilderFactory.newInstance(); - _document = factory.newDocumentBuilder().newDocument(); + _document = DocumentHelper.newDocumentBuilder().newDocument(); _root = _document; } @@ -68,9 +65,7 @@ public class Sax2Dom } else { - final DocumentBuilderFactory factory = - DocumentBuilderFactory.newInstance(); - _document = factory.newDocumentBuilder().newDocument(); + _document = DocumentHelper.newDocumentBuilder().newDocument(); _root = _document; } } Index: xmlbeans-2.6.0/src/store/org/apache/xmlbeans/impl/store/Locale.java =================================================================== --- xmlbeans-2.6.0.orig/src/store/org/apache/xmlbeans/impl/store/Locale.java +++ xmlbeans-2.6.0/src/store/org/apache/xmlbeans/impl/store/Locale.java @@ -15,7 +15,6 @@ package org.apache.xmlbeans.impl.store; -import org.apache.xmlbeans.XmlErrorCodes; import org.xml.sax.Locator; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; @@ -25,7 +24,6 @@ import org.xml.sax.InputSource; import org.xml.sax.ext.LexicalHandler; import org.xml.sax.ext.DeclHandler; import org.xml.sax.SAXParseException; -import org.xml.sax.InputSource; import org.xml.sax.XMLReader; import org.xml.sax.SAXException; import org.xml.sax.DTDHandler; @@ -38,13 +36,12 @@ import java.lang.ref.Reference; import java.lang.ref.PhantomReference; import java.lang.ref.SoftReference; -import java.lang.reflect.Method; - import java.io.InputStream; import java.io.Reader; import java.io.StringReader; import java.io.IOException; +import javax.xml.namespace.QName; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamException; @@ -59,15 +56,7 @@ import org.apache.xmlbeans.xml.stream.XM import org.apache.xmlbeans.xml.stream.XMLInputStream; import org.apache.xmlbeans.xml.stream.XMLName; -import org.w3c.dom.DOMImplementation; -import org.w3c.dom.Document; -import org.w3c.dom.DocumentType; -import org.w3c.dom.Node; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Element; - -import javax.xml.namespace.QName; - +import org.apache.xmlbeans.impl.common.SAXHelper; import org.apache.xmlbeans.impl.common.XMLNameHelper; import org.apache.xmlbeans.impl.common.QNameHelper; import org.apache.xmlbeans.impl.common.XmlLocale; @@ -89,10 +78,11 @@ import org.apache.xmlbeans.XmlBeans; import org.apache.xmlbeans.XmlLineNumber; import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlCursor.XmlBookmark; -import org.apache.xmlbeans.XmlSaxHandler; +import org.apache.xmlbeans.XmlErrorCodes; import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XmlSaxHandler; import org.apache.xmlbeans.SchemaType; import org.apache.xmlbeans.SchemaTypeLoader; import org.apache.xmlbeans.XmlTokenSource; @@ -106,8 +96,12 @@ import org.apache.xmlbeans.impl.values.T import org.apache.xmlbeans.impl.values.TypeStoreUser; import org.apache.xmlbeans.impl.values.TypeStoreUserFactory; -import org.apache.xmlbeans.impl.piccolo.xml.Piccolo; -import org.apache.xmlbeans.impl.piccolo.io.FileFormatException; +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Document; +import org.w3c.dom.DocumentType; +import org.w3c.dom.Node; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Element; public final class Locale implements DOMImplementation, SaajCallback, XmlLocale @@ -3048,18 +3042,7 @@ public final class Locale } } - private static SaxLoader getPiccoloSaxLoader() - { - SaxLoader piccoloLoader = (SaxLoader) SystemCache.get().getSaxLoader(); - if (piccoloLoader == null) - { - piccoloLoader = PiccoloSaxLoader.newInstance(); - SystemCache.get().setSaxLoader(piccoloLoader); - } - return piccoloLoader; - } - - private static SaxLoader getSaxLoader(XmlOptions options) + private static SaxLoader getSaxLoader(XmlOptions options) throws XmlException { options = XmlOptions.maskNull(options); @@ -3076,31 +3059,22 @@ public final class Locale er = new DefaultEntityResolver(); } - SaxLoader sl; - - if (options.hasOption(XmlOptions.LOAD_USE_XMLREADER)) - { - XMLReader xr = (XMLReader) options.get( - XmlOptions.LOAD_USE_XMLREADER); + XMLReader xr = (XMLReader) options.get(XmlOptions.LOAD_USE_XMLREADER); - if (xr == null) - throw new IllegalArgumentException("XMLReader is null"); - - sl = new XmlReaderSaxLoader(xr); - - // I've noticed that most XMLReaders don't like a null EntityResolver... - - if (er != null) - xr.setEntityResolver(er); + if (xr == null) { + try { + xr = SAXHelper.newXMLReader(); + } catch(Exception e) { + throw new XmlException("Problem creating XMLReader", e); + } } - else - { - sl = getPiccoloSaxLoader(); - // Piccolo doesnot mind a null entity resolver ... + SaxLoader sl = new XmlReaderSaxLoader(xr); - sl.setEntityResolver(er); - } + // I've noticed that most XMLReaders don't line a null EntityResolver... + + if (er != null) + xr.setEntityResolver(er); return sl; } @@ -3114,34 +3088,6 @@ public final class Locale } } - private static class PiccoloSaxLoader - extends SaxLoader - { - private PiccoloSaxLoader(Piccolo p) - { - super(p, p.getStartLocator()); - - _piccolo = p; - } - - static PiccoloSaxLoader newInstance() - { - return new PiccoloSaxLoader(new Piccolo()); - } - - void postLoad(Cur c) - { - XmlDocumentProperties props = getDocProps(c, true); - - props.setEncoding(_piccolo.getEncoding()); - props.setVersion(_piccolo.getVersion()); - - super.postLoad(c); - } - - private Piccolo _piccolo; - } - private static abstract class SaxHandler implements ContentHandler, LexicalHandler , DeclHandler, DTDHandler { @@ -3196,7 +3142,7 @@ public final class Locale if (local.length() == 0) local = qName; - // Out current parser (Piccolo) does not error when a + // Out current parser does not error when a // namespace is used and not defined. Check for these here if (qName.indexOf(':') >= 0 && uri.length() == 0) @@ -3486,12 +3432,6 @@ public final class Locale return c; } - catch (FileFormatException e) - { - _context.abort(); - - throw new XmlException(e.getMessage(), e); - } catch (XmlRuntimeException e) { _context.abort(); Index: xmlbeans-2.6.0/src/store/org/apache/xmlbeans/impl/store/Cur.java =================================================================== --- xmlbeans-2.6.0.orig/src/store/org/apache/xmlbeans/impl/store/Cur.java +++ xmlbeans-2.6.0/src/store/org/apache/xmlbeans/impl/store/Cur.java @@ -3466,28 +3466,36 @@ final class Cur String s = CharUtil.getString( src, off, cch ); - for ( int i = 0 ; i < s.length() ; i++ ) + for ( int i = 0 ; i < s.length(); ) { - if (i== 36) + if (i == 36) { o.print( "..." ); break; } - char ch = s.charAt( i ); + int codePoint = s.codePointAt( i ); + char[] chars = Character.toChars(codePoint); - if (ch >= 32 && ch < 127) - o.print( ch ); - else if (ch == '\n') - o.print( "\\n" ); - else if (ch == '\r') - o.print( "\\r" ); - else if (ch == '\t') - o.print( "\\t" ); - else if (ch == '\"') - o.print( "\\\"" ); - else - o.print( "<#" + ((int) ch) + ">" ); + if ( chars.length == 1 ) { + char ch = chars[0]; + if (ch >= 32 && ch < 127) + o.print( ch ); + else if (ch == '\n') + o.print( "\\n" ); + else if (ch == '\r') + o.print( "\\r" ); + else if (ch == '\t') + o.print( "\\t" ); + else if (ch == '\"') + o.print( "\\\"" ); + else + o.print( "<#" + ((int) ch) + ">" ); + } else { + o.print( "<#" + codePoint + ">" ); + } + + i += Character.charCount(codePoint); } o.print( "\"" ); @@ -3608,4 +3616,4 @@ final class Cur int _offSrc; int _cchSrc; -} \ No newline at end of file +} Index: xmlbeans-2.6.0/src/xmlcomp/org/apache/xmlbeans/impl/tool/StreamInstanceValidator.java =================================================================== --- xmlbeans-2.6.0.orig/src/xmlcomp/org/apache/xmlbeans/impl/tool/StreamInstanceValidator.java +++ xmlbeans-2.6.0/src/xmlcomp/org/apache/xmlbeans/impl/tool/StreamInstanceValidator.java @@ -21,6 +21,7 @@ import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlOptions; import org.apache.xmlbeans.XmlError; +import org.apache.xmlbeans.impl.common.StaxHelper; import org.apache.xmlbeans.impl.validator.ValidatingXMLStreamReader; import javax.xml.stream.XMLInputFactory; @@ -39,7 +40,7 @@ import java.util.HashSet; public class StreamInstanceValidator { - private static final XMLInputFactory XML_INPUT_FACTORY = XMLInputFactory.newInstance(); + private static final XMLInputFactory XML_INPUT_FACTORY = StaxHelper.newXMLInputFactory(); public static void printUsage() { Index: xmlbeans-2.6.0/NOTICE.txt =================================================================== --- xmlbeans-2.6.0.orig/NOTICE.txt +++ xmlbeans-2.6.0/NOTICE.txt @@ -22,8 +22,5 @@ - resolver.jar from Apache Xml Commons project, Copyright (c) 2001-2003 Apache Software Foundation - - Piccolo XML Parser for Java from http://piccolo.sourceforge.net/, - Copyright 2002 Yuval Oren under the terms of the Apache Software License 2.0 - - JSR-173 Streaming API for XML from http://sourceforge.net/projects/xmlpullparser/, Copyright 2005 BEA under the terms of the Apache Software License 2.0 Index: xmlbeans-2.6.0/build.xml =================================================================== --- xmlbeans-2.6.0.orig/build.xml +++ xmlbeans-2.6.0/build.xml @@ -430,7 +430,7 @@ <exclude name="bin/*.cmd"/> </tarfileset> </tar> - <jar jarfile="build/private/xmlbeans-${version.base}${version.rc}-sources.jar" index="false"> + <jar jarfile="build/private/xmlbeans-${version.base}${version.rc}-source.jar" index="false"> <fileset dir="src/common" includes="**/*.java"/> <fileset dir="src/configschema" includes="**/*.java"/> <fileset dir="src/jamsupport" includes="**/*.java"/> @@ -488,8 +488,8 @@ store.classes, saaj_api.classes, marshal.classes, xpath.classes, oldxbean.jar, xsdschema.classes, xmlinputstream.classes, resolver.jar, xbean_xpath.jar, - piccolo.classes, tools.classes, jamsupport.classes"> - <jar jarfile="build/lib/xbean.jar" index="true"> + tools.classes, jamsupport.classes"> + <jar jarfile="build/lib/xbean.jar" index="true" duplicate="preserve"> <fileset dir="build/classes/xmlpublic" excludes="javax/**"/> <fileset dir="build/classes/typeholder"/> @@ -501,15 +501,12 @@ <fileset dir="build/classes/toolschema"/> <fileset dir="build/classes/xsdschema"/> <fileset dir="build/classes/xmlschema"/> - <fileset dir="build/classes/store"> - <exclude name="org/w3c/dom/**" /> - </fileset> + <fileset dir="build/classes/store"/> <fileset dir="build/classes/saaj_api"/> <fileset dir="build/classes/xmlinputstream"/> <fileset dir="build/classes/marshal"/> <fileset dir="build/classes/repackage"/> <fileset dir="build/classes/jam"/> - <fileset dir="build/classes/piccolo"/> <fileset dir="build/classes/tools"/> <fileset file="LICENSE.txt"/> <fileset file="NOTICE.txt"/> @@ -739,7 +736,7 @@ <!-- store target ============================================== --> <target name="store.classes" - depends="dirs, common.classes, xmlpublic.classes, typestore.classes, saaj_api.classes, piccolo.classes"> + depends="dirs, common.classes, xmlpublic.classes, typestore.classes, saaj_api.classes"> <mkdir dir="build/classes/store"/> <javac srcdir="src/store" destdir="build/classes/store" source="${javac.source}" target="${javac.target}" debug="on"> <classpath id="store.compile.path"> @@ -749,7 +746,6 @@ <pathelement location="build/classes/xmlpublic"/> <pathelement location="build/classes/common"/> <pathelement location="build/classes/saaj_api"/> - <pathelement location="build/classes/piccolo"/> </classpath> </javac> </target> @@ -757,7 +753,7 @@ <!-- tools target ============================================== --> <target name="tools.classes" - depends="dirs, common.classes, xmlpublic.classes, typestore.classes, saaj_api.classes, piccolo.classes, + depends="dirs, common.classes, xmlpublic.classes, typestore.classes, saaj_api.classes, typeimpl.classes, xmlcomp.classes"> <mkdir dir="build/classes/tools"/> <javac srcdir="src/tools" destdir="build/classes/tools" source="${javac.source}" target="${javac.target}" debug="on"> @@ -768,7 +764,6 @@ <pathelement location="build/classes/xmlpublic"/> <pathelement location="build/classes/common"/> <pathelement location="build/classes/saaj_api"/> - <pathelement location="build/classes/piccolo"/> <pathelement location="build/classes/typeimpl"/> <pathelement location="build/classes/xmlcomp"/> </classpath> @@ -920,7 +915,6 @@ <property name="repackage_arg" value=""/> <property name="schema_compiler" value="org.apache.xmlbeans.impl.tool.SchemaCompiler"/> <property name="bootstrap_schema_compiler" value="org.apache.xmlbeans.impl.tool.SchemaCompiler"/> - <property name="piccolo_package_name" value="org.apache.xmlbeans.impl.piccolo"/> <property name="jam_package_name" value="org.apache.xmlbeans.impl.jam"/> <!-- @@ -1147,37 +1141,4 @@ </javac> </target> - <!-- Piccolo deployment --> - <target name="piccolo.classes.check"> - <uptodate property="piccolo.classes.notRequired" - targetfile="build/ar/xbean.jar"> - <srcfiles dir="external/lib" includes="**/piccolo_*.jar"/> - </uptodate> - </target> - - <target name="piccolo.classes" depends="piccolo.classes.check, dirs, repackage.classes" unless="piccolo.classes.notRequired"> - <delete dir="build/private/piccolo"/> - <mkdir dir="build/private/piccolo"/> - <unjar src="external/lib/piccolo_apache_dist_20040711_v2.jar" dest="build/private/piccolo"/> - - <echo message="Re-packaging Piccolo"/> - - <java classname="repackage.Repackage" fork="true" failonerror="true"> - <classpath> - <pathelement location="build/classes/repackage"/> - </classpath> - <arg line="-repackage com.bluecast:${piccolo_package_name} -f build/private/piccolo/src -t build/private/piccolo/src_repackage"/> - </java> - - <delete dir="build/classes/piccolo"/> - <mkdir dir="build/classes/piccolo"/> - <javac - destdir="build/classes/piccolo" - classpath="" - source="1.6" target="1.6" - debug="on"> - <src path="build/private/piccolo/src_repackage"/> - </javac> - </target> - </project> Index: xmlbeans-2.6.0/src/common/org/apache/xmlbeans/impl/common/DocumentHelper.java =================================================================== --- /dev/null +++ xmlbeans-2.6.0/src/common/org/apache/xmlbeans/impl/common/DocumentHelper.java @@ -0,0 +1,165 @@ +/* Copyright 2004-2018 The Apache Software Foundation + * + * Licensed 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. + */ + +package org.apache.xmlbeans.impl.common; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Method; + +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.stream.events.Namespace; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.ErrorHandler; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +public final class DocumentHelper { + private static XBLogger logger = XBLogFactory.getLogger(DocumentHelper.class); + + private DocumentHelper() {} + + private static class DocHelperErrorHandler implements ErrorHandler { + + public void warning(SAXParseException exception) throws SAXException { + printError(XBLogger.WARN, exception); + } + + public void error(SAXParseException exception) throws SAXException { + printError(XBLogger.ERROR, exception); + } + + public void fatalError(SAXParseException exception) throws SAXException { + printError(XBLogger.FATAL, exception); + throw exception; + } + + /** Prints the error message. */ + private void printError(int type, SAXParseException ex) { + StringBuilder sb = new StringBuilder(); + + String systemId = ex.getSystemId(); + if (systemId != null) { + int index = systemId.lastIndexOf('/'); + if (index != -1) + systemId = systemId.substring(index + 1); + sb.append(systemId); + } + sb.append(':'); + sb.append(ex.getLineNumber()); + sb.append(':'); + sb.append(ex.getColumnNumber()); + sb.append(": "); + sb.append(ex.getMessage()); + + logger.log(type, sb.toString(), ex); + } + } + + /** + * Creates a new document builder, with sensible defaults + * + * @throws IllegalStateException If creating the DocumentBuilder fails, e.g. + * due to {@link ParserConfigurationException}. + */ + public static synchronized DocumentBuilder newDocumentBuilder() { + try { + DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + documentBuilder.setEntityResolver(SAXHelper.IGNORING_ENTITY_RESOLVER); + documentBuilder.setErrorHandler(new DocHelperErrorHandler()); + return documentBuilder; + } catch (ParserConfigurationException e) { + throw new IllegalStateException("cannot create a DocumentBuilder", e); + } + } + + private static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + static { + documentBuilderFactory.setNamespaceAware(true); + documentBuilderFactory.setValidating(false); + trySetSAXFeature(documentBuilderFactory, XMLConstants.FEATURE_SECURE_PROCESSING, true); + trySetXercesSecurityManager(documentBuilderFactory); + } + + private static void trySetSAXFeature(DocumentBuilderFactory dbf, String feature, boolean enabled) { + try { + dbf.setFeature(feature, enabled); + } catch (Exception e) { + logger.log(XBLogger.WARN, "SAX Feature unsupported", feature, e); + } catch (AbstractMethodError ame) { + logger.log(XBLogger.WARN, "Cannot set SAX feature because outdated XML parser in classpath", feature, ame); + } + } + + private static void trySetXercesSecurityManager(DocumentBuilderFactory dbf) { + // Try built-in JVM one first, standalone if not + for (String securityManagerClassName : new String[]{ + //"com.sun.org.apache.xerces.internal.util.SecurityManager", + "org.apache.xerces.util.SecurityManager" + }) { + try { + Object mgr = Class.forName(securityManagerClassName).newInstance(); + Method setLimit = mgr.getClass().getMethod("setEntityExpansionLimit", Integer.TYPE); + setLimit.invoke(mgr, 4096); + dbf.setAttribute("http://apache.org/xml/properties/security-manager", mgr); + // Stop once one can be setup without error + return; + } catch (ClassNotFoundException e) { + // continue without log, this is expected in some setups + } catch (Throwable e) { // NOSONAR - also catch things like NoClassDefError here + logger.log(XBLogger.WARN, "SAX Security Manager could not be setup", e); + } + } + + // separate old version of Xerces not found => use the builtin way of setting the property + dbf.setAttribute("http://www.oracle.com/xml/jaxp/properties/entityExpansionLimit", 4096); + } + + /** + * Parses the given stream via the default (sensible) + * DocumentBuilder + * @param inp Stream to read the XML data from + * @return the parsed Document + */ + public static Document readDocument(InputStream inp) throws IOException, SAXException { + return newDocumentBuilder().parse(inp); + } + + /** + * Parses the given stream via the default (sensible) + * DocumentBuilder + * @param inp sax source to read the XML data from + * @return the parsed Document + */ + public static Document readDocument(InputSource inp) throws IOException, SAXException { + return newDocumentBuilder().parse(inp); + } + + // must only be used to create empty documents, do not use it for parsing! + private static final DocumentBuilder documentBuilderSingleton = newDocumentBuilder(); + + /** + * Creates a new DOM Document + */ + public static synchronized Document createDocument() { + return documentBuilderSingleton.newDocument(); + } +} Index: xmlbeans-2.6.0/src/common/org/apache/xmlbeans/impl/common/StaxHelper.java =================================================================== --- /dev/null +++ xmlbeans-2.6.0/src/common/org/apache/xmlbeans/impl/common/StaxHelper.java @@ -0,0 +1,78 @@ +/* Copyright 2017, 2018 The Apache Software Foundation + * + * Licensed 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. + */ + +package org.apache.xmlbeans.impl.common; + +import javax.xml.stream.XMLEventFactory; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; + + +/** + * Provides handy methods for working with StAX parsers and readers + */ +public final class StaxHelper { + private static final XBLogger logger = XBLogFactory.getLogger(StaxHelper.class); + + private StaxHelper() {} + + /** + * Creates a new StAX XMLInputFactory, with sensible defaults + */ + public static XMLInputFactory newXMLInputFactory() { + XMLInputFactory factory = XMLInputFactory.newFactory(); + trySetProperty(factory, XMLInputFactory.IS_NAMESPACE_AWARE, true); + trySetProperty(factory, XMLInputFactory.IS_VALIDATING, false); + trySetProperty(factory, XMLInputFactory.SUPPORT_DTD, false); + trySetProperty(factory, XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); + return factory; + } + + /** + * Creates a new StAX XMLOutputFactory, with sensible defaults + */ + public static XMLOutputFactory newXMLOutputFactory() { + XMLOutputFactory factory = XMLOutputFactory.newFactory(); + trySetProperty(factory, XMLOutputFactory.IS_REPAIRING_NAMESPACES, true); + return factory; + } + + /** + * Creates a new StAX XMLEventFactory, with sensible defaults + */ + public static XMLEventFactory newXMLEventFactory() { + return XMLEventFactory.newFactory(); + } + + private static void trySetProperty(XMLInputFactory factory, String feature, boolean flag) { + try { + factory.setProperty(feature, flag); + } catch (Exception e) { + logger.log(XBLogger.WARN, "StAX Property unsupported", feature, e); + } catch (AbstractMethodError ame) { + logger.log(XBLogger.WARN, "Cannot set StAX property because outdated StAX parser in classpath", feature, ame); + } + } + + private static void trySetProperty(XMLOutputFactory factory, String feature, boolean flag) { + try { + factory.setProperty(feature, flag); + } catch (Exception e) { + logger.log(XBLogger.WARN, "StAX Property unsupported", feature, e); + } catch (AbstractMethodError ame) { + logger.log(XBLogger.WARN, "Cannot set StAX property because outdated StAX parser in classpath", feature, ame); + } + } +} Index: xmlbeans-2.6.0/src/common/org/apache/xmlbeans/impl/common/SAXHelper.java =================================================================== --- /dev/null +++ xmlbeans-2.6.0/src/common/org/apache/xmlbeans/impl/common/SAXHelper.java @@ -0,0 +1,99 @@ +/* Copyright 2017, 2018 The Apache Software Foundation + * + * Licensed 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. + */ + +package org.apache.xmlbeans.impl.common; + +import java.io.IOException; +import java.io.StringReader; +import java.lang.reflect.Method; +import java.util.concurrent.TimeUnit; + +import javax.xml.XMLConstants; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; + +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; + +/** + * Provides handy methods for working with SAX parsers and readers + */ +public final class SAXHelper { + private static final XBLogger logger = XBLogFactory.getLogger(SAXHelper.class); + private static long lastLog; + + private SAXHelper() {} + + /** + * Creates a new SAX XMLReader, with sensible defaults + */ + public static synchronized XMLReader newXMLReader() throws SAXException, ParserConfigurationException { + XMLReader xmlReader = saxFactory.newSAXParser().getXMLReader(); + xmlReader.setEntityResolver(IGNORING_ENTITY_RESOLVER); + trySetSAXFeature(xmlReader, XMLConstants.FEATURE_SECURE_PROCESSING); + trySetXercesSecurityManager(xmlReader); + return xmlReader; + } + + static final EntityResolver IGNORING_ENTITY_RESOLVER = new EntityResolver() { + @Override + public InputSource resolveEntity(String publicId, String systemId) + throws SAXException, IOException { + return new InputSource(new StringReader("")); + } + }; + + static final SAXParserFactory saxFactory; + static { + saxFactory = SAXParserFactory.newInstance(); + saxFactory.setValidating(false); + saxFactory.setNamespaceAware(true); + } + + private static void trySetSAXFeature(XMLReader xmlReader, String feature) { + try { + xmlReader.setFeature(feature, true); + } catch (Exception e) { + logger.log(XBLogger.WARN, "SAX Feature unsupported", feature, e); + } catch (AbstractMethodError ame) { + logger.log(XBLogger.WARN, "Cannot set SAX feature because outdated XML parser in classpath", feature, ame); + } + } + + private static void trySetXercesSecurityManager(XMLReader xmlReader) { + // Try built-in JVM one first, standalone if not + for (String securityManagerClassName : new String[] { + "com.sun.org.apache.xerces.internal.util.SecurityManager", + "org.apache.xerces.util.SecurityManager" + }) { + try { + Object mgr = Class.forName(securityManagerClassName).newInstance(); + Method setLimit = mgr.getClass().getMethod("setEntityExpansionLimit", Integer.TYPE); + setLimit.invoke(mgr, 4096); + xmlReader.setProperty("http://apache.org/xml/properties/security-manager", mgr); + // Stop once one can be setup without error + return; + } catch (Throwable e) { // NOSONAR - also catch things like NoClassDefError here + // throttle the log somewhat as it can spam the log otherwise + if(System.currentTimeMillis() > lastLog + TimeUnit.MINUTES.toMillis(5)) { + logger.log(XBLogger.WARN, "SAX Security Manager could not be setup [log suppressed for 5 minutes]", e); + lastLog = System.currentTimeMillis(); + } + } + } + } +} Index: xmlbeans-2.6.0/src/common/org/apache/xmlbeans/impl/common/XBLogFactory.java =================================================================== --- /dev/null +++ xmlbeans-2.6.0/src/common/org/apache/xmlbeans/impl/common/XBLogFactory.java @@ -0,0 +1,117 @@ +/* Copyright 2017, 2018 The Apache Software Foundation + * + * Licensed 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. + */ + +package org.apache.xmlbeans.impl.common; + +import java.util.HashMap; +import java.util.Map; + +/** + * Provides logging without clients having to mess with + * configuration/initialization. + * + * @author Andrew C. Oliver (acoliver at apache dot org) + * @author Marc Johnson (mjohnson at apache dot org) + * @author Nicola Ken Barozzi (nicolaken at apache.org) + */ +public final class XBLogFactory { + /** + * Map of XBLogger instances, with classes as keys + */ + private static final Map<String,XBLogger> _loggers = new HashMap<String,XBLogger>(); + + /** + * A common instance of NullLogger, as it does nothing + * we only need the one + */ + private static final XBLogger _nullLogger = new NullLogger(); + /** + * The name of the class to use. Initialised the + * first time we need it + */ + static String _loggerClassName = null; + + /** + * Construct a XBLogFactory. + */ + private XBLogFactory() {} + + /** + * Get a logger, based on a class name + * + * @param theclass the class whose name defines the log + * + * @return a XBLogger for the specified class + */ + public static XBLogger getLogger(final Class<?> theclass) { + return getLogger(theclass.getName()); + } + + /** + * Get a logger, based on a String + * + * @param cat the String that defines the log + * + * @return a XBLogger for the specified class + */ + public static XBLogger getLogger(final String cat) { + // If we haven't found out what logger to use yet, + // then do so now + // Don't look it up until we're first asked, so + // that our users can set the system property + // between class loading and first use + if(_loggerClassName == null) { + try { + _loggerClassName = System.getProperty("org.apache.xmlbeans.impl.store.XBLogger"); + } catch(Exception e) { + // ignore any exception here + } + + // Use the default logger if none specified, + // or none could be fetched + if(_loggerClassName == null) { + _loggerClassName = _nullLogger.getClass().getName(); + } + } + + // Short circuit for the null logger, which + // ignores all categories + if(_loggerClassName.equals(_nullLogger.getClass().getName())) { + return _nullLogger; + } + + + // Fetch the right logger for them, creating + // it if that's required + XBLogger logger = _loggers.get(cat); + if (logger == null) { + try { + @SuppressWarnings("unchecked") + Class<? extends XBLogger> loggerClass = + (Class<? extends XBLogger>) Class.forName(_loggerClassName); + logger = loggerClass.newInstance(); + logger.initialize(cat); + } catch(Exception e) { + // Give up and use the null logger + logger = _nullLogger; + _loggerClassName = _nullLogger.getClass().getName(); + } + + // Save for next time + _loggers.put(cat, logger); + } + return logger; + } +} Index: xmlbeans-2.6.0/src/common/org/apache/xmlbeans/impl/common/XBLogger.java =================================================================== --- /dev/null +++ xmlbeans-2.6.0/src/common/org/apache/xmlbeans/impl/common/XBLogger.java @@ -0,0 +1,112 @@ +/* Copyright 2017, 2018 The Apache Software Foundation + * + * Licensed 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. + */ + +package org.apache.xmlbeans.impl.common; + +/** + * A logger interface that strives to make it as easy as possible for + * developers to write log calls, while simultaneously making those + * calls as cheap as possible by performing lazy evaluation of the log + * message.<p> + */ +public abstract class XBLogger { + + public static final int DEBUG = 1; + public static final int INFO = 3; + public static final int WARN = 5; + public static final int ERROR = 7; + public static final int FATAL = 9; + + /** Short strings for numeric log level. Use level as array index. */ + protected static final String LEVEL_STRINGS_SHORT[] = {"?", "D", "?", "I", "?", "W", "?", "E", "?", "F", "?"}; + /** Long strings for numeric log level. Use level as array index. */ + protected static final String LEVEL_STRINGS[] = {"?0?", "DEBUG", "?2?", "INFO", "?4?", "WARN", "?6?", "ERROR", "?8?", "FATAL", "?10+?"}; + + + /** + * package scope so it cannot be instantiated outside of the util + * package. You need a XBLogger? Go to the XBLogFactory for one + */ + XBLogger() { + // no fields to initialize + } + + abstract public void initialize(String cat); + + /** + * Log a message + * + * @param level One of DEBUG, INFO, WARN, ERROR, FATAL + * @param obj1 The object to log. This is converted to a string. + */ + abstract protected void _log(int level, Object obj1); + + /** + * Log a message + * + * @param level One of DEBUG, INFO, WARN, ERROR, FATAL + * @param obj1 The object to log. This is converted to a string. + * @param exception An exception to be logged + */ + abstract protected void _log(int level, Object obj1, final Throwable exception); + + + /** + * Check if a logger is enabled to log at the specified level + * This allows code to avoid building strings or evaluating functions in + * the arguments to log. + * + * An example: + * <code><pre> + * if (logger.check(XBLogger.INFO)) { + * logger.log(XBLogger.INFO, "Avoid concatenating " + " strings and evaluating " + functions()); + * } + * </pre></code> + * + * @param level One of DEBUG, INFO, WARN, ERROR, FATAL + */ + abstract public boolean check(int level); + + /** + * Log a message. Lazily appends Object parameters together. + * If the last parameter is a {@link Throwable} it is logged specially. + * + * @param level One of DEBUG, INFO, WARN, ERROR, FATAL + * @param objs the objects to place in the message + */ + public void log(int level, Object... objs) { + if (!check(level)) return; + StringBuilder sb = new StringBuilder(32); + Throwable lastEx = null; + for (int i=0; i<objs.length; i++) { + if (i == objs.length-1 && objs[i] instanceof Throwable) { + lastEx = (Throwable)objs[i]; + } else { + sb.append(objs[i]); + } + } + + String msg = sb.toString(); + msg = msg.replaceAll("[\r\n]+", " "); // log forging escape + + // somehow this ambiguity works and doesn't lead to a loop, + // but it's confusing ... + if (lastEx == null) { + _log(level, msg); + } else { + _log(level, msg, lastEx); + } + } +} Index: xmlbeans-2.6.0/src/common/org/apache/xmlbeans/impl/common/NullLogger.java =================================================================== --- /dev/null +++ xmlbeans-2.6.0/src/common/org/apache/xmlbeans/impl/common/NullLogger.java @@ -0,0 +1,75 @@ +/* Copyright 2017, 2018 The Apache Software Foundation + * + * Licensed 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. + */ + +package org.apache.xmlbeans.impl.common; + +/** + * A logger class that strives to make it as easy as possible for + * developers to write log calls, while simultaneously making those + * calls as cheap as possible by performing lazy evaluation of the log + * message.<p> + */ +public class NullLogger extends XBLogger { + @Override + public void initialize(final String cat) { + // do nothing + } + + /** + * Log a message + * + * @param level One of DEBUG, INFO, WARN, ERROR, FATAL + * @param obj1 The object to log. + */ + + @Override + protected void _log(final int level, final Object obj1) { + // do nothing + } + + /** + * Log a message + * + * @param level One of DEBUG, INFO, WARN, ERROR, FATAL + * @param obj1 The object to log. This is converted to a string. + * @param exception An exception to be logged + */ + @Override + protected void _log(int level, Object obj1, final Throwable exception) { + // do nothing + } + + /** + * Log a message. Lazily appends Object parameters together. + * If the last parameter is a {@link Throwable} it is logged specially. + * + * @param level One of DEBUG, INFO, WARN, ERROR, FATAL + * @param objs the objects to place in the message + */ + @Override + public void log(int level, Object... objs) { + // do nothing + } + + /** + * Check if a logger is enabled to log at the specified level + * + * @param level One of DEBUG, INFO, WARN, ERROR, FATAL + */ + @Override + public boolean check(final int level) { + return false; + } +}
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor