restlet / restlet-framework-java

The first REST API framework for Java
https://restlet.talend.com
649 stars 284 forks source link

TransformRepresentation - Transformation fails if initialised with SaxRepresentation #638

Open caleryn opened 12 years ago

caleryn commented 12 years ago

A bug appears to have been introduced into the xml extension between versions 2.0.13 and 2.0.14 and between 2.1-RC4 and 2.1-RC5 in that the TransformRepresentation will now fail to transform a SaxRepresentation but will successfully transform other types.

I suspect that this may have been introduced as a feature or side effect of the Commit "Fixed security bug in the XML extension that allows XML external entity attacks. Reported by Fabio Mancinelli." but I am uncertain, if this is a bug or a changed input requirement for Sax based input.

The issue can be replicated using the following test case against versions 2.0.14 and 2.1-RC5.

Graham Smith

import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import org.junit.Test;
import org.restlet.data.CharacterSet;
import org.restlet.data.MediaType;
import org.restlet.engine.io.BufferingRepresentation;
import org.restlet.ext.xml.SaxRepresentation;
import org.restlet.ext.xml.TransformRepresentation;
import org.restlet.representation.Representation;
import org.restlet.representation.StringRepresentation;
import static org.junit.Assert.*;

/**
*
* @author agsmith
*/
public class XsltTransformationTest {

    private static final String INPUT = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><foo><bar>value</bar></foo>";
    private static final String XSLT = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"><xsl:output method=\"xml\" indent=\"no\"/><xsl:template match=\"/\"><bar><foo><xsl:value-of select=\"foo/bar\"/></foo></bar></xsl:template></xsl:stylesheet>";
    private static final String EXPECTED_OUTPUT = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><bar><foo>value</foo></bar>";

    /**
    */
    @Test
    public void runSaxRepresentation() throws Exception {
        final OutputStream out = new ByteArrayOutputStream();

        final Representation source = new SaxRepresentation (
                new StringRepresentation(INPUT,
                MediaType.APPLICATION_XML, null, CharacterSet.UTF_8));

        final Representation xslt = new StringRepresentation(XSLT, MediaType.APPLICATION_W3C_XSLT);

        final URIResolver resolver = new URIResolver(){
            @Override
            public Source resolve(String href, String base) throws TransformerException {
                throw new UnsupportedOperationException("This should not be needed in this test.");
            }
        };

        new TransformRepresentation(resolver, source, xslt).write(out);

        assertEquals("The Transformed Xml is not as ", EXPECTED_OUTPUT, out.toString());
    }

    @Test
    public void runBufferingRepresentation() throws Exception {
        final OutputStream out = new ByteArrayOutputStream();

        final Representation source = new BufferingRepresentation(
                new StringRepresentation(INPUT,
                MediaType.APPLICATION_XML, null, CharacterSet.UTF_8));

        final Representation xslt = new StringRepresentation(XSLT, MediaType.APPLICATION_W3C_XSLT);

        final URIResolver resolver = new URIResolver(){
            @Override
            public Source resolve(String href, String base) throws TransformerException {
                throw new UnsupportedOperationException("This should not be needed in this test.");
            }
        };

        new TransformRepresentation(resolver, source, xslt).write(out);

        assertEquals("The Transformed Xml is not as ", EXPECTED_OUTPUT, out.toString());
    }

    @Test
    public void runStringRepresentation() throws Exception {
        final OutputStream out = new ByteArrayOutputStream();

        final Representation source =
                new StringRepresentation(INPUT,
                MediaType.APPLICATION_XML, null, CharacterSet.UTF_8);

        final Representation xslt = new StringRepresentation(XSLT, MediaType.APPLICATION_W3C_XSLT);

        final URIResolver resolver = new URIResolver(){
            @Override
            public Source resolve(String href, String base) throws TransformerException {
                throw new UnsupportedOperationException("This should not be needed in this test.");
            }
        };

        new TransformRepresentation(resolver, source, xslt).write(out);

        assertEquals("The Transformed Xml is not as ", EXPECTED_OUTPUT, out.toString());
    }
}
jlouvel commented 12 years ago

Thanks for the report. Could you try to suggest a fix ?