diff options
Diffstat (limited to 'modules/dav/main/util.c')
-rw-r--r-- | modules/dav/main/util.c | 87 |
1 files changed, 74 insertions, 13 deletions
diff --git a/modules/dav/main/util.c b/modules/dav/main/util.c index 9f24604..3f7822f 100644 --- a/modules/dav/main/util.c +++ b/modules/dav/main/util.c @@ -101,6 +101,9 @@ DAV_DECLARE(dav_error*) dav_join_error(dav_error *dest, dav_error *src) return dest; } +/* ### Unclear if this was designed to be used with an uninitialized + * dav_buffer struct, but is used on by dav_lock_get_activelock(). + * Hence check for pbuf->buf. */ DAV_DECLARE(void) dav_check_bufsize(apr_pool_t * p, dav_buffer *pbuf, apr_size_t extra_needed) { @@ -110,7 +113,8 @@ DAV_DECLARE(void) dav_check_bufsize(apr_pool_t * p, dav_buffer *pbuf, pbuf->alloc_len += extra_needed + DAV_BUFFER_PAD; newbuf = apr_palloc(p, pbuf->alloc_len); - memcpy(newbuf, pbuf->buf, pbuf->cur_len); + if (pbuf->buf) + memcpy(newbuf, pbuf->buf, pbuf->cur_len); pbuf->buf = newbuf; } } @@ -240,7 +244,7 @@ DAV_DECLARE(dav_lookup_result) dav_lookup_uri(const char *uri, request. the port must match our port. */ port = r->connection->local_addr->port; - if (strcasecmp(comp.scheme, scheme) != 0 + if (ap_cstr_casecmp(comp.scheme, scheme) != 0 #ifdef APACHE_PORT_HANDLING_IS_BUSTED || comp.port != port #endif @@ -312,26 +316,71 @@ DAV_DECLARE(dav_lookup_result) dav_lookup_uri(const char *uri, */ /* validate that the root element uses a given DAV: tagname (TRUE==valid) */ -DAV_DECLARE(int) dav_validate_root(const apr_xml_doc *doc, - const char *tagname) +DAV_DECLARE(int) dav_validate_root_ns(const apr_xml_doc *doc, + int ns, const char *tagname) { return doc->root && - doc->root->ns == APR_XML_NS_DAV_ID && + doc->root->ns == ns && strcmp(doc->root->name, tagname) == 0; } -/* find and return the (unique) child with a given DAV: tagname */ -DAV_DECLARE(apr_xml_elem *) dav_find_child(const apr_xml_elem *elem, - const char *tagname) +/* validate that the root element uses a given DAV: tagname (TRUE==valid) */ +DAV_DECLARE(int) dav_validate_root(const apr_xml_doc *doc, + const char *tagname) +{ + return dav_validate_root_ns(doc, APR_XML_NS_DAV_ID, tagname); +} + +/* find and return the next child with a tagname in the given namespace */ +DAV_DECLARE(apr_xml_elem *) dav_find_next_ns(const apr_xml_elem *elem, + int ns, const char *tagname) +{ + apr_xml_elem *child = elem->next; + + for (; child; child = child->next) + if (child->ns == ns && !strcmp(child->name, tagname)) + return child; + return NULL; +} + +/* find and return the (unique) child with a tagname in the given namespace */ +DAV_DECLARE(apr_xml_elem *) dav_find_child_ns(const apr_xml_elem *elem, + int ns, const char *tagname) { apr_xml_elem *child = elem->first_child; for (; child; child = child->next) - if (child->ns == APR_XML_NS_DAV_ID && !strcmp(child->name, tagname)) + if (child->ns == ns && !strcmp(child->name, tagname)) return child; return NULL; } +/* find and return the (unique) child with a given DAV: tagname */ +DAV_DECLARE(apr_xml_elem *) dav_find_child(const apr_xml_elem *elem, + const char *tagname) +{ + return dav_find_child_ns(elem, APR_XML_NS_DAV_ID, tagname); +} + +/* find and return the attribute with a name in the given namespace */ +DAV_DECLARE(apr_xml_attr *) dav_find_attr_ns(const apr_xml_elem *elem, + int ns, const char *attrname) +{ + apr_xml_attr *attr = elem->attr; + + for (; attr; attr = attr->next) + if (attr->ns == ns && !strcmp(attr->name, attrname)) + return attr; + return NULL; +} + +/* find and return the attribute with a given DAV: tagname */ +DAV_DECLARE(apr_xml_attr *) dav_find_attr(const apr_xml_elem *elem, + const char *attrname) +{ + return dav_find_attr_ns(elem, APR_XML_NS_DAV_ID, attrname); +} + /* gather up all the CDATA into a single string */ DAV_DECLARE(const char *) dav_xml_get_cdata(const apr_xml_elem *elem, apr_pool_t *pool, int strip_white) @@ -470,8 +519,8 @@ DAV_DECLARE(void) dav_xmlns_generate(dav_xmlns_info *xi, apr_hash_this(hi, &prefix, NULL, &uri); - s = apr_psprintf(xi->pool, " xmlns:%s=\"%s\"", - (const char *)prefix, (const char *)uri); + s = apr_pstrcat(xi->pool, " xmlns:", (const char *)prefix, "=\"", + (const char *)uri, "\"", NULL); apr_text_append(xi->pool, phdr, s); } } @@ -660,7 +709,13 @@ static dav_error * dav_process_if_header(request_rec *r, dav_if_header **p_ih) /* note that parsed_uri.path is allocated; we can trash it */ /* clean up the URI a bit */ - ap_getparents(parsed_uri.path); + if (!ap_normalize_path(parsed_uri.path, + AP_NORMALIZE_NOT_ABOVE_ROOT | + AP_NORMALIZE_DECODE_UNRESERVED)) { + return dav_new_error(r->pool, HTTP_BAD_REQUEST, + DAV_ERR_IF_TAGGED, rv, + "Invalid URI path tagged If-header."); + } /* the resources we will compare to have unencoded paths */ if (ap_unescape_url(parsed_uri.path) != OK) { @@ -746,8 +801,14 @@ static dav_error * dav_process_if_header(request_rec *r, dav_if_header **p_ih) "for the same state."); } condition = DAV_IF_COND_NOT; + list += 2; + } + else { + return dav_new_error(r->pool, HTTP_BAD_REQUEST, + DAV_ERR_IF_UNK_CHAR, 0, + "Invalid \"If:\" header: " + "Unexpected character in List"); } - list += 2; break; case ' ': |