8206132: DOM parser does not honor DocumentBuilderFactory.setExpandEntityReferences(false)
authorjoehw
Tue, 05 Feb 2019 09:57:35 -0800
changeset 53644 5d95a8dbb6e4
parent 53643 1126811a5124
child 53645 2c6c0fabe6a2
8206132: DOM parser does not honor DocumentBuilderFactory.setExpandEntityReferences(false) Reviewed-by: rriggs, lancea
src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java
src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/AbstractDOMParser.java
test/jaxp/javax/xml/jaxp/unittest/dom/DOMFeatureTest.java
test/jaxp/javax/xml/jaxp/unittest/dom/ElementTraversal.java
test/jaxp/javax/xml/jaxp/unittest/dom/ls/LSSerializerTest.java
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java	Tue Feb 05 09:56:19 2019 -0800
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java	Tue Feb 05 09:57:35 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -73,7 +73,7 @@
  * @author Eric Ye, IBM
  * @author Sunitha Reddy, SUN Microsystems
  *
- * @LastModified: Sep 2017
+ * @LastModified: Jan 2019
  */
 public class XMLDocumentFragmentScannerImpl
         extends XMLScanner
@@ -163,6 +163,10 @@
     protected static final String STANDARD_URI_CONFORMANT =
             Constants.XERCES_FEATURE_PREFIX +Constants.STANDARD_URI_CONFORMANT_FEATURE;
 
+    /** Feature id: create entity ref nodes. */
+    protected static final String CREATE_ENTITY_REF_NODES =
+            Constants.XERCES_FEATURE_PREFIX + Constants.CREATE_ENTITY_REF_NODES_FEATURE;
+
     /** Property identifier: Security property manager. */
     private static final String XML_SECURITY_PROPERTY_MANAGER =
             Constants.XML_SECURITY_PROPERTY_MANAGER;
@@ -322,6 +326,9 @@
     /** Xerces Feature: Disallow doctype declaration. */
     protected boolean fDisallowDoctype = false;
 
+    /** Create entity reference nodes. */
+    protected boolean fCreateEntityRefNodes = false;
+
     /**
      * CDATA chunk size limit
      */
@@ -596,6 +603,8 @@
         fSecurityManager = (XMLSecurityManager)componentManager.getProperty(Constants.SECURITY_MANAGER, null);
         fNotifyBuiltInRefs = componentManager.getFeature(NOTIFY_BUILTIN_REFS, false);
 
+        fCreateEntityRefNodes = componentManager.getFeature(CREATE_ENTITY_REF_NODES, fCreateEntityRefNodes);
+
         Object resolver = componentManager.getProperty(ENTITY_RESOLVER, null);
         fExternalSubsetResolver = (resolver instanceof ExternalSubsetResolver) ?
                 (ExternalSubsetResolver) resolver : null;
@@ -1837,14 +1846,20 @@
             } else
                 reportFatalError("EntityNotDeclared", new Object[]{name});
         }
-        //we are starting the entity even if the entity was not declared
-        //if that was the case it its taken care in XMLEntityManager.startEntity()
-        //we immediately call the endEntity. Application gets to know if there was
-        //any entity that was not declared.
-        fEntityManager.startEntity(true, name, false);
-        //set the scaner state to content.. parser will automatically revive itself at any point of time.
-        //setScannerState(SCANNER_STATE_CONTENT);
-        //return true ;
+
+        // create EntityReference only
+        if (fCreateEntityRefNodes) {
+            fDocumentHandler.startGeneralEntity(name, null, null, null);
+        } else {
+            //we are starting the entity even if the entity was not declared
+            //if that was the case it its taken care in XMLEntityManager.startEntity()
+            //we immediately call the endEntity. Application gets to know if there was
+            //any entity that was not declared.
+            fEntityManager.startEntity(true, name, false);
+            //set the scaner state to content.. parser will automatically revive itself at any point of time.
+            //setScannerState(SCANNER_STATE_CONTENT);
+            //return true ;
+        }
     } // scanEntityReference()
 
     // utility methods
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/AbstractDOMParser.java	Tue Feb 05 09:56:19 2019 -0800
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/AbstractDOMParser.java	Tue Feb 05 09:57:35 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 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 Andy Clark, IBM
  * @author Elena Litani, IBM
  *
