--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java Wed Feb 15 11:43:23 2017 +0800
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java Thu Feb 16 04:11:20 2017 +0300
@@ -415,9 +415,15 @@
/** Current DTD scanner. */
protected XMLDTDScanner fCurrentDTDScanner;
- /** Flag indiciating whether XML11 components have been initialized. */
+ /** Flag indicating whether XML11 components have been initialized. */
private boolean f11Initialized = false;
+ /** Flag indicating whether the symbol table instance was specified during construction **/
+ private boolean fSymbolTableProvided = false;
+
+ /** Flag indicating if the symbol table was initialized and never used before that **/
+ private boolean fSymbolTableJustInitialized = true;
+
//
// Constructors
//
@@ -566,15 +572,18 @@
};
addRecognizedProperties(recognizedProperties);
- if (symbolTable == null) {
- symbolTable = new SymbolTable();
+ // Remember if symbolTable was provided from outside
+ fSymbolTableProvided = symbolTable != null;
+ if (!fSymbolTableProvided) {
+ fSymbolTable = new SymbolTable();
+ } else {
+ fSymbolTable = symbolTable;
}
- fSymbolTable = symbolTable;
fProperties.put(SYMBOL_TABLE, fSymbolTable);
fGrammarPool = grammarPool;
if (fGrammarPool != null) {
- fProperties.put(XMLGRAMMAR_POOL, fGrammarPool);
+ fProperties.put(XMLGRAMMAR_POOL, fGrammarPool);
}
fEntityManager = new XMLEntityManager();
@@ -840,6 +849,7 @@
fValidationManager.reset();
fVersionDetector.reset(this);
fConfigUpdated = true;
+ resetSymbolTable();
resetCommon();
short version = fVersionDetector.determineDocVersion(fInputSource);
@@ -858,15 +868,7 @@
// resets and sets the pipeline.
fVersionDetector.startDocumentParsing((XMLEntityHandler) fCurrentScanner, version);
fInputSource = null;
- } catch (XNIException ex) {
- if (PRINT_EXCEPTION_STACK_TRACE)
- ex.printStackTrace();
- throw ex;
- } catch (IOException ex) {
- if (PRINT_EXCEPTION_STACK_TRACE)
- ex.printStackTrace();
- throw ex;
- } catch (RuntimeException ex) {
+ } catch (IOException | RuntimeException ex) {
if (PRINT_EXCEPTION_STACK_TRACE)
ex.printStackTrace();
throw ex;
@@ -879,15 +881,7 @@
try {
return fCurrentScanner.scanDocument(complete);
- } catch (XNIException ex) {
- if (PRINT_EXCEPTION_STACK_TRACE)
- ex.printStackTrace();
- throw ex;
- } catch (IOException ex) {
- if (PRINT_EXCEPTION_STACK_TRACE)
- ex.printStackTrace();
- throw ex;
- } catch (RuntimeException ex) {
+ } catch (IOException | RuntimeException ex) {
if (PRINT_EXCEPTION_STACK_TRACE)
ex.printStackTrace();
throw ex;
@@ -1589,6 +1583,23 @@
}
}
+
+ /**
+ * Reset the symbol table if it wasn't provided during construction
+ * and its not the first time when parse is called after initialization
+ */
+ private void resetSymbolTable() {
+ if (!fSymbolTableProvided) {
+ if (fSymbolTableJustInitialized) {
+ // Skip symbol table reallocation for the first parsing process
+ fSymbolTableJustInitialized = false;
+ } else {
+ fSymbolTable = new SymbolTable();
+ fProperties.put(SYMBOL_TABLE, fSymbolTable);
+ }
+ }
+ }
+
/**
* Returns the state of a feature. This method calls getFeature()
* on ParserConfigurationSettings, bypassing getFeature() on this
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/sax/SymbolTableResetTest.java Thu Feb 16 04:11:20 2017 +0300
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017, 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 sax;
+
+import java.io.StringReader;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.testng.Assert;
+import org.testng.annotations.Listeners;
+import org.testng.annotations.Test;
+import org.xml.sax.InputSource;
+import org.xml.sax.helpers.DefaultHandler;
+
+/*
+ * @test
+ * @bug 8173390
+ * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
+ * @run testng/othervm -DrunSecMngr=true sax.SymbolTableResetTest
+ * @run testng/othervm sax.SymbolTableResetTest
+ * @summary Test that SAXParser reallocates symbol table during
+ * subsequent parse operations
+ */
+@Listeners({jaxp.library.BasePolicy.class})
+public class SymbolTableResetTest {
+
+ /*
+ * Test mimics the SAXParser usage in SAAJ-RI that reuses the
+ * parsers from the internal pool. To avoid memory leaks, symbol
+ * table associated with the parser should be reallocated during each
+ * parse() operation.
+ */
+ @Test
+ public void testReset() throws Exception {
+ // Dummy xml input for parser
+ String input = "<dummy>Test</dummy>";
+ // Create SAXParser
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ SAXParser p = spf.newSAXParser();
+ // First parse iteration
+ p.parse(new InputSource(new StringReader(input)), new DefaultHandler());
+ // Get first symbol table reference
+ Object symTable1 = p.getProperty(SYMBOL_TABLE_PROPERTY);
+ p.reset();
+ // Second parse iteration
+ p.parse(new InputSource(new StringReader(input)), new DefaultHandler());
+ // Get second symbol table reference
+ Object symTable2 = p.getProperty(SYMBOL_TABLE_PROPERTY);
+ // Symbol table references should be different
+ Assert.assertNotSame(symTable1, symTable2, "Symbol table references");
+ }
+
+ // Symbol table property
+ private static final String SYMBOL_TABLE_PROPERTY = "http://apache.org/xml/properties/internal/symbol-table";
+
+}