UnsupportedEncodingException when opening an ISO-8859-1 XML stream with Turkish as the default locale (closes
Perform locale independent upper case conversions.
To handle properly lower cased character encoding name in XML prolog
with any default system locale, notably Turkish.
MODIFY
src/main/java/org/apache/commons/io/ByteOrderMark.java
src/main/java/org/apache/commons/io/ByteOrderMark.java
package org.apache.commons.io;
import java.io.Serializable;
+import java.util.Locale;
/**
* Byte Order Mark (BOM) representation - see {@link org.apache.commons.io.input.BOMInputStream}.
@@ -182,7 +183,7 @@ public String toString() {
builder.append(",");
}
builder.append("0x");
- builder.append(Integer.toHexString(0xFF & bytes[i]).toUpperCase());
+ builder.append(Integer.toHexString(0xFF & bytes[i]).toUpperCase(Locale.ROOT));
}
builder.append(']');
return builder.toString();

MODIFY
src/main/java/org/apache/commons/io/input/XmlStreamReader.java
src/main/java/org/apache/commons/io/input/XmlStreamReader.java
@@ -683,7 +683,7 @@ static String getContentTypeEncoding(final String httpContentType) {
final String postMime = httpContentType.substring(i + 1);
final Matcher m = CHARSET_PATTERN.matcher(postMime);
encoding = m.find() ? m.group(1) : null;
- encoding = encoding != null ? encoding.toUpperCase(Locale.US) : null;
+ encoding = encoding != null ? encoding.toUpperCase(Locale.ROOT) : null;
}
}
return encoding;
@@ -741,7 +741,7 @@ private static String getXmlProlog(final InputStream is, final String guessedEnc
}
final Matcher m = ENCODING_PATTERN.matcher(prolog);
if (m.find()) {
- encoding = m.group(1).toUpperCase();
+ encoding = m.group(1).toUpperCase(Locale.ROOT);
encoding = encoding.substring(1, encoding.length() - 1);
}
}

MODIFY
src/main/java/org/apache/commons/io/output/XmlStreamWriter.java
src/main/java/org/apache/commons/io/output/XmlStreamWriter.java
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
+import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -168,7 +169,7 @@ private void detectEncoding(final char[] cbuf, final int off, final int len)
final Matcher m = ENCODING_PATTERN.matcher(xmlProlog.substring(0,
xmlPrologEnd));
if (m.find()) {
- encoding = m.group(1).toUpperCase();
+ encoding = m.group(1).toUpperCase(Locale.ROOT);
encoding = encoding.substring(1, encoding.length() - 1);
} else {
// no encoding found in XML prolog: using default

MODIFY
src/test/java/org/apache/commons/io/input/XmlStreamReaderTest.java
src/test/java/org/apache/commons/io/input/XmlStreamReaderTest.java
@@ -277,6 +277,25 @@ public void testHttp() throws Exception {
_testHttpLenient("text/html;charset=UTF-32BE", "no-bom", "US-ASCII", "UTF-8", "UTF-8");
}
+ /**
+ * Check lower case encoding names are properly handled. Should be successfull
+ * with any system default locale, notably with Turkish language
+ * (-Duser.language=tr JVM parameter), which has specific rules to convert dotted and dottless
+ * i character.
+ */
+ @Test
+ public void testLowerCaseEncoding() throws Exception {
+ final String[] encodings = { "iso8859-1", "us-ascii", "utf-8" };
+ for (final String encoding : encodings) {
+ final String xml = getXML("no-bom", XML3, encoding, encoding);
+ try (final ByteArrayInputStream is = new ByteArrayInputStream(xml.getBytes(encoding));
+ final XmlStreamReader xmlReader = new XmlStreamReader(is);) {
+ assertTrue("Check encoding : " + encoding, encoding.equalsIgnoreCase(xmlReader.getEncoding()));
+ assertEquals("Check content", xml, IOUtils.toString(xmlReader));
+ }
+ }
+ }
+
@Test
public void testRawContent() throws Exception {
final String encoding = "UTF-8";

MODIFY
src/test/java/org/apache/commons/io/input/compatibility/XmlStreamReader.java
src/test/java/org/apache/commons/io/input/compatibility/XmlStreamReader.java
import java.net.URL;
import java.net.URLConnection;
import java.text.MessageFormat;
+import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -590,7 +591,7 @@ static String getContentTypeEncoding(final String httpContentType) {
final String postMime = httpContentType.substring(i + 1);
final Matcher m = CHARSET_PATTERN.matcher(postMime);
encoding = m.find() ? m.group(1) : null;
- encoding = encoding != null ? encoding.toUpperCase() : null;
+ encoding = encoding != null ? encoding.toUpperCase(Locale.ROOT) : null;
}
}
return encoding;
@@ -699,7 +700,7 @@ private static String getXmlProlog(final BufferedInputStream is, final String gu
}
final Matcher m = ENCODING_PATTERN.matcher(prolog);
if (m.find()) {
- encoding = m.group(1).toUpperCase();
+ encoding = m.group(1).toUpperCase(Locale.ROOT);
encoding = encoding.substring(1, encoding.length() - 1);
}
}

MODIFY
src/test/java/org/apache/commons/io/output/XmlStreamWriterTest.java
src/test/java/org/apache/commons/io/output/XmlStreamWriterTest.java
*/
package org.apache.commons.io.output;
-import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayOutputStream;
@@ -56,7 +55,7 @@ private static void checkXmlContent(final String xml, final String encoding, fin
writer.write(xml);
writer.close();
final byte[] xmlContent = out.toByteArray();
- assertEquals(encoding, writer.getEncoding());
+ assertTrue(encoding.equalsIgnoreCase(writer.getEncoding()));
assertTrue(Arrays.equals(xml.getBytes(encoding), xmlContent));
}
@@ -103,6 +102,19 @@ public void testDefaultEncoding() throws IOException {
checkXmlWriter(TEXT_UNICODE, null, "ISO-8859-1");
}
+ /**
+ * Check lower case encoding names are properly handled. Should be successfull
+ * with any system default locale, notably with Turkish language
+ * (-Duser.language=tr JVM parameter), which has specific rules to convert
+ * dotted and dottless i character.
+ */
+ @Test
+ public void testLowerCaseEncoding() throws IOException {
+ checkXmlWriter(TEXT_UNICODE, "utf-8");
+ checkXmlWriter(TEXT_LATIN1, "iso-8859-1");
+ checkXmlWriter(TEXT_LATIN7, "iso-8859-7");
+ }
+
@Test
public void testUTF8Encoding() throws IOException {
checkXmlWriter(TEXT_UNICODE, "UTF-8");

IO-557: UnsupportedEncodingException when opening an ISO-8859-1 XML stream with Turkish as the default locale (closes #51)

Perform locale independent upper case conversions.

To handle properly lower cased character encoding name in XML prolog
with any default system locale, notably Turkish.