luehe       2003/10/13 14:53:45

  Modified:    coyote/src/java/org/apache/coyote Response.java
  Log:
  Fixed Bugtraq 4934442 ("Response Content-Type has no charset even
                         though setCharacterEncoding was called")
  
  This fixes the problem where a response char setting via
  response.setCharacterEncoding() or response.setLocale() is not
  preserved by a call to response.setContentType() with a content type
  that has no charset, ie., response.getContentType(), following this
  sequence of calls:
  
    response.setCharacterEncoding("Shift_Jis");
    response.setContentType("text/html")
  
  used to return "text/html" instead of "text/html;charset=Shift_Jis",
  which violates the servlet spec.
  
  Revision  Changes    Path
  1.27      +59 -34    
jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/Response.java
  
  Index: Response.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/Response.java,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- Response.java     2 Sep 2003 21:34:38 -0000       1.26
  +++ Response.java     13 Oct 2003 21:53:45 -0000      1.27
  @@ -64,7 +64,6 @@
   import java.util.Locale;
   
   import org.apache.tomcat.util.buf.ByteChunk;
  -import org.apache.tomcat.util.http.ContentType;
   import org.apache.tomcat.util.http.MimeHeaders;
   
   /**
  @@ -87,15 +86,18 @@
       }
   
   
  -    // ----------------------------------------------------- Instance Variables
  -    
  -    
  -   /**
  +    // ----------------------------------------------------- Class Variables
  +
  +    /**
        * Default locale as mandated by the spec.
        */
       private static Locale DEFAULT_LOCALE = Locale.getDefault();
  -    
  -       
  +
  +    private static final int BEGIN_CHARSET_VALUE = "charset=".length();
  +
  +
  +    // ----------------------------------------------------- Instance Variables
  +
       /**
        * Status code.
        */
  @@ -471,44 +473,67 @@
               return;
   
        characterEncoding = charset;
  -
  -        String type = this.contentType;
  -     if (type != null) {
  -         int start = type.indexOf("charset=");
  -         if ( start != -1 ) {
  -             int end = type.indexOf(';', start+8);
  -             if (end >= 0) 
  -                 type = type.substring(0,start+8)
  -                     + charset + type.substring(end-1);
  -             else 
  -                 type = type.substring(0,start+8) + charset;
  -             this.contentType = type;
  -         } else {
  -             int end = type.indexOf(';');
  -             if (end >= 0) {
  -                 type = type.substring(0, end) + ";charset=" + charset;
  -             } else {
  -                 type = type + ";charset=" + charset;
  -             }            
  -         }
  -         setContentType( type );
  -        }
       }
   
       public String getCharacterEncoding() {
           return characterEncoding;
       }
   
  +    /**
  +     * Sets the content type.
  +     *
  +     * @param contentType the content type
  +     */
       public void setContentType(String contentType) {
  -        this.contentType = contentType;
  -        String encoding = ContentType.getCharsetFromContentType(contentType);
  -        if (encoding != null) {
  -            characterEncoding = encoding;
  +
  +        if (contentType == null) {
  +            this.contentType = null;
  +            return;
           }
  +
  +        /*
  +         * Remove the charset param (if any) from the Content-Type, and use it
  +         * to set the response encoding.
  +         * The most recent response encoding setting will be appended to the
  +         * response Content-Type (as its charset param) by getContentType();
  +         */
  +        int beginCharsetValue = BEGIN_CHARSET_VALUE;
  +        int beginCharsetParam = contentType.indexOf(";charset=");
  +        if (beginCharsetParam == -1) {
  +            beginCharsetParam = contentType.indexOf("; charset=");
  +            beginCharsetValue++;
  +        }
  +        if (beginCharsetParam == -1) {
  +            // no charset
  +            this.contentType = contentType;
  +            return;
  +        }
  +
  +        this.contentType = contentType.substring(0, beginCharsetParam);
  +        String tail = contentType.substring(beginCharsetParam + 1);
  +        int nextParam = tail.indexOf(';');
  +        String charsetValue = null;
  +        if (nextParam != -1) {
  +            this.contentType += tail.substring(nextParam);
  +            charsetValue = tail.substring(beginCharsetValue, nextParam);
  +        } else {
  +            charsetValue = tail.substring(beginCharsetValue);
  +        }
  +        // The charset value may be quoted, but must not contain any quotes.
  +        charsetValue = charsetValue.replace('"', ' ');
  +        this.characterEncoding = charsetValue.trim();
       }
   
       public String getContentType() {
  -        return contentType;
  +
  +        String ret = contentType;
  +
  +        if (ret != null && characterEncoding != null) {
  +            ret += ";charset=";
  +            ret += characterEncoding;
  +        }
  +
  +        return ret;
       }
       
       public void setContentLength(int contentLength) {
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to