Buggy code:
public static final int SC_RESP_CONTENT_TYPE = 40961 ; public static final int SC_RESP_CONTENT_LANGUAGE = 40962 ; public static final int SC_RESP_CONTENT_LENGTH = 40963 ; public static final int SC_RESP_DATE = 40964 ; public static final int SC_RESP_LAST_MODIFIED = 40965 ; public static final int SC_RESP_LOCATION = 40966 ; public static final int SC_RESP_SET_COOKIE = 40967 ; public static final int SC_RESP_SET_COOKIE2 = 40968 ; public static final int SC_RESP_SERVLET_ENGINE = 40969 ; public static final int SC_RESP_STATUS = 40970 ; public static final int SC_RESP_WWW_AUTHENTICATE = 40971 ; public static final byte SC_A_CONTEXT = 1 ; public static final byte SC_A_SERVLET_PATH = 2 ; public static final byte SC_A_REMOTE_USER = 3 ; public static final byte SC_A_AUTH_TYPE = 4 ; public static final byte SC_A_QUERY_STRING = 5 ; public static final byte SC_A_JVM_ROUTE = 6 ; public static final byte SC_A_SSL_CERT = 7 ; public static final byte SC_A_SSL_CIPHER = 8 ; public static final byte SC_A_SSL_SESSION = 9 ; public static final byte SC_A_REQ_ATTRIBUTE = 10 ; public static final byte SC_A_ARE_DONE = ( ( byte ) ( 255 ) ) ; public static final String [ ] methodTransArray = new String [ ] { "OPTIONS" , "GET" , "HEAD" , "POST" , "PUT" , "DELETE" , "TRACE" , "PROPFIND" , "PROPPATCH" , "MKCOL" , "COPY" , "MOVE" , "LOCK" , "UNLOCK" , "ACL" } ; public static final String [ ] headerTransArray = new String [ ] { "accept" , "accept-charset" , "accept-encoding" , "accept-language" , "authorization" , "connection" , "content-type" , "content-length" , "cookie" , "cookie2" , "host" , "pragma" , "referer" , "user-agent" } ; OutputStream out ; InputStream in ; OutputBuffer headersWriter = new OutputBuffer ( Ajp13 . MAX_PACKET_SIZE ) ; Ajp13Packet outBuf = new Ajp13Packet ( headersWriter ) ; Ajp13Packet inBuf = new Ajp13Packet ( Ajp13 . MAX_PACKET_SIZE ) ; Ajp13Packet hBuf = new Ajp13Packet ( Ajp13 . MAX_PACKET_SIZE ) ; byte [ ] bodyBuff = new byte [ Ajp13 . MAX_READ_SIZE ] ; int blen ; int pos ; public Ajp13 ( ) { } public void recycle ( ) { } public void setSocket ( Socket socket ) throws IOException { } public int receiveNextRequest ( Request req ) throws IOException { } private int decodeRequest ( Request req , Ajp13Packet msg ) throws IOException { boolean isSSL = false ; byte methodCode = msg . getByte ( ) ; req . method ( ) . setString ( Ajp13 . methodTransArray [ ( ( ( int ) ( methodCode ) ) - 1 ) ] ) ; msg . getMessageBytes ( req . protocol ( ) ) ; msg . getMessageBytes ( req . requestURI ( ) ) ; msg . getMessageBytes ( req . remoteAddr ( ) ) ; msg . getMessageBytes ( req . remoteHost ( ) ) ; msg . getMessageBytes ( req . serverName ( ) ) ; req . setServerPort ( msg . getInt ( ) ) ; isSSL = msg . getBool ( ) ; MimeHeaders headers = req . getMimeHeaders ( ) ; int hCount = msg . getInt ( ) ; for ( int i = 0 ; i < hCount ; i ++ ) { String hName = null ; int isc = msg . peekInt ( ) ; int hId = isc & 255 ; MessageBytes vMB = null ; isc &= 65280 ; if ( 40960 == isc ) { msg . getInt ( ) ; hName = Ajp13 . headerTransArray [ ( hId - 1 ) ] ; vMB = headers . addValue ( hName ) ; } else { vMB = msg . addHeader ( headers ) ; if ( vMB == null ) return 500 ; } msg . getMessageBytes ( vMB ) ; } byte attributeCode ; for ( attributeCode = msg . getByte ( ) ; attributeCode != ( Ajp13 . SC_A_ARE_DONE ) ; attributeCode = msg . getByte ( ) ) { switch ( attributeCode ) { case Ajp13 . SC_A_CONTEXT : break ; case Ajp13 . SC_A_SERVLET_PATH : break ; case Ajp13 . SC_A_REMOTE_USER : req . setRemoteUser ( msg . getString ( ) ) ; <START_BUG> req . setUserPrincipal ( new org . apache . tomcat . util . aaa . SimplePrincipal ( msg . getString ( ) ) ) ; <END_BUG> break ; case Ajp13 . SC_A_AUTH_TYPE : req . setAuthType ( msg . getString ( ) ) ; break ; case Ajp13 . SC_A_QUERY_STRING : msg . getMessageBytes ( req . queryString ( ) ) ; break ; case Ajp13 . SC_A_JVM_ROUTE : req . setJvmRoute ( msg . getString ( ) ) ; break ; case Ajp13 . SC_A_SSL_CERT : isSSL = true ; req . setAttribute ( "javax.servlet.request.X509Certificate" , msg . getString ( ) ) ; break ; case Ajp13 . SC_A_SSL_CIPHER : isSSL = true ; req . setAttribute ( "javax.servlet.request.cipher_suite" , msg . getString ( ) ) ; break ; case Ajp13 . SC_A_SSL_SESSION : isSSL = true ; req . setAttribute ( "javax.servlet.request.ssl_session" , msg . getString ( ) ) ; break ; case Ajp13 . SC_A_REQ_ATTRIBUTE : req . setAttribute ( msg . getString ( ) , msg . getString ( ) ) ; break ; default : return 500 ; } } if ( isSSL ) { req . scheme ( ) . setString ( "https" ) ; } MessageBytes clB = headers . getValue ( "content-length" ) ; int contentLength = ( clB == null ) ? - 1 : clB . getInt ( ) ; if ( contentLength > 0 ) { req . setContentLength ( contentLength ) ; int err = receive ( inBuf ) ; if ( err < 0 ) { return 500 ; } blen = inBuf . peekInt ( ) ; pos = 0 ; inBuf . getBytes ( bodyBuff ) ; } return 200 ; } public int doRead ( ) throws IOException { }

Fix:
req . setUserPrincipal ( new org . apache . tomcat . util . aaa . SimplePrincipal ( req . getRemoteUser ( ) ) ) ;