William A. Rowe, Jr. wrote:
[...]
>+static void remove_items(apr_pool_t *p, apr_array_header_t *remove,
>+ apr_hash_t *mappings, apr_size_t member)
>+{
>+ attrib_info *suffix = (attrib_info *) remove->elts;
>+ int i;
>+ for (i = 0; i < remove->nelts; i++) {
>+ extension_info *exinfo =
>+ (extension_info*)apr_hash_get(mappings,
>+ suffix[i].name,
>+ APR_HASH_KEY_STRING);
>+ /* If we find the entry, the given member isn't NULL,
>+ * and this exinfo wasn't allocated from the current pool,
>+ * then we must copy before we remove the given member.
>+ */
>
Why is it necessary to make a copy before overwriting the
field in exinfo with NULL?
[...]
>
>+ if (!base->extension_mappings && !add->extension_mappings)
>+ new->extension_mappings = NULL;
>+ else if (base->extension_mappings
>+ && ((base->pool == p) || !(add->extension_mappings
>+ || add->handlers_remove
>+ || add->types_remove
>+ || add->encodings_remove)))
>+ new->extension_mappings = base->extension_mappings;
>+ else {
>+ new->extension_mappings = apr_hash_make(p);
>+ if (base->extension_mappings)
> overlay_extension_mappings(p, base->extension_mappings,
> new->extension_mappings);
>+ }
>
One minor problem here (and I can't remember if it will be
a problem in practice): this logic can call overlay_extension_mappings
with one of its latter two arguments equal to NULL, and
overlay_extension_mappings
will dereference NULL without checking.
--Brian