TAP5-2219, TAP5-1778, TAP5-1714: when transforming the template stream, use the same encoding for the input and the output
Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/1a37c6ab Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/1a37c6ab Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/1a37c6ab Branch: refs/heads/master Commit: 1a37c6abd59254d3e9e6ce676cd7b300d704ecac Parents: 70d4efb Author: Jochen Kemnade <jochenkemn...@web.de> Authored: Sun Apr 27 15:30:30 2014 +0200 Committer: Jochen Kemnade <jochenkemn...@web.de> Committed: Sun Apr 27 15:30:30 2014 +0200 ---------------------------------------------------------------------- .../internal/services/XMLTokenStream.java | 6 +- .../internal/services/XMLTokenStreamTests.java | 110 +++++++++++++++++++ 2 files changed, 114 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1a37c6ab/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/XMLTokenStream.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/XMLTokenStream.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/XMLTokenStream.java index 1fe5656..b80c6d6 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/XMLTokenStream.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/XMLTokenStream.java @@ -345,12 +345,14 @@ public class XMLTokenStream private InputStream openStream() throws IOException { InputStream rawStream = resource.openStream(); + + String transformationEncoding = "UTF8"; - InputStreamReader rawReader = new InputStreamReader(rawStream, "UTF8"); + InputStreamReader rawReader = new InputStreamReader(rawStream, transformationEncoding); LineNumberReader reader = new LineNumberReader(rawReader); ByteArrayOutputStream bos = new ByteArrayOutputStream(5000); - PrintWriter writer = new PrintWriter(bos); + PrintWriter writer = new PrintWriter(new OutputStreamWriter(bos, transformationEncoding)); State state = State.MAYBE_XML; http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1a37c6ab/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/XMLTokenStreamTests.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/XMLTokenStreamTests.java b/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/XMLTokenStreamTests.java new file mode 100644 index 0000000..e80ad06 --- /dev/null +++ b/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/XMLTokenStreamTests.java @@ -0,0 +1,110 @@ +package org.apache.tapestry5.internal.services; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.net.URL; +import java.nio.charset.Charset; +import java.util.HashMap; + +import org.apache.tapestry5.internal.services.XMLTokenStream; +import org.apache.tapestry5.internal.services.XMLTokenType; +import org.apache.tapestry5.ioc.MappedConfiguration; +import org.apache.tapestry5.ioc.Resource; +import org.apache.tapestry5.ioc.internal.util.AbstractResource; +import org.testng.Assert; +import org.testng.annotations.Test; + + +public class XMLTokenStreamTests +{ + private static class MappedConfigurationStub<K,V> extends HashMap<K, V> implements MappedConfiguration<K, V> + { + public void add(K key, V value) + { + put(key,value); + } + public void override(K key, V value) + { + put(key,value); + } + public void addInstance(K key, Class<? extends V> clazz) + { + throw new UnsupportedOperationException(); + } + public void overrideInstance(K key, Class<? extends V> clazz) + { + throw new UnsupportedOperationException(); + } + } + + + + private static class ResourceStub extends AbstractResource + { + final byte[] content; + public ResourceStub(byte[] content) + { + super(""); + this.content=content; + } + public URL toURL() + { + return null; + } + protected Resource newResource(String path) + { + return null; + } + @Override + public InputStream openStream() throws IOException + { + return new ByteArrayInputStream(content); + } + } + + protected void resetDefaultCharset() throws Exception + { + // The charset is cached after system start - so we ned to clear that cache to force a certain file.encoding + Field field=Charset.class.getDeclaredField("defaultCharset"); + field.setAccessible(true); + field.set(null, null); + } + + /** + * This test sets the system's default encoding to cp1252 (as on german windows) and tries to parse a non-ascii xml file + * with XMLTokenStream. This is to test a critical section within XMLTokenStream.openStream() where the + * binary file is converted to charcters and back before it is parsed. + * @throws Exception + */ + @Test + public void testStreamEncoding() throws Exception + { + String oldEncoding=System.getProperty("file.encoding"); + System.setProperty("file.encoding","cp1252"); + resetDefaultCharset(); + try + { + MappedConfigurationStub<String, URL> parserUrlMap=new MappedConfigurationStub<String, URL>(); + + String unicodeString="\u00FC"; + + String testDocument="<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>"+unicodeString+"</root>\n"; + XMLTokenStream xts=new XMLTokenStream(new ResourceStub(testDocument.getBytes("utf-8")),parserUrlMap); + xts.parse(); + Assert.assertEquals(xts.next(), XMLTokenType.START_ELEMENT); + Assert.assertEquals(xts.getLocalName(), "root"); + Assert.assertEquals(xts.next(), XMLTokenType.CHARACTERS); + Assert.assertEquals(xts.getText(), unicodeString); + Assert.assertEquals(xts.next(), XMLTokenType.END_ELEMENT); + Assert.assertEquals(xts.next(), XMLTokenType.END_DOCUMENT); + } + finally + { + System.setProperty("file.encoding", oldEncoding); + resetDefaultCharset(); + } + } + +}