384493200f
Reviewed-by: alanb, joehw
160 lines
5.9 KiB
Java
160 lines
5.9 KiB
Java
/*
|
|
* 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:
|
|
*
|
|
* <?xml version=\"1.1\"?>
|
|
* <ROOT>
|
|
* <FILLER>ffffffff...fffff</FILLER>
|
|
* <TEST>content</TEST><TEST2>content2</TEST2>
|
|
* <FILLER>ffffffff...fffffffff</FILLER>
|
|
* </ROOT>
|
|
*
|
|
* 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 = "<TEST>content</TEST><TEST2>content2</TEST2>";
|
|
|
|
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("<?xml version=\"1.1\"?>");
|
|
result.append("<ROOT>");
|
|
|
|
int fillerLength = 8192 - bufferLimitPosition;
|
|
createFiller(result, fillerLength);
|
|
|
|
result.append(testString);
|
|
|
|
createFiller(result, 9000);
|
|
result.append("</ROOT>");
|
|
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("<FILLER>");
|
|
int fillLength = length - "<FILLER></FILLER>".length();
|
|
for (int i=0; i<fillLength; i++) {
|
|
buffer.append('f');
|
|
}
|
|
buffer.append("</FILLER>");
|
|
}
|
|
|
|
|
|
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 = "<?xml version=\"1.1\"?><ROOT>".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) + " ... ]");
|
|
}
|
|
}
|
|
}
|