Author: ltheussl Date: Fri Aug 21 10:57:56 2009 New Revision: 806492 URL: http://svn.apache.org/viewvc?rev=806492&view=rev Log: [DOXIA-362] Entities in attribute values are not escaped
Modified: maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/XhtmlBaseSink.java maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/parser/XhtmlBaseParserTest.java maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/XhtmlBaseSinkTest.java Modified: maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/XhtmlBaseSink.java URL: http://svn.apache.org/viewvc/maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/XhtmlBaseSink.java?rev=806492&r1=806491&r2=806492&view=diff ============================================================================== --- maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/XhtmlBaseSink.java (original) +++ maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/XhtmlBaseSink.java Fri Aug 21 10:57:56 2009 @@ -22,6 +22,7 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; +import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -844,7 +845,7 @@ */ public void figureGraphics( String name ) { - write( String.valueOf( SPACE ) + Attribute.SRC + EQUAL + QUOTE + name + QUOTE ); + write( String.valueOf( SPACE ) + Attribute.SRC + EQUAL + QUOTE + escapeHTML( name ) + QUOTE ); } /** {...@inheritdoc} */ @@ -858,13 +859,19 @@ writeStartTag( HtmlMarkup.P, atts ); } + MutableAttributeSet filtered = SinkUtils.filterAttributes( attributes, SinkUtils.SINK_IMG_ATTRIBUTES ); + if ( filtered != null ) + { + filtered.removeAttribute( Attribute.SRC.toString() ); + } + int count = ( attributes == null ? 1 : attributes.getAttributeCount() + 1 ); MutableAttributeSet atts = new SinkEventAttributeSet( count ); - atts.addAttribute( Attribute.SRC, src ); - atts.addAttributes( SinkUtils.filterAttributes( - attributes, SinkUtils.SINK_IMG_ATTRIBUTES ) ); + atts.addAttribute( Attribute.SRC, escapeHTML( src ) ); + atts.addAttributes( filtered ); + if ( atts.getAttribute( Attribute.ALT.toString() ) == null ) { atts.addAttribute( Attribute.ALT.toString(), "" ); @@ -1827,11 +1834,11 @@ { if ( tagType == TAG_TYPE_SIMPLE ) { - writeSimpleTag( tag, attributes ); + writeSimpleTag( tag, escapeAttributeValues( attributes ) ); } else if ( tagType == TAG_TYPE_START ) { - writeStartTag( tag, attributes ); + writeStartTag( tag, escapeAttributeValues( attributes ) ); } else if ( tagType == TAG_TYPE_END ) { @@ -1845,6 +1852,22 @@ } } + private SinkEventAttributes escapeAttributeValues( SinkEventAttributes attributes ) + { + SinkEventAttributeSet set = new SinkEventAttributeSet( attributes.getAttributeCount() ); + + Enumeration names = attributes.getAttributeNames(); + + while ( names.hasMoreElements() ) + { + Object name = names.nextElement(); + + set.addAttribute( name, escapeHTML( attributes.getAttribute( name ).toString() ) ); + } + + return set; + } + /** {...@inheritdoc} */ public void flush() { Modified: maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/parser/XhtmlBaseParserTest.java URL: http://svn.apache.org/viewvc/maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/parser/XhtmlBaseParserTest.java?rev=806492&r1=806491&r2=806492&view=diff ============================================================================== --- maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/parser/XhtmlBaseParserTest.java (original) +++ maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/parser/XhtmlBaseParserTest.java Fri Aug 21 10:57:56 2009 @@ -22,6 +22,7 @@ import java.util.Iterator; import org.apache.maven.doxia.logging.Log; +import org.apache.maven.doxia.sink.SinkEventAttributeSet; import org.apache.maven.doxia.sink.SinkEventElement; import org.apache.maven.doxia.sink.SinkEventTestingSink; @@ -630,4 +631,40 @@ assertEquals( "a1invalid", element.getArgs()[0] ); assertEquals( "anchor_", ( (SinkEventElement) it.next() ).getName() ); } + + /** + * Test entities in attributes. + * + * @throws java.lang.Exception if any. + */ + public void testAttributeEntities() + throws Exception + { + String text = "<script type=\"text/javascript\" src=\"http://ex.com/ex.js?v=l&l=e\"></script>"; + + parser.parse( text, sink ); + + Iterator it = sink.getEventList().iterator(); + + SinkEventElement event = (SinkEventElement) it.next(); + + assertEquals( "unknown", event.getName() ); + assertEquals( "script", event.getArgs()[0] ); + SinkEventAttributeSet attribs = (SinkEventAttributeSet) event.getArgs()[2]; + // ampersand should be un-escaped + assertEquals( "http://ex.com/ex.js?v=l&l=e", attribs.getAttribute( "src" ) ); + assertEquals( "unknown", ( (SinkEventElement) it.next() ).getName() ); + assertFalse( it.hasNext() ); + + sink.reset(); + text = "<img src=\"http://ex.com/ex.jpg?v=l&l=e\" alt=\"image\"/>"; + parser.parse( text, sink ); + + it = sink.getEventList().iterator(); + event = (SinkEventElement) it.next(); + assertEquals( "figureGraphics", event.getName() ); + attribs = (SinkEventAttributeSet) event.getArgs()[1]; + // ampersand should be un-escaped + assertEquals( "http://ex.com/ex.jpg?v=l&l=e", attribs.getAttribute( "src" ) ); + } } Modified: maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/XhtmlBaseSinkTest.java URL: http://svn.apache.org/viewvc/maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/XhtmlBaseSinkTest.java?rev=806492&r1=806491&r2=806492&view=diff ============================================================================== --- maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/XhtmlBaseSinkTest.java (original) +++ maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/XhtmlBaseSinkTest.java Fri Aug 21 10:57:56 2009 @@ -833,6 +833,37 @@ } /** + * Test entities in attribute values. + */ + public void testAttributeEntities() + { + final Object[] startTag = new Object[] { new Integer( XhtmlBaseSink.TAG_TYPE_START ) }; + final Object[] endTag = new Object[] { new Integer( XhtmlBaseSink.TAG_TYPE_END ) }; + final String script = XhtmlBaseSink.SCRIPT.toString(); + final SinkEventAttributes src = new SinkEventAttributeSet( + new String[] {SinkEventAttributes.SRC.toString(), "http://ex.com/ex.js?v=l&l=e"} ); + + try + { + sink = new XhtmlBaseSink( writer ); + + sink.unknown( script, startTag, src ); + sink.unknown( script, endTag, null ); + + sink.figureGraphics( "http://ex.com/ex.jpg?v=l&l=e", src ); + } + finally + { + sink.close(); + } + + String result = writer.toString(); + + assertTrue( result.indexOf( "ex.js?v=l&l=e" ) != -1 ); + assertTrue( result.indexOf( "ex.jpg?v=l&l=e" ) != -1 ); + } + + /** * Test of entity. */ public void testEntity()