JavaCC breakage under Kaffe 1.0.5 / kaffe.org down?

Frohwalt Egerer froh at iconsult.com
Sat Nov 6 08:03:26 PST 1999



[I'm just guessing the correct mail adress for the list, since the
 welcome message says it is kaffe at transvirtual.com - which bounces]


Hello everybody,

  trying to port some application to Kaffe I found at least two bugs
in Kaffe. The first bug are missing sanity checks in File*Stream
read/write, a Java application can pass bogus parameters to the
File*Stream and thus create a buffer overflow in the native code. I've
added an example program below to show this problem.

The other bug is the ByteToCharConverter and CharToByteConverter
holding internal state and thus not being thread safe. When two
strings are .getByteArray()'ed simultaneously, String.getBytes() uses
a CharToByteConverter which can mix up both strings. You can see this
effect when running JavaCC - or the second sample program I've added
below.

I'm currently considering to fix these bugs myself, provided nobody
else is working in these areas. What do people - and especially
Transvirtual, who market a non-GPL'ed version of Kaffe - think about
adding code from Classpath. I've downloaded Classpath yesterday night
and judging from only my first glimpse it has got a better
implementation of these converters.

By the way, I've added the bugs I mentioned to the Kaffe Bug Database
yesterday, but since that single moment the kaffe.org website seems to
be broken, links leading nowhere.

Froh




////////// crash1.java gets a core dump from Kaffe 1.0.5

import java.io.*;

public class crash1
{
    public static void main(String[] args)
        throws Exception
    {
        FileInputStream fis = new FileInputStream("/dev/zero");
        fis.read(new byte[0], 0, 10*1024*1024);
        System.err.println("We are dead by now.");
    }
}



////////// crash2.java simulates two threads calling String.getBytes() concurrently.

import java.io.*;
import kaffe.io.*;

public class crash2
{
    public static void main(String[] args)
        throws Exception
    {
        // We do not use threads in this example, but we imagine we did.
        //
        //
        // This is kaffe String's getBytes() routine:
        //
        // ByteArrayOutputStream out = new ByteArrayOutputStream( value.length);
        // 
        // byte[] buf = new byte[512];
        // int buflen = encoding.convert( value, offset, count, buf, 0, buf.length);
        // while (buflen > 0) {
        //         out.write(buf, 0, buflen);
        //         buflen = encoding.flush(buf, 0, buf.length);
        // }
        // 
        // return (out.toByteArray());
        //
        //
        // We now play a scenario that might happen with two threads:

        char[] a = new char[700];
        char[] b = new char[700];
        for (int i=0; i<700; i++)
        {
            a[i]='a';
            b[i]='b';
        }

        // a and b represent two String Objects A and B each 700 characters long.

        // We create two threads each wanting to getBytes() on one of these Strings.

        // Thread one starts and operates on a.
        CharToByteConverter encoding_a = CharToByteConverter.getDefault();
        byte[] buf_a = new byte[512];
        ByteArrayOutputStream out_a = new ByteArrayOutputStream(a.length);
        int buflen_a = encoding_a.convert(a, 0, 700, buf_a, 0, buf_a.length);
        
        // But behold! We got some preemption, Thread two is running now ...
        
        CharToByteConverter encoding_b = CharToByteConverter.getDefault();
        byte[] buf_b = new byte[512];
        ByteArrayOutputStream out_b = new ByteArrayOutputStream(b.length);
        int buflen_b = encoding_b.convert(b, 0, 700, buf_b, 0, buf_b.length);

        while (buflen_b > 0) {
                 out_b.write(buf_b, 0, buflen_b);
                 buflen_b = encoding_b.flush(buf_b, 0, buf_b.length);
        }

        System.err.println("B's output:");
        System.err.write(out_b.toByteArray());
        System.err.println("\n\n");
        
        // B is done, Thread A resumes ...

        while (buflen_a > 0) {
                 out_a.write(buf_a, 0, buflen_a);
                 buflen_a = encoding_a.flush(buf_a, 0, buf_a.length);
        }

        System.err.println("A's output:");
        System.err.write(out_a.toByteArray());
        System.err.println("\n\n");
    }

}


More information about the kaffe mailing list