Hi

I am sorry, I am asking something not really related to tomcat here.
While this may sound like a beginners question, I think I really what I am
doing in java, but this time I suspect I have found a scenario where the
sun/oracle VM exposes a bug with pure String handling.

So anyone who can find a bug in the procedure posted below is very welcome.
So is everyone who can direct me to some place better suited to ask this
question.

Finding bugs in a static method that only takes immutable arguments usually
seems easy... Turns out, it is not.

However, please note that I already tried to debug this in various ways and
the exception does NOT occur, as soon as a debugger is attached. The
exception is only thrown under 64bit Linux Server-VM, within tomcat. It is
neither thrown under 64bit Windows, nor on the very same Linux VM as
standalone testcase, nor when a debugger is remotely attached. The JREs
testest are 1.6u20 and 1.6u21.

The code in question is the following:


        @SuppressWarnings( "null" )
        public final static String replaceAll( String stack, String ...
replacements )
        {
                try {
                        if ( stack == null )
                                return stack;
                        int index, pos;
                        String niddle = null, string;
                        int niddleLength, stringLength;
                        for ( index = 0; true; index += 2 ) {
                                if ( index >= replacements.length )
                                        return stack;
                                niddle = replacements[ index ];
                                pos = stack.indexOf( niddle );
                                if ( pos != - 1 )
                                        break;
                        }
                        StringBuilder buffer = new StringBuilder( stack );
                        niddleLength = niddle.length();
                        string = replacements[ index + 1 ];
                        if ( string == null )
                                do
                                        buffer.delete( pos, pos +
niddleLength );
                                while ( ( pos = buffer.indexOf( niddle, pos
) ) != - 1 );
                        else {
                                stringLength = string.length();
                                do {
/*331*/                         buffer.replace( pos, pos + niddleLength,
string );
                                        pos += stringLength;
                                } while ( ( pos = buffer.indexOf( niddle,
pos ) ) != - 1 );
                        }
                        index += 2;
                        for ( ; index < replacements.length; index += 2 ) {
                                niddle = replacements[ index ];
                                string = replacements[ index + 1 ];
                                niddleLength = niddle.length();
                                if ( string == null )
                                        for ( pos = 0; ( pos =
buffer.indexOf( niddle, pos ) ) != - 1; )
                                                buffer.delete( pos, pos +
niddleLength );
                                else {
                                        stringLength = string.length();
                                        for ( pos = 0; ( pos =
buffer.indexOf( niddle, pos ) ) != - 1; pos += stringLength )
                                                buffer.replace( pos, pos +
niddleLength, string );
                                }
                        }
                        return buffer.toString();
                } catch ( Throwable t ) {
.... (code to dump the arguments and the stack trace) ...
                }
        }


Note, that when the method is called, there are two arguments: one String
and a String[] with a length of 1004 Strings.... (I guarantee that this
String array is NOT modified during execution, not even afterwards.)
The execption is (it is thrown indirectly in the marked line 331):

java.lang.StringIndexOutOfBoundsException: start > length()
        at
java.lang.AbstractStringBuilder.replace(AbstractStringBuilder.java:799)
        at java.lang.StringBuilder.replace(StringBuilder.java:271)
        at
com.osiris4.core.utils.StringUtils.replaceAll(StringUtils.java:331)
        ....


I can provide real arguments that lead to this exception, however, as there
are more than 1000 Strings (partially large ones) involved, I will skip them
here.
Anyone interested will get them by mail. I have various samples.


Currently this prevents loading my web application in about one of three
times. (And it also happens during internal computations which prevents
further work.) Sometimes this error can be "reproduced" (by restarting
tomcat) 10 times in a row, sometimes it does not occur within 20 restarts at
all. (Without changing anything in the systems configuration.)


Sorry again, for asking off-topic, but I don't know where to ask for help
anymore.

Regards,
  Steffen

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to