httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wr...@apache.org
Subject svn commit: r1764961 - in /httpd/httpd/trunk: docs/manual/mod/core.xml modules/http/http_filters.c server/core.c server/gen_test_char.c server/protocol.c server/util.c
Date Fri, 14 Oct 2016 20:48:44 GMT
Author: wrowe
Date: Fri Oct 14 20:48:43 2016
New Revision: 1764961

URL: http://svn.apache.org/viewvc?rev=1764961&view=rev
Log:

Dropped the never-released ap_has_cntrls() as it had very limited 
and inefficient application at that, added ap_scan_vchar_obstext()
to accomplish a similar purpose.

Dropped HttpProtocolOptions StrictURL option, this will be better
handled in the future with a specific directive and perhaps multiple
levels of scrutiny, use ap_scan_vchar_obstext() to simply ensure there
are no control characters or whitespace within the URI.

Changed the scanning of the response header table by check_headers()
to follow the same rulesets as reading request headers. Disallow any
CTL character within a response header value, and any CTL or whitespace
in response header field name, even in strict mode.

Apply HttpProtocolOptions Strict to chunk header parsing, invalid
whitespace is invalid, line termination must follow CRLF convention.


Modified:
    httpd/httpd/trunk/docs/manual/mod/core.xml
    httpd/httpd/trunk/modules/http/http_filters.c
    httpd/httpd/trunk/server/core.c
    httpd/httpd/trunk/server/gen_test_char.c
    httpd/httpd/trunk/server/protocol.c
    httpd/httpd/trunk/server/util.c

Modified: httpd/httpd/trunk/docs/manual/mod/core.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/core.xml?rev=1764961&r1=1764960&r2=1764961&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/core.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/core.xml Fri Oct 14 20:48:43 2016
@@ -1263,9 +1263,9 @@ EnableSendfile On
 <directivesynopsis>
 <name>HttpProtocolOptions</name>
 <description>Modify restrictions on HTTP Request Messages</description>
-<syntax>HttpProtocolOptions [Strict|Unsafe] [StrictURL|UnsafeURL]
- [RegisteredMethods|LenientMethods] [Allow0.9|Require1.0]</syntax>
-<default>HttpProtocolOptions Strict StrictURL LenientMethods Allow0.9</default>
+<syntax>HttpProtocolOptions [Strict|Unsafe] [RegisteredMethods|LenientMethods]
+ [Allow0.9|Require1.0]</syntax>
+<default>HttpProtocolOptions Strict LenientMethods Allow0.9</default>
 <contextlist><context>server config</context>
 <context>virtual host</context></contextlist>
 <compatibility>2.2.32 or 2.4.24 and later</compatibility>
@@ -1277,11 +1277,11 @@ EnableSendfile On
     (<a href="https://tools.ietf.org/html/rfc7230#section-3.2"
       >RFC 7230 &sect;3.2</a>), which are now applied by default or using
     the <code>Strict</code> option. Due to legacy modules, applications or
-    custom user-agents which must be deperecated, <code>Unsafe</code>
-    and <code>UnsafeURL</code> options have been added to revert to the legacy
-    behaviors. These rules are applied prior to request processing, so must be
-    configured at the global or default (first) matching virtual host section,
-    by IP/port interface and not by name, to be honored.</p>
+    custom user-agents which must be deperecated the <code>Unsafe</code>
+    option has been added to revert to the legacy behaviors. These rules
+    are applied prior to request processing, so must be configured at the
+    global or default (first) matching virtual host section, by IP/port
+    interface (and not by name) to be honored.</p>
 
     <p>Prior to the introduction of this directive, the Apache HTTP Server
     request message parsers were tolerant of a number of forms of input
@@ -1299,21 +1299,12 @@ EnableSendfile On
     mode, and the strict whitespace suggested by section 3.5 is enforced
     and cannot be relaxed.</p>
 
-    <p><a href="https://tools.ietf.org/html/rfc3986#section-2.2"
-         >RFC 3986 &sect;2.2 and 2.3</a> define "Reserved Characters" and
-    "Unreserved Characters". All other character octets are required to
-    be %XX encoded under this spec, and RFC7230 defers to these requirements.
-    By default the <code>StrictURI</code> option will reject all requests 
-    containing invalid characters. This rule can be relaxed with the
-    <code>UnsafeURI</code> option to support badly written user-agents.</p>
-    
     <p>Users are strongly cautioned against toggling the <code>Unsafe</code>
