Skip to content

Commit f3823cb

Browse files
committed
WriterOutputStream maps null Charset, Charset name, and CharsetEncoder
name to the platform default instead of throwing a NullPointerException.
1 parent da09365 commit f3823cb

3 files changed

Lines changed: 67 additions & 10 deletions

File tree

src/changes/changes.xml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,14 @@ The <action> type attribute can be add,update,fix,remove.
127127
When deleting symlinks, File/PathUtils.deleteDirectory() changes file permissions of the target.
128128
</action>
129129
<action dev="ggregory" type="fix" due-to="Gary Gregory">
130-
ReaderInputStream maps null Charset, Charset name, and CharsetEmcoder to the platform default instead of throwing a NullPointerException.
130+
ReaderInputStream maps null Charset, Charset name, and CharsetEncoder to the platform default instead of throwing a NullPointerException.
131131
</action>
132132
<action dev="ggregory" type="fix" due-to="Gary Gregory">
133133
CharSequenceInputStream maps null Charset and Charset name to the platform default instead of throwing a NullPointerException.
134134
</action>
135+
<action dev="ggregory" type="fix" due-to="Gary Gregory">
136+
WriterOutputStream maps null Charset, Charset name, and CharsetEncoder name to the platform default instead of throwing a NullPointerException.
137+
</action>
135138
<!-- ADD -->
136139
<action issue="IO-726" dev="ggregory" type="fix" due-to="shollander, Gary Gregory">
137140
Add MemoryMappedFileInputStream #215.

src/main/java/org/apache/commons/io/output/WriterOutputStream.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
import java.nio.charset.CoderResult;
2727
import java.nio.charset.CodingErrorAction;
2828

