Skip to content

Commit c287170

Browse files
author
Brian Burkhalter
committed
8254742: InputStream::readNBytes(int) result may contain zeros not in input
Reviewed-by: shade, bchristi
1 parent 7dcaba6 commit c287170

File tree

2 files changed

+42
-4
lines changed

2 files changed

+42
-4
lines changed

src/java.base/share/classes/java/io/InputStream.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1994, 2020, 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
@@ -416,6 +416,9 @@ public byte[] readNBytes(int len) throws IOException {
416416
if (MAX_BUFFER_SIZE - total < nread) {
417417
throw new OutOfMemoryError("Required array size too large");
418418
}
419+
if (nread < buf.length) {
420+
buf = Arrays.copyOfRange(buf, 0, nread);
421+
}
419422
total += nread;
420423
if (result == null) {
421424
result = buf;

test/jdk/java/io/InputStream/ReadNBytes.java

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2020, 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,7 +31,7 @@
3131

3232
/*
3333
* @test
34-
* @bug 8080835 8139206
34+
* @bug 8080835 8139206 8254742
3535
* @library /test/lib
3636
* @build jdk.test.lib.RandomFactory
3737
* @run main ReadNBytes
@@ -44,6 +44,7 @@ public class ReadNBytes {
4444
private static Random generator = RandomFactory.getRandom();
4545

4646
public static void main(String[] args) throws IOException {
47+
test();
4748
test(new byte[]{1, 2, 3});
4849
test(createRandomBytes(1024));
4950
for (int shift : new int[] {13, 15, 17}) {
@@ -135,6 +136,19 @@ static void test(int max) throws IOException {
135136
check(!in.isClosed(), "Stream unexpectedly closed");
136137
}
137138

139+
static void test() throws IOException {
140+
final int chunkSize = 8192;
141+
int size = (10 + generator.nextInt(11))*chunkSize;
142+
143+
byte[] buf = new byte[size];
144+
generator.nextBytes(buf);
145+
InputStream s = new ThrottledByteArrayInputStream(buf);
146+
147+
byte[] b = s.readNBytes(size);
148+
149+
check(Arrays.equals(b, buf), "Arrays not equal");
150+
}
151+
138152
static byte[] createRandomBytes(int size) {
139153
byte[] bytes = new byte[size];
140154
generator.nextBytes(bytes);
@@ -150,11 +164,32 @@ static void check(boolean cond, Object ... failedArgs) {
150164
throw new RuntimeException(sb.toString());
151165
}
152166

153-
154167
static class WrapperInputStream extends FilterInputStream {
155168
private boolean closed;
156169
WrapperInputStream(InputStream in) { super(in); }
157170
@Override public void close() throws IOException { closed = true; in.close(); }
158171
boolean isClosed() { return closed; }
159172
}
173+
174+
static class ThrottledByteArrayInputStream extends ByteArrayInputStream {
175+
private int count = 0;
176+
177+
ThrottledByteArrayInputStream(byte[] buf) {
178+
super(buf);
179+
}
180+
181+
@Override
182+
//
183+
// Sometimes return zero or a smaller count than requested.
184+
//
185+
public int read(byte[] buf, int off, int len) {
186+
if (generator.nextBoolean()) {
187+
return 0;
188+
} else if (++count / 3 == 0) {
189+
len /= 3;
190+
}
191+
192+
return super.read(buf, off, len);
193+
}
194+
}
160195
}

0 commit comments

Comments
 (0)