summaryrefslogtreecommitdiffstats
path: root/modules/dav/main/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/dav/main/util.c')
-rw-r--r--modules/dav/main/util.c87
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 ' ':