undefect. CWE-407 — 63 sites patched across 27 ecosystems

Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
This commit is contained in:
russell@unturf.com 2026-03-26 17:11:57 -04:00
commit 0a580b313d
70422 changed files with 17213626 additions and 0 deletions

View file

@ -0,0 +1,168 @@
/*
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
/*
* @test
* @bug 4358774 6516099 8139206
* @run junit NullInputStream
* @summary Check for expected behavior of InputStream.nullInputStream().
*/
public class NullInputStream {
private static InputStream openStream;
private static InputStream closedStream;
@BeforeAll
public static void setup() {
openStream = InputStream.nullInputStream();
closedStream = InputStream.nullInputStream();
assertDoesNotThrow(() -> closedStream.close());
}
@AfterAll
public static void closeStream() {
assertDoesNotThrow(() -> openStream.close());
}
@Test
public void testOpen() {
assertNotNull(openStream, "InputStream.nullInputStream() returned null");
}
@Test
public void testAvailable() throws IOException {
assertEquals(0, openStream.available());
}
@Test
public void testRead() throws IOException {
assertEquals(-1, openStream.read());
}
@Test
public void testReadBII() throws IOException {
assertEquals(-1, openStream.read(new byte[1], 0, 1));
}
@Test
public void testReadAllBytes() throws IOException {
assertEquals(0, openStream.readAllBytes().length);
}
@Test
public void testReadNBytes() throws IOException {
assertEquals(0, openStream.readNBytes(new byte[1], 0, 1));
}
@Test
public void testReadNBytesWithLength() throws IOException {
assertThrows(IllegalArgumentException.class,
() -> openStream.readNBytes(-1));
assertEquals(0, openStream.readNBytes(0).length);
assertEquals(0, openStream.readNBytes(1).length);
}
@Test
public void testSkip() throws IOException {
assertEquals(0L, openStream.skip(1));
}
@Test
public void testSkipNBytes() {
assertDoesNotThrow(() -> {
openStream.skipNBytes(-1);
openStream.skipNBytes(0);
});
}
@Test
public void testSkipNBytesEOF() throws IOException {
assertThrows(EOFException.class, () -> openStream.skipNBytes(1));
}
@Test
public void testTransferTo() throws IOException {
assertEquals(0L, openStream.transferTo(new ByteArrayOutputStream(7)));
}
@Test
public void testAvailableClosed() {
assertThrows(IOException.class, () -> closedStream.available());
}
@Test
public void testReadClosed() {
assertThrows(IOException.class, () -> closedStream.read());
}
@Test
public void testReadBIIClosed() {
assertThrows(IOException.class,
() -> closedStream.read(new byte[1], 0, 1));
}
@Test
public void testReadAllBytesClosed() {
assertThrows(IOException.class, () -> closedStream.readAllBytes());
}
@Test
public void testReadNBytesClosed() {
assertThrows(IOException.class, () ->
closedStream.readNBytes(new byte[1], 0, 1));
}
@Test
public void testReadNBytesWithLengthClosed() {
assertThrows(IOException.class, () -> closedStream.readNBytes(1));
}
@Test
public void testSkipClosed() {
assertThrows(IOException.class, () -> closedStream.skip(1));
}
@Test
public void testSkipNBytesClosed() {
assertThrows(IOException.class, () -> closedStream.skipNBytes(1));
}
@Test
public void testTransferToClosed() {
assertThrows(IOException.class,
() -> closedStream.transferTo(new ByteArrayOutputStream(7)));
}
}

View file

