Bug 37803 - MessageBytes makes it easy to have state problems
Summary: MessageBytes makes it easy to have state problems
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 5
Classification: Unclassified
Component: Unknown (show other bugs)
Version: 5.5.9
Hardware: Other other
: P3 normal (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-12-06 00:07 UTC by Doug Rand
Modified: 2005-12-06 02:27 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Doug Rand 2005-12-06 00:07:54 UTC
I spent awhile analyzing why our application was having a problem. We have an
unusual case - a product that was its own web server adapted to live under
JBoss/Tomcat. Now that we're running under Tomcat I decided that some new
browser UI should use JSF, but after I was running with JSF I started having
occasional problems with exceptions.

After tracking this down I finally understood the problem. We are probably (I'll
be tracking this down next) accessing an HttpServletRequest outside of the
standard loop that the dispatcher puts it through. I will grant a priori that
this is invalid and we shouldn't be doing so. 

However, the underlying issue is that methods in the request object end up
calling MessageBytes.toString. Our particular case calls the getScheme() method.
This wouldn't be a problem, but after recycle is called, the MessageBytes object
is "null". But if you call toString(), it returns false from isNull, and that
*is* a problem. My broken app should not be able to put this underlying data
structure into an invalid state by calling a getter. 

As a result of no longer being "null" from the isNull perspective, the
dispatcher no longer sets the scheme on the new request, which breaks the next
request that uses that request object.

I'd suggest two changes:

1) recycle the request right before use to limit the extent of the threading window
2) fix the toString method to not change the object's state for the null case

For #2, something like this might suffice, and is much safer than the current code:

    public String toString() {
	if( hasStrValue ) return strValue;

	switch (type) {
	case T_CHARS:
	    hasStrValue=true;
	    strValue=charC.toString();
	    return strValue;
	case T_BYTES:
            hasStrValue=true;
	    strValue=byteC.toString();
	    return strValue;
	}
	return null;
    }
Comment 1 william.barker 2005-12-06 04:20:58 UTC
I disagree.  Tomcat should be more robust than to allow a rogue webapp to 
place it into an inconsistant state.
Comment 2 william.barker 2005-12-06 04:25:56 UTC
I've committed a slightly modified version of your patch to SVN trunk.  
Hopefully it will make the cutoff to be included in 5.5.14.
Comment 3 Remy Maucherat 2005-12-06 11:00:21 UTC
(In reply to comment #1)
> I disagree.  Tomcat should be more robust than to allow a rogue webapp to 
> place it into an inconsistant state.

Oh cool :) Whatever you want Bill. Yet another patch which will not be in my
tree, I suppose.
Comment 4 Remy Maucherat 2005-12-06 11:27:38 UTC
(In reply to comment #3)
> Oh cool :) Whatever you want Bill. Yet another patch which will not be in my
> tree, I suppose.

After reviewing it, I'm actually taking in the patch, since it's a decent cleanup.

(In reply to comment #1)
> I disagree.  Tomcat should be more robust than to allow a rogue webapp to 
> place it into an inconsistant state.

There's a mode like that, and it happens using the security manager. This bug
report is actually a user list question.