- * @LastModified: Nov 2017
+ * @LastModified: Jan 2019
  */
 public class AbstractDOMParser extends AbstractXMLDocumentParser {
 
@@ -491,8 +491,10 @@
         if (DEBUG_EVENTS) {
             System.out.println ("==>startGeneralEntity ("+name+")");
             if (DEBUG_BASEURI) {
-                System.out.println ("   expandedSystemId( **baseURI): "+identifier.getExpandedSystemId ());
-                System.out.println ("   baseURI:"+ identifier.getBaseSystemId ());
+                System.out.println ("   expandedSystemId( **baseURI): " +
+                        identifier == null ? null : identifier.getExpandedSystemId());
+                System.out.println ("   baseURI:" +
+                        identifier == null ? null : identifier.getBaseSystemId());
             }
         }
 
@@ -512,7 +514,7 @@
                 EntityReferenceImpl erImpl =(EntityReferenceImpl)er;
 
                 // set base uri
-                erImpl.setBaseURI (identifier.getExpandedSystemId ());
+                erImpl.setBaseURI (identifier == null ? null : identifier.getExpandedSystemId());
                 if (fDocumentType != null) {
                     // set actual encoding
                     NamedNodeMap entities = fDocumentType.getEntities ();
@@ -528,12 +530,17 @@
             }
             fInEntityRef = true;
             fCurrentNode.appendChild (er);
-            fCurrentNode = er;
+
+            if (!fCreateEntityRefNodes) {
+                fCurrentNode = er;
+            } else {
+                ((NodeImpl)er).setReadOnly (true, true);
+            }
         }
         else {
 
-            int er =
-            fDeferredDocumentImpl.createDeferredEntityReference (name, identifier.getExpandedSystemId ());
+            int er = fDeferredDocumentImpl.createDeferredEntityReference (name,
+                    identifier == null ? null : identifier.getExpandedSystemId ());
             if (fDocumentTypeIndex != -1) {
                 // find corresponding Entity decl
                 int node = fDeferredDocumentImpl.getLastChild (fDocumentTypeIndex, false);
@@ -552,7 +559,10 @@
                 }
             }
             fDeferredDocumentImpl.appendChild (fCurrentNodeIndex, er);
-            fCurrentNodeIndex = er;
+
+            if (!fCreateEntityRefNodes) {
+                fCurrentNodeIndex = er;
+            }
         }
 
     } // startGeneralEntity(String,XMLResourceIdentifier, Augmentations)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jaxp/javax/xml/jaxp/unittest/dom/DOMFeatureTest.java	Tue Feb 05 09:57:35 2019 -0800