@ -0,0 +1,275 @@
/*
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 4181483
* @summary Test if InputStream methods will check if the stream
* has been closed.
*/
import java.io.*;
public enum OpsAfterClose {
READ { boolean check(InputStream is) {
try {
int read = is.read();
System.out.println("read returns: " + read);
} catch (IOException io) {
System.out.print("Excep Msg: "+ io.getMessage() + ", ");
return true;
}
return false;
} },
READ_BUF { boolean check(InputStream is) {
try {
byte buf[] = new byte[2];
int read = is.read(buf);
System.out.println("read(buf) returns: " + read);
} catch (IOException io) {
System.out.print("Excep Msg: "+ io.getMessage() + ", ");
return true;
}
return false;
} },
READ_BUF_OFF { boolean check(InputStream is) {
try {
byte buf[] = new byte[2];
int len = 1;
int read = is.read(buf, 0, len);
System.out.println("read(buf, 0, len) returns: " + read);
} catch (IOException io) {
System.out.print("Excep Msg: "+ io.getMessage() + ", ");
return true;
}
return false;
} },
AVAILABLE { boolean check(InputStream is) {
try {
int avail = is.available();
System.out.println("available() returns: " + avail);
return false;
} catch (IOException io) {
System.out.print("Excep Msg: "+ io.getMessage() + ", ");
return true;
}
} },
SKIP { boolean check(InputStream is) {
try {
long skipped = is.skip(1);
System.out.println("skip() returns: " + skipped);
} catch (IOException io) {
System.out.print("Excep Msg: "+ io.getMessage() + ", ");
return true;
}
return false;
} },
MARK { boolean check(InputStream is) {
is.mark(20);
return true;
} },
RESET { boolean check(InputStream is) {
try {
is.reset();
} catch (IOException io) {
System.out.print("Excep Msg: "+ io.getMessage() + ", ");
return true;
}
return false;
} },
MARK_SUPPORTED { boolean check(InputStream is) {
is.markSupported();
return true;
} },
CLOSE { boolean check(InputStream is) {
try {
is.close();
return true; // No Exception thrown on windows for FileInputStream
} catch (IOException io) {
System.out.print("Excep Msg: "+ io.getMessage() + ", ");
return true; // Exception thrown on solaris and linux for FileInputStream
}
} };
abstract boolean check(InputStream is);
public static void main(String args[]) throws Exception {
boolean failed = false;
File f = new File(System.getProperty("test.dir", "."),
"f.txt");
f.createNewFile();
f.deleteOnExit();
FileInputStream fis = new FileInputStream(f);
try {
if (testInputStream(fis)) {
failed = true;
}
if (testFileInputStream(fis)) {
failed = true;
}
} finally {
fis.close();
}
BufferedInputStream bs = new BufferedInputStream(
new FileInputStream(f));
try {
if (testInputStream(bs)) {
failed = true;
}
} finally {
bs.close();
}
DataInputStream dis = new DataInputStream(
new FileInputStream(f));
try {
if (testInputStream(dis)) {
failed = true;
}
} finally {
dis.close();
}
PushbackInputStream pbis = new PushbackInputStream(
new ByteArrayInputStream(new byte[20]));
if (testInputStream(pbis)) {
failed = true;
}
if (testPushbackInputStream(pbis)) {
failed = true;
}
PipedInputStream pis = new PipedInputStream(new PipedOutputStream());
if (testInputStream(pis)) {
failed = true;
}
/**
* The SequenceInputStream and ObjectInputStream does not throw IOException
SequenceInputStream sqis = new SequenceInputStream(
new FileInputStream(f),
new PipedInputStream(new PipedOutputStream())
);
if (testInputStream(sqis)) {
failed = true;
}
String serStr = "abc";
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream(f));
oos.writeObject(serStr);
oos.close();
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream(f));
if (testInputStream(ois)) {
failed = true;
}
*/
if (failed) {
throw new Exception(
"Some Op for some Stream failed, check the failed status above");
}
}
private static boolean testInputStream(InputStream is)
throws Exception {
is.close();
boolean failed = false;
boolean result;
System.out.println("Testing :" + is);
for (OpsAfterClose op : OpsAfterClose.values()) {
if (op.equals(AVAILABLE) && (is instanceof PipedInputStream)) {
// skip the test as available() returns 0
continue;
}
result = op.check(is);
if (!result) {
failed = true;
}
System.out.println(op + ":" + result);
}
if (failed) {
System.out.println("Test failed for the failed operation{s}" +
" above for :" + is);
}
return failed;
}
private static boolean testPushbackInputStream(PushbackInputStream pis)
throws Exception {
boolean failed = false;
try {
pis.unread(1);
System.out.println("Test failed for unread(int):" + pis);
failed = true;
} catch (IOException io) {
System.out.println("UNREAD(int):true");
}
byte buf[] = new byte[2];
try {
pis.unread(buf, 0, 2);
System.out.println("Test failed for unread(buf, offset, len):" +
pis);
failed = true;
} catch (IOException io) {
System.out.println("UNREAD(buf, offset, len):true");
}
try {
pis.unread(buf);
System.out.println("Test failed for unread(char[] buf):" + pis);
failed = true;
} catch (IOException io) {
System.out.println("UNREAD(buf):true");
}
return failed;
}
private static boolean testFileInputStream(FileInputStream fis)
throws Exception {
boolean failed = false;
try {
fis.getFD();
System.out.println("GetFD: true");
} catch (IOException io) {
System.out.println("GetFD: false");
failed = true;
}
fis.getChannel();
System.out.println("GetChannel: true");
return failed;
}
}

