From: Joe Orton Date: Mon, 6 Jul 2026 12:01:57 +0000 (+0000) Subject: mod_dav: Refactor Lock-Token parsing into dav_parse_locktoken() X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2ac25f0b50ef7d108e01f624b7f021f4184924ce;p=thirdparty%2Fapache%2Fhttpd.git mod_dav: Refactor Lock-Token parsing into dav_parse_locktoken() helper in util.c, replacing duplicated inline parsing in mod_dav.c and ms_wdv.c. * modules/dav/main/util.c (dav_parse_locktoken): New function. * modules/dav/main/mod_dav.h (dav_parse_locktoken): Declare it. * modules/dav/main/mod_dav.c (dav_method_unlock): Use dav_parse_locktoken() instead of inline bracket parsing. * modules/dav/main/ms_wdv.c (dav_process_ms_wdv_lock): Likewise. (dav_process_ms_wdv_if_header): Add length check before indexing the If header value to avoid reading past an empty string. Submitted by: metsw24-max Github: closes #618 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1935940 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/dav/main/mod_dav.c b/modules/dav/main/mod_dav.c index 42b651f281..2a024396f5 100644 --- a/modules/dav/main/mod_dav.c +++ b/modules/dav/main/mod_dav.c @@ -3606,18 +3606,9 @@ static int dav_method_unlock(request_rec *r) return HTTP_BAD_REQUEST; } - locktoken_txt = apr_pstrdup(r->pool, const_locktoken_txt); - if (locktoken_txt[0] != '<') { - /* ### should provide more specifics... */ - return HTTP_BAD_REQUEST; - } - locktoken_txt++; - - if (locktoken_txt[strlen(locktoken_txt) - 1] != '>') { - /* ### should provide more specifics... */ - return HTTP_BAD_REQUEST; - } - locktoken_txt[strlen(locktoken_txt) - 1] = '\0'; + err = dav_parse_locktoken(r->pool, const_locktoken_txt, &locktoken_txt); + if (err != NULL) + return dav_handle_err(r, err, NULL); if ((err = (*locks_hooks->parse_locktoken)(r->pool, locktoken_txt, &locktoken)) != NULL) { diff --git a/modules/dav/main/mod_dav.h b/modules/dav/main/mod_dav.h index a481c4dd28..dd15c29ac8 100644 --- a/modules/dav/main/mod_dav.h +++ b/modules/dav/main/mod_dav.h @@ -1331,6 +1331,9 @@ struct dav_hooks_propdb DAV_DECLARE(time_t) dav_get_timeout(request_rec *r); DAV_DECLARE(time_t) dav_get_timeout_string(request_rec *r, const char *s); +DAV_DECLARE(dav_error *) dav_parse_locktoken(apr_pool_t *p, + const char *input, + char **output); /* ** Opaque, provider-specific information for a lock database. @@ -2756,5 +2759,4 @@ DAV_DECLARE(const dav_resource_type_provider *) dav_get_resource_type_providers( #endif #endif /* _MOD_DAV_H_ */ -/** @} */ - +/** @} */ \ No newline at end of file diff --git a/modules/dav/main/ms_wdv.c b/modules/dav/main/ms_wdv.c index cd9bb10cf5..1b80b9a8e2 100644 --- a/modules/dav/main/ms_wdv.c +++ b/modules/dav/main/ms_wdv.c @@ -36,13 +36,16 @@ static void delete_if_fixup(request_rec *r) const char *if_hdr; const char *cp; apr_size_t len; + int has_open, has_close; if ((if_hdr = apr_table_get(r->headers_in, "If")) == NULL) goto out; /* check for parenthesis enclosed value */ len = strlen(if_hdr); - if (if_hdr[0] != '(' || if_hdr[len - 1]!= ')') + has_open = (len > 0 && if_hdr[0] == '('); + has_close = (len > 0 && if_hdr[len - 1] == ')'); + if (!has_open || !has_close) goto out; for (cp = if_hdr; *cp; cp++) { @@ -197,10 +200,13 @@ static dav_error *mswdv_combined_lock(request_rec *r) * section 4.5 suggests using Lock-Token without brakets. */ if (lock_token_hdr) { - apr_size_t len = strlen(lock_token_hdr); + char *parsed_locktoken; - if (lock_token_hdr[0] == '<' || lock_token_hdr[len - 1] == '>') - lock_token_hdr = apr_pstrndup(r->pool, lock_token_hdr + 1, len - 2); + err = dav_parse_locktoken(r->pool, lock_token_hdr, &parsed_locktoken); + if (err != NULL) + goto out; + + lock_token_hdr = parsed_locktoken; } if (lock_timeout_hdr) { @@ -832,4 +838,3 @@ DAV_DECLARE(apr_status_t) dav_mswdv_input(ap_filter_t *f, return APR_SUCCESS; } - diff --git a/modules/dav/main/util.c b/modules/dav/main/util.c index 87d110d1b2..df1b349b5c 100644 --- a/modules/dav/main/util.c +++ b/modules/dav/main/util.c @@ -590,6 +590,36 @@ DAV_DECLARE(time_t) dav_get_timeout_string(request_rec *r, return DAV_TIMEOUT_INFINITE; } +DAV_DECLARE(dav_error *) dav_parse_locktoken(apr_pool_t *p, + const char *input, + char **output) +{ + char *token; + apr_size_t len; + int has_open; + int has_close; + + *output = NULL; + + len = strlen(input); + has_open = (len > 0 && input[0] == '<'); + has_close = (len > 2 && input[len - 1] == '>'); + + if (len < 2 || !has_open || !has_close) { + return dav_new_error(p, HTTP_BAD_REQUEST, 0, 0, + "Malformed Lock-Token"); + } + + token = apr_pstrmemdup(p, input + 1, len - 2); + if (*token == '\0') { + return dav_new_error(p, HTTP_BAD_REQUEST, 0, 0, + "Malformed Lock-Token"); + } + + *output = token; + return NULL; +} + /* --------------------------------------------------------------- ** ** If Header processing