diff options
Diffstat (limited to 'ext/standard')
| -rw-r--r-- | ext/standard/basic_functions.c | 11 | ||||
| -rw-r--r-- | ext/standard/ftp_fopen_wrapper.c | 52 | ||||
| -rw-r--r-- | ext/standard/http_fopen_wrapper.c | 61 | ||||
| -rw-r--r-- | ext/standard/link.c | 2 | ||||
| -rw-r--r-- | ext/standard/link_win32.c | 5 | ||||
| -rw-r--r-- | ext/standard/php_fopen_wrapper.c | 13 | ||||
| -rw-r--r-- | ext/standard/streamsfuncs.c | 2 | ||||
| -rw-r--r-- | ext/standard/string.c | 32 | ||||
| -rw-r--r-- | ext/standard/tests/streams/bug75031.phpt | 25 | ||||
| -rw-r--r-- | ext/standard/url.c | 105 | ||||
| -rw-r--r-- | ext/standard/url.h | 14 | ||||
| -rw-r--r-- | ext/standard/url_scanner_ex.c | 395 | ||||
| -rw-r--r-- | ext/standard/url_scanner_ex.re | 46 |
13 files changed, 423 insertions, 340 deletions
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 383e988090..76fc2ef4a6 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -5411,9 +5411,9 @@ PHP_FUNCTION(ini_get_all) } /* }}} */ -static int php_ini_check_path(char *option_name, int option_len, char *new_option_name, int new_option_len) /* {{{ */ +static int php_ini_check_path(char *option_name, size_t option_len, char *new_option_name, size_t new_option_len) /* {{{ */ { - if (option_len != (new_option_len - 1)) { + if (option_len + 1 != new_option_len) { return 0; } @@ -5434,7 +5434,7 @@ PHP_FUNCTION(ini_set) Z_PARAM_STR(new_value) ZEND_PARSE_PARAMETERS_END(); - old_value = zend_ini_string(ZSTR_VAL(varname), (int)ZSTR_LEN(varname), 0); + old_value = zend_ini_string(ZSTR_VAL(varname), ZSTR_LEN(varname), 0); /* copy to return here, because alter might free it! */ if (old_value) { @@ -5451,7 +5451,7 @@ PHP_FUNCTION(ini_set) RETVAL_FALSE; } -#define _CHECK_PATH(var, var_len, ini) php_ini_check_path(var, (int)var_len, ini, sizeof(ini)) +#define _CHECK_PATH(var, var_len, ini) php_ini_check_path(var, var_len, ini, sizeof(ini)) /* open basedir check */ if (PG(open_basedir)) { if (_CHECK_PATH(ZSTR_VAL(varname), ZSTR_LEN(varname), "error_log") || @@ -5466,6 +5466,7 @@ PHP_FUNCTION(ini_set) } } } +#undef _CHECK_PATH if (zend_alter_ini_entry_ex(varname, new_value, PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0) == FAILURE) { zval_dtor(return_value); @@ -5917,7 +5918,7 @@ static void php_simple_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int cal } if (!(Z_STRLEN_P(arg1) > 1 && Z_STRVAL_P(arg1)[0] == '0') && is_numeric_string(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1), NULL, NULL, 0) == IS_LONG) { - zend_ulong key = (zend_ulong) zend_atol(Z_STRVAL_P(arg1), (int)Z_STRLEN_P(arg1)); + zend_ulong key = (zend_ulong) zend_atol(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1)); if ((find_hash = zend_hash_index_find(Z_ARRVAL_P(arr), key)) == NULL) { array_init(&hash); find_hash = zend_hash_index_update(Z_ARRVAL_P(arr), key, &hash); diff --git a/ext/standard/ftp_fopen_wrapper.c b/ext/standard/ftp_fopen_wrapper.c index d54f2f6ced..b548dddc5f 100644 --- a/ext/standard/ftp_fopen_wrapper.c +++ b/ext/standard/ftp_fopen_wrapper.c @@ -135,7 +135,7 @@ static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, const char { php_stream *stream = NULL, *reuseid = NULL; php_url *resource = NULL; - int result, use_ssl, use_ssl_on_data = 0, tmp_len; + int result, use_ssl, use_ssl_on_data = 0; char tmp_line[512]; char *transport; int transport_len; @@ -148,13 +148,13 @@ static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, const char return NULL; } - use_ssl = resource->scheme && (strlen(resource->scheme) > 3) && resource->scheme[3] == 's'; + use_ssl = resource->scheme && (ZSTR_LEN(resource->scheme) > 3) && ZSTR_VAL(resource->scheme)[3] == 's'; /* use port 21 if one wasn't specified */ if (resource->port == 0) resource->port = 21; - transport_len = (int)spprintf(&transport, 0, "tcp://%s:%d", resource->host, resource->port); + transport_len = (int)spprintf(&transport, 0, "tcp://%s:%d", ZSTR_VAL(resource->host), resource->port); stream = php_stream_xport_create(transport, transport_len, REPORT_ERRORS, STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT, NULL, NULL, context, NULL, NULL); efree(transport); if (stream == NULL) { @@ -245,11 +245,11 @@ static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, const char /* send the user name */ if (resource->user != NULL) { - tmp_len = (int)php_raw_url_decode(resource->user, (int)strlen(resource->user)); + ZSTR_LEN(resource->user) = php_raw_url_decode(ZSTR_VAL(resource->user), ZSTR_LEN(resource->user)); - PHP_FTP_CNTRL_CHK(resource->user, tmp_len, "Invalid login %s") + PHP_FTP_CNTRL_CHK(ZSTR_VAL(resource->user), ZSTR_LEN(resource->user), "Invalid login %s") - php_stream_printf(stream, "USER %s\r\n", resource->user); + php_stream_printf(stream, "USER %s\r\n", ZSTR_VAL(resource->user)); } else { php_stream_write_string(stream, "USER anonymous\r\n"); } @@ -262,11 +262,11 @@ static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, const char php_stream_notify_info(context, PHP_STREAM_NOTIFY_AUTH_REQUIRED, tmp_line, 0); if (resource->pass != NULL) { - tmp_len = (int)php_raw_url_decode(resource->pass, (int)strlen(resource->pass)); + ZSTR_LEN(resource->pass) = php_raw_url_decode(ZSTR_VAL(resource->pass), ZSTR_LEN(resource->pass)); - PHP_FTP_CNTRL_CHK(resource->pass, tmp_len, "Invalid password %s") + PHP_FTP_CNTRL_CHK(resource->pass, ZSTR_LEN(resource->pass), "Invalid password %s") - php_stream_printf(stream, "PASS %s\r\n", resource->pass); + php_stream_printf(stream, "PASS %s\r\n", ZSTR_VAL(resource->pass)); } else { /* if the user has configured who they are, send that as the password */ @@ -548,11 +548,11 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, const char *pa /* Append */ memcpy(tmp_line, "APPE", sizeof("APPE")); } - php_stream_printf(stream, "%s %s\r\n", tmp_line, (resource->path != NULL ? resource->path : "/")); + php_stream_printf(stream, "%s %s\r\n", tmp_line, (resource->path != NULL ? ZSTR_VAL(resource->path) : "/")); /* open the data channel */ if (hoststart == NULL) { - hoststart = resource->host; + hoststart = ZSTR_VAL(resource->host); } transport_len = (int)spprintf(&transport, 0, "tcp://%s:%d", hoststart, portno); datastream = php_stream_xport_create(transport, transport_len, REPORT_ERRORS, STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT, NULL, NULL, context, NULL, NULL); @@ -719,7 +719,7 @@ php_stream * php_stream_ftp_opendir(php_stream_wrapper *wrapper, const char *pat /* open the data channel */ if (hoststart == NULL) { - hoststart = resource->host; + hoststart = ZSTR_VAL(resource->host); } datastream = php_stream_sock_open_host(hoststart, portno, SOCK_STREAM, 0, 0); @@ -727,7 +727,7 @@ php_stream * php_stream_ftp_opendir(php_stream_wrapper *wrapper, const char *pat goto opendir_errexit; } - php_stream_printf(stream, "NLST %s\r\n", (resource->path != NULL ? resource->path : "/")); + php_stream_printf(stream, "NLST %s\r\n", (resource->path != NULL ? ZSTR_VAL(resource->path) : "/")); result = GET_FTP_RESULT(stream); if (result != 150 && result != 125) { @@ -792,7 +792,7 @@ static int php_stream_ftp_url_stat(php_stream_wrapper *wrapper, const char *url, } ssb->sb.st_mode = 0644; /* FTP won't give us a valid mode, so approximate one based on being readable */ - php_stream_printf(stream, "CWD %s\r\n", (resource->path != NULL ? resource->path : "/")); /* If we can CWD to it, it's a directory (maybe a link, but we can't tell) */ + php_stream_printf(stream, "CWD %s\r\n", (resource->path != NULL ? ZSTR_VAL(resource->path) : "/")); /* If we can CWD to it, it's a directory (maybe a link, but we can't tell) */ result = GET_FTP_RESULT(stream); if (result < 200 || result > 299) { ssb->sb.st_mode |= S_IFREG; @@ -808,7 +808,7 @@ static int php_stream_ftp_url_stat(php_stream_wrapper *wrapper, const char *url, goto stat_errexit; } - php_stream_printf(stream, "SIZE %s\r\n", (resource->path != NULL ? resource->path : "/")); + php_stream_printf(stream, "SIZE %s\r\n", (resource->path != NULL ? ZSTR_VAL(resource->path) : "/")); result = GET_FTP_RESULT(stream); if (result < 200 || result > 299) { /* Failure either means it doesn't exist @@ -823,7 +823,7 @@ static int php_stream_ftp_url_stat(php_stream_wrapper *wrapper, const char *url, ssb->sb.st_size = atoi(tmp_line + 4); } - php_stream_printf(stream, "MDTM %s\r\n", (resource->path != NULL ? resource->path : "/")); + php_stream_printf(stream, "MDTM %s\r\n", (resource->path != NULL ? ZSTR_VAL(resource->path) : "/")); result = GET_FTP_RESULT(stream); if (result == 213) { char *p = tmp_line + 4; @@ -922,7 +922,7 @@ static int php_stream_ftp_unlink(php_stream_wrapper *wrapper, const char *url, i } /* Attempt to delete the file */ - php_stream_printf(stream, "DELE %s\r\n", (resource->path != NULL ? resource->path : "/")); + php_stream_printf(stream, "DELE %s\r\n", (resource->path != NULL ? ZSTR_VAL(resource->path) : "/")); result = GET_FTP_RESULT(stream); if (result < 200 || result > 299) { @@ -965,10 +965,10 @@ static int php_stream_ftp_rename(php_stream_wrapper *wrapper, const char *url_fr !resource_to || !resource_from->scheme || !resource_to->scheme || - strcmp(resource_from->scheme, resource_to->scheme) || + !zend_string_equals(resource_from->scheme, resource_to->scheme) || !resource_from->host || !resource_to->host || - strcmp(resource_from->host, resource_to->host) || + !zend_string_equals(resource_from->host, resource_to->host) || (resource_from->port != resource_to->port && resource_from->port * resource_to->port != 0 && resource_from->port + resource_to->port != 21) || @@ -980,13 +980,13 @@ static int php_stream_ftp_rename(php_stream_wrapper *wrapper, const char *url_fr stream = php_ftp_fopen_connect(wrapper, url_from, "r", 0, NULL, context, NULL, NULL, NULL, NULL); if (!stream) { if (options & REPORT_ERRORS) { - php_error_docref(NULL, E_WARNING, "Unable to connect to %s", resource_from->host); + php_error_docref(NULL, E_WARNING, "Unable to connect to %s", ZSTR_VAL(resource_from->host)); } goto rename_errexit; } /* Rename FROM */ - php_stream_printf(stream, "RNFR %s\r\n", (resource_from->path != NULL ? resource_from->path : "/")); + php_stream_printf(stream, "RNFR %s\r\n", (resource_from->path != NULL ? ZSTR_VAL(resource_from->path) : "/")); result = GET_FTP_RESULT(stream); if (result < 300 || result > 399) { @@ -997,7 +997,7 @@ static int php_stream_ftp_rename(php_stream_wrapper *wrapper, const char *url_fr } /* Rename TO */ - php_stream_printf(stream, "RNTO %s\r\n", (resource_to->path != NULL ? resource_to->path : "/")); + php_stream_printf(stream, "RNTO %s\r\n", (resource_to->path != NULL ? ZSTR_VAL(resource_to->path) : "/")); result = GET_FTP_RESULT(stream); if (result < 200 || result > 299) { @@ -1051,14 +1051,14 @@ static int php_stream_ftp_mkdir(php_stream_wrapper *wrapper, const char *url, in } if (!recursive) { - php_stream_printf(stream, "MKD %s\r\n", resource->path); + php_stream_printf(stream, "MKD %s\r\n", ZSTR_VAL(resource->path)); result = GET_FTP_RESULT(stream); } else { /* we look for directory separator from the end of string, thus hopefuly reducing our work load */ char *p, *e, *buf; - buf = estrdup(resource->path); - e = buf + strlen(buf); + buf = estrndup(ZSTR_VAL(resource->path), ZSTR_LEN(resource->path)); + e = buf + ZSTR_LEN(resource->path); /* find a top level directory we need to create */ while ((p = strrchr(buf, '/'))) { @@ -1071,7 +1071,7 @@ static int php_stream_ftp_mkdir(php_stream_wrapper *wrapper, const char *url, in } } if (p == buf) { - php_stream_printf(stream, "MKD %s\r\n", resource->path); + php_stream_printf(stream, "MKD %s\r\n", ZSTR_VAL(resource->path)); result = GET_FTP_RESULT(stream); } else { php_stream_printf(stream, "MKD %s\r\n", buf); diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c index 7208404d1c..f0881c2a1c 100644 --- a/ext/standard/http_fopen_wrapper.c +++ b/ext/standard/http_fopen_wrapper.c @@ -152,7 +152,8 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, return NULL; } - if (strncasecmp(resource->scheme, "http", sizeof("http")) && strncasecmp(resource->scheme, "https", sizeof("https"))) { + if (!zend_string_equals_literal_ci(resource->scheme, "http") && + !zend_string_equals_literal_ci(resource->scheme, "https")) { if (!context || (tmpzval = php_stream_context_get_option(context, wrapper->wops->label, "proxy")) == NULL || Z_TYPE_P(tmpzval) != IS_STRING || @@ -176,7 +177,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, return NULL; } - use_ssl = resource->scheme && (strlen(resource->scheme) > 4) && resource->scheme[4] == 's'; + use_ssl = resource->scheme && (ZSTR_LEN(resource->scheme) > 4) && ZSTR_VAL(resource->scheme)[4] == 's'; /* choose default ports */ if (use_ssl && resource->port == 0) resource->port = 443; @@ -191,7 +192,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, transport_len = Z_STRLEN_P(tmpzval); transport_string = estrndup(Z_STRVAL_P(tmpzval), Z_STRLEN_P(tmpzval)); } else { - transport_len = spprintf(&transport_string, 0, "%s://%s:%d", use_ssl ? "ssl" : "tcp", resource->host, resource->port); + transport_len = spprintf(&transport_string, 0, "%s://%s:%d", use_ssl ? "ssl" : "tcp", ZSTR_VAL(resource->host), resource->port); } } @@ -234,13 +235,13 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, /* Set peer_name or name verification will try to use the proxy server name */ if (!context || (tmpzval = php_stream_context_get_option(context, "ssl", "peer_name")) == NULL) { - ZVAL_STRING(&ssl_proxy_peer_name, resource->host); + ZVAL_STR_COPY(&ssl_proxy_peer_name, resource->host); php_stream_context_set_option(PHP_STREAM_CONTEXT(stream), "ssl", "peer_name", &ssl_proxy_peer_name); zval_ptr_dtor(&ssl_proxy_peer_name); } smart_str_appendl(&header, "CONNECT ", sizeof("CONNECT ")-1); - smart_str_appends(&header, resource->host); + smart_str_appends(&header, ZSTR_VAL(resource->host)); smart_str_appendc(&header, ':'); smart_str_append_unsigned(&header, resource->port); smart_str_appendl(&header, " HTTP/1.0\r\n", sizeof(" HTTP/1.0\r\n")-1); @@ -388,8 +389,8 @@ finish: /* Send the traditional /path/to/file?query_string */ /* file */ - if (resource->path && *resource->path) { - smart_str_appends(&req_buf, resource->path); + if (resource->path && ZSTR_LEN(resource->path)) { + smart_str_appends(&req_buf, ZSTR_VAL(resource->path)); } else { smart_str_appendc(&req_buf, '/'); } @@ -397,7 +398,7 @@ finish: /* query string */ if (resource->query) { smart_str_appendc(&req_buf, '?'); - smart_str_appends(&req_buf, resource->query); + smart_str_appends(&req_buf, ZSTR_VAL(resource->query)); } } @@ -531,15 +532,15 @@ finish: zend_string *stmp; /* decode the strings first */ - php_url_decode(resource->user, strlen(resource->user)); + php_url_decode(ZSTR_VAL(resource->user), ZSTR_LEN(resource->user)); - strcpy(scratch, resource->user); + strcpy(scratch, ZSTR_VAL(resource->user)); strcat(scratch, ":"); /* Note: password is optional! */ if (resource->pass) { - php_url_decode(resource->pass, strlen(resource->pass)); - strcat(scratch, resource->pass); + php_url_decode(ZSTR_VAL(resource->pass), ZSTR_LEN(resource->pass)); + strcat(scratch, ZSTR_VAL(resource->pass)); } stmp = php_base64_encode((unsigned char*)scratch, strlen(scratch)); @@ -564,7 +565,7 @@ finish: /* Send Host: header so name-based virtual hosts work */ if ((have_header & HTTP_HEADER_HOST) == 0) { smart_str_appends(&req_buf, "Host: "); - smart_str_appends(&req_buf, resource->host); + smart_str_appends(&req_buf, ZSTR_VAL(resource->host)); if ((use_ssl && resource->port != 443 && resource->port != 0) || (!use_ssl && resource->port != 80 && resource->port != 0)) { smart_str_appendc(&req_buf, ':'); @@ -855,21 +856,24 @@ finish: { if (*location != '/') { if (*(location+1) != '\0' && resource->path) { - char *s = strrchr(resource->path, '/'); + char *s = strrchr(ZSTR_VAL(resource->path), '/'); if (!s) { - s = resource->path; - if (!s[0]) { - efree(s); - s = resource->path = estrdup("/"); + s = ZSTR_VAL(resource->path); + if (!ZSTR_LEN(resource->path)) { + zend_string_release(resource->path); + resource->path = zend_string_init("/", 1, 0); + s = ZSTR_VAL(resource->path); } else { *s = '/'; } } s[1] = '\0'; - if (resource->path && *(resource->path) == '/' && *(resource->path + 1) == '\0') { - snprintf(loc_path, sizeof(loc_path) - 1, "%s%s", resource->path, location); + if (resource->path && + ZSTR_VAL(resource->path)[0] == '/' && + ZSTR_VAL(resource->path)[1] == '\0') { + snprintf(loc_path, sizeof(loc_path) - 1, "%s%s", ZSTR_VAL(resource->path), location); } else { - snprintf(loc_path, sizeof(loc_path) - 1, "%s/%s", resource->path, location); + snprintf(loc_path, sizeof(loc_path) - 1, "%s/%s", ZSTR_VAL(resource->path), location); } } else { snprintf(loc_path, sizeof(loc_path) - 1, "/%s", location); @@ -878,9 +882,9 @@ finish: strlcpy(loc_path, location, sizeof(loc_path)); } if ((use_ssl && resource->port != 443) || (!use_ssl && resource->port != 80)) { - snprintf(new_path, sizeof(new_path) - 1, "%s://%s:%d%s", resource->scheme, resource->host, resource->port, loc_path); + snprintf(new_path, sizeof(new_path) - 1, "%s://%s:%d%s", ZSTR_VAL(resource->scheme), ZSTR_VAL(resource->host), resource->port, loc_path); } else { - snprintf(new_path, sizeof(new_path) - 1, "%s://%s%s", resource->scheme, resource->host, loc_path); + snprintf(new_path, sizeof(new_path) - 1, "%s://%s%s", ZSTR_VAL(resource->scheme), ZSTR_VAL(resource->host), loc_path); } } else { strlcpy(new_path, location, sizeof(new_path)); @@ -896,9 +900,8 @@ finish: #define CHECK_FOR_CNTRL_CHARS(val) { \ if (val) { \ unsigned char *s, *e; \ - size_t l; \ - l = php_url_decode(val, strlen(val)); \ - s = (unsigned char*)val; e = s + l; \ + ZSTR_LEN(val) = php_url_decode(ZSTR_VAL(val), ZSTR_LEN(val)); \ + s = (unsigned char*)ZSTR_VAL(val); e = s + ZSTR_LEN(val); \ while (s < e) { \ if (iscntrl(*s)) { \ php_stream_wrapper_log_error(wrapper, options, "Invalid redirect URL! %s", new_path); \ @@ -910,9 +913,9 @@ finish: } /* check for control characters in login, password & path */ if (strncasecmp(new_path, "http://", sizeof("http://") - 1) || strncasecmp(new_path, "https://", sizeof("https://") - 1)) { - CHECK_FOR_CNTRL_CHARS(resource->user) - CHECK_FOR_CNTRL_CHARS(resource->pass) - CHECK_FOR_CNTRL_CHARS(resource->path) + CHECK_FOR_CNTRL_CHARS(resource->user); + CHECK_FOR_CNTRL_CHARS(resource->pass); + CHECK_FOR_CNTRL_CHARS(resource->path); } stream = php_stream_url_wrap_http_ex( wrapper, new_path, mode, options, opened_path, context, diff --git a/ext/standard/link.c b/ext/standard/link.c index c55e6f4b0a..7e0a6d3876 100644 --- a/ext/standard/link.c +++ b/ext/standard/link.c @@ -57,7 +57,7 @@ PHP_FUNCTION(readlink) char *link; size_t link_len; char buff[MAXPATHLEN]; - int ret; + ssize_t ret; ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_PATH(link, link_len) diff --git a/ext/standard/link_win32.c b/ext/standard/link_win32.c index 53ce7fbb4d..406526128f 100644 --- a/ext/standard/link_win32.c +++ b/ext/standard/link_win32.c @@ -63,7 +63,7 @@ TODO: PHP_FUNCTION(readlink) { char *link; - size_t link_len; + ssize_t link_len; char target[MAXPATHLEN]; if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &link, &link_len) == FAILURE) { @@ -74,7 +74,8 @@ PHP_FUNCTION(readlink) RETURN_FALSE; } - if (php_sys_readlink(link, target, MAXPATHLEN) == -1) { + link_len = php_sys_readlink(link, target, MAXPATHLEN); + if (link_len == -1) { php_error_docref(NULL, E_WARNING, "readlink failed to read the symbolic link (%s), error %d)", link, GetLastError()); RETURN_FALSE; } diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c index 0031440704..34f5d3afbf 100644 --- a/ext/standard/php_fopen_wrapper.c +++ b/ext/standard/php_fopen_wrapper.c @@ -28,6 +28,7 @@ #include "php.h" #include "php_globals.h" #include "php_standard.h" +#include "php_memory_streams.h" #include "php_fopen_wrappers.h" #include "SAPI.h" @@ -203,20 +204,12 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const char *pa return NULL; } } - if (strpbrk(mode, "wa+")) { - mode_rw = TEMP_STREAM_DEFAULT; - } else { - mode_rw = TEMP_STREAM_READONLY; - } + mode_rw = php_stream_mode_from_str(mode); return php_stream_temp_create(mode_rw, max_memory); } if (!strcasecmp(path, "memory")) { - if (strpbrk(mode, "wa+")) { - mode_rw = TEMP_STREAM_DEFAULT; - } else { - mode_rw = TEMP_STREAM_READONLY; - } + mode_rw = php_stream_mode_from_str(mode); return php_stream_memory_create(mode_rw); } diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index 475fb060be..979a64b913 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -1559,7 +1559,7 @@ PHP_FUNCTION(stream_resolve_include_path) Z_PARAM_PATH(filename, filename_len) ZEND_PARSE_PARAMETERS_END(); - resolved_path = zend_resolve_path(filename, (int)filename_len); + resolved_path = zend_resolve_path(filename, filename_len); if (resolved_path) { RETURN_STR(resolved_path); diff --git a/ext/standard/string.c b/ext/standard/string.c index 6ffc2ae2bb..55bcca14db 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -2789,11 +2789,16 @@ PHP_FUNCTION(chr) /* {{{ php_ucfirst Uppercase the first character of the word in a native string */ -static void php_ucfirst(char *str) +static zend_string* php_ucfirst(zend_string *str) { - register char *r; - r = str; - *r = toupper((unsigned char) *r); + unsigned char r = toupper(ZSTR_VAL(str)[0]); + if (r == ZSTR_VAL(str)[0]) { + return zend_string_copy(str); + } else { + zend_string *s = zend_string_init(ZSTR_VAL(str), ZSTR_LEN(str), 0); + ZSTR_VAL(s)[0] = r; + return s; + } } /* }}} */ @@ -2811,18 +2816,22 @@ PHP_FUNCTION(ucfirst) RETURN_EMPTY_STRING(); } - ZVAL_STRINGL(return_value, ZSTR_VAL(str), ZSTR_LEN(str)); - php_ucfirst(Z_STRVAL_P(return_value)); + RETURN_STR(php_ucfirst(str)); } /* }}} */ /* {{{ Lowercase the first character of the word in a native string */ -static void php_lcfirst(char *str) +static zend_string* php_lcfirst(zend_string *str) { - register char *r; - r = str; - *r = tolower((unsigned char) *r); + unsigned char r = tolower(ZSTR_VAL(str)[0]); + if (r == ZSTR_VAL(str)[0]) { + return zend_string_copy(str); + } else { + zend_string *s = zend_string_init(ZSTR_VAL(str), ZSTR_LEN(str), 0); + ZSTR_VAL(s)[0] = r; + return s; + } } /* }}} */ @@ -2840,8 +2849,7 @@ PHP_FUNCTION(lcfirst) RETURN_EMPTY_STRING(); } - ZVAL_STRINGL(return_value, ZSTR_VAL(str), ZSTR_LEN(str)); - php_lcfirst(Z_STRVAL_P(return_value)); + RETURN_STR(php_lcfirst(str)); } /* }}} */ diff --git a/ext/standard/tests/streams/bug75031.phpt b/ext/standard/tests/streams/bug75031.phpt new file mode 100644 index 0000000000..f0d67a3524 --- /dev/null +++ b/ext/standard/tests/streams/bug75031.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #75031: Append mode in php://temp and php://memory +--FILE-- +<?php + +function test_75031($type, $mode) { + $fp = fopen($type, $mode); + fwrite($fp, "hello"); + fseek($fp, 0, SEEK_SET); + fwrite($fp, "world"); + var_dump(stream_get_contents($fp, -1, 0)); + fclose($fp); +} + +test_75031("php://temp", "w+"); +test_75031("php://memory", "w+"); +test_75031("php://temp", "a+"); +test_75031("php://memory", "a+"); + +?> +--EXPECT-- +string(5) "world" +string(5) "world" +string(10) "helloworld" +string(10) "helloworld" diff --git a/ext/standard/url.c b/ext/standard/url.c index a3a19a2b22..e909eee347 100644 --- a/ext/standard/url.c +++ b/ext/standard/url.c @@ -42,19 +42,19 @@ PHPAPI void php_url_free(php_url *theurl) { if (theurl->scheme) - efree(theurl->scheme); + zend_string_release(theurl->scheme); if (theurl->user) - efree(theurl->user); + zend_string_release(theurl->user); if (theurl->pass) - efree(theurl->pass); + zend_string_release(theurl->pass); if (theurl->host) - efree(theurl->host); + zend_string_release(theurl->host); if (theurl->path) - efree(theurl->path); + zend_string_release(theurl->path); if (theurl->query) - efree(theurl->query); + zend_string_release(theurl->query); if (theurl->fragment) - efree(theurl->fragment); + zend_string_release(theurl->fragment); efree(theurl); } /* }}} */ @@ -124,8 +124,8 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) } if (e + 1 == ue) { /* only scheme is available */ - ret->scheme = estrndup(s, (e - s)); - php_replace_controlchars_ex(ret->scheme, (e - s)); + ret->scheme = zend_string_init(s, (e - s), 0); + php_replace_controlchars_ex(ZSTR_VAL(ret->scheme), ZSTR_LEN(ret->scheme)); return ret; } @@ -146,18 +146,18 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) goto parse_port; } - ret->scheme = estrndup(s, (e-s)); - php_replace_controlchars_ex(ret->scheme, (e - s)); + ret->scheme = zend_string_init(s, (e-s), 0); + php_replace_controlchars_ex(ZSTR_VAL(ret->scheme), ZSTR_LEN(ret->scheme)); s = e + 1; goto just_path; } else { - ret->scheme = estrndup(s, (e-s)); - php_replace_controlchars_ex(ret->scheme, (e - s)); + ret->scheme = zend_string_init(s, (e-s), 0); + php_replace_controlchars_ex(ZSTR_VAL(ret->scheme), ZSTR_LEN(ret->scheme)); if (e + 2 < ue && *(e + 2) == '/') { s = e + 3; - if (!strncasecmp("file", ret->scheme, sizeof("file"))) { + if (zend_string_equals_literal_ci(ret->scheme, "file")) { if (e + 3 < ue && *(e + 3) == '/') { /* support windows drive letters as in: file:///c:/somedir/file.txt @@ -193,13 +193,11 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) s += 2; } } else { - if (ret->scheme) efree(ret->scheme); - efree(ret); + php_url_free(ret); return NULL; } } else if (p == pp && pp == ue) { - if (ret->scheme) efree(ret->scheme); - efree(ret); + php_url_free(ret); return NULL; } else if (s + 1 < ue && *s == '/' && *(s + 1) == '/') { /* relative-scheme URL */ s += 2; @@ -228,15 +226,15 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) /* check for login and password */ if ((p = zend_memrchr(s, '@', (e-s)))) { if ((pp = memchr(s, ':', (p-s)))) { - ret->user = estrndup(s, (pp-s)); - php_replace_controlchars_ex(ret->user, (pp - s)); + ret->user = zend_string_init(s, (pp-s), 0); + php_replace_controlchars_ex(ZSTR_VAL(ret->user), ZSTR_LEN(ret->user)); pp++; - ret->pass = estrndup(pp, (p-pp)); - php_replace_controlchars_ex(ret->pass, (p-pp)); + ret->pass = zend_string_init(pp, (p-pp), 0); + php_replace_controlchars_ex(ZSTR_VAL(ret->pass), ZSTR_LEN(ret->pass)); } else { - ret->user = estrndup(s, (p-s)); - php_replace_controlchars_ex(ret->user, (p-s)); + ret->user = zend_string_init(s, (p-s), 0); + php_replace_controlchars_ex(ZSTR_VAL(ret->user), ZSTR_LEN(ret->user)); } s = p + 1; @@ -256,10 +254,7 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) if (!ret->port) { p++; if (e-p > 5) { /* port cannot be longer then 5 characters */ - if (ret->scheme) efree(ret->scheme); - if (ret->user) efree(ret->user); - if (ret->pass) efree(ret->pass); - efree(ret); + php_url_free(ret); return NULL; } else if (e - p > 0) { zend_long port; @@ -269,10 +264,7 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) if (port > 0 && port <= 65535) { ret->port = (unsigned short)port; } else { - if (ret->scheme) efree(ret->scheme); - if (ret->user) efree(ret->user); - if (ret->pass) efree(ret->pass); - efree(ret); + php_url_free(ret); return NULL; } } @@ -284,15 +276,12 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) /* check if we have a valid host, if we don't reject the string as url */ if ((p-s) < 1) { - if (ret->scheme) efree(ret->scheme); - if (ret->user) efree(ret->user); - if (ret->pass) efree(ret->pass); - efree(ret); + php_url_free(ret); return NULL; } - ret->host = estrndup(s, (p-s)); - php_replace_controlchars_ex(ret->host, (p - s)); + ret->host = zend_string_init(s, (p-s), 0); + php_replace_controlchars_ex(ZSTR_VAL(ret->host), ZSTR_LEN(ret->host)); if (e == ue) { return ret; @@ -307,8 +296,8 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) if (p) { p++; if (p < e) { - ret->fragment = estrndup(p, (e - p)); - php_replace_controlchars_ex(ret->fragment, (e - p)); + ret->fragment = zend_string_init(p, (e - p), 0); + php_replace_controlchars_ex(ZSTR_VAL(ret->fragment), ZSTR_LEN(ret->fragment)); } e = p-1; } @@ -317,15 +306,15 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) if (p) { p++; if (p < e) { - ret->query = estrndup(p, (e - p)); - php_replace_controlchars_ex(ret->query, (e - p)); + ret->query = zend_string_init(p, (e - p), 0); + php_replace_controlchars_ex(ZSTR_VAL(ret->query), ZSTR_LEN(ret->query)); } e = p-1; } if (s < e || s == ue) { - ret->path = estrndup(s, (e - s)); - php_replace_controlchars_ex(ret->path, (e - s)); + ret->path = zend_string_init(s, (e - s), 0); + php_replace_controlchars_ex(ZSTR_VAL(ret->path), ZSTR_LEN(ret->path)); } return ret; @@ -357,28 +346,28 @@ PHP_FUNCTION(parse_url) if (key > -1) { switch (key) { case PHP_URL_SCHEME: - if (resource->scheme != NULL) RETVAL_STRING(resource->scheme); + if (resource->scheme != NULL) RETVAL_STR_COPY(resource->scheme); break; case PHP_URL_HOST: - if (resource->host != NULL) RETVAL_STRING(resource->host); + if (resource->host != NULL) RETVAL_STR_COPY(resource->host); break; case PHP_URL_PORT: if (resource->port != 0) RETVAL_LONG(resource->port); break; case PHP_URL_USER: - if (resource->user != NULL) RETVAL_STRING(resource->user); + if (resource->user != NULL) RETVAL_STR_COPY(resource->user); break; case PHP_URL_PASS: - if (resource->pass != NULL) RETVAL_STRING(resource->pass); + if (resource->pass != NULL) RETVAL_STR_COPY(resource->pass); break; case PHP_URL_PATH: - if (resource->path != NULL) RETVAL_STRING(resource->path); + if (resource->path != NULL) RETVAL_STR_COPY(resource->path); break; case PHP_URL_QUERY: - if (resource->query != NULL) RETVAL_STRING(resource->query); + if (resource->query != NULL) RETVAL_STR_COPY(resource->query); break; case PHP_URL_FRAGMENT: - if (resource->fragment != NULL) RETVAL_STRING(resource->fragment); + if (resource->fragment != NULL) RETVAL_STR_COPY(resource->fragment); break; default: php_error_docref(NULL, E_WARNING, "Invalid URL component identifier " ZEND_LONG_FMT, key); @@ -392,11 +381,11 @@ PHP_FUNCTION(parse_url) /* add the various elements to the array */ if (resource->scheme != NULL) { - ZVAL_STRING(&tmp, resource->scheme); + ZVAL_STR_COPY(&tmp, resource->scheme); zend_hash_add_new(Z_ARRVAL_P(return_value), ZSTR_KNOWN(ZEND_STR_SCHEME), &tmp); } if (resource->host != NULL) { - ZVAL_STRING(&tmp, resource->host); + ZVAL_STR_COPY(&tmp, resource->host); zend_hash_add_new(Z_ARRVAL_P(return_value), ZSTR_KNOWN(ZEND_STR_HOST), &tmp); } if (resource->port != 0) { @@ -404,23 +393,23 @@ PHP_FUNCTION(parse_url) zend_hash_add_new(Z_ARRVAL_P(return_value), ZSTR_KNOWN(ZEND_STR_PORT), &tmp); } if (resource->user != NULL) { - ZVAL_STRING(&tmp, resource->user); + ZVAL_STR_COPY(&tmp, resource->user); zend_hash_add_new(Z_ARRVAL_P(return_value), ZSTR_KNOWN(ZEND_STR_USER), &tmp); } if (resource->pass != NULL) { - ZVAL_STRING(&tmp, resource->pass); + ZVAL_STR_COPY(&tmp, resource->pass); zend_hash_add_new(Z_ARRVAL_P(return_value), ZSTR_KNOWN(ZEND_STR_PASS), &tmp); } if (resource->path != NULL) { - ZVAL_STRING(&tmp, resource->path); + ZVAL_STR_COPY(&tmp, resource->path); zend_hash_add_new(Z_ARRVAL_P(return_value), ZSTR_KNOWN(ZEND_STR_PATH), &tmp); } if (resource->query != NULL) { - ZVAL_STRING(&tmp, resource->query); + ZVAL_STR_COPY(&tmp, resource->query); zend_hash_add_new(Z_ARRVAL_P(return_value), ZSTR_KNOWN(ZEND_STR_QUERY), &tmp); } if (resource->fragment != NULL) { - ZVAL_STRING(&tmp, resource->fragment); + ZVAL_STR_COPY(&tmp, resource->fragment); zend_hash_add_new(Z_ARRVAL_P(return_value), ZSTR_KNOWN(ZEND_STR_FRAGMENT), &tmp); } done: diff --git a/ext/standard/url.h b/ext/standard/url.h index 7a2f20ed2b..8c4e63e60e 100644 --- a/ext/standard/url.h +++ b/ext/standard/url.h @@ -21,14 +21,14 @@ #define URL_H typedef struct php_url { - char *scheme; - char *user; - char *pass; - char *host; + zend_string *scheme; + zend_string *user; + zend_string *pass; + zend_string *host; unsigned short port; - char *path; - char *query; - char *fragment; + zend_string *path; + zend_string *query; + zend_string *fragment; } php_url; PHPAPI void php_url_free(php_url *theurl); diff --git a/ext/standard/url_scanner_ex.c b/ext/standard/url_scanner_ex.c index 484d5d9c13..af8a3781d6 100644 --- a/ext/standard/url_scanner_ex.c +++ b/ext/standard/url_scanner_ex.c @@ -1,4 +1,4 @@ -/* Generated by re2c 0.16 */ +/* Generated by re2c 0.13.5 */ #line 1 "ext/standard/url_scanner_ex.re" /* +----------------------------------------------------------------------+ @@ -182,8 +182,6 @@ PHP_INI_END() static inline void append_modified_url(smart_str *url, smart_str *dest, smart_str *url_app, const char *separator) { php_url *url_parts; - char *tmp; - size_t tmp_len; smart_str_0(url); /* FIXME: Bug #70480 php_url_parse_ex() crashes by processing chars exceed len */ url_parts = php_url_parse_ex(ZSTR_VAL(url->s), ZSTR_LEN(url->s)); @@ -196,21 +194,23 @@ static inline void append_modified_url(smart_str *url, smart_str *dest, smart_st /* Check protocol. Only http/https is allowed. */ if (url_parts->scheme - && strcasecmp("http", url_parts->scheme) - && strcasecmp("https", url_parts->scheme)) { + && !zend_string_equals_literal_ci(url_parts->scheme, "http") + && !zend_string_equals_literal_ci(url_parts->scheme, "https")) { smart_str_append_smart_str(dest, url); php_url_free(url_parts); return; } /* Check host whitelist. If it's not listed, do nothing. */ - if (url_parts->host - && (tmp_len = strlen(url_parts->host)) - && (tmp = php_strtolower(url_parts->host, tmp_len)) - && !zend_hash_str_find(&BG(url_adapt_session_hosts_ht), tmp, tmp_len)) { - smart_str_append_smart_str(dest, url); - php_url_free(url_parts); - return; + if (url_parts->host) { + zend_string *tmp = zend_string_tolower(url_parts->host); + if (!zend_hash_exists(&BG(url_adapt_session_hosts_ht), tmp)) { + zend_string_release(tmp); + smart_str_append_smart_str(dest, url); + php_url_free(url_parts); + return; + } + zend_string_release(tmp); } /* @@ -229,32 +229,32 @@ static inline void append_modified_url(smart_str *url, smart_str *dest, smart_st } if (url_parts->scheme) { - smart_str_appends(dest, url_parts->scheme); + smart_str_appends(dest, ZSTR_VAL(url_parts->scheme)); smart_str_appends(dest, "://"); } else if (*(ZSTR_VAL(url->s)) == '/' && *(ZSTR_VAL(url->s)+1) == '/') { smart_str_appends(dest, "//"); } if (url_parts->user) { - smart_str_appends(dest, url_parts->user); + smart_str_appends(dest, ZSTR_VAL(url_parts->user)); if (url_parts->pass) { - smart_str_appends(dest, url_parts->pass); + smart_str_appends(dest, ZSTR_VAL(url_parts->pass)); smart_str_appendc(dest, ':'); } smart_str_appendc(dest, '@'); } if (url_parts->host) { - smart_str_appends(dest, url_parts->host); + smart_str_appends(dest, ZSTR_VAL(url_parts->host)); } if (url_parts->port) { smart_str_appendc(dest, ':'); smart_str_append_unsigned(dest, (long)url_parts->port); } if (url_parts->path) { - smart_str_appends(dest, url_parts->path); + smart_str_appends(dest, ZSTR_VAL(url_parts->path)); } smart_str_appendc(dest, '?'); if (url_parts->query) { - smart_str_appends(dest, url_parts->query); + smart_str_appends(dest, ZSTR_VAL(url_parts->query)); smart_str_appends(dest, separator); smart_str_append_smart_str(dest, url_app); } else { @@ -262,7 +262,7 @@ static inline void append_modified_url(smart_str *url, smart_str *dest, smart_st } if (url_parts->fragment) { smart_str_appendc(dest, '#'); - smart_str_appends(dest, url_parts->fragment); + smart_str_appends(dest, ZSTR_VAL(url_parts->fragment)); } php_url_free(url_parts); } @@ -383,8 +383,8 @@ static int check_host_whitelist(url_adapt_state_ex_t *ctx) if (url_parts->scheme) { /* Only http/https should be handled. A bit hacky check this here, but saves a URL parse. */ - if (strcasecmp(url_parts->scheme, "http") && - strcasecmp(url_parts->scheme, "https")) { + if (!zend_string_equals_literal_ci(url_parts->scheme, "http") && + !zend_string_equals_literal_ci(url_parts->scheme, "https")) { php_url_free(url_parts); return FAILURE; } @@ -394,13 +394,11 @@ static int check_host_whitelist(url_adapt_state_ex_t *ctx) return SUCCESS; } if (!zend_hash_num_elements(allowed_hosts) && - check_http_host(url_parts->host) == SUCCESS) { + check_http_host(ZSTR_VAL(url_parts->host)) == SUCCESS) { php_url_free(url_parts); return SUCCESS; } - if (!zend_hash_str_find(allowed_hosts, - url_parts->host, - strlen(url_parts->host))) { + if (!zend_hash_find(allowed_hosts, url_parts->host)) { php_url_free(url_parts); return FAILURE; } @@ -513,7 +511,7 @@ state_plain_begin: state_plain: start = YYCURSOR; -#line 517 "ext/standard/url_scanner_ex.c" +#line 515 "ext/standard/url_scanner_ex.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -550,35 +548,34 @@ state_plain: 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, }; + if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; if (yybm[0+yych] & 128) { - goto yy2; + goto yy4; } - goto yy5; -yy2: + ++YYCURSOR; +#line 517 "ext/standard/url_scanner_ex.re" + { passthru(STD_ARGS); STATE = STATE_TAG; goto state_tag; } +#line 561 "ext/standard/url_scanner_ex.c" +yy4: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; if (yybm[0+yych] & 128) { - goto yy2; + goto yy4; } -#line 520 "ext/standard/url_scanner_ex.re" +#line 518 "ext/standard/url_scanner_ex.re" { passthru(STD_ARGS); goto state_plain; } -#line 569 "ext/standard/url_scanner_ex.c" -yy5: - ++YYCURSOR; -#line 519 "ext/standard/url_scanner_ex.re" - { passthru(STD_ARGS); STATE = STATE_TAG; goto state_tag; } -#line 574 "ext/standard/url_scanner_ex.c" +#line 571 "ext/standard/url_scanner_ex.c" } -#line 521 "ext/standard/url_scanner_ex.re" +#line 519 "ext/standard/url_scanner_ex.re" state_tag: start = YYCURSOR; -#line 582 "ext/standard/url_scanner_ex.c" +#line 579 "ext/standard/url_scanner_ex.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -615,27 +612,39 @@ state_tag: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; - if (YYLIMIT <= YYCURSOR) YYFILL(1); + if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; - if (yybm[0+yych] & 128) { - goto yy11; + if (yych <= '@') { + if (yych != ':') goto yy11; + } else { + if (yych <= 'Z') goto yy9; + if (yych <= '`') goto yy11; + if (yych >= '{') goto yy11; } +yy9: ++YYCURSOR; -#line 527 "ext/standard/url_scanner_ex.re" - { passthru(STD_ARGS); goto state_plain_begin; } -#line 627 "ext/standard/url_scanner_ex.c" + yych = *YYCURSOR; + goto yy14; +yy10: +#line 524 "ext/standard/url_scanner_ex.re" + { handle_tag(STD_ARGS); /* Sets STATE */; passthru(STD_ARGS); if (STATE == STATE_PLAIN) goto state_plain; else goto state_next_arg; } +#line 632 "ext/standard/url_scanner_ex.c" yy11: ++YYCURSOR; +#line 525 "ext/standard/url_scanner_ex.re" + { passthru(STD_ARGS); goto state_plain_begin; } +#line 637 "ext/standard/url_scanner_ex.c" +yy13: + ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; +yy14: if (yybm[0+yych] & 128) { - goto yy11; + goto yy13; } -#line 526 "ext/standard/url_scanner_ex.re" - { handle_tag(STD_ARGS); /* Sets STATE */; passthru(STD_ARGS); if (STATE == STATE_PLAIN) goto state_plain; else goto state_next_arg; } -#line 637 "ext/standard/url_scanner_ex.c" + goto yy10; } -#line 528 "ext/standard/url_scanner_ex.re" +#line 526 "ext/standard/url_scanner_ex.re" state_next_arg_begin: @@ -644,7 +653,7 @@ state_next_arg_begin: state_next_arg: start = YYCURSOR; -#line 648 "ext/standard/url_scanner_ex.c" +#line 657 "ext/standard/url_scanner_ex.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -683,57 +692,78 @@ state_next_arg: }; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; - if (yybm[0+yych] & 128) { - goto yy18; - } - if (yych <= '>') { - if (yych == '/') goto yy21; - if (yych >= '>') goto yy22; + if (yych <= '.') { + if (yych <= '\f') { + if (yych <= 0x08) goto yy25; + if (yych <= '\v') goto yy21; + goto yy25; + } else { + if (yych <= '\r') goto yy21; + if (yych == ' ') goto yy21; + goto yy25; + } } else { - if (yych <= 'Z') { - if (yych >= 'A') goto yy24; + if (yych <= '@') { + if (yych <= '/') goto yy17; + if (yych == '>') goto yy19; + goto yy25; } else { - if (yych <= '`') goto yy16; - if (yych <= 'z') goto yy24; + if (yych <= 'Z') goto yy23; + if (yych <= '`') goto yy25; + if (yych <= 'z') goto yy23; + goto yy25; } } -yy16: - ++YYCURSOR; yy17: -#line 539 "ext/standard/url_scanner_ex.re" - { passthru(STD_ARGS); goto state_plain_begin; } -#line 706 "ext/standard/url_scanner_ex.c" -yy18: ++YYCURSOR; - if (YYLIMIT <= YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - if (yybm[0+yych] & 128) { - goto yy18; - } + if ((yych = *YYCURSOR) == '>') goto yy28; +yy18: #line 537 "ext/standard/url_scanner_ex.re" - { passthru(STD_ARGS); goto state_next_arg; } -#line 716 "ext/standard/url_scanner_ex.c" + { passthru(STD_ARGS); goto state_plain_begin; } +#line 724 "ext/standard/url_scanner_ex.c" +yy19: + ++YYCURSOR; +yy20: +#line 534 "ext/standard/url_scanner_ex.re" + { passthru(STD_ARGS); handle_form(STD_ARGS); goto state_plain_begin; } +#line 730 "ext/standard/url_scanner_ex.c" yy21: - yych = *++YYCURSOR; - if (yych != '>') goto yy17; + ++YYCURSOR; + yych = *YYCURSOR; + goto yy27; yy22: +#line 535 "ext/standard/url_scanner_ex.re" + { passthru(STD_ARGS); goto state_next_arg; } +#line 738 "ext/standard/url_scanner_ex.c" +yy23: ++YYCURSOR; #line 536 "ext/standard/url_scanner_ex.re" - { passthru(STD_ARGS); handle_form(STD_ARGS); goto state_plain_begin; } -#line 724 "ext/standard/url_scanner_ex.c" -yy24: - ++YYCURSOR; -#line 538 "ext/standard/url_scanner_ex.re" { --YYCURSOR; STATE = STATE_ARG; goto state_arg; } -#line 729 "ext/standard/url_scanner_ex.c" +#line 743 "ext/standard/url_scanner_ex.c" +yy25: + yych = *++YYCURSOR; + goto yy18; +yy26: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy27: + if (yybm[0+yych] & 128) { + goto yy26; + } + goto yy22; +yy28: + ++YYCURSOR; + yych = *YYCURSOR; + goto yy20; } -#line 540 "ext/standard/url_scanner_ex.re" +#line 538 "ext/standard/url_scanner_ex.re" state_arg: start = YYCURSOR; -#line 737 "ext/standard/url_scanner_ex.c" +#line 767 "ext/standard/url_scanner_ex.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -770,35 +800,42 @@ state_arg: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; - if (YYLIMIT <= YYCURSOR) YYFILL(1); + if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; - if (yych <= '@') goto yy28; - if (yych <= 'Z') goto yy30; - if (yych <= '`') goto yy28; - if (yych <= 'z') goto yy30; -yy28: + if (yych <= '@') goto yy33; + if (yych <= 'Z') goto yy31; + if (yych <= '`') goto yy33; + if (yych >= '{') goto yy33; +yy31: ++YYCURSOR; -#line 546 "ext/standard/url_scanner_ex.re" + yych = *YYCURSOR; + goto yy36; +yy32: +#line 543 "ext/standard/url_scanner_ex.re" + { passthru(STD_ARGS); handle_arg(STD_ARGS); STATE = STATE_BEFORE_VAL; goto state_before_val; } +#line 817 "ext/standard/url_scanner_ex.c" +yy33: + ++YYCURSOR; +#line 544 "ext/standard/url_scanner_ex.re" { passthru(STD_ARGS); STATE = STATE_NEXT_ARG; goto state_next_arg; } -#line 784 "ext/standard/url_scanner_ex.c" -yy30: +#line 822 "ext/standard/url_scanner_ex.c" +yy35: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; +yy36: if (yybm[0+yych] & 128) { - goto yy30; + goto yy35; } -#line 545 "ext/standard/url_scanner_ex.re" - { passthru(STD_ARGS); handle_arg(STD_ARGS); STATE = STATE_BEFORE_VAL; goto state_before_val; } -#line 794 "ext/standard/url_scanner_ex.c" + goto yy32; } -#line 547 "ext/standard/url_scanner_ex.re" +#line 545 "ext/standard/url_scanner_ex.re" state_before_val: start = YYCURSOR; -#line 802 "ext/standard/url_scanner_ex.c" +#line 839 "ext/standard/url_scanner_ex.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -837,44 +874,54 @@ state_before_val: }; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; - if (yych == ' ') goto yy37; - if (yych == '=') goto yy38; - ++YYCURSOR; -yy36: -#line 553 "ext/standard/url_scanner_ex.re" - { --YYCURSOR; goto state_next_arg_begin; } -#line 847 "ext/standard/url_scanner_ex.c" -yy37: + if (yych == ' ') goto yy39; + if (yych == '=') goto yy41; + goto yy43; +yy39: yych = *(YYMARKER = ++YYCURSOR); - if (yych == ' ') goto yy41; - if (yych != '=') goto yy36; -yy38: + if (yych == ' ') goto yy46; + if (yych == '=') goto yy44; +yy40: +#line 551 "ext/standard/url_scanner_ex.re" + { --YYCURSOR; goto state_next_arg_begin; } +#line 888 "ext/standard/url_scanner_ex.c" +yy41: + ++YYCURSOR; + yych = *YYCURSOR; + goto yy45; +yy42: +#line 550 "ext/standard/url_scanner_ex.re" + { passthru(STD_ARGS); STATE = STATE_VAL; goto state_val; } +#line 896 "ext/standard/url_scanner_ex.c" +yy43: + yych = *++YYCURSOR; + goto yy40; +yy44: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; +yy45: if (yybm[0+yych] & 128) { - goto yy38; + goto yy44; } -#line 552 "ext/standard/url_scanner_ex.re" - { passthru(STD_ARGS); STATE = STATE_VAL; goto state_val; } -#line 861 "ext/standard/url_scanner_ex.c" -yy41: + goto yy42; +yy46: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; - if (yych == ' ') goto yy41; - if (yych == '=') goto yy38; + if (yych == ' ') goto yy46; + if (yych == '=') goto yy44; YYCURSOR = YYMARKER; - goto yy36; + goto yy40; } -#line 554 "ext/standard/url_scanner_ex.re" +#line 552 "ext/standard/url_scanner_ex.re" state_val: start = YYCURSOR; -#line 878 "ext/standard/url_scanner_ex.c" +#line 925 "ext/standard/url_scanner_ex.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -882,7 +929,7 @@ state_val: 224, 192, 192, 224, 224, 192, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 192, 224, 128, 224, 224, 224, 224, 64, + 192, 224, 64, 224, 224, 224, 224, 128, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 0, 224, @@ -913,69 +960,87 @@ state_val: }; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; - if (yybm[0+yych] & 32) { - goto yy46; + if (yych <= ' ') { + if (yych <= '\f') { + if (yych <= 0x08) goto yy54; + if (yych <= '\n') goto yy56; + goto yy54; + } else { + if (yych <= '\r') goto yy56; + if (yych <= 0x1F) goto yy54; + goto yy56; + } + } else { + if (yych <= '&') { + if (yych != '"') goto yy54; + } else { + if (yych <= '\'') goto yy53; + if (yych == '>') goto yy56; + goto yy54; + } } - if (yych <= ' ') goto yy49; - if (yych <= '"') goto yy51; - if (yych <= '\'') goto yy52; - goto yy49; -yy46: + yych = *(YYMARKER = ++YYCURSOR); + if (yych != '>') goto yy65; +yy52: +#line 561 "ext/standard/url_scanner_ex.re" + { passthru(STD_ARGS); goto state_next_arg_begin; } +#line 988 "ext/standard/url_scanner_ex.c" +yy53: + yych = *(YYMARKER = ++YYCURSOR); + if (yych == '>') goto yy52; + goto yy60; +yy54: + ++YYCURSOR; + yych = *YYCURSOR; + goto yy58; +yy55: +#line 560 "ext/standard/url_scanner_ex.re" + { handle_val(STD_ARGS, 0, ' '); goto state_next_arg_begin; } +#line 1000 "ext/standard/url_scanner_ex.c" +yy56: + yych = *++YYCURSOR; + goto yy52; +yy57: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; +yy58: if (yybm[0+yych] & 32) { - goto yy46; + goto yy57; } -#line 562 "ext/standard/url_scanner_ex.re" - { handle_val(STD_ARGS, 0, ' '); goto state_next_arg_begin; } -#line 933 "ext/standard/url_scanner_ex.c" -yy49: - ++YYCURSOR; -yy50: -#line 563 "ext/standard/url_scanner_ex.re" - { passthru(STD_ARGS); goto state_next_arg_begin; } -#line 939 "ext/standard/url_scanner_ex.c" -yy51: - yych = *(YYMARKER = ++YYCURSOR); - if (yych == '>') goto yy50; - goto yy54; -yy52: - yych = *(YYMARKER = ++YYCURSOR); - if (yych == '>') goto yy50; - goto yy59; -yy53: + goto yy55; +yy59: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; -yy54: +yy60: if (yybm[0+yych] & 64) { - goto yy53; + goto yy59; } - if (yych <= '"') goto yy56; -yy55: + if (yych <= '=') goto yy62; +yy61: YYCURSOR = YYMARKER; - goto yy50; -yy56: + goto yy52; +yy62: ++YYCURSOR; -#line 560 "ext/standard/url_scanner_ex.re" - { handle_val(STD_ARGS, 1, '"'); goto state_next_arg_begin; } -#line 964 "ext/standard/url_scanner_ex.c" -yy58: +#line 559 "ext/standard/url_scanner_ex.re" + { handle_val(STD_ARGS, 1, '\''); goto state_next_arg_begin; } +#line 1029 "ext/standard/url_scanner_ex.c" +yy64: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; -yy59: +yy65: if (yybm[0+yych] & 128) { - goto yy58; + goto yy64; } - if (yych >= '(') goto yy55; + if (yych >= '>') goto yy61; ++YYCURSOR; -#line 561 "ext/standard/url_scanner_ex.re" - { handle_val(STD_ARGS, 1, '\''); goto state_next_arg_begin; } -#line 977 "ext/standard/url_scanner_ex.c" +#line 558 "ext/standard/url_scanner_ex.re" + { handle_val(STD_ARGS, 1, '"'); goto state_next_arg_begin; } +#line 1042 "ext/standard/url_scanner_ex.c" } -#line 564 "ext/standard/url_scanner_ex.re" +#line 562 "ext/standard/url_scanner_ex.re" stop: @@ -1103,7 +1168,7 @@ static inline void php_url_scanner_session_handler_impl(char *output, size_t out if (ZSTR_LEN(url_state->url_app.s) != 0) { *handled_output = url_adapt_ext(output, output_len, &len, (zend_bool) (mode & (PHP_OUTPUT_HANDLER_END | PHP_OUTPUT_HANDLER_CONT | PHP_OUTPUT_HANDLER_FLUSH | PHP_OUTPUT_HANDLER_FINAL) ? 1 : 0), url_state); - if (sizeof(uint32_t) < sizeof(size_t)) { + if (sizeof(uint) < sizeof(size_t)) { if (len > UINT_MAX) len = UINT_MAX; } diff --git a/ext/standard/url_scanner_ex.re b/ext/standard/url_scanner_ex.re index 51a29b5f73..beb01c486e 100644 --- a/ext/standard/url_scanner_ex.re +++ b/ext/standard/url_scanner_ex.re @@ -185,8 +185,6 @@ alphadash = ([a-zA-Z] | "-"); static inline void append_modified_url(smart_str *url, smart_str *dest, smart_str *url_app, const char *separator) { php_url *url_parts; - char *tmp; - size_t tmp_len; smart_str_0(url); /* FIXME: Bug #70480 php_url_parse_ex() crashes by processing chars exceed len */ url_parts = php_url_parse_ex(ZSTR_VAL(url->s), ZSTR_LEN(url->s)); @@ -199,21 +197,23 @@ static inline void append_modified_url(smart_str *url, smart_str *dest, smart_st /* Check protocol. Only http/https is allowed. */ if (url_parts->scheme - && strcasecmp("http", url_parts->scheme) - && strcasecmp("https", url_parts->scheme)) { + && !zend_string_equals_literal_ci(url_parts->scheme, "http") + && !zend_string_equals_literal_ci(url_parts->scheme, "https")) { smart_str_append_smart_str(dest, url); php_url_free(url_parts); return; } /* Check host whitelist. If it's not listed, do nothing. */ - if (url_parts->host - && (tmp_len = strlen(url_parts->host)) - && (tmp = php_strtolower(url_parts->host, tmp_len)) - && !zend_hash_str_find(&BG(url_adapt_session_hosts_ht), tmp, tmp_len)) { - smart_str_append_smart_str(dest, url); - php_url_free(url_parts); - return; + if (url_parts->host) { + zend_string *tmp = zend_string_tolower(url_parts->host); + if (!zend_hash_exists(&BG(url_adapt_session_hosts_ht), tmp)) { + zend_string_release(tmp); + smart_str_append_smart_str(dest, url); + php_url_free(url_parts); + return; + } + zend_string_release(tmp); } /* @@ -232,32 +232,32 @@ static inline void append_modified_url(smart_str *url, smart_str *dest, smart_st } if (url_parts->scheme) { - smart_str_appends(dest, url_parts->scheme); + smart_str_appends(dest, ZSTR_VAL(url_parts->scheme)); smart_str_appends(dest, "://"); } else if (*(ZSTR_VAL(url->s)) == '/' && *(ZSTR_VAL(url->s)+1) == '/') { smart_str_appends(dest, "//"); } if (url_parts->user) { - smart_str_appends(dest, url_parts->user); + smart_str_appends(dest, ZSTR_VAL(url_parts->user)); if (url_parts->pass) { - smart_str_appends(dest, url_parts->pass); + smart_str_appends(dest, ZSTR_VAL(url_parts->pass)); smart_str_appendc(dest, ':'); } smart_str_appendc(dest, '@'); } if (url_parts->host) { - smart_str_appends(dest, url_parts->host); + smart_str_appends(dest, ZSTR_VAL(url_parts->host)); } if (url_parts->port) { smart_str_appendc(dest, ':'); smart_str_append_unsigned(dest, (long)url_parts->port); } if (url_parts->path) { - smart_str_appends(dest, url_parts->path); + smart_str_appends(dest, ZSTR_VAL(url_parts->path)); } smart_str_appendc(dest, '?'); if (url_parts->query) { - smart_str_appends(dest, url_parts->query); + smart_str_appends(dest, ZSTR_VAL(url_parts->query)); smart_str_appends(dest, separator); smart_str_append_smart_str(dest, url_app); } else { @@ -265,7 +265,7 @@ static inline void append_modified_url(smart_str *url, smart_str *dest, smart_st } if (url_parts->fragment) { smart_str_appendc(dest, '#'); - smart_str_appends(dest, url_parts->fragment); + smart_str_appends(dest, ZSTR_VAL(url_parts->fragment)); } php_url_free(url_parts); } @@ -386,8 +386,8 @@ static int check_host_whitelist(url_adapt_state_ex_t *ctx) if (url_parts->scheme) { /* Only http/https should be handled. A bit hacky check this here, but saves a URL parse. */ - if (strcasecmp(url_parts->scheme, "http") && - strcasecmp(url_parts->scheme, "https")) { + if (!zend_string_equals_literal_ci(url_parts->scheme, "http") && + !zend_string_equals_literal_ci(url_parts->scheme, "https")) { php_url_free(url_parts); return FAILURE; } @@ -397,13 +397,11 @@ static int check_host_whitelist(url_adapt_state_ex_t *ctx) return SUCCESS; } if (!zend_hash_num_elements(allowed_hosts) && - check_http_host(url_parts->host) == SUCCESS) { + check_http_host(ZSTR_VAL(url_parts->host)) == SUCCESS) { php_url_free(url_parts); return SUCCESS; } - if (!zend_hash_str_find(allowed_hosts, - url_parts->host, - strlen(url_parts->host))) { + if (!zend_hash_find(allowed_hosts, url_parts->host)) { php_url_free(url_parts); return FAILURE; } |