View file

@ -0,0 +1,100 @@
/*
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.ByteArrayInputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Random;
import jdk.test.lib.RandomFactory;
/*
* @test
* @bug 8080835 8193832
* @library /test/lib
* @build jdk.test.lib.RandomFactory
* @run main ReadAllBytes
* @summary Basic test for InputStream.readAllBytes
* @key randomness
*/
public class ReadAllBytes {
private static Random generator = RandomFactory.getRandom();
public static void main(String[] args) throws IOException {
test(new byte[]{});
test(new byte[]{1, 2, 3});
test(createRandomBytes(1024));
for (int shift : new int[] {13, 14, 15, 17}) {
for (int offset : new int[] {-1, 0, 1}) {
test(createRandomBytes((1 << shift) + offset));
}
}
}
static void test(byte[] expectedBytes) throws IOException {
int expectedLength = expectedBytes.length;
WrapperInputStream in = new WrapperInputStream(new ByteArrayInputStream(expectedBytes));
byte[] readBytes = in.readAllBytes();
int x;
byte[] tmp = new byte[10];
check((x = in.read()) == -1,
"Expected end of stream from read(), got " + x);
check((x = in.read(tmp)) == -1,
"Expected end of stream from read(byte[]), got " + x);
check((x = in.read(tmp, 0, tmp.length)) == -1,
"Expected end of stream from read(byte[], int, int), got " + x);
check(in.readAllBytes().length == 0,
"Expected readAllBytes to return empty byte array");
check(expectedLength == readBytes.length,
"Expected length " + expectedLength + ", got " + readBytes.length);
check(Arrays.equals(expectedBytes, readBytes),
"Expected[" + expectedBytes + "], got:[" + readBytes + "]");
check(!in.isClosed(), "Stream unexpectedly closed");
}
static byte[] createRandomBytes(int size) {
byte[] bytes = new byte[size];
generator.nextBytes(bytes);
return bytes;
}
static void check(boolean cond, Object ... failedArgs) {
if (cond)
return;
StringBuilder sb = new StringBuilder();
for (Object o : failedArgs)
sb.append(o);
throw new RuntimeException(sb.toString());
}
static class WrapperInputStream extends FilterInputStream {
private boolean closed;
WrapperInputStream(InputStream in) { super(in); }
@Override public void close() throws IOException { closed = true; in.close(); }
boolean isClosed() { return closed; }
}
}

View file