-    or <code>UnsafeURI</code> modes of operation, particularly on
-    outward-facing, publicly accessible server deployments.
-    If an interface is required for faulty monitoring or other custom service
-    consumers running on an intranet, users should toggle only those Unsafe
-    options which are necessary, and only on a specific virtual host configured
-    to service only their internal private network.</p>
+    mode of operation, particularly on outward-facing, publicly accessible
+    server deployments.  If an interface is required for faulty monitoring
+    or other custom service consumers running on an intranet, users should
+    toggle the Unsafe option only on a specific virtual host configured
+    to service their internal private network.</p>
 
     <p>Reviewing the messages logged to the <directive>ErrorLog</directive>,
     configured with <directive>LogLevel</directive> <code>debug</code>
level,

Modified: httpd/httpd/trunk/modules/http/http_filters.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http/http_filters.c?rev=1764961&r1=1764960&r2=1764961&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http/http_filters.c (original)
+++ httpd/httpd/trunk/modules/http/http_filters.c Fri Oct 14 20:48:43 2016
@@ -84,14 +84,15 @@ typedef struct http_filter_ctx
 
 /**
  * Parse a chunk line with optional extension, detect overflow.
- * There are two error cases:
+ * There are several error cases:
+ *  1) If the chunk link is misformatted, APR_EINVAL is returned.
  *  1) If the conversion would require too many bits, APR_EGENERAL is returned.
  *  2) If the conversion used the correct number of bits, but an overflow
  *     caused only the sign bit to flip, then APR_ENOSPC is returned.
- * In general, any negative number can be considered an overflow error.
+ * A negative chunk length always indicates an overflow error.
  */
 static apr_status_t parse_chunk_size(http_ctx_t *ctx, const char *buffer,
-                                     apr_size_t len, int linelimit)
+                                     apr_size_t len, int linelimit, int strict)
 {
     apr_size_t i = 0;
 
@@ -104,6 +105,12 @@ static apr_status_t parse_chunk_size(htt
         if (ctx->state == BODY_CHUNK_END
                 || ctx->state == BODY_CHUNK_END_LF) {
             if (c == LF) {
+                if (strict && (ctx->state != BODY_CHUNK_END_LF)) {
+                    /*
+                     * CR missing before LF.
+                     */
+                    return APR_EINVAL;
+                }
                 ctx->state = BODY_CHUNK;
             }
             else if (c == CR && ctx->state == BODY_CHUNK_END) {
@@ -111,7 +118,7 @@ static apr_status_t parse_chunk_size(htt
             }
             else {
                 /*
-                 * LF expected.
+                 * CRLF expected.
                  */
                 return APR_EINVAL;
             }
@@ -138,6 +145,12 @@ static apr_status_t parse_chunk_size(htt
         }
 
         if (c == LF) {
+            if (strict && (ctx->state != BODY_CHUNK_LF)) {
+                /*
+                 * CR missing before LF.
+                 */
+                return APR_EINVAL;
+            }
             if (ctx->remaining) {
                 ctx->state = BODY_CHUNK_DATA;
             }
@@ -159,13 +172,14 @@ static apr_status_t parse_chunk_size(htt
         }
         else if (ctx->state == BODY_CHUNK_EXT) {
             /*
-             * Control chars (but tabs) are invalid.
+             * Control chars (excluding tabs) are invalid.
+             * TODO: more precisely limit input
              */
             if (c != '\t' && apr_iscntrl(c)) {
                 return APR_EINVAL;
             }
         }
-        else if (c == ' ' || c == '\t') {
+        else if (!strict && (c == ' ' || c == '\t')) {
             /* Be lenient up to 10 BWS (term from rfc7230 - 3.2.3).
              */
             ctx->state = BODY_CHUNK_CR;
@@ -282,15 +296,15 @@ apr_status_t ap_http_filter(ap_filter_t
                             ap_input_mode_t mode, apr_read_type_e block,
                             apr_off_t readbytes)
 {
-    core_server_config *conf;
+    core_server_config *conf =
+        (core_server_config *) ap_get_module_config(f->r->server->module_config,
+                                                    &core_module);
+    int strict = (conf->http_conformance != AP_HTTP_CONFORMANCE_UNSAFE);
     apr_bucket *e;
     http_ctx_t *ctx = f->ctx;
     apr_status_t rv;
     int again;
 
-    conf = (core_server_config *)
-        ap_get_module_config(f->r->server->module_config, &core_module);
-
     /* just get out of the way of things we don't want. */
     if (mode != AP_MODE_READBYTES && mode != AP_MODE_GETLINE) {
         return ap_get_brigade(f->next, b, mode, block, readbytes);
@@ -478,7 +492,7 @@ apr_status_t ap_http_filter(ap_filter_t
 
                     if (rv == APR_SUCCESS) {
                         rv = parse_chunk_size(ctx, buffer, len,
-                                f->r->server->limit_req_fieldsize);
+                                f->r->server->limit_req_fieldsize, strict);
                     }
                     if (rv != APR_SUCCESS) {
                         ap_log_rerror(APLOG_MARK, APLOG_INFO, rv, f->r, APLOGNO(01590)
@@ -615,32 +629,49 @@ apr_status_t ap_http_filter(ap_filter_t
 
 struct check_header_ctx {
     request_rec *r;
-    int error;
+    int strict;
 };
 
 /* check a single header, to be used with apr_table_do() */
 static int check_header(void *arg, const char *name, const char *val)
 {
     struct check_header_ctx *ctx = arg;
+    const char *test;
+
     if (name[0] == '\0') {
-        ctx->error = 1;
         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, ctx->r, APLOGNO(02428)
                       "Empty response header name, aborting request");
         return 0;
     }
-    if (ap_has_cntrl(name)) {
-        ctx->error = 1;
+
+    if (ctx->strict) { 
+        test = ap_scan_http_token(name);
+    }
+    else {
+        test = ap_scan_vchar_obstext(name);
+    }
+    if (*test) {
         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, ctx->r, APLOGNO(02429)
-                      "Response header name '%s' contains control "
+                      "Response header name '%s' contains invalid "
                       "characters, aborting request",
                       name);
         return 0;
     }
-    if (ap_has_cntrl(val)) {
-        ctx->error = 1;
+
+    if (ctx->strict) { 
+        test = ap_scan_http_field_content(val);
+    }
+    else {
+        /* Simply terminate scanning on a CTL char, allowing whitespace */
+        test = val;
+        do {
+            test = ap_scan_vchar_obstext(test);
+        } while (*test == ' ' || *test == '\t');
+    }
+    if (*test) {
         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, ctx->r, APLOGNO(02430)
-                      "Response header '%s' contains control characters, "
-                      "aborting request: %s",
+                      "Response header '%s' value of '%s' contains invalid "
+                      "characters, aborting request",
                       name, val);
         return 0;
     }
@@ -654,11 +685,13 @@ static int check_header(void *arg, const
 static APR_INLINE int check_headers(request_rec *r)
 {
     const char *loc;
-    struct check_header_ctx ctx = { 0, 0 };
+    struct check_header_ctx ctx;
+    core_server_config *conf =
+            ap_get_core_module_config(r->server->module_config);
 
     ctx.r = r;
-    apr_table_do(check_header, &ctx, r->headers_out, NULL);
-    if (ctx.error)
+    ctx.strict = (conf->http_conformance != AP_HTTP_CONFORMANCE_UNSAFE);
+    if (!apr_table_do(check_header, &ctx, r->headers_out, NULL))
         return 0; /* problem has been logged by check_header() */
 
     if ((loc = apr_table_get(r->headers_out, "Location")) != NULL) {
@@ -1189,7 +1222,6 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_
     header_filter_ctx *ctx = f->ctx;
     const char *ctype;
     ap_bucket_error *eb = NULL;
-    core_server_config *conf;
 
     AP_DEBUG_ASSERT(!r->main);
 
@@ -1245,13 +1277,9 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_
                                            r->headers_out);
     }
 
-    conf = ap_get_core_module_config(r->server->module_config);
-    if (conf->http_conformance != AP_HTTP_CONFORMANCE_UNSAFE) {
-        int ok = check_headers(r);
-        if (!ok) {
-            ap_die(HTTP_INTERNAL_SERVER_ERROR, r);
-            return AP_FILTER_ERROR;
-        }
+    if (!check_headers(r)) {
+        ap_die(HTTP_INTERNAL_SERVER_ERROR, r);
+        return AP_FILTER_ERROR;
     }
 
     /*

Modified: httpd/httpd/trunk/server/core.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/core.c?rev=1764961&r1=1764960&r2=1764961&view=diff
==============================================================================
--- httpd/httpd/trunk/server/core.c (original)
+++ httpd/httpd/trunk/server/core.c Fri Oct 14 20:48:43 2016
@@ -537,9 +537,6 @@ static void *merge_core_server_configs(a
     if (virt->http_conformance != AP_HTTP_CONFORMANCE_UNSET)
         conf->http_conformance = virt->http_conformance;
 
-    if (virt->http_stricturi != AP_HTTP_URI_UNSET)
-        conf->http_stricturi = virt->http_stricturi;
-
     if (virt->http_methods != AP_HTTP_METHODS_UNSET)
         conf->http_methods = virt->http_methods;
 
@@ -4035,10 +4032,6 @@ static const char *set_http_protocol_opt
         conf->http_conformance |= AP_HTTP_CONFORMANCE_STRICT;
     else if (strcasecmp(arg, "unsafe") == 0)
         conf->http_conformance |= AP_HTTP_CONFORMANCE_UNSAFE;
-    else if (strcasecmp(arg, "stricturi") == 0)
-        conf->http_stricturi |= AP_HTTP_URI_STRICT;
-    else if (strcasecmp(arg, "unsafeuri") == 0)
-        conf->http_stricturi |= AP_HTTP_URI_UNSAFE;
     else if (strcasecmp(arg, "registeredmethods") == 0)
         conf->http_methods |= AP_HTTP_METHODS_REGISTERED;
     else if (strcasecmp(arg, "lenientmethods") == 0)
@@ -4046,7 +4039,6 @@ static const char *set_http_protocol_opt
     else
         return "HttpProtocolOptions accepts "
                "'Unsafe' or 'Strict' (default), "
-               "'UnsafeURI' or 'StrictURI' (default), "
                "'RegisteredMethods' or 'LenientMethods' (default), and "
                "'Require1.0' or 'Allow0.9' (default)";
 
@@ -4055,11 +4047,6 @@ static const char *set_http_protocol_opt
         return "HttpProtocolOptions 'Allow0.9' and 'Require1.0'"
                " are mutually exclusive";
 
-    if ((conf->http_stricturi & AP_HTTP_URI_STRICT)
-            && (conf->http_stricturi & AP_HTTP_URI_UNSAFE))
-        return "HttpProtocolOptions 'StrictURI' and 'UnsafeURI'"
-               " are mutually exclusive";
-
     if ((conf->http_conformance & AP_HTTP_CONFORMANCE_STRICT)
             && (conf->http_conformance & AP_HTTP_CONFORMANCE_UNSAFE))
         return "HttpProtocolOptions 'Strict' and 'Unsafe'"
@@ -4709,8 +4696,9 @@ AP_INIT_TAKE1("TraceEnable", set_trace_e
 AP_INIT_FLAG("MergeTrailers", set_merge_trailers, NULL, RSRC_CONF,
               "merge request trailers into request headers or not"),
 AP_INIT_ITERATE("HttpProtocolOptions", set_http_protocol_options, NULL, RSRC_CONF,
-              "'Allow0.9' or 'Require1.0' (default) to allow or deny HTTP/0.9; "
-              "'Unsafe' or 'Strict' (default) to process incorrect requests"),
+                "'Allow0.9' or 'Require1.0' (default); "
+                "'RegisteredMethods' or 'LenientMethods' (default); "
+                "'Unsafe' or 'Strict' (default). Sets HTTP acceptance rules"),
 AP_INIT_ITERATE("RegisterHttpMethod", set_http_method, NULL, RSRC_CONF,
                 "Registers non-standard HTTP methods"),
 AP_INIT_FLAG("HttpContentLengthHeadZero", set_cl_head_zero, NULL, OR_OPTIONS,

Modified: httpd/httpd/trunk/server/gen_test_char.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/gen_test_char.c?rev=1764961&r1=1764960&r2=1764961&view=diff
==============================================================================
--- httpd/httpd/trunk/server/gen_test_char.c (original)
+++ httpd/httpd/trunk/server/gen_test_char.c Fri Oct 14 20:48:43 2016
@@ -53,7 +53,7 @@
 #define T_ESCAPE_FORENSIC     (0x20)
 #define T_ESCAPE_URLENCODED   (0x40)
 #define T_HTTP_CTRLS          (0x80)
-#define T_URI_RFC3986        (0x100)
+#define T_VCHAR_OBSTEXT      (0x100)
 
 int main(int argc, char *argv[])
 {
@@ -70,7 +70,7 @@ int main(int argc, char *argv[])
            "#define T_ESCAPE_FORENSIC      (%u)\n"
            "#define T_ESCAPE_URLENCODED    (%u)\n"
            "#define T_HTTP_CTRLS           (%u)\n"
-           "#define T_URI_RFC3986          (%u)\n"
+           "#define T_VCHAR_OBSTEXT        (%u)\n"
            "\n"
            "static const unsigned short test_char_table[256] = {",
            T_ESCAPE_SHELL_CMD,
@@ -81,7 +81,7 @@ int main(int argc, char *argv[])
            T_ESCAPE_FORENSIC,
            T_ESCAPE_URLENCODED,
            T_HTTP_CTRLS,
-           T_URI_RFC3986);
+           T_VCHAR_OBSTEXT);
 
     for (c = 0; c < 256; ++c) {
         flags = 0;
@@ -143,11 +143,8 @@ int main(int argc, char *argv[])
          * and unreserved (2.3) that are possible somewhere within a URI.
          * Spec requires all others to be %XX encoded, including obs-text.
          */
-        if (c && (strchr("%"                              /* pct-encode */
-                         ":/?#[]@"                        /* gen-delims */ 
-                         "!$&'()*+,;="                    /* sub-delims */
-                         "-._~", c) || apr_isalnum(c))) { /* unreserved */
-            flags |= T_URI_RFC3986;
+        if (c && !apr_iscntrl(c) && c != ' ') {
+            flags |= T_VCHAR_OBSTEXT;
         }
 
         /* For logging, escape all control characters,

Modified: httpd/httpd/trunk/server/protocol.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/protocol.c?rev=1764961&r1=1764960&r2=1764961&view=diff
==============================================================================
--- httpd/httpd/trunk/server/protocol.c (original)
+++ httpd/httpd/trunk/server/protocol.c Fri Oct 14 20:48:43 2016
@@ -591,7 +591,6 @@ static int read_request_line(request_rec
     int num_blank_lines = DEFAULT_LIMIT_BLANK_LINES;
     core_server_config *conf = ap_get_core_module_config(r->server->module_config);
     int strict = (conf->http_conformance != AP_HTTP_CONFORMANCE_UNSAFE);
-    int stricturi = (conf->http_stricturi != AP_HTTP_URI_UNSAFE);
 
     /* Read past empty lines until we get a real request line,
      * a read error, the connection closes (EOF), or we timeout.
@@ -662,14 +661,15 @@ static int read_request_line(request_rec
      */
     if (strict) {
         ll = (char*) ap_scan_http_token(r->method);
-        if (((ll == r->method) || (*ll && !apr_isspace(*ll)))
-                && deferred_error == rrl_none) {
-            deferred_error = rrl_badmethod;
-            ll = strpbrk(ll, "\t\n\v\f\r ");
-        }
     }
     else {
-        ll = strpbrk(r->method, "\t\n\v\f\r ");
+        ll = (char*) ap_scan_vchar_obstext(r->method);
+    }
+
+    if (((ll == r->method) || (*ll && !apr_isspace(*ll)))
+            && deferred_error == rrl_none) {
+        deferred_error = rrl_badmethod;
+        ll = strpbrk(ll, "\t\n\v\f\r ");
     }
 
     /* Verify method terminated with a single SP, or mark as specific error */
@@ -697,18 +697,13 @@ static int read_request_line(request_rec
     if (!*uri && deferred_error == rrl_none)
         deferred_error = rrl_missinguri;
 
-    /* Scan the URI up to the next whitespace, ensure it contains only
-     * valid RFC3986 characters, otherwise mark in error
+    /* Scan the URI up to the next whitespace, ensure it contains no raw
+     * control characters, otherwise mark in error
      */
-    if (stricturi) {
-        ll = (char*) ap_scan_http_uri_safe(uri);
-        if (ll == uri || (*ll && !apr_isspace(*ll))) {
-            deferred_error = rrl_baduri;
-            ll = strpbrk(ll, "\t\n\v\f\r ");
-        }
-    }
-    else {
-        ll = strpbrk(uri, "\t\n\v\f\r ");
+    ll = (char*) ap_scan_vchar_obstext(uri);
+    if (ll == uri || (*ll && !apr_isspace(*ll))) {
+        deferred_error = rrl_baduri;
+        ll = strpbrk(ll, "\t\n\v\f\r ");
     }
 
     /* Verify method terminated with a single SP, or mark as specific error */
@@ -732,7 +727,7 @@ static int read_request_line(request_rec
     *ll = '\0';
 
     /* Scan the protocol up to the next whitespace, validation comes later */
-    if (!(ll = strpbrk(r->protocol, " \t\n\v\f\r"))) {
+    if (!(ll = (char*) ap_scan_vchar_obstext(r->protocol))) {
         len = strlen(r->protocol);
         goto rrl_done;
     }
@@ -742,7 +737,10 @@ static int read_request_line(request_rec
      * determine if trailing text is found, unconditionally mark in error,
      * finally NUL terminate the protocol string
      */
-    if (strict && *ll) {
+    if (*ll && !apr_isspace(*ll)) {
+        deferred_error = rrl_badprotocol;
+    }
+    else if (strict && *ll) {
         deferred_error = rrl_excesswhitespace;
     }
     else {
@@ -881,14 +879,6 @@ rrl_done:
     }
 
     if (strict) {
-        /* No sense re-testing here for what was evaulated above */
-        if (!stricturi && ap_has_cntrl(r->the_request)) {
-            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02420)
-                          "HTTP Request Line; URI must not contain control"
-                          " characters");
-            r->status = HTTP_BAD_REQUEST;
-            goto rrl_failed;
-        }
         if (r->parsed_uri.fragment) {
             /* RFC3986 3.5: no fragment */
             ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02421)

Modified: httpd/httpd/trunk/server/util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/util.c?rev=1764961&r1=1764960&r2=1764961&view=diff
==============================================================================
--- httpd/httpd/trunk/server/util.c (original)
+++ httpd/httpd/trunk/server/util.c Fri Oct 14 20:48:43 2016
@@ -1634,12 +1634,12 @@ AP_DECLARE(char *) ap_get_http_token(apr
     return tok;
 }
 
-/* Scan a string for valid URI characters per RFC3986, and 
- * return a pointer to the first non-URI character encountered.
+/* Scan a string for visible ASCII (0x21-0x7E) or obstext (0x80+)
+ * and return a pointer to the first ctrl/space character encountered.
  */
-AP_DECLARE(const char *) ap_scan_http_uri_safe(const char *ptr)
+AP_DECLARE(const char *) ap_scan_vchar_obstext(const char *ptr)
 {
-    for ( ; TEST_CHAR(*ptr, T_URI_RFC3986); ++ptr) ;
+    for ( ; TEST_CHAR(*ptr, T_VCHAR_OBSTEXT); ++ptr) ;
 
     return ptr;
 }
@@ -2244,16 +2244,6 @@ AP_DECLARE(void) ap_bin2hex(const void *
     *dest = '\0';
 }
 
-AP_DECLARE(int) ap_has_cntrl(const char *str)
-{
-    while (*str) {
-        if (apr_iscntrl(*str))
-            return 1;
-        str++;
-    }
-    return 0;
-}
-
 AP_DECLARE(int) ap_is_directory(apr_pool_t *p, const char *path)
 {
     apr_finfo_t finfo;



Mime
View raw message