8223291: Whitespace is added to CDATA tags when using OutputKeys.INDENT to format XML

Reviewed-by: dfuchs, lancea
This commit is contained in:
Joe Wang 2019-07-03 16:30:19 +00:00
parent 307b7e3c04
commit 5c12a30062
8 changed files with 92 additions and 34 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@ -40,7 +40,7 @@ import com.sun.org.apache.xml.internal.serializer.utils.Utils;
* because it is used from another package.
*
* @xsl.usage internal
* @LastModified: Sept 2018
* @LastModified: July 2019
*/
public final class ToHTMLStream extends ToStream
{
@ -719,7 +719,7 @@ public final class ToHTMLStream extends ToStream
public final void endDocument() throws org.xml.sax.SAXException
{
if (m_doIndent) {
flushCharactersBuffer();
flushCharactersBuffer(false);
}
flushPending();
if (m_doIndent && !m_isprevtext)
@ -782,7 +782,7 @@ public final class ToHTMLStream extends ToStream
if (m_doIndent) {
// will add extra one if having namespace but no matter
m_childNodeNum++;
flushCharactersBuffer();
flushCharactersBuffer(false);
}
ElemContext elemContext = m_elemContext;
@ -923,7 +923,7 @@ public final class ToHTMLStream extends ToStream
throws org.xml.sax.SAXException
{
if (m_doIndent) {
flushCharactersBuffer();
flushCharactersBuffer(false);
}
// deal with any pending issues
if (m_cdataTagOpen)
@ -1645,7 +1645,7 @@ public final class ToHTMLStream extends ToStream
{
if (m_doIndent) {
m_childNodeNum++;
flushCharactersBuffer();
flushCharactersBuffer(false);
}
// Process any pending starDocument and startElement first.
flushPending();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@ -51,7 +51,7 @@ import org.xml.sax.SAXException;
* serializers (xml, html, text ...) that write output to a stream.
*
* @xsl.usage internal
* @LastModified: Sept 2018
* @LastModified: July 2019
*/
abstract public class ToStream extends SerializerBase {
@ -1231,7 +1231,7 @@ abstract public class ToStream extends SerializerBase {
m_elemContext.m_startTagOpen = false;
}
if (!m_cdataTagOpen && shouldIndent())
if (!m_cdataTagOpen && shouldIndentForText())
indent();
boolean writeCDataBrackets =
@ -1270,6 +1270,7 @@ abstract public class ToStream extends SerializerBase {
closeCDATA();
}
m_isprevtext = true;
// time to fire off CDATA event
if (m_tracer != null)
super.fireCDATAEvent(ch, old_start, length);
@ -1536,11 +1537,13 @@ abstract public class ToStream extends SerializerBase {
}
/**
* Used to flush the buffered characters when indentation is on, this method
* will be called when the next node is traversed.
* Flushes the buffered characters when indentation is on. This method
* is called before the next node is traversed.
*
* @param isText indicates whether the node to be traversed is text
* @throws org.xml.sax.SAXException
*/
final protected void flushCharactersBuffer() throws SAXException {
final protected void flushCharactersBuffer(boolean isText) throws SAXException {
try {
if (shouldFormatOutput() && m_charactersBuffer.isAnyCharactersBuffered()) {
if (m_elemContext.m_isCdataSection) {
@ -1553,7 +1556,9 @@ abstract public class ToStream extends SerializerBase {
return;
}
m_childNodeNum++;
if (!isText) {
m_childNodeNum++;
}
boolean skipBeginningNewlines = false;
if (shouldIndentForText()) {
indent();
@ -1846,7 +1851,7 @@ abstract public class ToStream extends SerializerBase {
if (m_doIndent) {
m_childNodeNum++;
flushCharactersBuffer();
flushCharactersBuffer(false);
}
if (m_needToCallStartDocument)
@ -2117,7 +2122,7 @@ abstract public class ToStream extends SerializerBase {
return;
if (m_doIndent) {
flushCharactersBuffer();
flushCharactersBuffer(false);
}
// namespaces declared at the current depth are no longer valid
// so get rid of them
@ -2309,7 +2314,7 @@ abstract public class ToStream extends SerializerBase {
return;
if (m_doIndent) {
m_childNodeNum++;
flushCharactersBuffer();
flushCharactersBuffer(false);
}
if (m_elemContext.m_startTagOpen)
{
@ -2491,8 +2496,7 @@ abstract public class ToStream extends SerializerBase {
public void startCDATA() throws org.xml.sax.SAXException
{
if (m_doIndent) {
m_childNodeNum++;
flushCharactersBuffer();
flushCharactersBuffer(true);
}
m_cdataStartCalled = true;

View File

@ -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.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@ -40,6 +40,7 @@ import org.xml.sax.SAXException;
* be viewed as internal or package private, this is not an API.
*
* @xsl.usage internal
* @LastModified: July 2019
*/
public final class ToXMLStream extends ToStream
{
@ -200,7 +201,7 @@ public final class ToXMLStream extends ToStream
public void endDocument() throws org.xml.sax.SAXException
{
if (m_doIndent) {
flushCharactersBuffer();
flushCharactersBuffer(false);
}
flushPending();
if (m_doIndent && !m_isprevtext)
@ -267,7 +268,7 @@ public final class ToXMLStream extends ToStream
if (m_doIndent) {
m_childNodeNum++;
flushCharactersBuffer();
flushCharactersBuffer(false);
}
flushPending();

View File

@ -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
@ -60,7 +60,7 @@ import org.xml.sax.SAXException;
/*
* @test
* @bug 6439439 8087303 8174025
* @bug 6439439 8087303 8174025 8223291
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true common.prettyprint.PrettyPrintTest
* @run testng/othervm common.prettyprint.PrettyPrintTest
@ -382,7 +382,6 @@ public class PrettyPrintTest {
private Document toXmlDocument(String xmlString) throws Exception {
InputSource xmlInputSource = new InputSource(new StringReader(xmlString));
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(true);
DocumentBuilder xmlDocumentBuilder = dbf.newDocumentBuilder();
Document node = xmlDocumentBuilder.parse(xmlInputSource);
return node;

View File

@ -1,3 +1 @@
<a>
<![CDATA[ ]]>
</a>
<a><![CDATA[ ]]></a>

View File

@ -1,5 +1,3 @@
<a>
<![CDATA[ abc def
<a><![CDATA[ abc def
line2 &a
test]]>
</a>
test]]></a>

View File

@ -1,6 +1,5 @@
<root>
t
<![CDATA[ ]]>
t<![CDATA[ ]]>
t
<child1/>

View File

@ -24,21 +24,79 @@
package transform;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Properties;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
/*
* @test
* @bug 8219705
* @bug 8219705 8223291
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng transform.OutputPropertiesTest
* @summary Verifies the output properties are set correctly
*/
public class OutputPropertiesTest {
/*
DataProvider: for testing indentation
Data: xml, expected result
*/
@DataProvider(name = "Indentation")
public Object[][] getData() {
String mix = "\n" +
" abc\n" +
" mix\n" +
" xyz\n" +
" ";
return new Object[][]{
{"abc<![CDATA[data]]>xyz", "abcdataxyz"},
{"abc<![CDATA[ & ]]>xyz", "abc & xyz"},
{"<![CDATA[data]]>", "data"},
{"abc<mix>mix</mix>xyz", mix}
};
}
/**
* bug 8223291
* Verifies that no extra indentation is added for CDATA.
* @param xml the xml content to be tested
* @param expected the expected result
* @throws Exception
*/
@Test(dataProvider = "Indentation")
public void testIndentation(String xml, String expected) throws Exception
{
StreamSource source = new StreamSource(new StringReader("<foo><bar>" + xml + "</bar></foo>"));
StreamResult result = new StreamResult(new StringWriter());
Transformer tform = TransformerFactory.newInstance().newTransformer();
tform.setOutputProperty(OutputKeys.INDENT, "yes");
tform.transform(source, result);
String xml1 = result.getWriter().toString();
Document document = DocumentBuilderFactory.newInstance()
.newDocumentBuilder()
.parse(new InputSource(new StringReader(xml1)));
String resultData = document.getElementsByTagName("bar")
.item(0)
.getTextContent();
Assert.assertEquals(resultData, expected);
}
@Test
public void testOutputProperties() throws Exception {
String xslData = "<?xml version='1.0'?>"
@ -70,4 +128,5 @@ public class OutputPropertiesTest {
prNames[i] + ": actual: " + value + ", expected: " + prValues[i]);
}
}
}