8157830: Errors in XSLT stylesheet are not dispatched correctly to ErrorListener

Reviewed-by: lancea
This commit is contained in:
Joe Wang 2019-07-19 02:40:59 +00:00
parent ba9c952f87
commit a91f9c4c7e
6 changed files with 199 additions and 15 deletions

View File

@ -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.Stack;
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 @@ import org.xml.sax.helpers.AttributesImpl;
* @author G. Todd Miller
* @author Morten Jorgensen
* @author Erwin Bolwidt <ejb@klomp.org>
* @LastModified: Nov 2017
* @LastModified: July 2019
*/
public class Parser implements Constants, ContentHandler {
@ -98,9 +99,13 @@ public class Parser implements Constants, ContentHandler {
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 @@ public class Parser implements Constants, ContentHandler {
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);

View File

@ -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 @@ import org.xml.sax.XMLReader;
* @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 @@ public final class XSLTC {
/**
* 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<>();

View File

@ -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 @@ import org.xml.sax.SAXException;
* 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 @@ public class TemplatesHandlerImpl
/**
* 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);

View File

@ -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 @@ import org.xml.sax.XMLReader;
* @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 @@ public class TransformerFactoryImpl
*/
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 @@ public class TransformerFactoryImpl
"TransformerFactory");
throw new IllegalArgumentException(err.toString());
}
_hasUserErrListener = true;
_errorListener = listener;
}
@ -946,7 +950,7 @@ public class TransformerFactoryImpl
}
// 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 @@ public class TransformerFactoryImpl
// through the factory instance
buildCatalogFeatures();
final TemplatesHandlerImpl handler =
new TemplatesHandlerImpl(_indentNumber, this);
new TemplatesHandlerImpl(_indentNumber, this, _hasUserErrListener);
if (_uriResolver != null) {
handler.setURIResolver(_uriResolver);
}

View File

@ -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;
}
}

View File

@ -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());
}
}
}