@ -0,0 +1,195 @@
/*
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.ByteArrayInputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Random;
import jdk.test.lib.RandomFactory;
/*
* @test
* @bug 8080835 8139206 8254742
* @library /test/lib
* @build jdk.test.lib.RandomFactory
* @run main ReadNBytes
* @summary Basic test for InputStream.readNBytes
* @key randomness
*/
public class ReadNBytes {
private static Random generator = RandomFactory.getRandom();
public static void main(String[] args) throws IOException {
test();
test(new byte[]{1, 2, 3});
test(createRandomBytes(1024));
for (int shift : new int[] {13, 15, 17}) {
for (int offset : new int[] {-1, 0, 1}) {
test(createRandomBytes((1 << shift) + offset));
}
}
test(-1);
test(0);
for (int shift : new int[] {13, 15, 17}) {
for (int offset : new int[] {-1, 0, 1}) {
test((1 << shift) + offset);
}
}
}
static void test(byte[] inputBytes) throws IOException {
int length = inputBytes.length;
WrapperInputStream in = new WrapperInputStream(new ByteArrayInputStream(inputBytes));
byte[] readBytes = new byte[(length / 2) + 1];
int nread = in.readNBytes(readBytes, 0, readBytes.length);
int x;
byte[] tmp;
check(nread == readBytes.length,
"Expected number of bytes read: " + readBytes.length + ", got: " + nread);
check(Arrays.equals((tmp = Arrays.copyOf(inputBytes, nread)), readBytes),
"Expected[" + tmp + "], got:[" + readBytes + "]");
check(!in.isClosed(), "Stream unexpectedly closed");
// Read again
nread = in.readNBytes(readBytes, 0, readBytes.length);
check(nread == length - readBytes.length,
"Expected number of bytes read: " + (length - readBytes.length) + ", got: " + nread);
check(Arrays.equals((tmp = Arrays.copyOfRange(inputBytes, readBytes.length, length)),
Arrays.copyOf(readBytes, nread)),
"Expected[" + tmp + "], got:[" + readBytes + "]");
// Expect end of stream
check((x = in.read()) == -1,
"Expected end of stream from read(), got " + x);
check((x = in.read(tmp)) == -1,
"Expected end of stream from read(byte[]), got " + x);
check((x = in.read(tmp, 0, tmp.length)) == -1,
"Expected end of stream from read(byte[], int, int), got " + x);
check((x = in.readNBytes(tmp, 0, tmp.length)) == 0,
"Expected end of stream, 0, from readNBytes(byte[], int, int), got " + x);
check(!in.isClosed(), "Stream unexpectedly closed");
}
static void test(int max) throws IOException {
byte[] inputBytes = max <= 0 ? new byte[0] : createRandomBytes(max);
WrapperInputStream in =
new WrapperInputStream(new ByteArrayInputStream(inputBytes));
if (max < 0) {
try {
in.readNBytes(max);
check(false, "Expected IllegalArgumentException not thrown");
} catch (IllegalArgumentException iae) {
return;
}
} else if (max == 0) {
int x;
check((x = in.readNBytes(max).length) == 0,
"Expected zero bytes, got " + x);
return;
}
int off = Math.toIntExact(in.skip(generator.nextInt(max/2)));
int len = generator.nextInt(max - 1 - off);
byte[] readBytes = in.readNBytes(len);
check(readBytes.length == len,
"Expected " + len + " bytes, got " + readBytes.length);
check(Arrays.equals(inputBytes, off, off + len, readBytes, 0, len),
"Expected[" + Arrays.copyOfRange(inputBytes, off, off + len) +
"], got:[" + readBytes + "]");
int remaining = max - (off + len);
readBytes = in.readNBytes(remaining);
check(readBytes.length == remaining,
"Expected " + remaining + "bytes, got " + readBytes.length);
check(Arrays.equals(inputBytes, off + len, max,
readBytes, 0, remaining),
"Expected[" + Arrays.copyOfRange(inputBytes, off + len, max) +
"], got:[" + readBytes + "]");
check(!in.isClosed(), "Stream unexpectedly closed");
}
static void test() throws IOException {
final int chunkSize = 8192;
int size = (10 + generator.nextInt(11))*chunkSize;
byte[] buf = new byte[size];
generator.nextBytes(buf);
InputStream s = new ThrottledByteArrayInputStream(buf);
byte[] b = s.readNBytes(size);
check(Arrays.equals(b, buf), "Arrays not equal");
}
static byte[] createRandomBytes(int size) {
byte[] bytes = new byte[size];
generator.nextBytes(bytes);
return bytes;
}
static void check(boolean cond, Object ... failedArgs) {
if (cond)
return;
StringBuilder sb = new StringBuilder();
for (Object o : failedArgs)
sb.append(o);
throw new RuntimeException(sb.toString());
}
static class WrapperInputStream extends FilterInputStream {
private boolean closed;
WrapperInputStream(InputStream in) { super(in); }
@Override public void close() throws IOException { closed = true; in.close(); }
boolean isClosed() { return closed; }
}
static class ThrottledByteArrayInputStream extends ByteArrayInputStream {
private int count = 0;
ThrottledByteArrayInputStream(byte[] buf) {
super(buf);
}
@Override
//
// Sometimes return zero or a smaller count than requested.
//
public int read(byte[] buf, int off, int len) {
if (generator.nextBoolean()) {
return 0;
} else if (++count / 3 == 0) {
len /= 3;
}
return super.read(buf, off, len);
}
}
}

View file