29+
import org.apache.commons.io.Charsets;
30+
import org.apache.commons.io.charset.CharsetDecoders;
31+
2932
/**
3033
* {@link OutputStream} implementation that transforms a byte stream to a
3134
* character stream using a specified charset encoding and writes the resulting
@@ -164,15 +167,16 @@ public WriterOutputStream(final Writer writer, final Charset charset) {
164167
* output buffer will only be flushed when it overflows or when
165168
* {@link #flush()} or {@link #close()} is called.
166169
*/
167-
public WriterOutputStream(final Writer writer, final Charset charset, final int bufferSize,
168-
final boolean writeImmediately) {
170+
public WriterOutputStream(final Writer writer, final Charset charset, final int bufferSize, final boolean writeImmediately) {
171+
// @formatter:off
169172
this(writer,
170-
charset.newDecoder()
173+
Charsets.toCharset(charset).newDecoder()
171174
.onMalformedInput(CodingErrorAction.REPLACE)
172175
.onUnmappableCharacter(CodingErrorAction.REPLACE)
173176
.replaceWith("?"),
174177
bufferSize,
175178
writeImmediately);
179+
// @formatter:on
176180
}
177181

178182
/**
@@ -201,11 +205,10 @@ public WriterOutputStream(final Writer writer, final CharsetDecoder decoder) {
201205
* {@link #flush()} or {@link #close()} is called.
202206
* @since 2.1
203207
*/
204-
public WriterOutputStream(final Writer writer, final CharsetDecoder decoder, final int bufferSize,
205-
final boolean writeImmediately) {
206-
checkIbmJdkWithBrokenUTF16( decoder.charset());
208+
public WriterOutputStream(final Writer writer, final CharsetDecoder decoder, final int bufferSize, final boolean writeImmediately) {
209+
checkIbmJdkWithBrokenUTF16(CharsetDecoders.toCharsetDecoder(decoder).charset());
207210
this.writer = writer;
208-
this.decoder = decoder;
211+
this.decoder = CharsetDecoders.toCharsetDecoder(decoder);
209212
this.writeImmediately = writeImmediately;
210213
decoderOut = CharBuffer.allocate(bufferSize);
211214
}
@@ -236,7 +239,7 @@ public WriterOutputStream(final Writer writer, final String charsetName) {
236239
*/
237240
public WriterOutputStream(final Writer writer, final String charsetName, final int bufferSize,
238241
final boolean writeImmediately) {
239-
this(writer, Charset.forName(charsetName), bufferSize, writeImmediately);
242+
this(writer, Charsets.toCharset(charsetName), bufferSize, writeImmediately);
240243
}
241244

242245
/**

src/test/java/org/apache/commons/io/output/WriterOutputStreamTest.java

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,13 @@
2121

2222
import java.io.IOException;
2323
import java.io.StringWriter;
24+
import java.nio.charset.Charset;
25+
import java.nio.charset.CharsetDecoder;
2426
import java.nio.charset.StandardCharsets;
2527
import java.util.Random;
2628

29+
import org.apache.commons.io.Charsets;
30+
import org.apache.commons.io.charset.CharsetDecoders;
2731
import org.junit.jupiter.api.Test;
2832

2933
public class WriterOutputStreamTest {
@@ -51,6 +55,16 @@ public void testFlush() throws IOException {
5155
}
5256
}
5357

58+
@Test
59+
public void testLargeUTF8CharsetWithBufferedWrite() throws IOException {
60+
testWithBufferedWrite(LARGE_TEST_STRING, "UTF-8");
61+
}
62+
63+
@Test
64+
public void testLargeUTF8CharsetWithSingleByteWrite() throws IOException {
65+
testWithSingleByteWrite(LARGE_TEST_STRING, StandardCharsets.UTF_8);
66+
}
67+
5468
@Test
5569
public void testLargeUTF8WithBufferedWrite() throws IOException {
5670
testWithBufferedWrite(LARGE_TEST_STRING, "UTF-8");
@@ -61,6 +75,21 @@ public void testLargeUTF8WithSingleByteWrite() throws IOException {
6175
testWithSingleByteWrite(LARGE_TEST_STRING, "UTF-8");
6276
}
6377

78+
@Test
79+
public void testNullCharsetNameWithSingleByteWrite() throws IOException {
80+
testWithSingleByteWrite(TEST_STRING, (String) null);
81+
}
82+
83+
@Test
84+
public void testNullCharsetWithSingleByteWrite() throws IOException {
85+
testWithSingleByteWrite(TEST_STRING, (Charset) null);
86+
}
87+
88+
@Test
89+
public void testNullCharsetDecoderWithSingleByteWrite() throws IOException {
90+
testWithSingleByteWrite(TEST_STRING, (CharsetDecoder) null);
91+
}
92+
6493
@Test
6594
public void testUTF16BEWithBufferedWrite() throws IOException {
6695
testWithBufferedWrite(TEST_STRING, "UTF-16BE");
@@ -128,8 +157,30 @@ private void testWithBufferedWrite(final String testString, final String charset
128157
}
129158

130159

160+
private void testWithSingleByteWrite(final String testString, final Charset charset) throws IOException {
161+
final byte[] bytes = testString.getBytes(Charsets.toCharset(charset));
162+
final StringWriter writer = new StringWriter();
163+
try (final WriterOutputStream out = new WriterOutputStream(writer, charset)) {
164+
for (final byte b : bytes) {
165+
out.write(b);
166+
}
167+
}
168+
assertEquals(testString, writer.toString());
169+
}
170+
171+
private void testWithSingleByteWrite(final String testString, final CharsetDecoder charsetDecoder) throws IOException {
172+
final byte[] bytes = testString.getBytes(CharsetDecoders.toCharsetDecoder(charsetDecoder).charset());
173+
final StringWriter writer = new StringWriter();
174+
try (final WriterOutputStream out = new WriterOutputStream(writer, charsetDecoder)) {
175+
for (final byte b : bytes) {
176+
out.write(b);
177+
}
178+
}
179+
assertEquals(testString, writer.toString());
180+
}
181+
131182
private void testWithSingleByteWrite(final String testString, final String charsetName) throws IOException {
132-
final byte[] bytes = testString.getBytes(charsetName);
183+
final byte[] bytes = testString.getBytes(Charsets.toCharset(charsetName));
133184
final StringWriter writer = new StringWriter();
134185
try (final WriterOutputStream out = new WriterOutputStream(writer, charsetName)) {
135186
for (final byte b : bytes) {

0 commit comments

Comments
 (0)