From 80c8d84af303d2fddc9ba9f181c7117b9040811d Mon Sep 17 00:00:00 2001 From: Zheng SHAO Date: Wed, 18 Jan 2017 18:50:21 +0900 Subject: [PATCH] Fixed bug #61471 --- NEWS | 4 +++ sapi/apache2handler/php_apache.h | 1 + sapi/apache2handler/sapi_apache2.c | 47 +++++++++++++++++++++++++++++- 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 43462597741..5ff0ee7f638 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,10 @@ PHP NEWS . Fixed bug #73954 (NAN check fails on Alpine Linux with musl). (Andrea) . Fixed bug #74039 (is_infinite(-INF) returns false). (Christian Schmidt) +- Apache: + . Fixed bug #61471 (Incomplete POST does not timeout but is passed to PHP). + (Zheng Shao) + - GD: . Fixed bug #74031 (ReflectionFunction for imagepng is missing last two parameters). (finwe) diff --git a/sapi/apache2handler/php_apache.h b/sapi/apache2handler/php_apache.h index 38e4716779b..bd3e1813a24 100644 --- a/sapi/apache2handler/php_apache.h +++ b/sapi/apache2handler/php_apache.h @@ -73,6 +73,7 @@ typedef struct { zend_bool engine; zend_bool xbithack; zend_bool last_modified; + zend_bool post_read_error; } php_apache2_info_struct; extern zend_module_entry apache2_module_entry; diff --git a/sapi/apache2handler/sapi_apache2.c b/sapi/apache2handler/sapi_apache2.c index bf22d2c783e..204904ab11e 100644 --- a/sapi/apache2handler/sapi_apache2.c +++ b/sapi/apache2handler/sapi_apache2.c @@ -63,6 +63,33 @@ #define PHP_SOURCE_MAGIC_TYPE "application/x-httpd-php-source" #define PHP_SCRIPT "php7-script" +/* if apache's version is newer than 2.2.31 or 2.4.16 */ +#if MODULE_MAGIC_COOKIE == 0x41503232UL && AP_MODULE_MAGIC_AT_LEAST(20051115,40) || \ + MODULE_MAGIC_COOKIE == 0x41503234UL && AP_MODULE_MAGIC_AT_LEAST(20120211,47) +#define php_ap_map_http_request_error ap_map_http_request_error +#else +static int php_ap_map_http_request_error(apr_status_t rv, int status) +{ + switch (rv) { + case AP_FILTER_ERROR: { + return AP_FILTER_ERROR; + } + case APR_ENOSPC: { + return HTTP_REQUEST_ENTITY_TOO_LARGE; + } + case APR_ENOTIMPL: { + return HTTP_NOT_IMPLEMENTED; + } + case APR_ETIMEDOUT: { + return HTTP_REQUEST_TIME_OUT; + } + default: { + return status; + } + } +} +#endif + /* A way to specify the location of the php.ini dir in an apache directive */ char *apache2_php_ini_path_override = NULL; #if defined(PHP_WIN32) && defined(ZTS) @@ -184,6 +211,7 @@ php_apache_sapi_read_post(char *buf, size_t count_bytes) php_struct *ctx = SG(server_context); request_rec *r; apr_bucket_brigade *brigade; + apr_status_t ret; r = ctx->r; brigade = ctx->brigade; @@ -195,7 +223,7 @@ php_apache_sapi_read_post(char *buf, size_t count_bytes) * need to make sure that if data is available we fill the buffer completely. */ - while (ap_get_brigade(r->input_filters, brigade, AP_MODE_READBYTES, APR_BLOCK_READ, len) == APR_SUCCESS) { + while ((ret=ap_get_brigade(r->input_filters, brigade, AP_MODE_READBYTES, APR_BLOCK_READ, len)) == APR_SUCCESS) { apr_brigade_flatten(brigade, buf, &len); apr_brigade_cleanup(brigade); tlen += len; @@ -206,6 +234,15 @@ php_apache_sapi_read_post(char *buf, size_t count_bytes) len = count_bytes - tlen; } + if (ret != APR_SUCCESS) { + AP2(post_read_error) = 1; + if (APR_STATUS_IS_TIMEUP(ret)) { + SG(sapi_headers).http_response_code = php_ap_map_http_request_error(ret, HTTP_REQUEST_TIME_OUT); + } else { + SG(sapi_headers).http_response_code = php_ap_map_http_request_error(ret, HTTP_BAD_REQUEST); + } + } + return tlen; } @@ -487,6 +524,7 @@ static int php_apache_request_ctor(request_rec *r, php_struct *ctx) SG(request_info).proto_num = r->proto_num; SG(request_info).request_uri = apr_pstrdup(r->pool, r->uri); SG(request_info).path_translated = apr_pstrdup(r->pool, r->filename); + AP2(post_read_error) = 0; r->no_local_copy = 1; content_length = (char *) apr_table_get(r->headers_in, "Content-Length"); @@ -656,6 +694,13 @@ zend_first_try { brigade = ctx->brigade; } + if (AP2(post_read_error)) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Error while attempting to read POST data: %d", SG(sapi_headers).http_response_code); + apr_brigade_cleanup(brigade); + PHPAP_INI_OFF; + return SG(sapi_headers).http_response_code; + } + if (AP2(last_modified)) { ap_update_mtime(r, r->finfo.mtime); ap_set_last_modified(r);