@ -0,0 +1,231 @@
/*
* Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4008296 4008293 4190090 4193729 4358774
* @summary Check for correct handling of parameters to
* XXXXInputStream.read(b, off, len).
*
*/
import java.io.*;
import java.util.zip.ZipInputStream;
import java.util.zip.InflaterInputStream;
import java.util.zip.DeflaterOutputStream;
public class ReadParams {
/* check for correct handling of different values of off and len */
public static void doTest(InputStream in) throws Exception {
int off[] = {-1, -1, 0, 0, 33, 33, 0, 32, 32, 4, 1, 0, -1,
Integer.MAX_VALUE, 1, Integer.MIN_VALUE,
Integer.MIN_VALUE, 1};
int len[] = {-1, 0, -1, 33, 0, 4, 32, 0, 4, 16, 31, 0,
Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE,
1, -1, Integer.MIN_VALUE};
boolean results[] = { false, false, false, false, false, false,
true, true, false, true, true, true, false,
false, false, false, false, false};
int numCases = off.length;
byte b[] = new byte[32];
int numBad = 0;
for(int i = 0; i < numCases; i++) {
try {
in.read(b , off[i] , len[i]);
} catch (IndexOutOfBoundsException aiobe) {
if (results[i]) {
System.err.println("Error:IndexOutOfBoundsException thrown"+
" for read(b, " + off[i] + " " + len[i] +
" ) on " + in + "\nb.length = 32");
numBad++;
} else {
/* System.err.println("PassE: " + off[i] + " " + len[i]); */
}
continue;
} catch (OutOfMemoryError ome) {
System.err.println("Error: OutOfMemoryError in read(b, " +
off[i] + " " + len[i] + " ) on " + in +
"\nb.length = 32");
numBad++;
continue;
}
if (!results[i]) {
System.err.println("Error:No IndexOutOfBoundsException thrown"+
" for read(b, " + off[i] + " " + len[i] +
" ) on " + in + "\nb.length = 32");
numBad++;
} else {
/* System.err.println("Pass: " + off[i] + " " + len[i]); */
}
}
if (numBad > 0) {
throw new RuntimeException(in + " Failed " + numBad + " cases");
} else {
System.err.println("Successfully completed bounds tests on " + in);
}
}
/* check for correct handling of null b */
public static void doTest1(InputStream in) throws Exception {
byte b[] = null;
try {
in.read(b, 0, 32);
} catch (NullPointerException npe) {
System.err.println("SuccessFully completed null b test on " + in);
return;
}
throw new RuntimeException(in + " Failed null b test");
}
public static void main(String args[]) throws Exception{
/* initialise stuff */
File fn = new File("x.ReadBounds");
FileOutputStream fout = new FileOutputStream(fn);
for (int i = 0; i < 32; i++) {
fout.write(i);
}
fout.close();
byte b[] = new byte[64];
for(int i = 0; i < 64; i++) {
b[i] = 1;
}
/* test all input streams */
FileInputStream fis = new FileInputStream(fn);
doTest(fis);
doTest1(fis);
fis.close();
BufferedInputStream bis =
new BufferedInputStream(new MyInputStream(1024));
doTest(bis);
doTest1(bis);
bis.close();
ByteArrayInputStream bais = new ByteArrayInputStream(b);
doTest(bais);
doTest1(bais);
bais.close();
FileOutputStream fos = new FileOutputStream(fn);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeInt(12345);
oos.writeObject("Today");
oos.writeObject(new Integer(32));
oos.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fn));
doTest(ois);
doTest1(ois);
ois.close();
DataInputStream dis = new DataInputStream(new MyInputStream(1024));
doTest(dis);
doTest1(dis);
dis.close();
LineNumberInputStream lis =
new LineNumberInputStream(new MyInputStream(1024));
doTest(lis);
doTest1(lis);
lis.close();
PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream();
pos.connect(pis);
pos.write(b, 0, 64);
doTest(pis);
doTest1(pis);
pis.close();
PushbackInputStream pbis =
new PushbackInputStream(new MyInputStream(1024));
doTest(pbis);
doTest1(pbis);
pbis.close();
StringBufferInputStream sbis =
new StringBufferInputStream(new String(b));
doTest(sbis);
doTest1(sbis);
sbis.close();
SequenceInputStream sis =
new SequenceInputStream(new MyInputStream(1024),
new MyInputStream(1024));
doTest(sis);
doTest1(sis);
sis.close();
ZipInputStream zis = new ZipInputStream(new FileInputStream(fn));
doTest(zis);
doTest1(zis);
zis.close();
byte[] data = new byte[256];
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DeflaterOutputStream dos = new DeflaterOutputStream(bos);
dos.write(data, 0, data.length);
dos.close();
InflaterInputStream ifs = new InflaterInputStream
(new ByteArrayInputStream(bos.toByteArray()));
doTest(ifs);
doTest1(ifs);
ifs.close();
InputStream nis = InputStream.nullInputStream();
doTest(nis);
doTest1(nis);
nis.close();
/* cleanup */
fn.delete();
}
}
/* An InputStream class used in the above tests */
class MyInputStream extends InputStream {
private int readctr = 0;
private long endoffile;
public MyInputStream(long endoffile) {
this.endoffile = endoffile;
}
public int read() {
if (readctr == endoffile) {
return -1;
}
else {
readctr++;
return 0;
}
}
public int available() { return 0; }
}

