com php-src: Fixed bug #61471: NEWS sapi/apache2handler/php _apache.h sapi/apache2handler/sapi_apache2.c

[email protected] (Nikita Popov)
Newsgroups php.cvs
Message-ID <[email protected]>
Commit:    80c8d84af303d2fddc9ba9f181c7117b9040811d
Author:    Zheng SHAO <[email protected]>         Wed, 18 Jan 2017 18:50:21 +0900
Committer: Nikita Popov <[email protected]>      Wed, 8 Feb 2017 01:10:13 +0100
Parents:   7a0adb4cd2ec0eef10f2ae6453c61e90b7615462
Branches:  PHP-7.0 PHP-7.1 master

Link:       http://git.php.net/?p=php-src.git;a=commitdiff;h=80c8d84af303d2fddc9ba9f181c7117b9040811d

Log:
Fixed bug #61471

Bugs:
https://bugs.php.net/61471

Changed paths:
  M  NEWS
  M  sapi/apache2handler/php_apache.h
  M  sapi/apache2handler/sapi_apache2.c


Diff:
diff --git a/NEWS b/NEWS
index 4346259..5ff0ee7 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 38e4716..bd3e181 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 bf22d2c..204904a 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);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.