From: Luca Toscano Date: Tue, 25 Apr 2017 09:06:26 +0000 (+0000) Subject: Evaluate nested If/ElseIf/Else config sections X-Git-Tag: 2.5.0-alpha~450 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fafe95b9050ac01b29274221e58f42311aad1ba2;p=thirdparty%2Fapache%2Fhttpd.git Evaluate nested If/ElseIf/Else config sections It has been reported multiple times that nested If/ElseIf/Else sections are not evaluated but silently ignored. This patch adds a simple recursion to the ap_if_walk logic in order to allow arbitrary nested configs. The overhead seems negligible compared to the actual version of the ap_if_walk, but more expert feedback is surely needed since this code gets called for every HTTP request. Tests are going to be added to t/apache/if_sections.t git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1792589 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 1a589ea629c..687cf65e6b6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,9 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.0 + *) Evaluate nested If/ElseIf/Else configuration blocks. + [Luca Toscano, Jacob Champion] + *) Introduce request taint checking framework to prevent privilege hijacking through .htaccess. [Nick Kew] diff --git a/server/request.c b/server/request.c index 5336eb26d08..016504d1cdc 100644 --- a/server/request.c +++ b/server/request.c @@ -1781,10 +1781,9 @@ AP_DECLARE(int) ap_file_walk(request_rec *r) return OK; } -AP_DECLARE(int) ap_if_walk(request_rec *r) +static int ap_if_walk_sub(request_rec *r, core_dir_config* dconf) { ap_conf_vector_t *now_merged = NULL; - core_dir_config *dconf = ap_get_core_module_config(r->per_dir_config); ap_conf_vector_t **sec_ent = NULL; int num_sec = 0; walk_cache_t *cache; @@ -1795,7 +1794,7 @@ AP_DECLARE(int) ap_if_walk(request_rec *r) int prev_result = -1; walk_walked_t *last_walk; - if (dconf->sec_if) { + if (dconf && dconf->sec_if) { sec_ent = (ap_conf_vector_t **)dconf->sec_if->elts; num_sec = dconf->sec_if->nelts; } @@ -1910,9 +1909,25 @@ AP_DECLARE(int) ap_if_walk(request_rec *r) } cache->per_dir_result = r->per_dir_config; + if (now_merged) { + core_dir_config *dconf_merged = ap_get_core_module_config(now_merged); + + /* Allow nested s and their configs to get merged + * with the current one. + */ + return ap_if_walk_sub(r, dconf_merged); + } + return OK; } +AP_DECLARE(int) ap_if_walk(request_rec *r) +{ + core_dir_config *dconf = ap_get_core_module_config(r->per_dir_config); + int status = ap_if_walk_sub(r, dconf); + return status; +} + /***************************************************************** * * The sub_request mechanism.