View file

@ -0,0 +1,228 @@
/*
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 4016710 6516099
* @summary check for correct implementation of InputStream.skip{NBytes}
*/
import java.io.EOFException;
import java.io.InputStream;
import java.io.IOException;
public class Skip {
private static final int EOF = -1;
private static void dotest(InputStream in, int curpos, long total,
long toskip, long expected) throws Exception {
try {
System.err.println("\n\nCurrently at pos = " + curpos +
"\nTotal bytes in the Stream = " + total +
"\nNumber of bytes to skip = " + toskip +
"\nNumber of bytes that should be skipped = " +
expected);
long skipped = in.skip(toskip);
System.err.println("actual number skipped: "+ skipped);
if ((skipped < 0) || (skipped > expected)) {
throw new RuntimeException("Unexpected byte count skipped");
}
} catch (IOException e) {
System.err.println("IOException is thrown: " + e);
} catch (Throwable e) {
throw new RuntimeException("Unexpected " + e + " is thrown!");
}
}
private static void dotestExact(MyInputStream in, long curpos, long total,
long toskip, boolean expectIOE, boolean expectEOFE) {
System.err.println("\n\nCurrently at pos = " + curpos +
"\nTotal bytes in the Stream = " + total +
"\nNumber of bytes to skip = " + toskip);
try {
long pos = in.position();
assert pos == curpos : pos + " != " + curpos;
in.skipNBytes(toskip);
if (in.position() != pos + (toskip < 0 ? 0 : toskip)) {
throw new RuntimeException((in.position() - pos) +
" bytes skipped; expected " + toskip);
}
} catch (EOFException eofe) {
if (!expectEOFE) {
throw new RuntimeException("Unexpected EOFException", eofe);
}
System.err.println("Caught expected EOFException");
} catch (IOException ioe) {
if (!expectIOE) {
throw new RuntimeException("Unexpected IOException", ioe);
}
System.err.println("Caught expected IOException");
}
}
public static void main( String argv[] ) throws Exception {
MyInputStream in = new MyInputStream(11);
// test for negative skip
dotest(in, 0, 11, -23, 0);
// check for skip beyond EOF starting from before EOF
dotest(in, 0, 11, 20, 11);
// check for skip after EOF
dotest(in, EOF, 11, 20, 0);
in = new MyInputStream(9000);
// check for skip equal to the read chunk size in InputStream.java
dotest(in, 0, 9000, 2048, 2048);
// check for skip larger than the read chunk size in InputStream.java
dotest(in, 2048, 9000, 5000, 5000);
// check for skip beyond EOF starting from before EOF
dotest(in, 7048, 9000, 5000, 1952);
in = new MyInputStream(5000);
// check for multiple chunk reads
dotest(in, 0, 5000, 6000, 5000);
/*
* check for skip larger than Integer.MAX_VALUE
* (Takes about 2 hrs on a sparc ultra-1)
* long total = (long)Integer.MAX_VALUE + (long)10;
* long toskip = total - (long)6;
* in = new MyInputStream(total);
* dotest(in, 0, total, toskip, toskip);
*/
// tests for skipping an exact number of bytes
final long streamLength = Long.MAX_VALUE;
in = new MyInputStream(streamLength);
// negative skip: OK
dotestExact(in, 0, streamLength, -1, false, false);
// negative skip at EOF: OK
in.position(streamLength);
dotestExact(in, streamLength, streamLength, -1, false, false);
in.position(0);
// zero skip: OK
dotestExact(in, 0, streamLength, 0, false, false);
// zero skip at EOF: OK
in.position(streamLength);
dotestExact(in, streamLength, streamLength, 0, false, false);
// skip(1) at EOF: EOFE
dotestExact(in, streamLength, streamLength, 1, false, true);
in.position(0);
final long n = 31; // skip count
long pos = 0;
// skip(n) returns negative value: IOE
in.setState(-1, 100);
dotestExact(in, pos, streamLength, n, true, false);
// skip(n) returns n + 1: IOE
in.setState(n + 1, 100);
dotestExact(in, pos, streamLength, n, true, false);
pos += n + 1;
// skip(n) returns n/2 but only n/4 subsequent reads succeed: EOFE
in.setState(n/2, n/2 + n/4);
dotestExact(in, pos, streamLength, n, false, true);
pos += n/2 + n/4;
// skip(n) returns n/2 but n - n/2 subsequent reads succeed: OK
in.setState(n/2, n);
dotestExact(in, pos, streamLength, n, false, false);
pos += n;
}
}
class MyInputStream extends InputStream {
private static final int EOF = -1;
private final long endoffile;
private long readctr = 0;
private boolean isStateSet = false;
private long skipReturn;
private long readLimit;
public MyInputStream(long endoffile) {
this.endoffile = endoffile;
}
/**
* Limits the behavior of skip() and read().
*
* @param skipReturn the value to be returned by skip()
* @param maxReads the maximum number of reads past the current position
* before EOF is reached
*/
public void setState(long skipReturn, long maxReads) {
this.skipReturn = skipReturn;
this.readLimit = readctr + maxReads;
isStateSet = true;
}
public int read() {
if (readctr == endoffile ||
(isStateSet && readctr >= readLimit)) {
return EOF;
}
else {
readctr++;
return 0;
}
}
public int available() { return 0; }
public long position() { return readctr; }
public void position(long pos) {
readctr = pos < 0 ? 0 : Math.min(pos, endoffile);
}
public long skip(long n) throws IOException {
if (isStateSet) {
return skipReturn < 0 ? skipReturn : super.skip(skipReturn);
}
// InputStream skip implementation.
return super.skip(n); // readctr is implicitly incremented
}
}

