From: Ruediger Pluem Date: Tue, 8 Feb 2011 10:01:42 +0000 (+0000) Subject: Merge r1026743 from trunk: X-Git-Tag: 2.2.18~156 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8bf40ce600f5ac1b983d76b79ef20f7b2821e676;p=thirdparty%2Fapache%2Fhttpd.git Merge r1026743 from trunk: If a malformed Content-Range header is received for a PUT request, we must not use the supplied content per RFC 2616 14.16. Send 400 response instead of ignoring the Content-Range. PR: 49825 Submitted by: sf Reviewed by: rpluem, jorton, covener git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@1068309 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index d89ae3a13a8..fe2c03370b5 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,9 @@ -*- coding: utf-8 -*- Changes with Apache 2.2.18 + *) mod_dav: Send 400 error if malformed Content-Range header is received for + a put request (RFC 2616 14.16). PR 49825. [Stefan Fritsch] + *) mod_userdir: Add merging of enable, disable, and filename arguments to UserDir directive, leaving enable/disable of userlists unmerged. PR 44076 [Eric Covener] diff --git a/STATUS b/STATUS index 23418727d4e..6e86cd11541 100644 --- a/STATUS +++ b/STATUS @@ -98,16 +98,6 @@ PATCHES ACCEPTED TO BACKPORT FROM TRUNK: 2.2.x patch: http://people.apache.org/~minfrin/httpd-mod_cache-304-fix-2.patch +1: minfrin, jim, covener - * mod_dav: If a malformed Content-Range header is received for a PUT request, - we must not use the supplied content per RFC 2616 14.16. Send 400 response - instead of ignoring the Content-Range. - PR: 49825 - Trunk version of patch: - http://svn.apache.org/viewvc?rev=1026743&view=rev - Backport version for 2.2.x of patch: - Trunk version of patch works - +1: rpluem, jorton, covener - * mod_dav: If an unknown Content-* header is received for a PUT request, we must not ignore it but reply with 501 per RFC 2616 9.6. PR: 42978 diff --git a/modules/dav/main/mod_dav.c b/modules/dav/main/mod_dav.c index c57bffb32cd..90370c6cc32 100644 --- a/modules/dav/main/mod_dav.c +++ b/modules/dav/main/mod_dav.c @@ -761,6 +761,11 @@ static dav_error * dav_open_lockdb(request_rec *r, int ro, dav_lockdb **lockdb) return (*hooks->open_lockdb)(r, ro, 0, lockdb); } +/** + * @return 1 if valid content-range, + * 0 if no content-range, + * -1 if malformed content-range + */ static int dav_parse_range(request_rec *r, apr_off_t *range_start, apr_off_t *range_end) { @@ -778,21 +783,20 @@ static int dav_parse_range(request_rec *r, if (strncasecmp(range, "bytes ", 6) != 0 || (dash = ap_strchr(range, '-')) == NULL || (slash = ap_strchr(range, '/')) == NULL) { - /* malformed header. ignore it (per S14.16 of RFC2616) */ - return 0; + /* malformed header */ + return -1; } *dash++ = *slash++ = '\0'; - /* ignore invalid ranges. (per S14.16 of RFC2616) */ + /* detect invalid ranges */ if (apr_strtoff(range_start, range + 6, &errp, 10) || *errp || *range_start < 0) { - return 0; + return -1; } - if (apr_strtoff(range_end, dash, &errp, 10) || *errp || *range_end < 0 || *range_end < *range_start) { - return 0; + return -1; } if (*slash != '*') { @@ -800,7 +804,7 @@ static int dav_parse_range(request_rec *r, if (apr_strtoff(&dummy, slash, &errp, 10) || *errp || dummy <= *range_end) { - return 0; + return -1; } } @@ -939,6 +943,22 @@ static int dav_method_put(request_rec *r) return dav_handle_err(r, err, multi_response); } + has_range = dav_parse_range(r, &range_start, &range_end); + if (has_range < 0) { + /* RFC 2616 14.16: If we receive an invalid Content-Range we must + * not use the content. + */ + body = apr_psprintf(r->pool, + "Malformed Content-Range header for PUT %s.", + ap_escape_html(r->pool, r->uri)); + return dav_error_response(r, HTTP_BAD_REQUEST, body); + } else if (has_range) { + mode = DAV_MODE_WRITE_SEEKABLE; + } + else { + mode = DAV_MODE_WRITE_TRUNC; + } + /* make sure the resource can be modified (if versioning repository) */ if ((err = dav_auto_checkout(r, resource, 0 /* not parent_only */, @@ -947,14 +967,6 @@ static int dav_method_put(request_rec *r) return dav_handle_err(r, err, NULL); } - /* truncate and rewrite the file unless we see a Content-Range */ - mode = DAV_MODE_WRITE_TRUNC; - - has_range = dav_parse_range(r, &range_start, &range_end); - if (has_range) { - mode = DAV_MODE_WRITE_SEEKABLE; - } - /* Create the new file in the repository */ if ((err = (*resource->hooks->open_stream)(resource, mode, &stream)) != NULL) {