JavaCC breakage under Kaffe 1.0.5 / down?

Frohwalt Egerer froh at
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 - 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

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 website seems to
be broken, links leading nowhere.


////////// gets a core dump from Kaffe 1.0.5


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

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


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 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:");
        // 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:");


More information about the kaffe mailing list