diff --git a/modules/metadata/mod_cern_meta.c b/modules/metadata/mod_cern_meta.c index a150b3c9fa1..10b5903a6a7 100644 --- a/modules/metadata/mod_cern_meta.c +++ b/modules/metadata/mod_cern_meta.c @@ -244,9 +244,9 @@ static int scan_meta_file(request_rec *r, apr_file_t *f) char *tmp; /* Nuke trailing whitespace */ - char *endp = l + strlen(l) - 1; - while (endp > l && apr_isspace(*endp)) - *endp-- = '\0'; + char *endp = l + strlen(l); + while (endp > l && apr_isspace(endp[-1])) + *--endp = '\0'; tmp = apr_pstrdup(r->pool, l); ap_content_type_tolower(tmp); diff --git a/modules/proxy/mod_proxy_hcheck.c b/modules/proxy/mod_proxy_hcheck.c index 38c5c2b5609..169dd3c24b6 100644 --- a/modules/proxy/mod_proxy_hcheck.c +++ b/modules/proxy/mod_proxy_hcheck.c @@ -776,8 +776,9 @@ static int hc_read_headers(request_rec *r) ++value; while (apr_isspace(*value)) ++value; /* Skip to start of value */ - for (end = &value[strlen(value)-1]; end > value && apr_isspace(*end); --end) - *end = '\0'; + for (end = value + strlen(value); + end > value && apr_isspace(end[-1]); --end) + end[-1] = '\0'; apr_table_add(r->headers_out, buffer, value); } diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c index 970487be6ea..50e50520e2c 100644 --- a/modules/proxy/mod_proxy_http.c +++ b/modules/proxy/mod_proxy_http.c @@ -973,8 +973,9 @@ static apr_status_t ap_proxy_read_headers(request_rec *r, request_rec *rr, ++value; /* Skip to start of value */ /* should strip trailing whitespace as well */ - for (end = &value[strlen(value)-1]; end > value && apr_isspace(*end); --end) - *end = '\0'; + for (end = value + strlen(value); + end > value && apr_isspace(end[-1]); --end) + end[-1] = '\0'; /* make sure we add so as not to destroy duplicated headers * Modify headers requiring canonicalisation and/or affected diff --git a/modules/proxy/mod_proxy_uwsgi.c b/modules/proxy/mod_proxy_uwsgi.c index 26091087263..d003faaaf6d 100644 --- a/modules/proxy/mod_proxy_uwsgi.c +++ b/modules/proxy/mod_proxy_uwsgi.c @@ -386,9 +386,9 @@ static int uwsgi_response(request_rec *r, proxy_conn_rec * backend, } while (apr_isspace(*value)) ++value; - for (end = &value[strlen(value) - 1]; - end > value && apr_isspace(*end); --end) - *end = '\0'; + for (end = value + strlen(value); + end > value && apr_isspace(end[-1]); --end) + end[-1] = '\0'; if (*ap_scan_http_field_content(value)) { /* invalid value */ len = -1; diff --git a/server/util_script.c b/server/util_script.c index 6a18aec8c90..d794c7b3208 100644 --- a/server/util_script.c +++ b/server/util_script.c @@ -649,9 +649,9 @@ AP_DECLARE(int) ap_scan_script_header_err_core_ex(request_rec *r, char *buffer, /* Nuke trailing whitespace */ - char *endp = l + strlen(l) - 1; - while (endp > l && apr_isspace(*endp)) { - *endp-- = '\0'; + char *endp = l + strlen(l); + while (endp > l && apr_isspace(endp[-1])) { + *--endp = '\0'; } tmp = apr_pstrdup(r->pool, l); diff --git a/test/modules/proxy/test_03_response.py b/test/modules/proxy/test_03_response.py index 60a4afa8af9..5c22528debd 100644 --- a/test/modules/proxy/test_03_response.py +++ b/test/modules/proxy/test_03_response.py @@ -16,6 +16,16 @@ def _make_response(self, data): return """HTTP/1.1 200 OK\r\nContent-Type: text/html\x00extra\r\n\r\n""".encode() + if "/empty-header" in path: + body = b"Hello" + return ( + b"HTTP/1.1 200 OK\r\n" + b"X-Empty:\r\n" + b"Content-Length: 5\r\n" + b"\r\n" + + body + ) + if "/forwarded" in path: headers = data.split(b"\r\n\r\n")[0].decode("latin-1") forwarded = [] @@ -89,6 +99,13 @@ def test_proxy_03_001(self, env): lognos=["AH01106", "AH10404"] ) + # empty backend response header values are valid + def test_proxy_03_004(self, env): + r = env.curl_get(env.mkurl("http", "test1", "/empty-header")) + assert r.response["status"] == 200 + assert "x-empty" in r.response["header"] + assert r.response["body"] == b"Hello" + # checks X-Forwarded headers def test_proxy_03_002(self, env): if not env.httpd_is_at_least("2.4.54"): diff --git a/test/modules/proxy/test_05_uwsgi.py b/test/modules/proxy/test_05_uwsgi.py index b0733aba7dd..0b360b89ff6 100644 --- a/test/modules/proxy/test_05_uwsgi.py +++ b/test/modules/proxy/test_05_uwsgi.py @@ -17,6 +17,17 @@ def hello(data): + body ) + @staticmethod + def empty_header(data): + body = b"Hello" + return ( + b"HTTP/1.1 200 OK\r\n" + b"X-Empty:\r\n" + b"Content-Length: 5\r\n" + b"\r\n" + + body + ) + class TestProxyUwsgi: @@ -51,3 +62,11 @@ def test_proxy_005_01(self, env, _class_scope): assert data[3] == 0x00 # standard WSGI request assert len(data) == 4 + datasize + # empty backend response header values are valid + def test_proxy_005_02(self, env, _class_scope): + _class_scope._make_response = _UWSGIFaker.empty_header + r = env.curl_get(env.mkurl("http", "test1", "/")) + assert r.response["status"] == 200 + assert "x-empty" in r.response["header"] + assert r.response["body"] == b"Hello" +