Skip to content

Commit 8b7c042

Browse files
author
Datadog Syncup Service
committed
Merge branch 'upstream-master'
2 parents 84ef4e1 + 95fe05a commit 8b7c042

File tree

4 files changed

+190
-17
lines changed

4 files changed

+190
-17
lines changed

src/java.base/share/classes/sun/nio/cs/StreamEncoder.java

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,8 @@ void implFlush() throws IOException {
322322
}
323323

324324
void implClose() throws IOException {
325-
flushLeftoverChar(null, true);
326-
try {
325+
try (ch; out) {
326+
flushLeftoverChar(null, true);
327327
for (;;) {
328328
CoderResult cr = encoder.flush(bb);
329329
if (cr.isUnderflow())
@@ -338,15 +338,8 @@ void implClose() throws IOException {
338338

339339
if (bb.position() > 0)
340340
writeBytes();
341-
if (ch != null)
342-
ch.close();
343-
else {
344-
try {
345-
out.flush();
346-
} finally {
347-
out.close();
348-
}
349-
}
341+
if (out != null)
342+
out.flush();
350343
} catch (IOException x) {
351344
encoder.reset();
352345
throw x;
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/* @test
25+
* @bug 8136895
26+
* @summary Verify stream closed after write error in StreamEncoder::implClose
27+
*/
28+
29+
import java.io.IOException;
30+
import java.io.OutputStream;
31+
import java.io.OutputStreamWriter;
32+
import java.io.Writer;
33+
import java.nio.charset.MalformedInputException;
34+
import java.nio.charset.StandardCharsets;
35+
36+
public class CloseWriterOnFailedFlush {
37+
private static final String STR_IOE = "Test"; // IOException
38+
private static final String STR_MIE = "\ud83c"; // MalformedInputException
39+
40+
public static void main(String[] args) throws IOException {
41+
boolean failed = false;
42+
43+
for (String s : new String[] {STR_IOE, STR_MIE}) {
44+
System.out.println("string: " + s);
45+
ErroringOutputStream stream = new ErroringOutputStream();
46+
try (Writer writer = new OutputStreamWriter(stream,
47+
StandardCharsets.UTF_8.newEncoder())) {
48+
writer.write(s);
49+
} catch (IOException ex) {
50+
Class exClass = ex.getClass();
51+
if (s.equals(STR_IOE) && exClass != IOException.class ||
52+
s.equals(STR_MIE) && exClass != MalformedInputException.class)
53+
throw ex;
54+
}
55+
56+
if (stream.isOpen()) {
57+
System.err.println("Stream is STILL open");
58+
failed = true;
59+
} else {
60+
System.out.println("Stream is closed");
61+
}
62+
}
63+
64+
if (failed)
65+
throw new RuntimeException("Test failed");
66+
}
67+
68+
private static class ErroringOutputStream extends OutputStream {
69+
private boolean open = true;
70+
71+
@Override
72+
public void write(int b) throws IOException {
73+
throw new IOException();
74+
}
75+
76+
public boolean isOpen() {
77+
return open;
78+
}
79+
80+
@Override
81+
public void close() throws IOException {
82+
open = false;
83+
System.out.println("Closing");
84+
}
85+
}
86+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/* @test
25+
* @bug 8136895
26+
* @summary Verify channel closed after write error in StreamEncoder::implClose
27+
*/
28+
29+
import java.io.IOException;
30+
import java.io.Writer;
31+
import java.nio.ByteBuffer;
32+
import java.nio.channels.Channels;
33+
import java.nio.channels.WritableByteChannel;
34+
import java.nio.charset.MalformedInputException;
35+
import java.nio.charset.StandardCharsets;
36+
37+
public class CloseWriterOnFailedFlush {
38+
private static final String STR_IOE = "Test"; // IOException
39+
private static final String STR_MIE = "\ud83c"; // MalformedInputException
40+
41+
public static void main(String[] args) throws IOException {
42+
boolean failed = false;
43+
44+
for (String s : new String[] {STR_IOE, STR_MIE}) {
45+
System.out.println("string: " + s);
46+
ErroringByteChannel channel = new ErroringByteChannel();
47+
try (Writer writer = Channels.newWriter
48+
(channel, StandardCharsets.UTF_8.newEncoder(), -1 )) {
49+
writer.write(s);
50+
} catch (IOException ex) {
51+
Class exClass = ex.getClass();
52+
if (s.equals(STR_IOE) && exClass != IOException.class ||
53+
s.equals(STR_MIE) && exClass != MalformedInputException.class)
54+
throw ex;
55+
}
56+
57+
if (channel.isOpen()) {
58+
System.err.println("Channel is STILL open");
59+
failed = true;
60+
} else {
61+
System.out.println("Channel is closed");
62+
}
63+
}
64+
65+
if (failed)
66+
throw new RuntimeException("Test failed");
67+
}
68+
69+
private static class ErroringByteChannel implements WritableByteChannel {
70+
private boolean open = true;
71+
72+
@Override
73+
public int write(ByteBuffer src) throws IOException {
74+
throw new IOException();
75+
}
76+
77+
@Override
78+
public boolean isOpen() {
79+
return open;
80+
}
81+
82+
@Override
83+
public void close() {
84+
open = false;
85+
System.out.println("Closing");
86+
}
87+
}
88+
}

test/jdk/sun/nio/cs/StreamEncoderClose.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,15 @@
3131

3232
import java.io.*;
3333
public class StreamEncoderClose {
34+
private static void ck(String s, int actual, int expected)
35+
throws IOException {
36+
if (actual != expected) {
37+
String msg = String.format("%s: actual (%d) != expected (%d)%n",
38+
s, actual, expected);
39+
throw new IOException(msg);
40+
}
41+
}
42+
3443
public static void main( String arg[] ) throws Exception {
3544
byte[] expected = {(byte)0x1b,(byte)0x24,(byte)0x42,
3645
(byte)0x30,(byte)0x6c,
@@ -46,13 +55,10 @@ public static void main( String arg[] ) throws Exception {
4655

4756
//double check, probably not necessary
4857
byte[] out = baos.toByteArray();
49-
if (out.length != expected.length) {
50-
throw new IOException("Failed");
51-
}
58+
ck("Lengths are unequal", out.length, expected.length);
5259
for (int i = 0; i < out.length; i++) {
5360
//System.out.printf("(byte)0x%x,", out[i] & 0xff);
54-
if (out[i] != expected[i])
55-
throw new IOException("Failed");
61+
ck("Values are unequal", out[i], expected[i]);
5662
}
5763
}
5864

0 commit comments

Comments
 (0)