kazvictor kazvictor - 3 months ago 9
Java Question

Execute XSLT with Xalan in secure mode to create XHTML throws TransformerConfigurationException on creating attributes

I'm trying to use the updated version of Xalan (2.7.2) in secure mode and Having issue with it not able to understand unknown attributes.
The problem is, it prevents you from using any stylesheet that emits XHTML (in secure processing mode) because it disallows things like “colspan” attributes of “th” elements.

The associated changed file is here: http://svn.apache.org/viewvc/xalan/java/branches/xalan-j_2_7_1_maint/src/org/apache/xalan/processor/XSLTElementProcessor.java?r1=1359736&r2=1581058&pathrev=1581058&diff_format=h

See the following example:

import javax.xml.XMLConstants;
import javax.xml.transform.*;
import javax.xml.transform.stream.StreamSource;
import java.io.StringReader;

public class XalanSecureAttributeRepro {
private static final String XSL =
"<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n" +
" <xsl:output method=\"html\"/>\n" +
" <xsl:template match=\"/*\">\n" +
" <th colspan=\"2\"/>\n" +
" </xsl:template>\n" +
"</xsl:stylesheet>";

public static void main( String[] args ) throws Exception {
System.setProperty( "javax.xml.transform.TransformerFactory", "org.apache.xalan.processor.TransformerFactoryImpl" );

TransformerFactory tf = TransformerFactory.newInstance();
tf.setFeature( XMLConstants.FEATURE_SECURE_PROCESSING, true);
tf.setErrorListener( new DefaultErrorHandler( true ) );

final Source source = new StreamSource( new StringReader( XSL ) );
Templates templates = tf.newTemplates( source ); // throws:
// TransformerException: "colspan" attribute is not allowed on the th element!
}
}


It returns this error:

Exception in thread "main" javax.xml.transform.TransformerConfigurationException: javax.xml.transform.TransformerException: org.xml.sax.SAXException: "colspan" attribute is not allowed on the th element!
javax.xml.transform.TransformerException: "colspan" attribute is not allowed on the th element!
at org.apache.xalan.processor.TransformerFactoryImpl.newTemplates(TransformerFactoryImpl.java:933)
at com.l7tech.example.XalanSecureAttributeRepro.main(XalanSecureAttributeRepro.java:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: javax.xml.transform.TransformerException: org.xml.sax.SAXException: "colspan" attribute is not allowed on the th element!
javax.xml.transform.TransformerException: "colspan" attribute is not allowed on the th element!
at org.apache.xalan.processor.TransformerFactoryImpl.newTemplates(TransformerFactoryImpl.java:925)
... 6 more
Caused by: org.xml.sax.SAXException: "colspan" attribute is not allowed on the th element!
javax.xml.transform.TransformerException: "colspan" attribute is not allowed on the th element!
at org.apache.xalan.processor.StylesheetHandler.error(StylesheetHandler.java:919)
at org.apache.xalan.processor.StylesheetHandler.error(StylesheetHandler.java:947)
at org.apache.xalan.processor.XSLTElementProcessor.setPropertiesFromAttributes(XSLTElementProcessor.java:347)
at org.apache.xalan.processor.XSLTElementProcessor.setPropertiesFromAttributes(XSLTElementProcessor.java:267)
at org.apache.xalan.processor.ProcessorLRE.startElement(ProcessorLRE.java:283)
at org.apache.xalan.processor.StylesheetHandler.startElement(StylesheetHandler.java:623)
at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
at org.apache.xerces.parsers.AbstractXMLDocumentParser.emptyElement(Unknown Source)
at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at org.apache.xalan.processor.TransformerFactoryImpl.newTemplates(TransformerFactoryImpl.java:917)
... 6 more
Caused by: javax.xml.transform.TransformerException: "colspan" attribute is not allowed on the th element!
at org.apache.xalan.processor.StylesheetHandler.error(StylesheetHandler.java:904)
... 22 more


Am I doing something wrong with the stylesheet or am I missing setting a feature on the transformer factory. How would you transform a stylesheet that emits (X)HTML in secure processing mode using Xalan?

Answer

The offending line in the referred to version of the Xalan source is:

if(attrDef.getName().compareTo("*")==0 && handler.getStylesheetProcessor().isSecureProcessing())

I'm not 100% sure what is in attrDef, but I would guess it's your attribute, which will never have the value of * (but from the documentation on XSLTAttributeDef, the value * is allowed, but I don't know how, as it is not a qname).

The documentation on secure processing only limits the amount of attributes on a single element, but the limit is high, 10,000.

The way I see it, you hit a bug of Xalan 2.7.1. It prevents you from using any attribute. If the limit is imposed because only known attributes can be used, it still seems to be a bug, because th is allowed to take colspan as an attribute in both HTML and XHTML. You might try, though, if you see the same behavior if you change your output from HTML to XML.