diff options
author | Justin Erenkrantz <jerenkrantz@apache.org> | 2002-06-18 00:46:30 +0200 |
---|---|---|
committer | Justin Erenkrantz <jerenkrantz@apache.org> | 2002-06-18 00:46:30 +0200 |
commit | 3ea796a16681e2ed8031edb11412ddbae007051a (patch) | |
tree | 2e6d98663b4281ff676e17ffbbe4563fa38f5e1e /modules | |
parent | Ooops... newline. Caught it (diff) | |
download | apache2-3ea796a16681e2ed8031edb11412ddbae007051a.tar.xz apache2-3ea796a16681e2ed8031edb11412ddbae007051a.zip |
Do not use atol() for the Content-Length parsing as its handling of error
cases is undetermined by the ANSI C standard.
Instead, use strtol() with a check for the ERANGE error condition.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@95740 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules')
-rw-r--r-- | modules/http/http_protocol.c | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/modules/http/http_protocol.c b/modules/http/http_protocol.c index 3ffe91a91d..20c0da994d 100644 --- a/modules/http/http_protocol.c +++ b/modules/http/http_protocol.c @@ -794,14 +794,37 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, } else if (lenp) { const char *pos = lenp; + int conversion_error = 0; + /* This ensures that the number can not be negative. */ while (apr_isdigit(*pos) || apr_isspace(*pos)) { ++pos; } if (*pos == '\0') { + char *endstr; ctx->state = BODY_LENGTH; - ctx->remaining = atol(lenp); + ctx->remaining = strtol(lenp, &endstr, 10); + + if (errno == ERANGE) { + conversion_error = 1; + } + } + + if (*pos != '\0' || conversion_error) { + apr_bucket_brigade *bb; + + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r, + "Invalid Content-Length"); + + bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc); + e = ap_bucket_error_create(HTTP_REQUEST_ENTITY_TOO_LARGE, NULL, + f->r->pool, f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, e); + e = apr_bucket_eos_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, e); + ctx->eos_sent = 1; + return ap_pass_brigade(f->r->output_filters, bb); } /* If we have a limit in effect and we know the C-L ahead of @@ -1683,17 +1706,26 @@ AP_DECLARE(int) ap_setup_client_block(request_rec *r, int read_policy) } else if (lenp) { const char *pos = lenp; + int conversion_error = 0; while (apr_isdigit(*pos) || apr_isspace(*pos)) { ++pos; } - if (*pos != '\0') { + + if (*pos == '\0') { + char *endstr; + r->remaining = strtol(lenp, &endstr, 10); + + if (errno == ERANGE || errno == EINVAL) { + conversion_error = 1; + } + } + + if (*pos != '\0' || conversion_error) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "Invalid Content-Length %s", lenp); + "Invalid Content-Length"); return HTTP_BAD_REQUEST; } - - r->remaining = atol(lenp); } if ((r->read_body == REQUEST_NO_BODY) |