Patch patch.txt for HTTP related Bug #73882
Patch version 2017-01-06 15:55 UTC
Return to Bug #73882 |
Download this patch
Patch Revisions:
Developer: laurentconstantin@free.fr
--- ext/standard/http_fopen_wrapper.c.ORI 2016-12-08 07:29:33.000000000 +0100
+++ ext/standard/http_fopen_wrapper.c 2017-01-06 16:27:49.882410127 +0100
@@ -109,6 +109,65 @@ static inline void strip_header(char *he
}
}
+/* Check if the header_line matches the header_name followed by ':' and followed by any spaces.
+ Return value:
+ - zero when the line is not recognized/malformed.
+ - one when the line matches. The offset to the begining of the value is stored in *poffset.
+ For example:
+ match_header_and_indicate_value_offset("Head: value", "Test", &of) returns 0 (no match).
+ match_header_and_indicate_value_offset("Head:", "Head", &of) returns 0 (malformed).
+ match_header_and_indicate_value_offset("Head: value", "Head", &of) returns 1, of=6 (offset 4+1+1).
+ match_header_and_indicate_value_offset("Head: value", "Head", &of) returns 1, of=7 (offset 4+1+2).
+*/
+static inline int match_header_and_indicate_value_offset(const char *header_line, const char *header_name, int *poffset) {
+ int header_name_length;
+ int offset;
+
+ /* Match the header name. */
+ header_name_length = strlen(header_name);
+ if (strncasecmp(header_line, header_name, header_name_length)) {
+ /* No match. */
+ return(0);
+ }
+ offset = header_name_length;
+
+ /* Match the ':', or a premature end of string. */
+ if (header_line[offset] != ':') {
+ /* No match or malformed. */
+ return(0);
+ }
+ offset++;
+
+ /* Match any space. */
+ while (header_line[offset] == ' ') {
+ offset++;
+ }
+ if (header_line[offset] == '\0') {
+ /* Premature end. */
+ return(0);
+ }
+
+ /* Set the offset of the header value. */
+ *poffset = offset;
+ return(1 /*success*/);
+}
+
+/* Check if the header_line matches the header_name followed by ': *' and wanted_value.
+ Return value:
+ - zero when the line is not recognized/malformed.
+ - one when the line matches.
+*/
+static inline int match_header_and_value(const char *header_line, const char *header_name, const char *wanted_value) {
+ int offset_of_matched_header;
+
+ if (! match_header_and_indicate_value_offset(header_line, header_name, &offset_of_matched_header)) {
+ /* No match or malformed. */
+ return(0);
+ }
+
+ return(! strcmp(header_line + offset_of_matched_header, wanted_value));
+}
+
php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper,
const char *path, const char *mode, int options, char **opened_path,
php_stream_context *context, int redirect_max, int flags STREAMS_DC TSRMLS_DC) /* {{{ */
@@ -141,6 +200,7 @@ php_stream *php_stream_url_wrap_http_ex(
int follow_location = 1;
php_stream_filter *transfer_encoding = NULL;
int response_code;
+ int offset_of_matched_header;
tmp_line[0] = '\0';
@@ -776,7 +836,7 @@ finish:
http_header_line_length = e - http_header_line + 1;
http_header_line[http_header_line_length] = '\0';
- if (!strncasecmp(http_header_line, "Location: ", 10)) {
+ if (match_header_and_indicate_value_offset(http_header_line, "Location", &offset_of_matched_header)) {
if (context && php_stream_context_get_option(context, "http", "follow_location", &tmpzval) == SUCCESS) {
SEPARATE_ZVAL(tmpzval);
convert_to_long_ex(tmpzval);
@@ -788,13 +848,13 @@ finish:
RFC 7238 defines 308: http://tools.ietf.org/html/rfc7238 */
follow_location = 0;
}
- strlcpy(location, http_header_line + 10, sizeof(location));
- } else if (!strncasecmp(http_header_line, "Content-Type: ", 14)) {
- php_stream_notify_info(context, PHP_STREAM_NOTIFY_MIME_TYPE_IS, http_header_line + 14, 0);
- } else if (!strncasecmp(http_header_line, "Content-Length: ", 16)) {
- file_size = atoi(http_header_line + 16);
+ strlcpy(location, http_header_line + offset_of_matched_header, sizeof(location));
+ } else if (match_header_and_indicate_value_offset(http_header_line, "Content-Type", &offset_of_matched_header)) {
+ php_stream_notify_info(context, PHP_STREAM_NOTIFY_MIME_TYPE_IS, http_header_line + offset_of_matched_header, 0);
+ } else if (match_header_and_indicate_value_offset(http_header_line, "Content-Length", &offset_of_matched_header)) {
+ file_size = atoi(http_header_line + offset_of_matched_header);
php_stream_notify_file_size(context, file_size, http_header_line, 0);
- } else if (!strncasecmp(http_header_line, "Transfer-Encoding: chunked", sizeof("Transfer-Encoding: chunked"))) {
+ } else if (match_header_and_value(http_header_line, "Transfer-Encoding", "chunked")) {
/* create filter to decode response body */
if (!(options & STREAM_ONLY_GET_HEADERS)) {
|