This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-io.git
commit f3823cb310c3409c87d6f4979f616c8650381766 Author: Gary Gregory <garydgreg...@gmail.com> AuthorDate: Tue Jan 11 09:22:27 2022 -0500 WriterOutputStream maps null Charset, Charset name, and CharsetEncoder name to the platform default instead of throwing a NullPointerException. --- src/changes/changes.xml | 5 +- .../commons/io/output/WriterOutputStream.java | 19 ++++---- .../commons/io/output/WriterOutputStreamTest.java | 53 +++++++++++++++++++++- 3 files changed, 67 insertions(+), 10 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 151b755..0720199 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -127,11 +127,14 @@ The <action> type attribute can be add,update,fix,remove. When deleting symlinks, File/PathUtils.deleteDirectory() changes file permissions of the target. </action> <action dev="ggregory" type="fix" due-to="Gary Gregory"> - ReaderInputStream maps null Charset, Charset name, and CharsetEmcoder to the platform default instead of throwing a NullPointerException. + ReaderInputStream maps null Charset, Charset name, and CharsetEncoder to the platform default instead of throwing a NullPointerException. </action> <action dev="ggregory" type="fix" due-to="Gary Gregory"> CharSequenceInputStream maps null Charset and Charset name to the platform default instead of throwing a NullPointerException. </action> + <action dev="ggregory" type="fix" due-to="Gary Gregory"> + WriterOutputStream maps null Charset, Charset name, and CharsetEncoder name to the platform default instead of throwing a NullPointerException. + </action> <!-- ADD --> <action issue="IO-726" dev="ggregory" type="fix" due-to="shollander, Gary Gregory"> Add MemoryMappedFileInputStream #215. diff --git a/src/main/java/org/apache/commons/io/output/WriterOutputStream.java b/src/main/java/org/apache/commons/io/output/WriterOutputStream.java index ae6d1a5..b5d6f46 100644 --- a/src/main/java/org/apache/commons/io/output/WriterOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/WriterOutputStream.java @@ -26,6 +26,9 @@ import java.nio.charset.CharsetDecoder; import java.nio.charset.CoderResult; import java.nio.charset.CodingErrorAction; +import org.apache.commons.io.Charsets; +import org.apache.commons.io.charset.CharsetDecoders; + /** * {@link OutputStream} implementation that transforms a byte stream to a * character stream using a specified charset encoding and writes the resulting @@ -164,15 +167,16 @@ public class WriterOutputStream extends OutputStream { * output buffer will only be flushed when it overflows or when * {@link #flush()} or {@link #close()} is called. */ - public WriterOutputStream(final Writer writer, final Charset charset, final int bufferSize, - final boolean writeImmediately) { + public WriterOutputStream(final Writer writer, final Charset charset, final int bufferSize, final boolean writeImmediately) { + // @formatter:off this(writer, - charset.newDecoder() + Charsets.toCharset(charset).newDecoder() .onMalformedInput(CodingErrorAction.REPLACE) .onUnmappableCharacter(CodingErrorAction.REPLACE) .replaceWith("?"), bufferSize, writeImmediately); + // @formatter:on } /** @@ -201,11 +205,10 @@ public class WriterOutputStream extends OutputStream { * {@link #flush()} or {@link #close()} is called. * @since 2.1 */ - public WriterOutputStream(final Writer writer, final CharsetDecoder decoder, final int bufferSize, - final boolean writeImmediately) { - checkIbmJdkWithBrokenUTF16( decoder.charset()); + public WriterOutputStream(final Writer writer, final CharsetDecoder decoder, final int bufferSize, final boolean writeImmediately) { + checkIbmJdkWithBrokenUTF16(CharsetDecoders.toCharsetDecoder(decoder).charset()); this.writer = writer; - this.decoder = decoder; + this.decoder = CharsetDecoders.toCharsetDecoder(decoder); this.writeImmediately = writeImmediately; decoderOut = CharBuffer.allocate(bufferSize); } @@ -236,7 +239,7 @@ public class WriterOutputStream extends OutputStream { */ public WriterOutputStream(final Writer writer, final String charsetName, final int bufferSize, final boolean writeImmediately) { - this(writer, Charset.forName(charsetName), bufferSize, writeImmediately); + this(writer, Charsets.toCharset(charsetName), bufferSize, writeImmediately); } /** diff --git a/src/test/java/org/apache/commons/io/output/WriterOutputStreamTest.java b/src/test/java/org/apache/commons/io/output/WriterOutputStreamTest.java index 61da71c..50c840d 100644 --- a/src/test/java/org/apache/commons/io/output/WriterOutputStreamTest.java +++ b/src/test/java/org/apache/commons/io/output/WriterOutputStreamTest.java @@ -21,9 +21,13 @@ import static org.junit.jupiter.api.Assertions.fail; import java.io.IOException; import java.io.StringWriter; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; import java.nio.charset.StandardCharsets; import java.util.Random; +import org.apache.commons.io.Charsets; +import org.apache.commons.io.charset.CharsetDecoders; import org.junit.jupiter.api.Test; public class WriterOutputStreamTest { @@ -52,6 +56,16 @@ public class WriterOutputStreamTest { } @Test + public void testLargeUTF8CharsetWithBufferedWrite() throws IOException { + testWithBufferedWrite(LARGE_TEST_STRING, "UTF-8"); + } + + @Test + public void testLargeUTF8CharsetWithSingleByteWrite() throws IOException { + testWithSingleByteWrite(LARGE_TEST_STRING, StandardCharsets.UTF_8); + } + + @Test public void testLargeUTF8WithBufferedWrite() throws IOException { testWithBufferedWrite(LARGE_TEST_STRING, "UTF-8"); } @@ -62,6 +76,21 @@ public class WriterOutputStreamTest { } @Test + public void testNullCharsetNameWithSingleByteWrite() throws IOException { + testWithSingleByteWrite(TEST_STRING, (String) null); + } + + @Test + public void testNullCharsetWithSingleByteWrite() throws IOException { + testWithSingleByteWrite(TEST_STRING, (Charset) null); + } + + @Test + public void testNullCharsetDecoderWithSingleByteWrite() throws IOException { + testWithSingleByteWrite(TEST_STRING, (CharsetDecoder) null); + } + + @Test public void testUTF16BEWithBufferedWrite() throws IOException { testWithBufferedWrite(TEST_STRING, "UTF-16BE"); } @@ -128,8 +157,30 @@ public class WriterOutputStreamTest { } + private void testWithSingleByteWrite(final String testString, final Charset charset) throws IOException { + final byte[] bytes = testString.getBytes(Charsets.toCharset(charset)); + final StringWriter writer = new StringWriter(); + try (final WriterOutputStream out = new WriterOutputStream(writer, charset)) { + for (final byte b : bytes) { + out.write(b); + } + } + assertEquals(testString, writer.toString()); + } + + private void testWithSingleByteWrite(final String testString, final CharsetDecoder charsetDecoder) throws IOException { + final byte[] bytes = testString.getBytes(CharsetDecoders.toCharsetDecoder(charsetDecoder).charset()); + final StringWriter writer = new StringWriter(); + try (final WriterOutputStream out = new WriterOutputStream(writer, charsetDecoder)) { + for (final byte b : bytes) { + out.write(b); + } + } + assertEquals(testString, writer.toString()); + } + private void testWithSingleByteWrite(final String testString, final String charsetName) throws IOException { - final byte[] bytes = testString.getBytes(charsetName); + final byte[] bytes = testString.getBytes(Charsets.toCharset(charsetName)); final StringWriter writer = new StringWriter(); try (final WriterOutputStream out = new WriterOutputStream(writer, charsetName)) { for (final byte b : bytes) {