# HG changeset patch # User simonis # Date 1392129187 -3600 # Node ID 2b5229245d967483b01f4208a21130d801fb56d4 # Parent 3e0093b60a750e404f8e33dce3558713d39a12f6 8034087: XML parser may overwrite element content if that content falls onto the border of an entity scanner buffer Contributed-by: steffen.schreiber@sap.com diff --git a/test/javax/xml/jaxp/parsers/8034087/FragmentScannerBufferLimitTest.java b/test/javax/xml/jaxp/parsers/8034087/FragmentScannerBufferLimitTest.java new file mode 100644 --- /dev/null +++ b/test/javax/xml/jaxp/parsers/8034087/FragmentScannerBufferLimitTest.java @@ -0,0 +1,159 @@ +/* + * Copyright 2014, SAP AG. 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. + */ + +/** + * @test + * @bug 8034087 8027359 + * @summary XML parser may overwrite element content if that content falls onto the border of an entity scanner buffer + * @run main FragmentScannerBufferLimitTest + */ +import java.io.*; + +import javax.xml.parsers.*; +import javax.xml.transform.*; +import org.w3c.dom.*; +import org.xml.sax.*; + +/** + * Test for overwriting of XML element content by the XML parser when reading over buffer + * limits. + * + * We create a simple XML document of the form: + * + * + * + * ffffffff...fffff + * contentcontent2 + * ffffffff...fffffffff + * + * + * What's important here is, that the test content is at the border of an entity scanner + * buffer (XMLEntityScanner uses 8192 byte buffers). That's why there are filler elements + * of sufficient length that ensure there is a buffer break inside the test content + * and there is enough to read to require another buffer read after the content has been + * read. + * + * With the faulty implementation, the test content gets overwritten with characters + * read from the next buffer, i.e. 'f's. + * + * @author steffen.schreiber@sap.com + */ +public class FragmentScannerBufferLimitTest { + + static int errCount = 0; + + /** + * Check the test content. + */ + public static void main(String[] args) throws ParserConfigurationException, + SAXException, IOException, TransformerConfigurationException, + TransformerException, TransformerFactoryConfigurationError { + + String testString = "contentcontent2"; + + for (int i = 0; i < testString.length(); i++) { + test(createDocument(testString.toString(), i), ""+ i); + } + + if (errCount == 0) { + System.out.println("OK"); + } + else { + System.out.println("ERROR"); + throw new RuntimeException("Parsing error: element content has been overwritten"); + } + } + + /** + * Create the test XML document. + * @param testString the test content string + * @param bufferLimitPosition the position in the string where the buffer should break + * @return the document + */ + private static String createDocument(String testString, int bufferLimitPosition) throws UnsupportedEncodingException { + StringBuilder result = new StringBuilder(); + result.append(""); + result.append(""); + + int fillerLength = 8192 - bufferLimitPosition; + createFiller(result, fillerLength); + + result.append(testString); + + createFiller(result, 9000); + result.append(""); + return result.toString(); + } + + /** + * Create the filler element of the given length. + * @param buffer the output buffer + * @param length the required length of the element, including the element tags + */ + private static void createFiller(StringBuilder buffer, int length) { + buffer.append(""); + int fillLength = length - "".length(); + for (int i=0; i"); + } + + + private static void test(String document, String testName) throws SAXException, IOException, ParserConfigurationException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + + Document doc = builder.parse(new ByteArrayInputStream(document.getBytes("UTF-8"))); + + // check that there is the root node + NodeList roots = doc.getElementsByTagName("ROOT"); + assert roots.getLength() == 1; + Node root = roots.item(0); + + // check that root has children "FILLER" and "TEST" + NodeList children = root.getChildNodes(); + assert children.getLength() == 4; + assert children.item(0).getNodeName().equals("FILLER"); + assert children.item(1).getNodeName().equals("TEST"); + assert children.item(2).getNodeName().equals("TEST2"); + assert children.item(3).getNodeName().equals("FILLER"); + + // check that the test node has content "content" + checkContent(children.item(1).getTextContent(), "content", document); + checkContent(children.item(2).getTextContent(), "content2", document); + } + + private static void checkContent(String found, String expected, String document) { + if (! (found.equals(expected))) { + errCount++; + int bufferStart = "".length() +1; + int bufferStart2 = bufferStart + 8192; + System.err.println("\nError:: expected \"" + expected + + "\", but found \"" + found + "\"!"); + System.err.println("Buffer was (probably): [ ... " + + document.substring(bufferStart2 - 20, bufferStart2) + "] [" + + document.substring(bufferStart2, bufferStart2 + 30) + " ... ]"); + } + } +}