View file

@ -0,0 +1,327 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.ByteArrayOutputStream;
import java.io.FilterInputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Random;
import static java.lang.String.format;
/*
* @test
* @bug 8066867
* @summary tests whether java.io.InputStream.transferTo conforms to its
* contract defined in the javadoc
* @key randomness
*/
public class TransferTo {
public static void main(String[] args) throws IOException {
ifOutIsNullThenNpeIsThrown();
ifExceptionInInputNeitherStreamIsClosed();
ifExceptionInOutputNeitherStreamIsClosed();
onReturnNeitherStreamIsClosed();
onReturnInputIsAtEnd();
contents();
}
private static void ifOutIsNullThenNpeIsThrown() throws IOException {
try (InputStream in = input()) {
assertThrowsNPE(() -> in.transferTo(null), "out");
}
try (InputStream in = input((byte) 1)) {
assertThrowsNPE(() -> in.transferTo(null), "out");
}
try (InputStream in = input((byte) 1, (byte) 2)) {
assertThrowsNPE(() -> in.transferTo(null), "out");
}
InputStream in = null;
try {
InputStream fin = in = new ThrowingInputStream();
// null check should precede everything else:
// InputStream shouldn't be touched if OutputStream is null
assertThrowsNPE(() -> fin.transferTo(null), "out");
} finally {
if (in != null)
try {
in.close();
} catch (IOException ignored) { }
}
}
private static void ifExceptionInInputNeitherStreamIsClosed()
throws IOException {
transferToThenCheckIfAnyClosed(input(0, new byte[]{1, 2, 3}), output());
transferToThenCheckIfAnyClosed(input(1, new byte[]{1, 2, 3}), output());
transferToThenCheckIfAnyClosed(input(2, new byte[]{1, 2, 3}), output());
}
private static void ifExceptionInOutputNeitherStreamIsClosed()
throws IOException {
transferToThenCheckIfAnyClosed(input(new byte[]{1, 2, 3}), output(0));
transferToThenCheckIfAnyClosed(input(new byte[]{1, 2, 3}), output(1));
transferToThenCheckIfAnyClosed(input(new byte[]{1, 2, 3}), output(2));
}
private static void transferToThenCheckIfAnyClosed(InputStream input,
OutputStream output)
throws IOException {
try (CloseLoggingInputStream in = new CloseLoggingInputStream(input);
CloseLoggingOutputStream out =
new CloseLoggingOutputStream(output)) {
boolean thrown = false;
try {
in.transferTo(out);
} catch (IOException ignored) {
thrown = true;
}
if (!thrown)
throw new AssertionError();
if (in.wasClosed() || out.wasClosed()) {
throw new AssertionError();
}
}
}
private static void onReturnNeitherStreamIsClosed()
throws IOException {
try (CloseLoggingInputStream in =
new CloseLoggingInputStream(input(new byte[]{1, 2, 3}));
CloseLoggingOutputStream out =
new CloseLoggingOutputStream(output())) {
in.transferTo(out);
if (in.wasClosed() || out.wasClosed()) {
throw new AssertionError();
}
}
}
private static void onReturnInputIsAtEnd() throws IOException {
try (InputStream in = input(new byte[]{1, 2, 3});
OutputStream out = output()) {
in.transferTo(out);
if (in.read() != -1) {
throw new AssertionError();
}
}
}
private static void contents() throws IOException {
checkTransferredContents(new byte[0]);
checkTransferredContents(createRandomBytes(1024, 4096));
// to span through several batches
checkTransferredContents(createRandomBytes(16384, 16384));
}
private static void checkTransferredContents(byte[] bytes)
throws IOException {
try (InputStream in = input(bytes);
ByteArrayOutputStream out = new ByteArrayOutputStream()) {
in.transferTo(out);
byte[] outBytes = out.toByteArray();
if (!Arrays.equals(bytes, outBytes)) {
throw new AssertionError(
format("bytes.length=%s, outBytes.length=%s",
bytes.length, outBytes.length));
}
}
}
private static byte[] createRandomBytes(int min, int maxRandomAdditive) {
Random rnd = new Random();
byte[] bytes = new byte[min + rnd.nextInt(maxRandomAdditive)];
rnd.nextBytes(bytes);
return bytes;
}
private static OutputStream output() {
return output(-1);
}
private static OutputStream output(int exceptionPosition) {
return new OutputStream() {
int pos;
@Override
public void write(int b) throws IOException {
if (pos++ == exceptionPosition)
throw new IOException();
}
};
}
private static InputStream input(byte... bytes) {
return input(-1, bytes);
}
private static InputStream input(int exceptionPosition, byte... bytes) {
return new InputStream() {
int pos;
@Override
public int read() throws IOException {
if (pos == exceptionPosition) {
// because of the pesky IOException swallowing in
// java.io.InputStream.read(byte[], int, int)
// pos++;
throw new IOException();
}
if (pos >= bytes.length)
return -1;
return bytes[pos++] & 0xff;
}
};
}
private static class ThrowingInputStream extends InputStream {
boolean closed;
@Override
public int read(byte[] b) throws IOException {
throw new IOException();
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
throw new IOException();
}
@Override
public long skip(long n) throws IOException {
throw new IOException();
}
@Override
public int available() throws IOException {
throw new IOException();
}
@Override
public void close() throws IOException {
if (!closed) {
closed = true;
throw new IOException();
}
}
@Override
public void reset() throws IOException {
throw new IOException();
}
@Override
public int read() throws IOException {
throw new IOException();
}
}
private static class CloseLoggingInputStream extends FilterInputStream {
boolean closed;
CloseLoggingInputStream(InputStream in) {
super(in);
}
@Override
public void close() throws IOException {
closed = true;
super.close();
}
boolean wasClosed() {
return closed;
}
}
private static class CloseLoggingOutputStream extends FilterOutputStream {
boolean closed;
CloseLoggingOutputStream(OutputStream out) {
super(out);
}
@Override
public void close() throws IOException {
closed = true;
super.close();
}
boolean wasClosed() {
return closed;
}
}
public interface Thrower {
public void run() throws Throwable;
}
public static void assertThrowsNPE(Thrower thrower, String message) {
assertThrows(thrower, NullPointerException.class, message);
}
public static <T extends Throwable> void assertThrows(Thrower thrower,
Class<T> throwable,
String message) {
Throwable thrown;
try {
thrower.run();
thrown = null;
} catch (Throwable caught) {
thrown = caught;
}
if (!throwable.isInstance(thrown)) {
String caught = thrown == null ?
"nothing" : thrown.getClass().getCanonicalName();
throw new AssertionError(
format("Expected to catch %s, but caught %s",
throwable, caught), thrown);
}
if (thrown != null && !message.equals(thrown.getMessage())) {
throw new AssertionError(
format("Expected exception message to be '%s', but it's '%s'",
message, thrown.getMessage()));
}
}
}