From a99bc9cbb543e4677f326f425c55e41575cf735a Mon Sep 17 00:00:00 2001 From: "William A. Rowe Jr" Date: Wed, 1 Aug 2001 23:33:08 +0000 Subject: [PATCH] Solve the merge bugs, by storing a copy bit to save us a ton of reallocation in the merge config phase. Should keep most of the savings realized by moving to tables. Need others to vet this code, please! Look at this and the prior patch as a single diff (-r n -r n-2) to see the overall changes. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@89865 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 3 ++ modules/http/mod_mime.c | 86 ++++++++++++++++++++++++++++++++++------- 2 files changed, 75 insertions(+), 14 deletions(-) diff --git a/CHANGES b/CHANGES index 37b3f736bf..21b5ade14f 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,8 @@ Changes with Apache 2.0.23-dev + *) Fix broken mod_mime behavior in merging its arguments. Possible + cause of unexplicable crashes introduced in 2.0.20. [William Rowe] + *) Solve many mod_ssl porting issues (too many to detail) with help from the whole team, but most notably [Ralf S. Engelschall, Madhusudan Mathihalli , diff --git a/modules/http/mod_mime.c b/modules/http/mod_mime.c index 0a6950c973..e2257417a0 100644 --- a/modules/http/mod_mime.c +++ b/modules/http/mod_mime.c @@ -105,11 +105,14 @@ typedef struct extension_info { char *language_type; /* Added with AddLanguage... */ char *handler; /* Added with AddHandler... */ char *charset_type; /* Added with AddCharset... */ + int copy; /* To avoid dupping in the merge */ } extension_info; typedef struct { apr_hash_t *extension_mappings; /* Map from extension name to * extension_info structure */ + int copy_mappings; /* To avoid dupping in the merge */ + apr_array_header_t *handlers_remove; /* List of handlers to remove */ apr_array_header_t *types_remove; /* List of MIME types to remove */ apr_array_header_t *encodings_remove; /* List of encodings to remove */ @@ -147,6 +150,8 @@ static void *create_mime_dir_config(apr_pool_t *p, char *dummy) (mime_dir_config *) apr_palloc(p, sizeof(mime_dir_config)); new->extension_mappings = apr_hash_make(p); + new->copy_mappings = 0; + new->handlers_remove = NULL; new->types_remove = NULL; new->encodings_remove = NULL; @@ -171,8 +176,18 @@ static void overlay_extension_mappings(apr_pool_t *p, extension_info *overlay_info, *base_info; apr_hash_this(index, (const void**)&key, &klen, (void**)&overlay_info); + base_info = (extension_info*)apr_hash_get(base, key, klen); + if (base_info) { + if (!base_info->copy) { + extension_info *copyinfo = base_info; + base_info = (extension_info*)apr_palloc(p, sizeof(*base_info)); + apr_hash_set(base, key, klen, base_info); + memcpy(base_info, copyinfo, sizeof(*base_info)); + base_info->copy = 1; + } + if (overlay_info->forced_type) { base_info->forced_type = overlay_info->forced_type; } @@ -190,9 +205,7 @@ static void overlay_extension_mappings(apr_pool_t *p, } } else { - base_info = (extension_info*)apr_palloc(p, sizeof(extension_info)); - memcpy(base_info, overlay_info, sizeof(extension_info)); - apr_hash_set(base, key, klen, base_info); + apr_hash_set(base, key, klen, overlay_info); } } } @@ -206,18 +219,37 @@ static void *merge_mime_dir_configs(apr_pool_t *p, void *basev, void *addv) int i; attrib_info *suffix; - if (base->extension_mappings == NULL) { - new->extension_mappings = add->extension_mappings; - } - else if (add->extension_mappings == NULL) { - new->extension_mappings = base->extension_mappings; - } - else { - new->extension_mappings = apr_hash_make(p); - overlay_extension_mappings(p, base->extension_mappings, - new->extension_mappings); + if (base->extension_mappings && add->extension_mappings) { + if (base->copy_mappings) + new->extension_mappings = base->extension_mappings; + else { + new->extension_mappings = apr_hash_make(p); + /* XXX as slow as can be... just use an apr_hash_dup! */ + overlay_extension_mappings(p, base->extension_mappings, + new->extension_mappings); + } overlay_extension_mappings(p, add->extension_mappings, new->extension_mappings); + new->copy_mappings = 1; + } + else { + if (base->extension_mappings == NULL) { + new->extension_mappings = add->extension_mappings; + new->copy_mappings = add->copy_mappings; + } + else if (add->extension_mappings == NULL) { + new->extension_mappings = base->extension_mappings; + new->copy_mappings = base->copy_mappings; + } + if (!new->copy_mappings && (add->handlers_remove + || add->types_remove + || add->encodings_remove)) { + apr_hash_t *copyhash = new->extension_mappings; + new->extension_mappings = apr_hash_make(p); + /* XXX as slow as can be... just use an apr_hash_dup! */ + overlay_extension_mappings(p, copyhash, new->extension_mappings); + new->copy_mappings = 1; + } } if (add->handlers_remove) { @@ -228,6 +260,14 @@ static void *merge_mime_dir_configs(apr_pool_t *p, void *basev, void *addv) suffix[i].name, APR_HASH_KEY_STRING); if (exinfo) { + if (!exinfo->copy) { + extension_info *copyinfo = exinfo; + exinfo = (extension_info*)apr_palloc(p, sizeof(*exinfo)); + apr_hash_set(new->extension_mappings, suffix[i].name, + APR_HASH_KEY_STRING, exinfo); + memcpy(exinfo, copyinfo, sizeof(*exinfo)); + exinfo->copy = 1; + } exinfo->handler = NULL; } } @@ -241,6 +281,14 @@ static void *merge_mime_dir_configs(apr_pool_t *p, void *basev, void *addv) suffix[i].name, APR_HASH_KEY_STRING); if (exinfo) { + if (!exinfo->copy) { + extension_info *copyinfo = exinfo; + exinfo = (extension_info*)apr_palloc(p, sizeof(*exinfo)); + apr_hash_set(new->extension_mappings, suffix[i].name, + APR_HASH_KEY_STRING, exinfo); + memcpy(exinfo, copyinfo, sizeof(*exinfo)); + exinfo->copy = 1; + } exinfo->forced_type = NULL; } } @@ -254,6 +302,14 @@ static void *merge_mime_dir_configs(apr_pool_t *p, void *basev, void *addv) suffix[i].name, APR_HASH_KEY_STRING); if (exinfo) { + if (!exinfo->copy) { + extension_info *copyinfo = exinfo; + exinfo = (extension_info*)apr_palloc(p, sizeof(*exinfo)); + apr_hash_set(new->extension_mappings, suffix[i].name, + APR_HASH_KEY_STRING, exinfo); + memcpy(exinfo, copyinfo, sizeof(*exinfo)); + exinfo->copy = 1; + } exinfo->encoding_type = NULL; } } @@ -266,6 +322,7 @@ static void *merge_mime_dir_configs(apr_pool_t *p, void *basev, void *addv) return new; } + static extension_info *get_extension_info(apr_pool_t *p, mime_dir_config *m, const char* key) { @@ -274,6 +331,7 @@ static extension_info *get_extension_info(apr_pool_t *p, mime_dir_config *m, exinfo = (extension_info*)apr_hash_get(m->extension_mappings, key, APR_HASH_KEY_STRING); if (!exinfo) { + /* pcalloc sets ->copy to false */ exinfo = apr_pcalloc(p, sizeof(extension_info)); apr_hash_set(m->extension_mappings, apr_pstrdup(p, key), APR_HASH_KEY_STRING, exinfo); @@ -480,7 +538,7 @@ static void mime_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, types_confname = ap_server_root_relative(p, types_confname); - if ((status = ap_pcfg_openfile(&f, p, types_confname)) != APR_SUCCESS) { + if ((status = ap_pcfg_openfile(&f, ptemp, types_confname)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, status, s, "could not open mime types config file %s.", types_confname); exit(1); -- 2.50.1