On 07/29/2016 07:37 PM, [email protected] wrote:
> Author: wrowe
> Date: Fri Jul 29 17:37:41 2016
> New Revision: 1754556
> 
> URL: http://svn.apache.org/viewvc?rev=1754556&view=rev
> Log:
> Introduce ap_scan_http_token / ap_scan_http_field_content for a much
> more efficient pass through the header text; rather than reparsing
> the strings over and over under the HTTP_CONFORMANCE_STRICT fules.
> 
> Improve logic and legibility by eliminating multiple repetitive tests
> of the STRICT flag, and simply reorder 'classic' behavior first and
> this new parser second to simplify the diff. Because of the whitespace
> change (which I had wished to dodge), reading this --ignore-all-space
> is a whole lot easier. Particularly against 2.4.x branch, which is now
> identical in the 'classic' logic flow. Both of which I'll share with dev@
> 
> 
> Modified:
>     httpd/httpd/trunk/server/protocol.c
> 
> Modified: httpd/httpd/trunk/server/protocol.c
> URL: 
> http://svn.apache.org/viewvc/httpd/httpd/trunk/server/protocol.c?rev=1754556&r1=1754555&r2=1754556&view=diff
> ==============================================================================
> --- httpd/httpd/trunk/server/protocol.c (original)
> +++ httpd/httpd/trunk/server/protocol.c Fri Jul 29 17:37:41 2016
> @@ -900,71 +900,106 @@ AP_DECLARE(void) ap_get_mime_headers_cor
>                      return;
>                  }
>  
> -                if (!(value = strchr(last_field, ':'))) { /* Find ':' or    
> */
> -                    r->status = HTTP_BAD_REQUEST;      /* abort bad request 
> */
> -                    apr_table_setn(r->notes, "error-notes",
> -                                   apr_psprintf(r->pool,
> -                                               "Request header field is "
> -                                               "missing ':' separator.<br 
> />\n"
> -                                               "<pre>\n%.*s</pre>\n", 
> -                                               (int)LOG_NAME_MAX_LEN,
> -                                               ap_escape_html(r->pool,
> -                                                              last_field)));
> -                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 
> APLOGNO(00564)
> -                                  "Request header field is missing ':' "
> -                                  "separator: %.*s", (int)LOG_NAME_MAX_LEN,
> -                                  last_field);
> -                    return;
> -                }
> +                if (!(conf->http_conformance & AP_HTTP_CONFORMANCE_STRICT)) {
> +                {
> +                    /* Not Strict, using the legacy parser */
> +
> +                    if (!(value = strchr(last_field, ':'))) { /* Find ':' or 
> */
> +                        r->status = HTTP_BAD_REQUEST;   /* abort bad request 
> */
> +                        apr_table_setn(r->notes, "error-notes",
> +                            apr_psprintf(r->pool,
> +                                         "Request header field is "
> +                                         "missing ':' separator.<br />\n"
> +                                         "<pre>\n%.*s</pre>\n", 
> +                                         (int)LOG_NAME_MAX_LEN,
> +                                         ap_escape_html(r->pool,
> +                                                        last_field)));
> +                        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 
> APLOGNO(00564)
> +                                      "Request header field is missing ':' "
> +                                      "separator: %.*s", 
> (int)LOG_NAME_MAX_LEN,
> +                                      last_field);
> +                        return;
> +                    }
>  
> -                tmp_field = value - 1; /* last character of field-name */
> +                    tmp_field = value - 1; /* last character of field-name */
>  
> -                *value++ = '\0'; /* NUL-terminate at colon */
> +                    *value++ = '\0'; /* NUL-terminate at colon */
>  
> -                while (*value == ' ' || *value == '\t') {
> -                    ++value;            /* Skip to start of value   */
> -                }
> +                    while (*value == ' ' || *value == '\t') {
> +                         ++value;            /* Skip to start of value   */
> +                    }
>  
> -                /* Strip LWS after field-name: */
> -                while (tmp_field > last_field
> -                       && (*tmp_field == ' ' || *tmp_field == '\t')) {
> -                    *tmp_field-- = '\0';
> -                }
> +                    /* Strip LWS after field-name: */
> +                    while (tmp_field > last_field
> +                           && (*tmp_field == ' ' || *tmp_field == '\t')) {
> +                        *tmp_field-- = '\0';
> +                    }
>  
> -                /* Strip LWS after field-value: */
> -                tmp_field = last_field + last_len - 1;
> -                while (tmp_field > value
> -                       && (*tmp_field == ' ' || *tmp_field == '\t')) {
> -                    *tmp_field-- = '\0';
> +                    /* Strip LWS after field-value: */
> +                    tmp_field = last_field + last_len - 1;
> +                    while (tmp_field > value
> +                           && (*tmp_field == ' ' || *tmp_field == '\t')) {
> +                        *tmp_field-- = '\0';
> +                    }
>                  }
> +                else /* Using strict RFC7230 parsing */
> +                {
> +                    /* Ensure valid token chars before ':' per RFC 7230 
> 3.2.4 */
> +                    if (!(value = (char *)ap_scan_http_token(last_field))

Hm, how could ap_scan_http_token ever return NULL?

> +                            || *value != ':') {
> +                        r->status = HTTP_BAD_REQUEST;
> +                        apr_table_setn(r->notes, "error-notes",
> +                            apr_psprintf(r->pool,
> +                                         "Request header field name "
> +                                         "is malformed.<br />\n"
> +                                         "<pre>\n%.*s</pre>\n", 
> +                                         (int)LOG_NAME_MAX_LEN,
> +                                         ap_escape_html(r->pool, 
> last_field)));
> +                        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 
> APLOGNO(02426)
> +                                      "Request header field name is 
> malformed: "
> +                                      "%.*s", (int)LOG_NAME_MAX_LEN, 
> last_field);
> +                        return;
> +                    }

Regards

RĂ¼diger

Reply via email to