[kaffe] RandomAccessFile causes StackOverflowError
Ito Kazumitsu
ito.kazumitsu at hitachi-cable.co.jp
Thu Apr 3 05:35:01 PST 2003
In message "Re: [kaffe] RandomAccessFile causes StackOverflowError"
on 03/04/02, Dalibor Topic <robilad at yahoo.com> writes:
> I've attached some hand written tests as a start. They
> have both discovered new bugs.
Copying your test programs, I wrote two programs which checkes
circular relations between read(byte[]) and read(byte[], int, int)
and between write(byte[]) and write(byte[], int, int).
The results are shown below. What differs between kaffe
and Sun's JDK is the resuls of FileInputStream and
FileOutputStream: kaffe fails and JDK does not. But as
for other classes, both kaffe and JDK fail.
IMHO, Sun's read(byte[]) and write(byte[]) in InputStream
and OutputStream seem to be a simple call to read(byte[], int, int)
and write(byte[], int, int), which is the same with kaffe
and GNU classpath.
So, as for circular relations between read(byte[]) and
read(byte[], int, int) and between write(byte[]) and
write(byte[], int, int), patches are needed only for
FileInputStream and FileOutputStream, I think.
Results and Test Programs.
read(byte[]) and read(byte[], int, int)
kaffe:
class java.io.BufferedInputStream
Failed
class java.io.ByteArrayInputStream
Failed
class java.io.DataInputStream
class java.io.FilterInputStream
Failed
class java.io.FileInputStream
Failed
class java.io.PushbackInputStream
Failed
class java.io.LineNumberInputStream
Failed
J2SDK 1.4.1_02:
class java.io.BufferedInputStream
Failed
class java.io.ByteArrayInputStream
Failed
class java.io.DataInputStream
class java.io.FilterInputStream
Failed
class java.io.FileInputStream
class java.io.PushbackInputStream
Failed
class java.io.LineNumberInputStream
Failed
between write(byte[]) and write(byte[], int, int)
kaffe:
class java.io.BufferedOutputStream
Failed
class java.io.ByteArrayOutputStream
Failed
class java.io.DataOutputStream
class java.io.FilterOutputStream
Failed
class java.io.FileOutputStream
Failed
class java.io.RandomAccessFile
J2SDK 1.4.1_02:
class java.io.BufferedOutputStream
Failed
class java.io.ByteArrayOutputStream
Failed
class java.io.DataOutputStream
class java.io.FilterOutputStream
Failed
class java.io.FileOutputStream
class java.io.RandomAccessFile
bash$ cat CircularDelegation3.java
/* This class tests if circular read delegation leads to stack overflows
*
* Author: Dalibor Topic <robilad at yahoo.com>
*
* Based on a test case from Ito Kasumitsu.
*/
import java.io.*;
class ZeroInputStream extends InputStream {
public int read() throws IOException {
return 0;
}
}
public class CircularDelegation3 {
private static final ZeroInputStream ZERO_STREAM = new ZeroInputStream();
private static FileInputStream fis;
static {
try {
fis = new FileInputStream("0.csv")
{
public int read(byte [] buf, int off, int len) throws IOException {
byte[] buf1 = new byte[1]; int l = super.read(buf1);
if (l <= 0) return l;
buf[off] = buf1[0]; return 1;
}
};
}
catch (Exception e) {}
}
private static final InputStream [] ISTREAMS = {
new BufferedInputStream(ZERO_STREAM)
{
public int read(byte [] buf, int off, int len) throws IOException {
byte[] buf1 = new byte[1]; int l = super.read(buf1);
if (l <= 0) return l;
buf[off] = buf1[0]; return 1;
}
},
new ByteArrayInputStream(new byte[1024])
{
public int read(byte [] buf, int off, int len) {
byte[] buf1 = new byte[1];
try {
int l = super.read(buf1);
if (l <= 0) return l;
buf[off] = buf1[0]; return 1;
}
catch (Exception e) {
return -1;
}
}
},
new DataInputStream(ZERO_STREAM)
{
},
new FilterInputStream(ZERO_STREAM)
{
public int read(byte [] buf, int off, int len) throws IOException {
byte[] buf1 = new byte[1]; int l = super.read(buf1);
if (l <= 0) return l;
buf[off] = buf1[0]; return 1;
}
},
fis,
new PushbackInputStream(ZERO_STREAM)
{
public int read(byte [] buf, int off, int len) throws IOException {
byte[] buf1 = new byte[1]; int l = super.read(buf1);
if (l <= 0) return l;
buf[off] = buf1[0]; return 1;
}
},
new LineNumberInputStream(ZERO_STREAM)
{
public int read(byte [] buf, int off, int len) throws IOException {
byte[] buf1 = new byte[1]; int l = super.read(buf1);
if (l <= 0) return l;
buf[off] = buf1[0]; return 1;
}
},
};
public static void main(String [] args) {
for (int i = 0 ; i < ISTREAMS.length; ++i) {
InputStream istream = ISTREAMS[i];
System.out.println(istream.getClass().getSuperclass());
try {
istream.read(new byte[1]);
}
catch (IOException e) {
e.printStackTrace();
}
catch (StackOverflowError e) {
System.out.println("Failed");
}
}
}
}
bash$ cat CircularDelegation4.java
/* This class tests if circular read delegation leads to stack overflows
*
* Author: Dalibor Topic <robilad at yahoo.com>
*
* Based on a test case from Ito Kasumitsu.
*/
import java.io.*;
class ZeroOutputStream extends OutputStream {
public void write(int b) throws IOException {
return;
}
}
public class CircularDelegation4 {
private static final ZeroOutputStream ZERO_STREAM = new ZeroOutputStream();
private static FileOutputStream fos;
private static RandomAccessFile raf;
static {
try {
fos = new FileOutputStream("0")
{
public void write(byte [] buf, int off, int len) throws IOException {
byte[] buf1 = new byte[buf.length];
System.arraycopy(buf, 0, buf1, 0, buf1.length);
super.write(buf1);
}
};
raf = new RandomAccessFile("0","rw")
{
public void write(byte [] buf, int off, int len) throws IOException {
byte[] buf1 = new byte[buf.length];
System.arraycopy(buf, 0, buf1, 0, buf1.length);
super.write(buf1);
}
};
}
catch (Exception e) {}
}
private static final OutputStream [] OSTREAMS = {
new BufferedOutputStream(ZERO_STREAM)
{
public void write(byte [] buf, int off, int len) throws IOException {
byte[] buf1 = new byte[buf.length];
System.arraycopy(buf, 0, buf1, 0, buf1.length);
super.write(buf1);
}
},
new ByteArrayOutputStream(1024)
{
public void write(byte [] buf, int off, int len) {
byte[] buf1 = new byte[buf.length];
System.arraycopy(buf, 0, buf1, 0, buf1.length);
try {
super.write(buf1);
}
catch (Exception e) {}
}
},
new DataOutputStream(ZERO_STREAM)
{
},
new FilterOutputStream(ZERO_STREAM)
{
public void write(byte [] buf, int off, int len) throws IOException {
byte[] buf1 = new byte[buf.length];
System.arraycopy(buf, 0, buf1, 0, buf1.length);
super.write(buf1);
}
},
fos
};
public static void main(String [] args) {
for (int i = 0 ; i < OSTREAMS.length; ++i) {
OutputStream ostream = OSTREAMS[i];
System.out.println(ostream.getClass().getSuperclass());
try {
byte[] bytes = {'A'};
ostream.write(bytes);
}
catch (IOException e) {
e.printStackTrace();
}
catch (StackOverflowError e) {
System.out.println("Failed");
}
}
System.out.println(raf.getClass().getSuperclass());
try {
byte[] bytes = {'A'};
raf.write(bytes);
}
catch (IOException e) {
e.printStackTrace();
}
catch (StackOverflowError e) {
System.out.println("Failed");
}
}
}
bash$
More information about the kaffe
mailing list