summaryrefslogtreecommitdiff
path: root/ext/standard
diff options
context:
space:
mode:
Diffstat (limited to 'ext/standard')
-rw-r--r--ext/standard/basic_functions.c11
-rw-r--r--ext/standard/ftp_fopen_wrapper.c52
-rw-r--r--ext/standard/http_fopen_wrapper.c61
-rw-r--r--ext/standard/link.c2
-rw-r--r--ext/standard/link_win32.c5
-rw-r--r--ext/standard/php_fopen_wrapper.c13
-rw-r--r--ext/standard/streamsfuncs.c2
-rw-r--r--ext/standard/string.c32
-rw-r--r--ext/standard/tests/streams/bug75031.phpt25
-rw-r--r--ext/standard/url.c105
-rw-r--r--ext/standard/url.h14
-rw-r--r--ext/standard/url_scanner_ex.c395
-rw-r--r--ext/standard/url_scanner_ex.re46
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;
}