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:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
168
test/jdk/java/io/InputStream/NullInputStream.java
Normal file
168
test/jdk/java/io/InputStream/NullInputStream.java
Normal 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)));
|
||||
}
|
||||
}
|
||||
275
test/jdk/java/io/InputStream/OpsAfterClose.java
Normal file
275
test/jdk/java/io/InputStream/OpsAfterClose.java
Normal 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;
|
||||
}
|
||||
}
|
||||
100
test/jdk/java/io/InputStream/ReadAllBytes.java
Normal file
100
test/jdk/java/io/InputStream/ReadAllBytes.java
Normal 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; }
|
||||
}
|
||||
}
|
||||
195
test/jdk/java/io/InputStream/ReadNBytes.java
Normal file
195
test/jdk/java/io/InputStream/ReadNBytes.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
231
test/jdk/java/io/InputStream/ReadParams.java
Normal file
231
test/jdk/java/io/InputStream/ReadParams.java
Normal 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; }
|
||||
}
|
||||
228
test/jdk/java/io/InputStream/Skip.java
Normal file
228
test/jdk/java/io/InputStream/Skip.java
Normal 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
|
||||
}
|
||||
}
|
||||
327
test/jdk/java/io/InputStream/TransferTo.java
Normal file
327
test/jdk/java/io/InputStream/TransferTo.java
Normal 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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue