Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#51: PrettyPrintXMLWriter fails with a java.util.NoSuchElementException (Java 1.7 only) #52

Merged
merged 3 commits into from Dec 1, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -304,7 +304,15 @@ public void endElement()
{
finishTag();

write( "</" + elementStack.removeLast() + ">" );
// see issue #51: https://github.com/codehaus-plexus/plexus-utils/issues/51
// Rationale: removed the element into a variable first, and only THEN
// concatenate the string.
// (this avoids the string concatenation optimization bug detected in Java 7)
// TODO: change the below code to a more efficient expression when the library
// be ready to target Java 8.
write( "</" );
write( elementStack.removeLast() );
write( ">" );
}

readyForNewLine = true;
Expand Down
Expand Up @@ -16,7 +16,12 @@
* limitations under the License.
*/

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.util.NoSuchElementException;

import javax.swing.text.html.HTML.Tag;

Expand All @@ -28,6 +33,7 @@
* Test of {@link PrettyPrintXMLWriter}
*
* @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
* @author <a href="mailto:belingueres@gmail.com">Gabriel Belingueres</a>
* @version $Id$
*/
public class PrettyPrintXMLWriterTest
Expand Down Expand Up @@ -128,6 +134,75 @@ public void testEscapeXmlAttribute()
assertEquals( "<div class=\"sect&#10;ion\"/>", w.toString() );
}

public void testendElementAlreadyClosed()
{
try
{
writer.startElement( Tag.DIV.toString() );
writer.addAttribute( "class", "someattribute" );
writer.endElement(); // Tag.DIV closed
writer.endElement(); // Tag.DIV already closed, and there is no other outer tag!
fail( "Should throw a NoSuchElementException" );
}
catch ( NoSuchElementException e )
{
assert ( true );
}
}

/**
* Issue #51: https://github.com/codehaus-plexus/plexus-utils/issues/51
*
* Purpose: test if concatenation string optimization bug is present.
*
* Target environment: Java 7 (u79 and u80 verified) running on Windows.
*
* Detection strategy: Tries to build a big XML file (~750MB size) and with
* many nested tags to force the JVM to trigger the concatenation string
* optimization bug that throws a NoSuchElementException when calling
* endElement() method.
*
* @throws IOException if an I/O error occurs
*/
public void testIssue51DetectJava7ConcatenationBug()
throws IOException
{
File dir = new File( "target/test-xml" );
if ( !dir.exists() )
{
assertTrue( "cannot create directory test-xml", dir.mkdir() );
}
File xmlFile = new File( dir, "test-issue-51.xml" );
OutputStreamWriter osw = new OutputStreamWriter( new FileOutputStream( xmlFile ), "UTF-8" );
writer = new PrettyPrintXMLWriter( osw );

int iterations = 20000;

try
{
for ( int i = 0; i < iterations; ++i )
{
writer.startElement( Tag.DIV.toString() + i );
writer.addAttribute( "class", "someattribute" );
}
for ( int i = 0; i < iterations; ++i )
{
writer.endElement(); // closes Tag.DIV + i
}
}
catch ( NoSuchElementException e )
{
fail( "Should not throw a NoSuchElementException" );
}
finally
{
if ( osw != null )
{
osw.close();
}
}
}

private void writeXhtmlHead( XMLWriter writer )
{
writer.startElement( Tag.HEAD.toString() );
Expand Down