@@ -0,0 +1,188 @@
+/*
+ * 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 dom;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Listeners;
+import org.testng.annotations.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.EntityReference;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+import org.xml.sax.SAXException;
+
+/*
+ * @test
+ * @bug 8206132
+ * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
+ * @run testng dom.DOMFeatureTest
+ * @summary Tests DOM features.
+ */
+@Listeners({jaxp.library.BasePolicy.class})
+public class DOMFeatureTest {
+
+    private static final String XML1 = "<?xml version=\"1.0\"?>\n"
+            + "<!DOCTYPE document [\n"
+            + "    <!ENTITY author \"William Shakespeare\">\n"
+            + "    <!ELEMENT document (title)>\n"
+            + "    <!ELEMENT title (#PCDATA)>\n"
+            + "]>\n"
+            + "<document>\n"
+            + "    <title>&author;</title>\n"
+            + "</document>";
+
+    private static final String XML2 = "<?xml version=\"1.0\"?>\n"
+            + "<!DOCTYPE document [\n"
+            + "    <!ENTITY author \"William Shakespeare\">\n"
+            + "    <!ELEMENT document (title)>\n"
+            + "    <!ELEMENT title (#PCDATA|chapter)*>\n"
+            + "    <!ELEMENT chapter (#PCDATA)>\n"
+            + "]>\n"
+            + "<document>\n"
+            + "    <title>&author;  Hamlet<chapter>Chapter 1</chapter></title>\n"
+            + "</document>";
+
+    private static final String XML3 = "<?xml version=\"1.0\"?>\n"
+        + "<!DOCTYPE document [\n"
+        + "    <!ENTITY author SYSTEM \"https://openjdk_java_net/author.dtd\">"
+        + "    <!ELEMENT document (title)>\n"
+        + "    <!ELEMENT title (#PCDATA|chapter)*>\n"
+        + "    <!ELEMENT chapter (#PCDATA)>\n"
+        + "]>\n"
+        + "<document>\n"
+        + "    <title>&author;  Hamlet<chapter>Chapter 1</chapter></title>\n"
+        + "</document>";
+
+    /*
+     * DataProvider: for testing the EntityExpansion feature
+     * Data columns: case number, feature setting (true/false), xml file,
+     *               number of nodes expected, text content expected, element if any
+     */
+    @DataProvider(name = "EntityExpansion")
+    Object[][] getData() throws Exception {
+        return new Object[][]{
+            {1, true, XML1, 1, "William Shakespeare", null},
+            {2, true, XML2, 2, "William Shakespeare  Hamlet", "chapter"},
+            {3, false, XML1, 1, null, null},
+            {4, false, XML2, 3, "  Hamlet", "chapter"},
+            {4, false, XML3, 3, "  Hamlet", "chapter"},
+        };
+    }
+
+    /*
+     * DataProvider: for testing the EntityExpansion feature
+     * Data columns: feature setting (true/false), xml file
+     */
+    @DataProvider(name = "EntityExpansion1")
+    Object[][] getData1() throws Exception {
+        return new Object[][]{
+            {true, XML3},
+        };
+    }
+    /**
+     * Verifies the EntityExpansion feature.
+     * @param caseNo the case number
+     * @param feature flag indicating the setting of the feature
+     * @param xml the XML string
+     * @param n the number of nodes expected
+     * @param expectedText expected Text string
+     * @param expectedElement expected Element
+     * @throws Exception
+     */
+    @Test(dataProvider = "EntityExpansion")
+    public void testEntityExpansion(int caseNo, boolean feature, String xml,
+            int n, String expectedText, String expectedElement) throws Exception {
+        final Document doc = getDocument(feature, xml);
+        final Element e = (Element) doc.getElementsByTagName("title").item(0);
+        final NodeList nl = e.getChildNodes();
+
+        switch (caseNo) {
+            case 1:
+                // The DOM tree should contain just the Text node
+                Assert.assertTrue(nl.item(0) instanceof Text);
+                Assert.assertEquals(nl.item(0).getNodeValue(), expectedText);
+                Assert.assertEquals(nl.getLength(), n);
+                break;
+            case 2:
+                // The DOM tree contains the Text node and an Element (chapter)
+                Assert.assertTrue(nl.item(0) instanceof Text);
+                Assert.assertEquals(nl.item(0).getNodeValue(), expectedText);
+                Assert.assertTrue(nl.item(1) instanceof Element);
+                Assert.assertEquals(nl.item(1).getNodeName(), expectedElement);
+                Assert.assertEquals(nl.getLength(), n);
+                break;
+            case 3:
+                // The DOM tree contains just the EntityReference node
+                Assert.assertTrue(nl.item(0) instanceof EntityReference);
+                Assert.assertEquals(nl.item(0).getNodeValue(), null);
+                Assert.assertEquals(nl.getLength(), n);
+                break;
+            case 4:
+                // The DOM tree contains a EntityReference, Text and an Element
+                Assert.assertTrue(nl.item(0) instanceof EntityReference);
+                Assert.assertEquals(nl.item(0).getNodeValue(), null);
+                Assert.assertTrue(nl.item(1) instanceof Text);
+                Assert.assertEquals(nl.item(1).getNodeValue(), expectedText);
+                Assert.assertTrue(nl.item(2) instanceof Element);
+                Assert.assertEquals(nl.item(2).getNodeName(), expectedElement);
+                Assert.assertEquals(nl.getLength(), n);
+                break;
+        }
+    }
+
+    /**
+     * Verifies the EntityExpansion feature. When the feature is set to true, the
+     * parser will attempt to resolve the external reference, that in turn will
+     * result in an Exception.
+     * @param feature flag indicating the setting of the feature
+     * @param xml the XML string
+     * @throws Exception: when a non-existent external reference is encountered
+     */
+    @Test(dataProvider = "EntityExpansion1", expectedExceptions = java.net.UnknownHostException.class)
+    public void testEntityExpansion1(boolean feature, String xml)
+            throws Exception {
+        final Document doc = getDocument(feature, xml);
+        final Element e = (Element) doc.getElementsByTagName("title").item(0);
+        final NodeList nl = e.getChildNodes();
+    }
+
+    private static Document getDocument(boolean expand, String xml)
+            throws SAXException, IOException, ParserConfigurationException {
+        final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+        dbf.setExpandEntityReferences(expand);
+
+        final DocumentBuilder docBuilder = dbf.newDocumentBuilder();
+
+        InputStream a = new ByteArrayInputStream(xml.getBytes());
+        Document out = docBuilder.parse(a);
+        return out;
+    }
+}
--- a/test/jaxp/javax/xml/jaxp/unittest/dom/ElementTraversal.java	Tue Feb 05 09:56:19 2019 -0800
+++ b/test/jaxp/javax/xml/jaxp/unittest/dom/ElementTraversal.java	Tue Feb 05 09:57:35 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -125,7 +125,6 @@
         Document doc = null;
         try {
             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
-            dbf.setExpandEntityReferences(false);
             DocumentBuilder db = dbf.newDocumentBuilder();
             doc = db.parse(xmlFile);
         } catch (ParserConfigurationException | SAXException | IOException e) {
--- a/test/jaxp/javax/xml/jaxp/unittest/dom/ls/LSSerializerTest.java	Tue Feb 05 09:56:19 2019 -0800
+++ b/test/jaxp/javax/xml/jaxp/unittest/dom/ls/LSSerializerTest.java	Tue Feb 05 09:57:35 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -35,6 +35,7 @@
 import javax.xml.parsers.ParserConfigurationException;
 
 import org.testng.Assert;
+import org.testng.annotations.DataProvider;
 import org.testng.annotations.Listeners;
 import org.testng.annotations.Test;
 import org.w3c.dom.DOMError;
@@ -52,7 +53,7 @@
 
 /*
  * @test
- * @bug 8080906 8114834
+ * @bug 8080906 8114834 8206132
  * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
  * @run testng/othervm -DrunSecMngr=true dom.ls.LSSerializerTest
  * @run testng/othervm dom.ls.LSSerializerTest
@@ -225,31 +226,111 @@
         Assert.assertEquals(XML11_DOCUMENT_OUTPUT, defaultSerialization, "Invalid serialization of XML 1.1 document: ");
     }
 
+    // XML source
+    private static final String XML =
+            "<?xml version=\"1.1\" encoding=\"UTF-16\"?>\n" +
+            "<!DOCTYPE author [\n" +
+            " <!ENTITY name \"Jo Smith\">" +
+            " <!ENTITY name1 \"&name;\">" +
+            " <!ENTITY name2 \"&name1;\">" +
+            "<!ENTITY ele \"<aa><bb>text</bb></aa>\">" +
+            " <!ENTITY ele1 \"&ele;\">" +
+            " <!ENTITY ele2 \"&ele1;\">" +
+            " ]>" +
+            " <author><a>&name1;</a>" +
+            "<b>b &name2; &name1; b</b>" +
+            "<c> &name; </c>" +
+            "<d>&ele1;d</d>" +
+            "<e> &ele2;eee </e>" +
+            "<f>&lt;att&gt;</f>" +
+            "<g> &ele; g</g>" +
+            "<h>&ele2;</h></author>" ;
+
+    // result when "entities" = true, equvalent to setting ExpandEntityReference to false
+    private static final String RESULT_TRUE =
+            "<?xml version=\"1.1\" encoding=\"UTF-16\"?><!DOCTYPE author [ \n" +
+            "<!ENTITY name 'Jo Smith'>\n" +
+            "<!ENTITY name1 '&name;'>\n" +
+            "<!ENTITY name2 '&name1;'>\n" +
+            "<!ENTITY ele '<aa><bb>text</bb></aa>'>\n" +
+            "<!ENTITY ele1 '&ele;'>\n" +
+            "<!ENTITY ele2 '&ele1;'>\n" +
+            "]>\n" +
+            "<author>\n" +
+            "    <a>&name1;</a>\n" +
+            "    <b>b &name2;&name1; b</b>\n" +
+            "    <c>&name;</c>\n" +
+            "    <d>&ele1;d</d>\n" +
+            "    <e>&ele2;eee </e>\n" +
+            "    <f>&lt;att&gt;</f>\n" +
+            "    <g>&ele; g</g>\n" +
+            "    <h>&ele2;</h>\n" +
+            "</author>\n";
+
+    // result when "entities" = false, equvalent to setting ExpandEntityReference to true
+    private static final String RESULT_FALSE =
+            "<?xml version=\"1.1\" encoding=\"UTF-16\"?><!DOCTYPE author [ \n" +
+            "<!ENTITY name 'Jo Smith'>\n" +
+            "<!ENTITY name1 '&name;'>\n" +
+            "<!ENTITY name2 '&name1;'>\n" +
+            "<!ENTITY ele '<aa><bb>text</bb></aa>'>\n" +
+            "<!ENTITY ele1 '&ele;'>\n" +
+            "<!ENTITY ele2 '&ele1;'>\n" +
+            "]>\n" +
+            "<author>\n" +
+            "    <a>Jo Smith</a>\n" +
+            "    <b>b Jo Smith Jo Smith b</b>\n" +
+            "    <c> Jo Smith </c>\n" +
+            "    <d>\n" +
+            "        <aa>\n" +
+            "            <bb>text</bb>\n" +
+            "        </aa>\n" +
+            "        d\n" +
+            "    </d>\n" +
+            "    <e>\n" +
+            "        <aa>\n" +
+            "            <bb>text</bb>\n" +
+            "        </aa>\n" +
+            "        eee \n" +
+            "    </e>\n" +
+            "    <f>&lt;att&gt;</f>\n" +
+            "    <g>\n" +
+            "        <aa>\n" +
+            "            <bb>text</bb>\n" +
+            "        </aa>\n" +
+            "         g\n" +
+            "    </g>\n" +
+            "    <h>\n" +
+            "        <aa>\n" +
+            "            <bb>text</bb>\n" +
+            "        </aa>\n" +
+            "    </h>\n" +
+            "</author>\n";
+
     /*
-     * @bug 8114834 test entity reference, nested entity reference when entities
-     * is true and false
+     * DataProvider: for testing the entities parameter
+     * Data columns: xml source, entities setting, expected result
      */
-    @Test
-    public void testEntityReference() throws Exception {
-        final String XML_DOCUMENT = "<?xml version=\"1.1\" encoding=\"UTF-16\"?>\n" +
-                "<!DOCTYPE author [\n" +
-                " <!ENTITY name \"Jo Smith\">" +
-                " <!ENTITY name1 \"&name;\">" +
-                " <!ENTITY name2 \"&name1;\">" +
-                "<!ENTITY ele \"<aa><bb>text</bb></aa>\">" +
-                " <!ENTITY ele1 \"&ele;\">" +
-                " <!ENTITY ele2 \"&ele1;\">" +
-                " ]>" +
-                " <author><a>&name1;</a>" +
-                "<b>b &name2; &name1; b</b>" +
-                "<c> &name; </c>" +
-                "<d>&ele1;d</d>" +
-                "<e> &ele2;eee </e>" +
-                "<f>&lt;att&gt;</f>" +
-                "<g> &ele; g</g>" +
-                "<h>&ele2;</h></author>" ;
+    @DataProvider(name = "entities")
+    Object[][] getData() throws Exception {
+        return new Object[][]{
+            {XML, Boolean.TRUE, RESULT_TRUE},
+            {XML, Boolean.FALSE, RESULT_FALSE},
+        };
+    }
 
-
+    /**
+     * Tests serializing DOM Document with DOMConfiguration's "entities" parameter.
+     *
+     * @param source the XML source
+     * @param entities the entities parameter setting
+     * @param expected expected string result
+     * @throws Exception
+     * @bug 8114834 8206132
+     */
+    @Test(dataProvider = "entities")
+    public void testEntityReference(String source, Boolean entities, String expected)
+            throws Exception {
         DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
         DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
 
@@ -257,76 +338,18 @@
         DOMImplementationLS domImplementationLS = (DOMImplementationLS) domImplementation;
 
         LSParser domParser = domImplementationLS.createLSParser(MODE_SYNCHRONOUS, null);
-        domParser.getDomConfig().setParameter("entities", Boolean.TRUE);
+        domParser.getDomConfig().setParameter("entities", entities);
 
         LSInput src = domImplementationLS.createLSInput();
-        src.setStringData(XML_DOCUMENT);
+        src.setStringData(source);
         Document document = domParser.parse(src);
 
         LSSerializer lsSerializer = domImplementationLS.createLSSerializer();
-
         lsSerializer.getDomConfig().setParameter("format-pretty-print", true);
-        System.out.println("test with default entities is " + lsSerializer.getDomConfig().getParameter("entities"));
-        Assert.assertEquals(lsSerializer.writeToString(document),
-                "<?xml version=\"1.1\" encoding=\"UTF-16\"?><!DOCTYPE author [ \n" +
-                "<!ENTITY name 'Jo Smith'>\n" +
-                "<!ENTITY name1 '&name;'>\n" +
-                "<!ENTITY name2 '&name1;'>\n" +
-                "<!ENTITY ele '<aa><bb>text</bb></aa>'>\n" +
-                "<!ENTITY ele1 '&ele;'>\n" +
-                "<!ENTITY ele2 '&ele1;'>\n" +
-                "]>\n" +
-                "<author>\n" +
-                "    <a>&name1;Jo Smith</a>\n" +
-                "    <b>b &name2;Jo Smith &name1;Jo Smith b</b>\n" +
-                "    <c>&name;Jo Smith </c>\n" +
-                "    <d>&ele1;d</d>\n" +
-                "    <e>&ele2;eee </e>\n" +
-                "    <f>&lt;att&gt;</f>\n" +
-                "    <g>&ele; g</g>\n" +
-                "    <h>&ele2;</h>\n" +
-                "</author>\n");
+        System.out.println("test with default entities is " +
+                lsSerializer.getDomConfig().getParameter("entities"));
 
-        lsSerializer.getDomConfig().setParameter("entities", Boolean.FALSE);
-        System.out.println("test with entities is false");
-        Assert.assertEquals(lsSerializer.writeToString(document),
-                "<?xml version=\"1.1\" encoding=\"UTF-16\"?><!DOCTYPE author [ \n" +
-                "<!ENTITY name 'Jo Smith'>\n" +
-                "<!ENTITY name1 '&name;'>\n" +
-                "<!ENTITY name2 '&name1;'>\n" +
-                "<!ENTITY ele '<aa><bb>text</bb></aa>'>\n" +
-                "<!ENTITY ele1 '&ele;'>\n" +
-                "<!ENTITY ele2 '&ele1;'>\n" +
-                "]>\n" +
-                "<author>\n" +
-                "    <a>&name;Jo Smith</a>\n" +
-                "    <b>b &name;Jo Smith &name;Jo Smith b</b>\n" +
-                "    <c>&name;Jo Smith </c>\n" +
-                "    <d>\n" +
-                "        <aa>\n" +
-                "            <bb>text</bb>\n" +
-                "        </aa>\n" +
-                "        d\n" +
-                "    </d>\n" +
-                "    <e>\n" +
-                "        <aa>\n" +
-                "            <bb>text</bb>\n" +
-                "        </aa>\n" +
-                "        eee \n" +
-                "    </e>\n" +
-                "    <f>&lt;att&gt;</f>\n" +
-                "    <g>\n" +
-                "        <aa>\n" +
-                "            <bb>text</bb>\n" +
-                "        </aa>\n" +
-                "         g\n" +
-                "    </g>\n" +
-                "    <h>\n" +
-                "        <aa>\n" +
-                "            <bb>text</bb>\n" +
-                "        </aa>\n" +
-                "    </h>\n" +
-                "</author>\n");
-
+        String result = lsSerializer.writeToString(document);
+        Assert.assertEquals(result, expected);
     }
 }