[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