From: Greg Stein Date: Mon, 3 Jul 2000 22:51:03 +0000 (+0000) Subject: Joe Orton writes: X-Git-Tag: APACHE_2_0_ALPHA_5~184 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6dcafac17f320bba2a71eb28a10199bb93d0660c;p=thirdparty%2Fapache%2Fhttpd.git Joe Orton writes: This updates mod_dav for the util_xml changes posted previously: * dav_xml -> ap_xml, and dav_text -> ap_text renaming * Add 'dav_elem_private' to hook mod_dav-specific info up to the parsed XML tree. Initialize this in several places, I think I got all necessary? [gjs: yes, you did] * Removal of the old "gross_hack", and all the XML code that was moved into util_xml Submitted by: Joe Orton Reviewed by: Greg Stein git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@85761 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/dav/fs/repos.c b/modules/dav/fs/repos.c index 7c23e178ac5..5481e9664d5 100644 --- a/modules/dav/fs/repos.c +++ b/modules/dav/fs/repos.c @@ -1685,7 +1685,7 @@ static int dav_fs_find_prop(const char *ns_uri, const char *name) static dav_prop_insert dav_fs_insert_prop(const dav_resource *resource, int propid, int insvalue, const int *ns_map, - dav_text_header *phdr) + ap_text_header *phdr) { const char *value; const char *s; @@ -1781,6 +1781,7 @@ static dav_prop_insert dav_fs_insert_prop(const dav_resource *resource, for (scan = dav_fs_props; scan->name != NULL; ++scan) if (scan->propid == propid) break; + /* assert: scan->name != NULL */ /* map our NS index into a global NS index */ @@ -1799,14 +1800,14 @@ static dav_prop_insert dav_fs_insert_prop(const dav_resource *resource, s = ap_psprintf(p, "" DEBUG_CR, ns, scan->name); which = DAV_PROP_INSERT_NAME; } - dav_text_append(p, phdr, s); + ap_text_append(p, phdr, s); /* we inserted a name or value (this prop is done) */ return which; } static void dav_fs_insert_all(const dav_resource *resource, int insvalue, - const int *ns_map, dav_text_header *phdr) + const int *ns_map, ap_text_header *phdr) { if (!resource->exists) { /* a lock-null resource */ @@ -1859,16 +1860,17 @@ static dav_prop_rw dav_fs_is_writeable(const dav_resource *resource, } static dav_error *dav_fs_patch_validate(const dav_resource *resource, - const dav_xml_elem *elem, + const ap_xml_elem *elem, int operation, void **context, int *defer_to_dead) { - const dav_text *cdata; - const dav_text *f_cdata; + const ap_text *cdata; + const ap_text *f_cdata; char value; + dav_elem_private *priv = elem->private; - if (elem->propid != DAV_PROPID_FS_executable) { + if (priv->propid != DAV_PROPID_FS_executable) { *defer_to_dead = 1; return NULL; } @@ -1885,7 +1887,7 @@ static dav_error *dav_fs_patch_validate(const dav_resource *resource, ? NULL : elem->first_child->following_cdata.first; - DBG3("name=%s cdata=%s f_cdata=%s",elem->name,cdata ? cdata->text : "[null]",f_cdata ? f_cdata->text : "[null]"); + /* DBG3("name=%s cdata=%s f_cdata=%s",elem->name,cdata ? cdata->text : "[null]",f_cdata ? f_cdata->text : "[null]"); */ if (cdata == NULL) { if (f_cdata == NULL) { @@ -1923,7 +1925,7 @@ static dav_error *dav_fs_patch_validate(const dav_resource *resource, } static dav_error *dav_fs_patch_exec(dav_resource *resource, - const dav_xml_elem *elem, + const ap_xml_elem *elem, int operation, void *context, dav_liveprop_rollback **rollback_ctx) @@ -1935,7 +1937,7 @@ static dav_error *dav_fs_patch_exec(dav_resource *resource, /* assert: prop == executable. operation == SET. */ /* don't do anything if there is no change. no rollback info either. */ - DBG2("new value=%d (old=%d)", value, old_value); + /* DBG2("new value=%d (old=%d)", value, old_value); */ if (value == old_value) return NULL; diff --git a/modules/dav/main/mod_dav.c b/modules/dav/main/mod_dav.c index 48a2634f294..ab7709313ee 100644 --- a/modules/dav/main/mod_dav.c +++ b/modules/dav/main/mod_dav.c @@ -546,7 +546,7 @@ static const char *dav_xml_escape_uri(ap_pool_t *p, const char *uri) ** Note: this is a teeny bit of overkill since we know there are no ** '<' or '>' characters, but who cares. */ - return dav_quote_string(p, e_uri, 0); + return ap_xml_quote_string(p, e_uri, 0); } static void dav_send_multistatus(request_rec *r, int status, @@ -569,7 +569,7 @@ static void dav_send_multistatus(request_rec *r, int status, for (i = namespaces->nelts; i--; ) { ap_rprintf(r, " xmlns:ns%d=\"%s\"", i, - DAV_GET_URI_ITEM(namespaces, i)); + AP_XML_GET_URI_ITEM(namespaces, i)); } } @@ -577,7 +577,7 @@ static void dav_send_multistatus(request_rec *r, int status, ap_rputs(">" DEBUG_CR, r); for (; first != NULL; first = first->next) { - dav_text *t; + ap_text *t; if (first->propresult.xmlns == NULL) { ap_rputs("", r); @@ -1563,27 +1563,27 @@ static int dav_method_options(request_rec *r) static void dav_cache_badprops(dav_walker_ctx *ctx) { - const dav_xml_elem *elem; - dav_text_header hdr = { 0 }; + const ap_xml_elem *elem; + ap_text_header hdr = { 0 }; /* just return if we built the thing already */ if (ctx->propstat_404 != NULL) { return; } - dav_text_append(ctx->pool, &hdr, - "" DEBUG_CR - "" DEBUG_CR); + ap_text_append(ctx->pool, &hdr, + "" DEBUG_CR + "" DEBUG_CR); elem = dav_find_child(ctx->doc->root, "prop"); for (elem = elem->first_child; elem; elem = elem->next) { - dav_text_append(ctx->pool, &hdr, dav_empty_elem(ctx->pool, elem)); + ap_text_append(ctx->pool, &hdr, ap_xml_empty_elem(ctx->pool, elem)); } - dav_text_append(ctx->pool, &hdr, - "" DEBUG_CR - "HTTP/1.1 404 Not Found" DEBUG_CR - "" DEBUG_CR); + ap_text_append(ctx->pool, &hdr, + "" DEBUG_CR + "HTTP/1.1 404 Not Found" DEBUG_CR + "" DEBUG_CR); ctx->propstat_404 = hdr.first; } @@ -1645,8 +1645,8 @@ static int dav_method_propfind(request_rec *r) int depth; dav_error *err; int result; - dav_xml_doc *doc; - const dav_xml_elem *child; + ap_xml_doc *doc; + const ap_xml_elem *child; dav_walker_ctx ctx = { 0 }; /* Ask repository module to resolve the resource */ @@ -1681,7 +1681,7 @@ static int dav_method_propfind(request_rec *r) } } - if ((result = dav_parse_input(r, &doc)) != OK) { + if ((result = ap_xml_parse_input(r, &doc)) != OK) { return result; } /* note: doc == NULL if no request body */ @@ -1769,10 +1769,10 @@ static int dav_method_propfind(request_rec *r) return DONE; } -static dav_text * dav_failed_proppatch(ap_pool_t *p, +static ap_text * dav_failed_proppatch(ap_pool_t *p, ap_array_header_t *prop_ctx) { - dav_text_header hdr = { 0 }; + ap_text_header hdr = { 0 }; int i = prop_ctx->nelts; dav_prop_ctx *ctx = (dav_prop_ctx *)prop_ctx->elts; dav_error *err424_set = NULL; @@ -1782,11 +1782,11 @@ static dav_text * dav_failed_proppatch(ap_pool_t *p, /* ### might be nice to sort by status code and description */ for ( ; i-- > 0; ++ctx ) { - dav_text_append(p, &hdr, - "" DEBUG_CR - ""); - dav_text_append(p, &hdr, dav_empty_elem(p, ctx->prop)); - dav_text_append(p, &hdr, "" DEBUG_CR); + ap_text_append(p, &hdr, + "" DEBUG_CR + ""); + ap_text_append(p, &hdr, ap_xml_empty_elem(p, ctx->prop)); + ap_text_append(p, &hdr, "" DEBUG_CR); if (ctx->err == NULL) { /* nothing was assigned here yet, so make it a 424 */ @@ -1815,24 +1815,24 @@ static dav_text * dav_failed_proppatch(ap_pool_t *p, "HTTP/1.1 %d (status)" "" DEBUG_CR, ctx->err->status); - dav_text_append(p, &hdr, s); + ap_text_append(p, &hdr, s); /* ### we should use compute_desc if necessary... */ if (ctx->err->desc != NULL) { - dav_text_append(p, &hdr, "" DEBUG_CR); - dav_text_append(p, &hdr, ctx->err->desc); - dav_text_append(p, &hdr, "" DEBUG_CR); + ap_text_append(p, &hdr, "" DEBUG_CR); + ap_text_append(p, &hdr, ctx->err->desc); + ap_text_append(p, &hdr, "" DEBUG_CR); } - dav_text_append(p, &hdr, "" DEBUG_CR); + ap_text_append(p, &hdr, "" DEBUG_CR); } return hdr.first; } -static dav_text * dav_success_proppatch(ap_pool_t *p, ap_array_header_t *prop_ctx) +static ap_text * dav_success_proppatch(ap_pool_t *p, ap_array_header_t *prop_ctx) { - dav_text_header hdr = { 0 }; + ap_text_header hdr = { 0 }; int i = prop_ctx->nelts; dav_prop_ctx *ctx = (dav_prop_ctx *)prop_ctx->elts; @@ -1841,15 +1841,15 @@ static dav_text * dav_success_proppatch(ap_pool_t *p, ap_array_header_t *prop_ct ** ### this code assumes everything will return status==200. */ - dav_text_append(p, &hdr, - "" DEBUG_CR - "" DEBUG_CR); + ap_text_append(p, &hdr, + "" DEBUG_CR + "" DEBUG_CR); for ( ; i-- > 0; ++ctx ) { - dav_text_append(p, &hdr, dav_empty_elem(p, ctx->prop)); + ap_text_append(p, &hdr, ap_xml_empty_elem(p, ctx->prop)); } - dav_text_append(p, &hdr, + ap_text_append(p, &hdr, "" DEBUG_CR "HTTP/1.1 200 OK" DEBUG_CR "" DEBUG_CR); @@ -1904,12 +1904,12 @@ static int dav_method_proppatch(request_rec *r) dav_error *err; dav_resource *resource; int result; - dav_xml_doc *doc; - dav_xml_elem *child; + ap_xml_doc *doc; + ap_xml_elem *child; dav_propdb *propdb; int failure = 0; dav_response resp = { 0 }; - dav_text *propstat_text; + ap_text *propstat_text; ap_array_header_t *ctx_list; dav_prop_ctx *ctx; @@ -1922,7 +1922,7 @@ static int dav_method_proppatch(request_rec *r) return HTTP_NOT_FOUND; } - if ((result = dav_parse_input(r, &doc)) != OK) { + if ((result = ap_xml_parse_input(r, &doc)) != OK) { return result; } /* note: doc == NULL if no request body */ @@ -1963,11 +1963,11 @@ static int dav_method_proppatch(request_rec *r) /* do a first pass to ensure that all "remove" properties exist */ for (child = doc->root->first_child; child; child = child->next) { int is_remove; - dav_xml_elem *prop_group; - dav_xml_elem *one_prop; + ap_xml_elem *prop_group; + ap_xml_elem *one_prop; /* Ignore children that are not set/remove */ - if (child->ns != DAV_NS_DAV_ID + if (child->ns != AP_XML_NS_DAV_ID || (!(is_remove = strcmp(child->name, "remove") == 0) && strcmp(child->name, "set") != 0)) { continue; @@ -2601,7 +2601,7 @@ static int dav_method_lock(request_rec *r) int result; int depth; int new_lock_request = 0; - dav_xml_doc *doc = NULL; + ap_xml_doc *doc = NULL; dav_lock *lock; dav_response *multi_response = NULL; dav_lockdb *lockdb; @@ -2612,7 +2612,7 @@ static int dav_method_lock(request_rec *r) if (locks_hooks == NULL) return DECLINED; - if ((result = dav_parse_input(r, &doc)) != OK) + if ((result = ap_xml_parse_input(r, &doc)) != OK) return result; depth = dav_get_depth(r, DAV_INFINITY); diff --git a/modules/dav/main/mod_dav.h b/modules/dav/main/mod_dav.h index 746f5a0abdc..d33901e6006 100644 --- a/modules/dav/main/mod_dav.h +++ b/modules/dav/main/mod_dav.h @@ -64,6 +64,8 @@ extern "C" { #endif #include "httpd.h" +#include "util_xml.h" + #include /* for INT_MAX */ @@ -333,24 +335,11 @@ void dav_buffer_place_mem(ap_pool_t *p, dav_buffer *pbuf, const void *mem, ** HANDY UTILITIES */ -/* simple strutures to keep a linked list of pieces of text */ -typedef struct dav_text -{ - const char *text; - struct dav_text *next; -} dav_text; - -typedef struct -{ - dav_text *first; - dav_text *last; -} dav_text_header; - /* contains results from one of the getprop functions */ typedef struct { - dav_text * propstats; /* element text */ - dav_text * xmlns; /* namespace decls for elem */ + ap_text * propstats; /* element text */ + ap_text * xmlns; /* namespace decls for elem */ } dav_get_props_result; /* holds the contents of a element */ @@ -374,10 +363,9 @@ typedef struct } dav_lookup_result; -void dav_text_append(ap_pool_t *p, dav_text_header *hdr, const char *text); - dav_lookup_result dav_lookup_uri(const char *uri, request_rec *r); +/* ### this stuff is private to dav/fs/repos.c; move it... */ /* format a time string (buf must be at least DAV_TIMEBUF_SIZE chars) */ #define DAV_STYLE_ISO8601 1 #define DAV_STYLE_RFC822 2 @@ -385,6 +373,9 @@ dav_lookup_result dav_lookup_uri(const char *uri, request_rec *r); int dav_get_depth(request_rec *r, int def_depth); +int dav_validate_root(const ap_xml_doc *doc, const char *tagname); +ap_xml_elem *dav_find_child(const ap_xml_elem *elem, const char *tagname); + /* -------------------------------------------------------------------- ** @@ -626,147 +617,6 @@ typedef struct dav_locktoken_list dav_error * dav_get_locktoken_list(request_rec *r, dav_locktoken_list **ltl); -/* -------------------------------------------------------------------- -** -** XML PARSING -*/ - -/* -** Qualified namespace values -** -** DAV_NS_DAV_ID -** We always insert the "DAV:" namespace URI at the head of the -** namespace array. This means that it will always be at ID==0, -** making it much easier to test for. -** -** DAV_NS_NONE -** This special ID is used for two situations: -** -** 1) The namespace prefix begins with "xml" (and we do not know -** what it means). Namespace prefixes with "xml" (any case) as -** their first three characters are reserved by the XML Namespaces -** specification for future use. mod_dav will pass these through -** unchanged. When this identifier is used, the prefix is LEFT in -** the element/attribute name. Downstream processing should not -** prepend another prefix. -** -** 2) The element/attribute does not have a namespace. -** -** a) No prefix was used, and a default namespace has not been -** defined. -** b) No prefix was used, and the default namespace was specified -** to mean "no namespace". This is done with a namespace -** declaration of: xmlns="" -** (this declaration is typically used to override a previous -** specification for the default namespace) -** -** In these cases, we need to record that the elem/attr has no -** namespace so that we will not attempt to prepend a prefix. -** All namespaces that are used will have a prefix assigned to -** them -- mod_dav will never set or use the default namespace -** when generating XML. This means that "no prefix" will always -** mean "no namespace". -** -** In both cases, the XML generation will avoid prepending a prefix. -** For the first case, this means the original prefix/name will be -** inserted into the output stream. For the latter case, it means -** the name will have no prefix, and since we never define a default -** namespace, this means it will have no namespace. -** -** Note: currently, mod_dav understands the "xmlns" prefix and the -** "xml:lang" attribute. These are handled specially (they aren't -** left within the XML tree), so the DAV_NS_NONE value won't ever -** really apply to these values. -*/ -#define DAV_NS_DAV_ID 0 /* namespace ID for "DAV:" */ -#define DAV_NS_NONE -10 /* no namespace for this elem/attr */ - -#define DAV_NS_ERROR_BASE -100 /* used only during processing */ -#define DAV_NS_IS_ERROR(e) ((e) <= DAV_NS_ERROR_BASE) - - -/* -** dav_xml_doc: holds a parsed XML document -** dav_xml_elem: holds a parsed XML element -** dav_xml_attr: holds a parsed XML attribute -** -** dav_xml_ns_scope: internal struct used during processing to scope -** namespace declarations -*/ - -typedef struct dav_xml_attr -{ - const char *name; /* attribute name */ - int ns; /* index into namespace array */ - - const char *value; /* attribute value */ - - struct dav_xml_attr *next; /* next attribute */ -} dav_xml_attr; - -typedef struct dav_xml_elem -{ - const char *name; /* element name */ - int ns; /* index into namespace array */ - const char *lang; /* xml:lang for attrs/contents */ - - dav_text_header first_cdata; /* cdata right after start tag */ - dav_text_header following_cdata; /* cdata after MY end tag */ - - struct dav_xml_elem *parent; /* parent element */ - struct dav_xml_elem *next; /* next (sibling) element */ - struct dav_xml_elem *first_child; /* first child element */ - struct dav_xml_attr *attr; /* first attribute */ - - /* used only during parsing */ - struct dav_xml_elem *last_child; /* last child element */ - struct dav_xml_ns_scope *ns_scope; /* namespaces scoped by this elem */ - - /* used during request processing */ - int propid; /* live property ID */ - const dav_hooks_liveprop *provider; /* the provider defining this prop */ - const int *ns_map; /* ns map for this provider */ - -} dav_xml_elem; - -#define DAV_ELEM_IS_EMPTY(e) ((e)->first_child == NULL && \ - (e)->first_cdata.first == NULL) - -typedef struct dav_xml_doc -{ - dav_xml_elem *root; /* root element */ - ap_array_header_t *namespaces; /* array of namespaces used */ - -} dav_xml_doc; - - -int dav_parse_input(request_rec *r, dav_xml_doc **pdoc); - -int dav_validate_root(const dav_xml_doc *doc, const char *tagname); - -dav_xml_elem *dav_find_child( - const dav_xml_elem *elem, - const char *tagname); - -void dav_xml2text( - ap_pool_t *p, - const dav_xml_elem *elem, - int style, - ap_array_header_t *namespaces, - int *ns_map, - const char **pbuf, - size_t *psize - ); -#define DAV_X2T_FULL 0 /* start tag, contents, end tag */ -#define DAV_X2T_INNER 1 /* contents only */ -#define DAV_X2T_LANG_INNER 2 /* xml:lang + inner contents */ -#define DAV_X2T_FULL_NS_LANG 3 /* FULL + ns defns + xml:lang */ - -const char *dav_empty_elem(ap_pool_t *p, const dav_xml_elem *elem); -void dav_quote_xml_elem(ap_pool_t *p, dav_xml_elem *elem); -const char * dav_quote_string(ap_pool_t *p, const char *s, int quotes); - - /* -------------------------------------------------------------------- ** ** LIVE PROPERTY HANDLING @@ -835,7 +685,7 @@ struct dav_hooks_liveprop */ dav_prop_insert (*insert_prop)(const dav_resource *resource, int propid, int insvalue, - const int *ns_map, dav_text_header *phdr); + const int *ns_map, ap_text_header *phdr); /* ** Insert all known/defined property names (and values). This is @@ -843,7 +693,7 @@ struct dav_hooks_liveprop ** rather than specific, individual properties. */ void (*insert_all)(const dav_resource *resource, int insvalue, - const int *ns_map, dav_text_header *phdr); + const int *ns_map, ap_text_header *phdr); /* ** Determine whether a given property is writeable. @@ -896,14 +746,14 @@ struct dav_hooks_liveprop ** database. Note: it will be set to zero on entry. */ dav_error * (*patch_validate)(const dav_resource *resource, - const dav_xml_elem *elem, + const ap_xml_elem *elem, int operation, void **context, int *defer_to_dead); /* ### doc... */ dav_error * (*patch_exec)(dav_resource *resource, - const dav_xml_elem *elem, + const ap_xml_elem *elem, int operation, void *context, dav_liveprop_rollback **rollback_ctx); @@ -1091,7 +941,7 @@ const char *dav_get_lockdb_path(const request_rec *r); dav_error * dav_lock_parse_lockinfo(request_rec *r, const dav_resource *resrouce, dav_lockdb *lockdb, - const dav_xml_doc *doc, + const ap_xml_doc *doc, dav_lock **lock_request); int dav_unlock(request_rec *r, const dav_resource *resource, const dav_locktoken *locktoken); @@ -1351,7 +1201,7 @@ void dav_close_propdb(dav_propdb *db); dav_get_props_result dav_get_props( dav_propdb *db, - dav_xml_doc *doc); + ap_xml_doc *doc); dav_get_props_result dav_get_allprops( dav_propdb *db, @@ -1402,7 +1252,7 @@ typedef struct dav_prop_ctx #define DAV_PROP_OP_DELETE 2 /* delete a prop value */ /* ### add a GET? */ - dav_xml_elem *prop; /* property to affect */ + ap_xml_elem *prop; /* property to affect */ dav_error *err; /* error (if any) */ @@ -1463,13 +1313,13 @@ typedef struct dav_walker_ctx dav_response *response; /* OUT: multistatus responses */ /* for PROPFIND operations */ - dav_xml_doc *doc; + ap_xml_doc *doc; int propfind_type; #define DAV_PROPFIND_IS_ALLPROP 1 #define DAV_PROPFIND_IS_PROPNAME 2 #define DAV_PROPFIND_IS_PROP 3 - dav_text *propstat_404; /* (cached) propstat giving a 404 error */ + ap_text *propstat_404; /* (cached) propstat giving a 404 error */ /* for COPY and MOVE operations */ int is_move; @@ -1835,12 +1685,11 @@ ap_table_t *dav_get_dir_params(const request_rec *r); /* fetch the "LimitXMLRequestBody" in force for this resource */ size_t dav_get_limit_xml_body(const request_rec *r); -/* manage an array of unique URIs: dav_insert_uri() and DAV_GET_URI_ITEM() */ - -/* return the URI's (existing) index, or insert it and return a new index */ -int dav_insert_uri(ap_array_header_t *uri_array, const char *uri); -#define DAV_GET_URI_ITEM(ary, i) (((const char * const *)(ary)->elts)[i]) - +typedef struct { + int propid; /* live property ID */ + const dav_hooks_liveprop *provider; /* the provider defining this prop */ + const int *ns_map; /* ns map for this provider */ +} dav_elem_private; #ifdef __cplusplus } diff --git a/modules/dav/main/props.c b/modules/dav/main/props.c index 4a9c3973979..2a346c77ff3 100644 --- a/modules/dav/main/props.c +++ b/modules/dav/main/props.c @@ -202,7 +202,7 @@ #define DAV_EMPTY_VALUE "\0" /* TWO null terms */ /* the namespace URI was not found; no ID is available */ -#define DAV_NS_ERROR_NOT_FOUND (DAV_NS_ERROR_BASE) +#define AP_XML_NS_ERROR_NOT_FOUND (AP_XML_NS_ERROR_BASE) typedef struct { unsigned char major; @@ -322,42 +322,43 @@ static const char *dav_get_ns_table_uri(dav_propdb *propdb, int ns) } #endif -static void dav_find_liveprop(dav_propdb *propdb, dav_xml_elem *elem) +static void dav_find_liveprop(dav_propdb *propdb, ap_xml_elem *elem) { int propid; const char *ns_uri; const dav_dyn_hooks *ddh; + dav_elem_private *priv = elem->private; - if (elem->ns == DAV_NS_DAV_ID) { + if (elem->ns == AP_XML_NS_DAV_ID) { const char * const *p = dav_core_props; for (propid = DAV_PROPID_CORE; *p != NULL; ++p, ++propid) if (strcmp(elem->name, *p) == 0) { - elem->propid = propid; + priv->propid = propid; return; } /* didn't find it. fall thru. a provider can define DAV: props */ } - else if (elem->ns == DAV_NS_NONE) { + else if (elem->ns == AP_XML_NS_NONE) { /* policy: liveprop providers cannot define no-namespace properties */ - elem->propid = DAV_PROPID_CORE_UNKNOWN; + priv->propid = DAV_PROPID_CORE_UNKNOWN; return; } - ns_uri = DAV_GET_URI_ITEM(propdb->ns_xlate, elem->ns); + ns_uri = AP_XML_GET_URI_ITEM(propdb->ns_xlate, elem->ns); for (ddh = propdb->liveprop; ddh != NULL; ddh = ddh->next) { propid = (*DAV_AS_HOOKS_LIVEPROP(ddh)->find_prop)(ns_uri, elem->name); if (propid != 0) { - elem->propid = propid; - elem->provider = DAV_AS_HOOKS_LIVEPROP(ddh); - elem->ns_map = ddh->ctx.ns_map; + priv->propid = propid; + priv->provider = DAV_AS_HOOKS_LIVEPROP(ddh); + priv->ns_map = ddh->ctx.ns_map; return; } } - elem->propid = DAV_PROPID_CORE_UNKNOWN; + priv->propid = DAV_PROPID_CORE_UNKNOWN; } /* is the live property read/write? */ @@ -415,7 +416,7 @@ static void dav_do_prop_subreq(dav_propdb *propdb) static dav_error * dav_insert_coreprop(dav_propdb *propdb, int propid, const char *name, int getvals, - dav_text_header *phdr, + ap_text_header *phdr, int *inserted) { const char *value = NULL; @@ -542,7 +543,7 @@ static dav_error * dav_insert_coreprop(dav_propdb *propdb, /* use D: prefix to refer to the DAV: namespace URI */ s = ap_psprintf(propdb->p, "" DEBUG_CR, name); } - dav_text_append(propdb->p, phdr, s); + ap_text_append(propdb->p, phdr, s); *inserted = 1; } @@ -551,22 +552,23 @@ static dav_error * dav_insert_coreprop(dav_propdb *propdb, } static dav_error * dav_insert_liveprop(dav_propdb *propdb, - const dav_xml_elem *elem, + const ap_xml_elem *elem, int getvals, - dav_text_header *phdr, + ap_text_header *phdr, int *inserted) { dav_prop_insert pi; + dav_elem_private *priv = elem->private; *inserted = 0; - if (DAV_IS_CORE_PROP(elem->propid)) - return dav_insert_coreprop(propdb, elem->propid, elem->name, + if (DAV_IS_CORE_PROP(priv->propid)) + return dav_insert_coreprop(propdb, priv->propid, elem->name, getvals, phdr, inserted); /* ask the provider (that defined this prop) to insert the prop */ - pi = (*elem->provider->insert_prop)(propdb->resource, elem->propid, - getvals, elem->ns_map, phdr); + pi = (*priv->provider->insert_prop)(propdb->resource, priv->propid, + getvals, priv->ns_map, phdr); #if DAV_DEBUG if (pi == DAV_PROP_INSERT_NOTME) { /* ### the provider should have returned NOTDEF, at least */ @@ -585,7 +587,7 @@ static dav_error * dav_insert_liveprop(dav_propdb *propdb, static void dav_append_prop(dav_propdb *propdb, const char *name, const char *value, - dav_text_header *phdr) + ap_text_header *phdr) { const char *s; const char *lang = value; @@ -621,7 +623,7 @@ static void dav_append_prop(dav_propdb *propdb, else { s = ap_psprintf(propdb->p, "%s" DEBUG_CR, name, value, name); } - dav_text_append(propdb->p, phdr, s); + ap_text_append(propdb->p, phdr, s); } /* @@ -640,7 +642,7 @@ static void dav_append_prop(dav_propdb *propdb, ** ### we should always initialize the propdb namespace array with "DAV:" ** ### since we know it will be entered anyhow (by virtue of it always ** ### occurring in the ns_xlate array). That will allow us to use -** ### DAV_NS_DAV_ID for propdb ns values, too. +** ### AP_XML_NS_DAV_ID for propdb ns values, too. */ static void dav_prep_ns_map(dav_propdb *propdb, int add_ns) { @@ -678,7 +680,7 @@ static void dav_prep_ns_map(dav_propdb *propdb, int add_ns) if (updating) { /* updating an existing mapping... we can skip a lot of stuff */ - if (*pmap != DAV_NS_ERROR_NOT_FOUND) { + if (*pmap != AP_XML_NS_ERROR_NOT_FOUND) { /* This entry has been filled in, so we can skip it */ continue; } @@ -711,7 +713,7 @@ static void dav_prep_ns_map(dav_propdb *propdb, int add_ns) } if (!add_ns) { - *pmap = DAV_NS_ERROR_NOT_FOUND; + *pmap = AP_XML_NS_ERROR_NOT_FOUND; /* ** This flag indicates that we have an ns_map with missing @@ -763,16 +765,16 @@ static int dav_find_dav_id(dav_propdb *propdb) } static void dav_insert_xmlns(ap_pool_t *p, const char *pre_prefix, int ns, - const char *ns_uri, dav_text_header *phdr) + const char *ns_uri, ap_text_header *phdr) { const char *s; s = ap_psprintf(p, " xmlns:%s%d=\"%s\"", pre_prefix, ns, ns_uri); - dav_text_append(p, phdr, s); + ap_text_append(p, phdr, s); } /* return all known namespaces (in this propdb) */ -static void dav_get_propdb_xmlns(dav_propdb *propdb, dav_text_header *phdr) +static void dav_get_propdb_xmlns(dav_propdb *propdb, ap_text_header *phdr) { int i; const char *p = propdb->ns_table.buf + sizeof(dav_propdb_metadata); @@ -791,14 +793,14 @@ static void dav_get_propdb_xmlns(dav_propdb *propdb, dav_text_header *phdr) static void dav_add_marked_xmlns(dav_propdb *propdb, char *marks, int ns, ap_array_header_t *ns_table, const char *pre_prefix, - dav_text_header *phdr) + ap_text_header *phdr) { if (marks[ns]) return; marks[ns] = 1; dav_insert_xmlns(propdb->p, - pre_prefix, ns, DAV_GET_URI_ITEM(ns_table, ns), + pre_prefix, ns, AP_XML_GET_URI_ITEM(ns_table, ns), phdr); } @@ -809,7 +811,7 @@ static void dav_add_marked_xmlns(dav_propdb *propdb, char *marks, int ns, ** value must be copied or no longer used if this function is ** called again. */ -static dav_datum dav_gdbm_key(dav_propdb *propdb, const dav_xml_elem *elem) +static dav_datum dav_gdbm_key(dav_propdb *propdb, const ap_xml_elem *elem) { int ns; char nsbuf[20]; @@ -822,7 +824,7 @@ static dav_datum dav_gdbm_key(dav_propdb *propdb, const dav_xml_elem *elem) * so the keys will have the form ":name". Otherwise, the keys will * have the form "#:name". */ - if (elem->ns == DAV_NS_NONE) { + if (elem->ns == AP_XML_NS_NONE) { nsbuf[0] = '\0'; l_ns = 0; } @@ -837,7 +839,7 @@ static dav_datum dav_gdbm_key(dav_propdb *propdb, const dav_xml_elem *elem) } ns = propdb->ns_map[elem->ns]; - if (DAV_NS_IS_ERROR(ns)) + if (AP_XML_NS_IS_ERROR(ns)) return key; /* zeroed */ l_ns = sprintf(nsbuf, "%d", ns); @@ -1021,8 +1023,8 @@ void dav_close_propdb(dav_propdb *propdb) dav_get_props_result dav_get_allprops(dav_propdb *propdb, int getvals) { const dav_hooks_db *db_hooks = propdb->db_hooks; - dav_text_header hdr = { 0 }; - dav_text_header hdr_ns = { 0 }; + ap_text_header hdr = { 0 }; + ap_text_header hdr_ns = { 0 }; dav_get_props_result result = { 0 }; int found_resourcetype = 0; int found_contenttype = 0; @@ -1036,9 +1038,9 @@ dav_get_props_result dav_get_allprops(dav_propdb *propdb, int getvals) dav_get_propdb_xmlns(propdb, &hdr_ns); /* initialize the result with some start tags... */ - dav_text_append(propdb->p, &hdr, - "" DEBUG_CR - "" DEBUG_CR); + ap_text_append(propdb->p, &hdr, + "" DEBUG_CR + "" DEBUG_CR); /* if there ARE properties, then scan them */ if (propdb->db != NULL) { @@ -1167,23 +1169,23 @@ dav_get_props_result dav_get_allprops(dav_propdb *propdb, int getvals) } /* terminate the result */ - dav_text_append(propdb->p, &hdr, - "" DEBUG_CR - "HTTP/1.1 200 OK" DEBUG_CR - "" DEBUG_CR); + ap_text_append(propdb->p, &hdr, + "" DEBUG_CR + "HTTP/1.1 200 OK" DEBUG_CR + "" DEBUG_CR); result.propstats = hdr.first; result.xmlns = hdr_ns.first; return result; } -dav_get_props_result dav_get_props(dav_propdb *propdb, dav_xml_doc *doc) +dav_get_props_result dav_get_props(dav_propdb *propdb, ap_xml_doc *doc) { const dav_hooks_db *db_hooks = propdb->db_hooks; - dav_xml_elem *elem = dav_find_child(doc->root, "prop"); - dav_text_header hdr_good = { 0 }; - dav_text_header hdr_bad = { 0 }; - dav_text_header hdr_ns = { 0 }; + ap_xml_elem *elem = dav_find_child(doc->root, "prop"); + ap_text_header hdr_good = { 0 }; + ap_text_header hdr_bad = { 0 }; + ap_text_header hdr_ns = { 0 }; int have_good = 0; dav_get_props_result result = { 0 }; char *marks_input; @@ -1193,9 +1195,9 @@ dav_get_props_result dav_get_props(dav_propdb *propdb, dav_xml_doc *doc) the marks */ /* we will ALWAYS provide a "good" result, even if it is EMPTY */ - dav_text_append(propdb->p, &hdr_good, - "" DEBUG_CR - "" DEBUG_CR); + ap_text_append(propdb->p, &hdr_good, + "" DEBUG_CR + "" DEBUG_CR); /* generate all the namespaces that are in the propdb */ dav_get_propdb_xmlns(propdb, &hdr_ns); @@ -1211,6 +1213,7 @@ dav_get_props_result dav_get_props(dav_propdb *propdb, dav_xml_doc *doc) for (elem = elem->first_child; elem; elem = elem->next) { dav_datum key; dav_datum value = { 0 }; + dav_elem_private *priv; /* ** Note: the key may be NULL if we have no properties that are in @@ -1223,6 +1226,11 @@ dav_get_props_result dav_get_props(dav_propdb *propdb, dav_xml_doc *doc) (void) (*db_hooks->fetch)(propdb->db, key, &value); } + if (elem->private == NULL) { + elem->private = ap_pcalloc(propdb->p, sizeof(*elem->private)); + } + priv = elem->private; + /* ** If we did not find the property in the database, then it may ** be a liveprop that we can handle specially. @@ -1232,7 +1240,7 @@ dav_get_props_result dav_get_props(dav_propdb *propdb, dav_xml_doc *doc) int inserted; /* cache the propid; dav_get_props() could be called many times */ - if (elem->propid == 0) + if (priv->propid == 0) dav_find_liveprop(propdb, elem); /* insert the property. returns 1 if an insertion was done. */ @@ -1248,12 +1256,12 @@ dav_get_props_result dav_get_props(dav_propdb *propdb, dav_xml_doc *doc) ** Add the liveprop's namespace URIs. Note that provider==NULL ** for core properties. */ - if (elem->provider != NULL) { + if (priv->provider != NULL) { const char * const * scan_ns_uri; const int * scan_ns; - for (scan_ns_uri = elem->provider->namespace_uris, - scan_ns = elem->ns_map; + for (scan_ns_uri = priv->provider->namespace_uris, + scan_ns = priv->ns_map; *scan_ns_uri != NULL; ++scan_ns_uri, ++scan_ns) { @@ -1271,9 +1279,9 @@ dav_get_props_result dav_get_props(dav_propdb *propdb, dav_xml_doc *doc) /* make sure we've started our "bad" propstat */ if (hdr_bad.first == NULL) { - dav_text_append(propdb->p, &hdr_bad, - "" DEBUG_CR - "" DEBUG_CR); + ap_text_append(propdb->p, &hdr_bad, + "" DEBUG_CR + "" DEBUG_CR); } /* note: key.dptr may be NULL if the propdb doesn't have an @@ -1281,7 +1289,7 @@ dav_get_props_result dav_get_props(dav_propdb *propdb, dav_xml_doc *doc) if (key.dptr == NULL) { const char *s; - if (elem->ns == DAV_NS_NONE) { + if (elem->ns == AP_XML_NS_NONE) { /* * elem has a prefix already (xml...:name) or the elem * simply has no namespace. @@ -1296,7 +1304,7 @@ dav_get_props_result dav_get_props(dav_propdb *propdb, dav_xml_doc *doc) s = ap_psprintf(propdb->p, "" DEBUG_CR, elem->ns, elem->name); } - dav_text_append(propdb->p, &hdr_bad, s); + ap_text_append(propdb->p, &hdr_bad, s); } else { /* add in the bad prop using our namespace decl */ @@ -1314,7 +1322,7 @@ dav_get_props_result dav_get_props(dav_propdb *propdb, dav_xml_doc *doc) } } - dav_text_append(propdb->p, &hdr_good, + ap_text_append(propdb->p, &hdr_good, "" DEBUG_CR "HTTP/1.1 200 OK" DEBUG_CR "" DEBUG_CR); @@ -1324,10 +1332,10 @@ dav_get_props_result dav_get_props(dav_propdb *propdb, dav_xml_doc *doc) /* we may not have any "bad" results */ if (hdr_bad.first != NULL) { - dav_text_append(propdb->p, &hdr_bad, - "" DEBUG_CR - "HTTP/1.1 404 Not Found" DEBUG_CR - "" DEBUG_CR); + ap_text_append(propdb->p, &hdr_bad, + "" DEBUG_CR + "HTTP/1.1 404 Not Found" DEBUG_CR + "" DEBUG_CR); /* if there are no good props, then just return the bad */ if (!have_good) { @@ -1346,7 +1354,10 @@ dav_get_props_result dav_get_props(dav_propdb *propdb, dav_xml_doc *doc) void dav_prop_validate(dav_prop_ctx *ctx) { dav_propdb *propdb = ctx->propdb; - dav_xml_elem *prop = ctx->prop; + ap_xml_elem *prop = ctx->prop; + dav_elem_private *priv; + + priv = ctx->prop->private = ap_pcalloc(propdb->p, sizeof(*priv)); /* ** Check to see if this is a live property, and fill the fields @@ -1355,17 +1366,17 @@ void dav_prop_validate(dav_prop_ctx *ctx) ** Verify that the property is read/write. If not, then it cannot ** be SET or DELETEd. */ - if (prop->propid == 0) { + if (priv->propid == 0) { dav_find_liveprop(propdb, prop); /* it's a liveprop if a provider was found */ /* ### actually the "core" props should really be liveprops, but ### there is no "provider" for those and the r/w props are ### treated as dead props anyhow */ - ctx->is_liveprop = prop->provider != NULL; + ctx->is_liveprop = priv->provider != NULL; } - if (!dav_rw_liveprop(propdb, prop->propid)) { + if (!dav_rw_liveprop(propdb, priv->propid)) { ctx->err = dav_new_error(propdb->p, HTTP_CONFLICT, DAV_ERR_PROP_READONLY, "Property is read-only."); @@ -1375,7 +1386,7 @@ void dav_prop_validate(dav_prop_ctx *ctx) if (ctx->is_liveprop) { int defer_to_dead = 0; - ctx->err = (*prop->provider->patch_validate)(propdb->resource, + ctx->err = (*priv->provider->patch_validate)(propdb->resource, prop, ctx->operation, &ctx->liveprop_ctx, &defer_to_dead); @@ -1434,15 +1445,16 @@ void dav_prop_exec(dav_prop_ctx *ctx) dav_propdb *propdb = ctx->propdb; dav_error *err = NULL; dav_rollback_item *rollback; + dav_elem_private *priv = ctx->prop->private; rollback = ap_pcalloc(propdb->p, sizeof(*rollback)); ctx->rollback = rollback; if (ctx->is_liveprop) { - err = (*ctx->prop->provider->patch_exec)(propdb->resource, - ctx->prop, ctx->operation, - ctx->liveprop_ctx, - &ctx->rollback->liveprop); + err = (*priv->provider->patch_exec)(propdb->resource, + ctx->prop, ctx->operation, + ctx->liveprop_ctx, + &ctx->rollback->liveprop); } else { dav_datum key; @@ -1463,12 +1475,12 @@ void dav_prop_exec(dav_prop_ctx *ctx) /* Note: propdb->ns_map was set in dav_prop_validate() */ /* quote all the values in the element */ - dav_quote_xml_elem(propdb->p, ctx->prop); + ap_xml_quote_elem(propdb->p, ctx->prop); /* generate a text blob for the xml:lang plus the contents */ - dav_xml2text(propdb->p, ctx->prop, DAV_X2T_LANG_INNER, NULL, - propdb->ns_map, - (const char **)&value.dptr, &value.dsize); + ap_xml_to_text(propdb->p, ctx->prop, AP_XML_X2T_LANG_INNER, NULL, + propdb->ns_map, + (const char **)&value.dptr, &value.dsize); err = (*propdb->db_hooks->store)(propdb->db, key, value); @@ -1504,22 +1516,25 @@ void dav_prop_exec(dav_prop_ctx *ctx) void dav_prop_commit(dav_prop_ctx *ctx) { + dav_elem_private *priv = ctx->prop->private; + /* ** Note that a commit implies ctx->err is NULL. The caller should assume ** a status of HTTP_OK for this case. */ if (ctx->is_liveprop) { - (*ctx->prop->provider->patch_commit)(ctx->propdb->resource, - ctx->operation, - ctx->liveprop_ctx, - ctx->rollback->liveprop); + (*priv->provider->patch_commit)(ctx->propdb->resource, + ctx->operation, + ctx->liveprop_ctx, + ctx->rollback->liveprop); } } void dav_prop_rollback(dav_prop_ctx *ctx) { dav_error *err = NULL; + dav_elem_private *priv = ctx->prop->private; /* do nothing if there is no rollback information. */ if (ctx->rollback == NULL) @@ -1532,10 +1547,10 @@ void dav_prop_rollback(dav_prop_ctx *ctx) */ if (ctx->is_liveprop) { - err = (*ctx->prop->provider->patch_rollback)(ctx->propdb->resource, - ctx->operation, - ctx->liveprop_ctx, - ctx->rollback->liveprop); + err = (*priv->provider->patch_rollback)(ctx->propdb->resource, + ctx->operation, + ctx->liveprop_ctx, + ctx->rollback->liveprop); } else if (ctx->rollback->value.dptr == NULL) { /* don't fail if the thing isn't really there */ diff --git a/modules/dav/main/util.c b/modules/dav/main/util.c index 4dac978d99a..e05d27dd698 100644 --- a/modules/dav/main/util.c +++ b/modules/dav/main/util.c @@ -94,24 +94,6 @@ dav_error *dav_push_error(ap_pool_t *p, int status, int error_id, const char *de return err; } -void dav_text_append(ap_pool_t * p, dav_text_header *hdr, const char *text) -{ - dav_text *t = ap_palloc(p, sizeof(*t)); - - t->text = text; - t->next = NULL; - - if (hdr->first == NULL) { - /* no text elements yet */ - hdr->first = hdr->last = t; - } - else { - /* append to the last text element */ - hdr->last->next = t; - hdr->last = t; - } -} - void dav_check_bufsize(ap_pool_t * p, dav_buffer *pbuf, size_t extra_needed) { /* grow the buffer if necessary */ @@ -179,51 +161,6 @@ void dav_buffer_place_mem(ap_pool_t *p, dav_buffer *pbuf, const void *mem, memcpy(pbuf->buf + pbuf->cur_len, mem, amt); } - -#if APACHE_RELEASE == 10304100 -/* ### this code can be used for 1.3.4 installations. use this function - * ### instead of ap_sub_req_method_uri() - */ -/* - * ### don't look at this code. - * ### it is a Crime Against All That is Right and Good - */ -#include "http_core.h" /* for SATISFY_* */ -static request_rec *gross_hack(const char *new_file, const request_rec * r) -{ - request_rec *rnew = ap_sub_req_lookup_uri(new_file, r); - int res; - - /* ### these aren't exported properly from the headers */ - extern int ap_check_access(request_rec *); /* check access on non-auth basis */ - extern int ap_check_user_id(request_rec *); /* obtain valid username from client auth */ - extern int ap_check_auth(request_rec *); /* check (validated) user is authorized here */ - - if (rnew->status != HTTP_OK) - return rnew; - - /* re-run portions with a modified method */ - rnew->method = r->method; - rnew->method_number = r->method_number; - - if ((ap_satisfies(rnew) == SATISFY_ALL - || ap_satisfies(rnew) == SATISFY_NOSPEC) - ? ((res = ap_check_access(rnew)) - || (ap_some_auth_required(rnew) - && ((res = ap_check_user_id(rnew)) - || (res = ap_check_auth(rnew))))) - : ((res = ap_check_access(rnew)) - && (!ap_some_auth_required(rnew) - || ((res = ap_check_user_id(rnew)) - || (res = ap_check_auth(rnew))))) - ) { - rnew->status = res; - } - - return rnew; -} -#endif /* APACHE_RELEASE == 10304100 */ - /* ** dav_lookup_uri() ** @@ -329,11 +266,7 @@ dav_lookup_result dav_lookup_uri(const char *uri, request_rec * r) * same HTTP method on the destination. This allows the destination * to apply appropriate restrictions (e.g. readonly). */ -#if APACHE_RELEASE == 10304100 - result.rnew = gross_hack(new_file, r); -#else result.rnew = ap_sub_req_method_uri(r->method, new_file, r); -#endif return result; } @@ -344,373 +277,24 @@ dav_lookup_result dav_lookup_uri(const char *uri, request_rec * r) */ /* validate that the root element uses a given DAV: tagname (TRUE==valid) */ -int dav_validate_root(const dav_xml_doc *doc, const char *tagname) +int dav_validate_root(const ap_xml_doc *doc, const char *tagname) { return doc->root && - doc->root->ns == DAV_NS_DAV_ID && + doc->root->ns == AP_XML_NS_DAV_ID && strcmp(doc->root->name, tagname) == 0; } /* find and return the (unique) child with a given DAV: tagname */ -dav_xml_elem *dav_find_child(const dav_xml_elem *elem, const char *tagname) +ap_xml_elem *dav_find_child(const ap_xml_elem *elem, const char *tagname) { - dav_xml_elem *child = elem->first_child; + ap_xml_elem *child = elem->first_child; for (; child; child = child->next) - if (child->ns == DAV_NS_DAV_ID && !strcmp(child->name, tagname)) + if (child->ns == AP_XML_NS_DAV_ID && !strcmp(child->name, tagname)) return child; return NULL; } - -/* how many characters for the given integer? */ -#define DAV_NS_LEN(ns) ((ns) < 10 ? 1 : (ns) < 100 ? 2 : (ns) < 1000 ? 3 : \ - (ns) < 10000 ? 4 : (ns) < 100000 ? 5 : \ - (ns) < 1000000 ? 6 : (ns) < 10000000 ? 7 : \ - (ns) < 100000000 ? 8 : (ns) < 1000000000 ? 9 : 10) - -static int dav_text_size(const dav_text *t) -{ - int size = 0; - - for (; t; t = t->next) - size += strlen(t->text); - return size; -} - -static size_t dav_elem_size(const dav_xml_elem *elem, int style, - ap_array_header_t *namespaces, int *ns_map) -{ - size_t size; - - if (style == DAV_X2T_FULL || style == DAV_X2T_FULL_NS_LANG) { - const dav_xml_attr *attr; - - size = 0; - - if (style == DAV_X2T_FULL_NS_LANG) { - int i; - - /* - ** The outer element will contain xmlns:ns%d="%s" attributes - ** and an xml:lang attribute, if applicable. - */ - - for (i = namespaces->nelts; i--;) { - /* compute size of: ' xmlns:ns%d="%s"' */ - size += (9 + DAV_NS_LEN(i) + 2 + - strlen(DAV_GET_URI_ITEM(namespaces, i)) + 1); - } - - if (elem->lang != NULL) { - /* compute size of: ' xml:lang="%s"' */ - size += 11 + strlen(elem->lang) + 1; - } - } - - if (elem->ns == DAV_NS_NONE) { - /* compute size of: <%s> */ - size += 1 + strlen(elem->name) + 1; - } - else { - int ns = ns_map ? ns_map[elem->ns] : elem->ns; - - /* compute size of: */ - size += 3 + DAV_NS_LEN(ns) + 1 + strlen(elem->name) + 1; - } - - if (DAV_ELEM_IS_EMPTY(elem)) { - /* insert a closing "/" */ - size += 1; - } - else { - /* - * two of above plus "/": - * ... - * OR <%s> ... - */ - size = 2 * size + 1; - } - - for (attr = elem->attr; attr; attr = attr->next) { - if (attr->ns == DAV_NS_NONE) { - /* compute size of: ' %s="%s"' */ - size += 1 + strlen(attr->name) + 2 + strlen(attr->value) + 1; - } - else { - /* compute size of: ' ns%d:%s="%s"' */ - size += 3 + DAV_NS_LEN(attr->ns) + 1 + strlen(attr->name) + 2 + strlen(attr->value) + 1; - } - } - - /* - ** If the element has an xml:lang value that is *different* from - ** its parent, then add the thing in: ' xml:lang="%s"'. - ** - ** NOTE: we take advantage of the pointer equality established by - ** the parsing for "inheriting" the xml:lang values from parents. - */ - if (elem->lang != NULL && - (elem->parent == NULL || elem->lang != elem->parent->lang)) { - size += 11 + strlen(elem->lang) + 1; - } - } - else if (style == DAV_X2T_LANG_INNER) { - /* - * This style prepends the xml:lang value plus a null terminator. - * If a lang value is not present, then we insert a null term. - */ - size = elem->lang ? strlen(elem->lang) + 1 : 1; - } - else - size = 0; - - size += dav_text_size(elem->first_cdata.first); - - for (elem = elem->first_child; elem; elem = elem->next) { - /* the size of the child element plus the CDATA that follows it */ - size += (dav_elem_size(elem, DAV_X2T_FULL, NULL, ns_map) + - dav_text_size(elem->following_cdata.first)); - } - - return size; -} - -static char *dav_write_text(char *s, const dav_text *t) -{ - for (; t; t = t->next) { - size_t len = strlen(t->text); - memcpy(s, t->text, len); - s += len; - } - return s; -} - -static char *dav_write_elem(char *s, const dav_xml_elem *elem, int style, - ap_array_header_t *namespaces, int *ns_map) -{ - const dav_xml_elem *child; - size_t len; - int ns; - - if (style == DAV_X2T_FULL || style == DAV_X2T_FULL_NS_LANG) { - int empty = DAV_ELEM_IS_EMPTY(elem); - const dav_xml_attr *attr; - - if (elem->ns == DAV_NS_NONE) { - len = sprintf(s, "<%s", elem->name); - } - else { - ns = ns_map ? ns_map[elem->ns] : elem->ns; - len = sprintf(s, "name); - } - s += len; - - for (attr = elem->attr; attr; attr = attr->next) { - if (attr->ns == DAV_NS_NONE) - len = sprintf(s, " %s=\"%s\"", attr->name, attr->value); - else - len = sprintf(s, " ns%d:%s=\"%s\"", attr->ns, attr->name, attr->value); - s += len; - } - - /* add the xml:lang value if necessary */ - if (elem->lang != NULL && - (style == DAV_X2T_FULL_NS_LANG || - elem->parent == NULL || - elem->lang != elem->parent->lang)) { - len = sprintf(s, " xml:lang=\"%s\"", elem->lang); - s += len; - } - - /* add namespace definitions, if required */ - if (style == DAV_X2T_FULL_NS_LANG) { - int i; - - for (i = namespaces->nelts; i--;) { - len = sprintf(s, " xmlns:ns%d=\"%s\"", i, - DAV_GET_URI_ITEM(namespaces, i)); - s += len; - } - } - - /* no more to do. close it up and go. */ - if (empty) { - *s++ = '/'; - *s++ = '>'; - return s; - } - - /* just close it */ - *s++ = '>'; - } - else if (style == DAV_X2T_LANG_INNER) { - /* prepend the xml:lang value */ - if (elem->lang != NULL) { - len = strlen(elem->lang); - memcpy(s, elem->lang, len); - s += len; - } - *s++ = '\0'; - } - - s = dav_write_text(s, elem->first_cdata.first); - - for (child = elem->first_child; child; child = child->next) { - s = dav_write_elem(s, child, DAV_X2T_FULL, NULL, ns_map); - s = dav_write_text(s, child->following_cdata.first); - } - - if (style == DAV_X2T_FULL || style == DAV_X2T_FULL_NS_LANG) { - if (elem->ns == DAV_NS_NONE) { - len = sprintf(s, "", elem->name); - } - else { - ns = ns_map ? ns_map[elem->ns] : elem->ns; - len = sprintf(s, "", ns, elem->name); - } - s += len; - } - - return s; -} - -/* convert an element to a text string */ -void dav_xml2text(ap_pool_t * p, - const dav_xml_elem *elem, - int style, - ap_array_header_t *namespaces, - int *ns_map, - const char **pbuf, - size_t *psize) -{ - /* get the exact size, plus a null terminator */ - size_t size = dav_elem_size(elem, style, namespaces, ns_map) + 1; - char *s = ap_palloc(p, size); - - (void) dav_write_elem(s, elem, style, namespaces, ns_map); - s[size - 1] = '\0'; - - *pbuf = s; - if (psize) - *psize = size; -} - -const char *dav_empty_elem(ap_pool_t * p, const dav_xml_elem *elem) -{ - if (elem->ns == DAV_NS_NONE) { - /* - * The prefix (xml...) is already within the prop name, or - * the element simply has no prefix. - */ - return ap_psprintf(p, "<%s/>" DEBUG_CR, elem->name); - } - - return ap_psprintf(p, "" DEBUG_CR, elem->ns, elem->name); -} - -/* -** dav_quote_string: quote an XML string -** -** Replace '<', '>', and '&' with '<', '>', and '&'. -** If quotes is true, then replace '"' with '"'. -** -** quotes is typically set to true for XML strings that will occur within -** double quotes -- attribute values. -*/ -const char * dav_quote_string(ap_pool_t *p, const char *s, int quotes) -{ - const char *scan; - int len = 0; - int extra = 0; - char *qstr; - char *qscan; - char c; - - for (scan = s; (c = *scan) != '\0'; ++scan, ++len) { - if (c == '<' || c == '>') - extra += 3; /* < or > */ - else if (c == '&') - extra += 4; /* & */ - else if (quotes && c == '"') - extra += 5; /* " */ - } - - /* nothing to do? */ - if (extra == 0) - return s; - - qstr = ap_palloc(p, len + extra + 1); - for (scan = s, qscan = qstr; (c = *scan) != '\0'; ++scan) { - if (c == '<') { - *qscan++ = '&'; - *qscan++ = 'l'; - *qscan++ = 't'; - *qscan++ = ';'; - } - else if (c == '>') { - *qscan++ = '&'; - *qscan++ = 'g'; - *qscan++ = 't'; - *qscan++ = ';'; - } - else if (c == '&') { - *qscan++ = '&'; - *qscan++ = 'a'; - *qscan++ = 'm'; - *qscan++ = 'p'; - *qscan++ = ';'; - } - else if (quotes && c == '"') { - *qscan++ = '&'; - *qscan++ = 'q'; - *qscan++ = 'u'; - *qscan++ = 'o'; - *qscan++ = 't'; - *qscan++ = ';'; - } - else { - *qscan++ = c; - } - } - - *qscan = '\0'; - return qstr; -} - -void dav_quote_xml_elem(ap_pool_t *p, dav_xml_elem *elem) -{ - dav_text *scan_txt; - dav_xml_attr *scan_attr; - dav_xml_elem *scan_elem; - - /* convert the element's text */ - for (scan_txt = elem->first_cdata.first; - scan_txt != NULL; - scan_txt = scan_txt->next) { - scan_txt->text = dav_quote_string(p, scan_txt->text, 0); - } - for (scan_txt = elem->following_cdata.first; - scan_txt != NULL; - scan_txt = scan_txt->next) { - scan_txt->text = dav_quote_string(p, scan_txt->text, 0); - } - - /* convert the attribute values */ - for (scan_attr = elem->attr; - scan_attr != NULL; - scan_attr = scan_attr->next) { - scan_attr->value = dav_quote_string(p, scan_attr->value, 1); - } - - /* convert the child elements */ - for (scan_elem = elem->first_child; - scan_elem != NULL; - scan_elem = scan_elem->next) { - dav_quote_xml_elem(p, scan_elem); - } -} - /* --------------------------------------------------------------- ** ** Timeout header processing @@ -1805,7 +1389,7 @@ dav_error * dav_validate_request(request_rec *r, dav_resource *resource, ** to construct a standard 207 response. */ if (err == NULL && response != NULL && *response != NULL) { - dav_text *propstat = NULL; + ap_text *propstat = NULL; if ((flags & DAV_VALIDATE_USE_424) != 0) { /* manufacture a 424 error to hold the multistatus response(s) */ @@ -2109,19 +1693,3 @@ dav_error *dav_revert_resource_writability(request_rec *r, return NULL; } - -/* return the URI's (existing) index, or insert it and return a new index */ -int dav_insert_uri(ap_array_header_t *uri_array, const char *uri) -{ - int i; - const char **pelt; - - for (i = uri_array->nelts; i--;) { - if (strcmp(uri, DAV_GET_URI_ITEM(uri_array, i)) == 0) - return i; - } - - pelt = ap_push_array(uri_array); - *pelt = uri; /* assume uri is const or in a pool */ - return uri_array->nelts - 1; -} diff --git a/modules/dav/main/util_lock.c b/modules/dav/main/util_lock.c index a86a2ec56e3..44382e6d7bd 100644 --- a/modules/dav/main/util_lock.c +++ b/modules/dav/main/util_lock.c @@ -194,13 +194,13 @@ const char *dav_lock_get_activelock(request_rec *r, dav_lock *lock, dav_error * dav_lock_parse_lockinfo(request_rec *r, const dav_resource *resource, dav_lockdb *lockdb, - const dav_xml_doc *doc, + const ap_xml_doc *doc, dav_lock **lock_request) { const dav_hooks_locks *hooks = DAV_GET_HOOKS_LOCKS(r); ap_pool_t *p = r->pool; dav_error *err; - dav_xml_elem *child; + ap_xml_elem *child; dav_lock *lock; if (!dav_validate_root(doc, "lockinfo")) { @@ -248,14 +248,14 @@ dav_error * dav_lock_parse_lockinfo(request_rec *r, const char *text; /* quote all the values in the element */ - dav_quote_xml_elem(p, child); + ap_xml_quote_elem(p, child); /* ** Store a full element with namespace definitions ** and an xml:lang definition, if applicable. */ - dav_xml2text(p, child, DAV_X2T_FULL_NS_LANG, doc->namespaces, NULL, - &text, NULL); + ap_xml_to_text(p, child, AP_XML_X2T_FULL_NS_LANG, doc->namespaces, + NULL, &text, NULL); lock->owner = text; continue;