--- old/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java 2019-07-18 17:32:27.650372619 +0000 +++ new/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java 2019-07-18 17:32:27.411365800 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -42,6 +42,7 @@ import java.util.StringTokenizer; import javax.xml.XMLConstants; import javax.xml.catalog.CatalogFeatures; +import jdk.xml.internal.ErrorHandlerProxy; import jdk.xml.internal.JdkXmlFeatures; import jdk.xml.internal.JdkXmlUtils; import jdk.xml.internal.SecuritySupport; @@ -61,7 +62,7 @@ * @author G. Todd Miller * @author Morten Jorgensen * @author Erwin Bolwidt - * @LastModified: Nov 2017 + * @LastModified: July 2019 */ public class Parser implements Constants, ContentHandler { @@ -98,9 +99,13 @@ private boolean _overrideDefaultParser; - public Parser(XSLTC xsltc, boolean useOverrideDefaultParser) { + // flag indicates whether there's an user's ErrorListener + private boolean _hasUserErrListener; + + public Parser(XSLTC xsltc, boolean useOverrideDefaultParser, boolean hasUserErrListener) { _xsltc = xsltc; _overrideDefaultParser = useOverrideDefaultParser; + _hasUserErrListener = hasUserErrListener; } public void init() { @@ -426,6 +431,11 @@ try { // Parse the input document and build the abstract syntax tree reader.setContentHandler(this); + if (_hasUserErrListener) { + // Set a ErrorHandler proxy to pass any parsing error on to be handled + // by the user's ErrorListener + reader.setErrorHandler(new ErrorHandlerProxy()); + } reader.parse(input); // Find the start of the stylesheet within the tree return getStylesheet(_root); --- old/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java 2019-07-18 17:32:28.513397244 +0000 +++ new/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java 2019-07-18 17:32:28.276390481 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -58,7 +58,7 @@ * @author G. Todd Miller * @author Morten Jorgensen * @author John Howard (johnh@schemasoft.com) - * @LastModified: Oct 2017 + * @LastModified: July 2019 */ public final class XSLTC { @@ -175,10 +175,10 @@ /** * XSLTC compiler constructor */ - public XSLTC(JdkXmlFeatures featureManager) { + public XSLTC(JdkXmlFeatures featureManager, boolean hasListener) { _overrideDefaultParser = featureManager.getFeature( JdkXmlFeatures.XmlFeature.JDK_OVERRIDE_PARSER); - _parser = new Parser(this, _overrideDefaultParser); + _parser = new Parser(this, _overrideDefaultParser, hasListener); _xmlFeatures = featureManager; _extensionClassLoader = null; _externalExtensionFunctions = new HashMap<>(); --- old/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java 2019-07-18 17:32:29.372421754 +0000 +++ new/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java 2019-07-18 17:32:29.136415020 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -47,6 +47,7 @@ * Implementation of a JAXP1.1 TemplatesHandler * @author Morten Jorgensen * @author Santiago Pericas-Geertsen + * @LastModified: July 2019 */ public class TemplatesHandlerImpl implements ContentHandler, TemplatesHandler, SourceLoader @@ -91,14 +92,14 @@ /** * Default constructor */ - protected TemplatesHandlerImpl(int indentNumber, - TransformerFactoryImpl tfactory) + protected TemplatesHandlerImpl(int indentNumber, TransformerFactoryImpl tfactory, + boolean hasUserErrListener) { _indentNumber = indentNumber; _tfactory = tfactory; // Instantiate XSLTC and get reference to parser object - XSLTC xsltc = new XSLTC(tfactory.getJdkXmlFeatures()); + XSLTC xsltc = new XSLTC(tfactory.getJdkXmlFeatures(), hasUserErrListener); if (tfactory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING)) xsltc.setSecureProcessing(true); --- old/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java 2019-07-18 17:32:30.238446463 +0000 +++ new/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java 2019-07-18 17:32:29.997439587 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -84,7 +84,7 @@ * @author G. Todd Miller * @author Morten Jorgensen * @author Santiago Pericas-Geertsen - * @LastModified: July 2018 + * @LastModified: July 2019 */ public class TransformerFactoryImpl extends SAXTransformerFactory implements SourceLoader, ErrorListener @@ -107,6 +107,9 @@ */ private ErrorListener _errorListener = this; + // flag indicating whether there's an user's ErrorListener + private boolean _hasUserErrListener; + /** * This URIResolver is passed to all created Templates and Transformers */ @@ -297,6 +300,7 @@ "TransformerFactory"); throw new IllegalArgumentException(err.toString()); } + _hasUserErrListener = true; _errorListener = listener; } @@ -946,7 +950,7 @@ } // Create and initialize a stylesheet compiler - final XSLTC xsltc = new XSLTC(_xmlFeatures); + final XSLTC xsltc = new XSLTC(_xmlFeatures, _hasUserErrListener); if (_debug) xsltc.setDebug(true); if (_enableInlining) xsltc.setTemplateInlining(true); @@ -1104,7 +1108,7 @@ // through the factory instance buildCatalogFeatures(); final TemplatesHandlerImpl handler = - new TemplatesHandlerImpl(_indentNumber, this); + new TemplatesHandlerImpl(_indentNumber, this, _hasUserErrListener); if (_uriResolver != null) { handler.setURIResolver(_uriResolver); } --- /dev/null 2019-05-31 22:23:04.554000000 +0000 +++ new/src/java.xml/share/classes/jdk/xml/internal/ErrorHandlerProxy.java 2019-07-18 17:32:30.872464553 +0000 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.xml.internal; + +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +/** + * Implements an ErrorHandler that simply passes on the Exception. + */ +public class ErrorHandlerProxy implements ErrorHandler { + + @Override + public void warning(SAXParseException exception) throws SAXException { + throw exception; + } + + @Override + public void error(SAXParseException exception) throws SAXException { + throw exception; + } + + @Override + public void fatalError(SAXParseException exception) throws SAXException { + throw exception; + } +} --- /dev/null 2019-05-31 22:23:04.554000000 +0000 +++ new/test/jaxp/javax/xml/jaxp/unittest/transform/ErrorListenerTest.java 2019-07-18 17:32:31.775490319 +0000 @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package transform; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.PrintStream; + +import javax.xml.transform.ErrorListener; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXSource; +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import org.xml.sax.InputSource; + +/* + * @test + * @bug 8157830 + * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest + * @run testng/othervm transform.ErrorListenerTest + * @summary Verifies that ErrorListeners are handled properly + */ +public class ErrorListenerTest { + + static final private String INVALID_STYLESHEET = "xxx"; + static final private String SYSTEM_ID = "http://openjdk_java_net/xsl/dummy.xsl"; + + PrintStream original; + + @BeforeClass + public void setUpClass() throws Exception { + // save the PrintStream + original = System.err; + } + + @AfterClass + protected void tearDown() throws Exception { + // set back to the original + System.setErr(original); + } + + /** + * Verifies that when an ErrorListener is registered, parser errors are passed + * onto the listener without other output. + * + * @throws Exception + */ + @Test + public void test() throws Exception { + InputStream is = new ByteArrayInputStream(INVALID_STYLESHEET.getBytes()); + InputSource source = new InputSource(is); + source.setSystemId(SYSTEM_ID); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintStream ps = new PrintStream(baos); + System.setErr(ps); + + TransformerFactory factory = TransformerFactory.newInstance(); + factory.setErrorListener(new ErrListener()); + + try { + factory.newTransformer(new SAXSource(source)); + } catch (TransformerConfigurationException e) { + // nothing + } + + // all errors are handled by the ErrorListener, no other output + Assert.assertEquals(baos.toString(), ""); + + } + + class ErrListener implements ErrorListener { + + @Override + public void error(TransformerException exception) + throws TransformerException { + System.out.println("Correctly handled error: " + exception.getMessage()); + } + + @Override + public void fatalError(TransformerException exception) + throws TransformerException { + System.out.println("Correctly handled fatal: " + exception.getMessage()); + } + + @Override + public void warning(TransformerException exception) + throws TransformerException { + System.out.println("Correctly handled warning: " + exception.getMessage()); + } + } +}