php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #60826
Patch iis-cgi-chunked-poc revision 2020-02-27 17:50 UTC by cmb@php.net
Patch IIS-FastCGI-transfer-encoding-chuncked revision 2012-04-11 13:52 UTC by andres at fenestrae dot com

Patch IIS-FastCGI-transfer-encoding-chuncked for CGI/CLI related Bug #60826

Patch version 2012-04-11 13:52 UTC

Return to Bug #60826 | Download this patch
Patch Revisions:

Developer: andres@fenestrae.com

The patch covers 2 files


file: sapi/cgi/fastcgi.c
// Do not read data from more then 1 chunk, thus preventing to read the terminating chunk 
// as additional data in attempt to fill the buffer up to 100%

int fcgi_read(fcgi_request *req, char *str, int len)
{
	int ret, n, rest;
	fcgi_header hdr;
	unsigned char buf[255];

	n = 0;
	rest = len;
-	while (rest > 0) { 
+	if (rest > 0) {
		if (req->in_len == 0) {
			if (safe_read(req, &hdr, sizeof(fcgi_header)) != sizeof(fcgi_header) ||
			    hdr.version < FCGI_VERSION_1 ||
			    hdr.type != FCGI_STDIN) {
				req->keep = 0;
				return 0;
			}
			req->in_len = (hdr.contentLengthB1 << 8) | hdr.contentLengthB0;
			req->in_pad = hdr.paddingLength;
			if (req->in_len == 0) {
				return n;
			}
		}

		if (req->in_len >= rest) {
			ret = safe_read(req, str, rest);
		} else {
			ret = safe_read(req, str, req->in_len);
		}
		if (ret < 0) {
			req->keep = 0;
			return ret;
		} else if (ret > 0) {
			req->in_len -= ret;
			rest -= ret;
			n += ret;
			str += ret;
			if (req->in_len == 0) {
				if (req->in_pad) {
					if (safe_read(req, buf, req->in_pad) != req->in_pad) {
						req->keep = 0;
						return ret;
					}
				}
			} else {
				return n;
			}
		} else {
			return n;
		}
	}
	return n;
}


file: sapi/cgi/cgi_main.c
// in case of reading the terminator calculate the actual content-length
// and remember this value, preventing consecutive calls to sapi_cgi_read_post 
// to attempt and read data that will never come.

static int sapi_cgi_read_post(char *buffer, uint count_bytes TSRMLS_DC)
{
	uint read_bytes = 0;
	int tmp_read_bytes;

	count_bytes = MIN(count_bytes, (uint) SG(request_info).content_length - SG(read_post_bytes));
	while (read_bytes < count_bytes) {
		if (fcgi_is_fastcgi()) {
			fcgi_request *request = (fcgi_request*) SG(server_context);
			tmp_read_bytes = fcgi_read(request, buffer + read_bytes, count_bytes - read_bytes);
+            if ((tmp_read_bytes == 0) && (SG(request_info).content_length == -1 ) ){
+                SG(request_info).content_length = SG(read_post_bytes) + read_bytes;
+            }
		} else {
			tmp_read_bytes = read(STDIN_FILENO, buffer + read_bytes, count_bytes - read_bytes);
		}
		if (tmp_read_bytes <= 0) {
			break;
		}
		read_bytes += tmp_read_bytes;
	}
	return read_bytes;
}
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 26 19:01:29 2024 UTC