Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
streams: Refactor rename stream op to use zend_string
  • Loading branch information
Girgias committed Aug 23, 2024
commit 8d5e3a9be265c0e7fa980ed8cfc61caedd0035eb
32 changes: 16 additions & 16 deletions ext/phar/stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -741,7 +741,7 @@ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int
}
/* }}} */

static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context) /* {{{ */
static bool phar_wrapper_rename(php_stream_wrapper *wrapper, const zend_string *url_from, const zend_string *url_to, int options, php_stream_context *context) /* {{{ */
{
php_url *resource_from, *resource_to;
char *error;
Expand All @@ -753,8 +753,8 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from

error = NULL;

if ((resource_from = phar_parse_url(wrapper, url_from, "wb", options|PHP_STREAM_URL_STAT_QUIET)) == NULL) {
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": invalid or non-writable url \"%s\"", url_from, url_to, url_from);
if ((resource_from = phar_parse_url(wrapper, ZSTR_VAL(url_from), "wb", options|PHP_STREAM_URL_STAT_QUIET)) == NULL) {
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": invalid or non-writable url \"%s\"", ZSTR_VAL(url_from), ZSTR_VAL(url_to), ZSTR_VAL(url_from));
return 0;
}
if (SUCCESS != phar_get_archive(&pfrom, ZSTR_VAL(resource_from->host), ZSTR_LEN(resource_from->host), NULL, 0, &error)) {
Expand All @@ -769,9 +769,9 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from
return 0;
}

if ((resource_to = phar_parse_url(wrapper, url_to, "wb", options|PHP_STREAM_URL_STAT_QUIET)) == NULL) {
if ((resource_to = phar_parse_url(wrapper, ZSTR_VAL(url_to), "wb", options|PHP_STREAM_URL_STAT_QUIET)) == NULL) {
php_url_free(resource_from);
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": invalid or non-writable url \"%s\"", url_from, url_to, url_to);
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": invalid or non-writable url \"%s\"", ZSTR_VAL(url_from), ZSTR_VAL(url_to), ZSTR_VAL(url_to));
return 0;
}
if (SUCCESS != phar_get_archive(&pto, ZSTR_VAL(resource_to->host), ZSTR_LEN(resource_to->host), NULL, 0, &error)) {
Expand All @@ -790,36 +790,36 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from
if (!zend_string_equals(resource_from->host, resource_to->host)) {
php_url_free(resource_from);
php_url_free(resource_to);
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\", not within the same phar archive", url_from, url_to);
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\", not within the same phar archive", ZSTR_VAL(url_from), ZSTR_VAL(url_to));
return 0;
}

/* we must have at the very least phar://alias.phar/internalfile.php */
if (!resource_from->scheme || !resource_from->host || !resource_from->path) {
php_url_free(resource_from);
php_url_free(resource_to);
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": invalid url \"%s\"", url_from, url_to, url_from);
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": invalid url \"%s\"", ZSTR_VAL(url_from), ZSTR_VAL(url_to), ZSTR_VAL(url_from));
return 0;
}

if (!resource_to->scheme || !resource_to->host || !resource_to->path) {
php_url_free(resource_from);
php_url_free(resource_to);
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": invalid url \"%s\"", url_from, url_to, url_to);
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": invalid url \"%s\"", ZSTR_VAL(url_from), ZSTR_VAL(url_to), ZSTR_VAL(url_to));
return 0;
}

if (!zend_string_equals_literal_ci(resource_from->scheme, "phar")) {
php_url_free(resource_from);
php_url_free(resource_to);
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": not a phar stream url \"%s\"", url_from, url_to, url_from);
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": not a phar stream url \"%s\"", ZSTR_VAL(url_from), ZSTR_VAL(url_to), ZSTR_VAL(url_from));
return 0;
}

if (!zend_string_equals_literal_ci(resource_to->scheme, "phar")) {
php_url_free(resource_from);
php_url_free(resource_to);
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": not a phar stream url \"%s\"", url_from, url_to, url_to);
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": not a phar stream url \"%s\"", ZSTR_VAL(url_from), ZSTR_VAL(url_to), ZSTR_VAL(url_to));
return 0;
}

Expand All @@ -828,15 +828,15 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from
if (SUCCESS != phar_get_archive(&phar, ZSTR_VAL(resource_from->host), host_len, NULL, 0, &error)) {
php_url_free(resource_from);
php_url_free(resource_to);
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": %s", url_from, url_to, error);
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": %s", ZSTR_VAL(url_from), ZSTR_VAL(url_to), error);
efree(error);
return 0;
}

if (phar->is_persistent && FAILURE == phar_copy_on_write(&phar)) {
php_url_free(resource_from);
php_url_free(resource_to);
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": could not make cached phar writeable", url_from, url_to);
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": could not make cached phar writeable", ZSTR_VAL(url_from), ZSTR_VAL(url_to));
return 0;
}

Expand All @@ -847,7 +847,7 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from
if (entry->is_deleted) {
php_url_free(resource_from);
php_url_free(resource_to);
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\" from extracted phar archive, source has been deleted", url_from, url_to);
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\" from extracted phar archive, source has been deleted", ZSTR_VAL(url_from), ZSTR_VAL(url_to));
return 0;
}
/* transfer all data over to the new entry */
Expand All @@ -867,7 +867,7 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from
if (FAILURE == phar_copy_entry_fp(source, entry, &error)) {
php_url_free(resource_from);
php_url_free(resource_to);
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": %s", url_from, url_to, error);
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": %s", ZSTR_VAL(url_from), ZSTR_VAL(url_to), error);
efree(error);
zend_hash_str_del(&(phar->manifest), entry->filename, strlen(entry->filename));
return 0;
Expand All @@ -882,7 +882,7 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from
/* file does not exist */
php_url_free(resource_from);
php_url_free(resource_to);
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\" from extracted phar archive, source does not exist", url_from, url_to);
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\" from extracted phar archive, source does not exist", ZSTR_VAL(url_from), ZSTR_VAL(url_to));
return 0;

}
Expand Down Expand Up @@ -963,7 +963,7 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from
if (error) {
php_url_free(resource_from);
php_url_free(resource_to);
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": %s", url_from, url_to, error);
php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": %s", ZSTR_VAL(url_from), ZSTR_VAL(url_to), error);
efree(error);
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion ext/phar/stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const
void phar_entry_remove(phar_entry_data *idata, char **error);

static php_stream* phar_wrapper_open_url(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, zend_string **opened_path, php_stream_context *context STREAMS_DC);
static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context);
static bool phar_wrapper_rename(php_stream_wrapper *wrapper, const zend_string *url_from, const zend_string *url_to, int options, php_stream_context *context);
static int phar_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context);
static int phar_wrapper_stat(php_stream_wrapper *wrapper, const char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context);

Expand Down
11 changes: 5 additions & 6 deletions ext/standard/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -1257,20 +1257,19 @@ PHPAPI PHP_FUNCTION(fpassthru)
/* {{{ Rename a file */
PHP_FUNCTION(rename)
{
char *old_name, *new_name;
size_t old_name_len, new_name_len;
zend_string *old_name, *new_name;
zval *zcontext = NULL;
php_stream_wrapper *wrapper;
php_stream_context *context;

ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_PATH(old_name, old_name_len)
Z_PARAM_PATH(new_name, new_name_len)
Z_PARAM_PATH_STR(old_name)
Z_PARAM_PATH_STR(new_name)
Z_PARAM_OPTIONAL
Z_PARAM_RESOURCE_OR_NULL(zcontext)
ZEND_PARSE_PARAMETERS_END();

wrapper = php_stream_locate_url_wrapper(old_name, NULL, 0);
wrapper = php_stream_locate_url_wrapper(ZSTR_VAL(old_name), NULL, 0);

if (!wrapper || !wrapper->wops) {
php_error_docref(NULL, E_WARNING, "Unable to locate stream wrapper");
Expand All @@ -1282,7 +1281,7 @@ PHP_FUNCTION(rename)
RETURN_FALSE;
}

if (wrapper != php_stream_locate_url_wrapper(new_name, NULL, 0)) {
if (wrapper != php_stream_locate_url_wrapper(ZSTR_VAL(new_name), NULL, 0)) {
php_error_docref(NULL, E_WARNING, "Cannot rename a file across wrapper types");
RETURN_FALSE;
}
Expand Down
8 changes: 4 additions & 4 deletions ext/standard/ftp_fopen_wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -941,15 +941,15 @@ static int php_stream_ftp_unlink(php_stream_wrapper *wrapper, const char *url, i
/* }}} */

/* {{{ php_stream_ftp_rename */
static int php_stream_ftp_rename(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context)
static bool php_stream_ftp_rename(php_stream_wrapper *wrapper, const zend_string *url_from, const zend_string *url_to, int options, php_stream_context *context)
{
php_stream *stream = NULL;
php_url *resource_from = NULL, *resource_to = NULL;
int result;
char tmp_line[512];

resource_from = php_url_parse(url_from);
resource_to = php_url_parse(url_to);
resource_from = php_url_parse(ZSTR_VAL(url_from));
resource_to = php_url_parse(ZSTR_VAL(url_to));
/* Must be same scheme (ftp/ftp or ftps/ftps), same host, and same port
(or a 21/0 0/21 combination which is also "same")
Also require paths to/from */
Expand All @@ -969,7 +969,7 @@ static int php_stream_ftp_rename(php_stream_wrapper *wrapper, const char *url_fr
goto rename_errexit;
}

stream = php_ftp_fopen_connect(wrapper, url_from, "r", 0, NULL, context, NULL, NULL, NULL, NULL);
stream = php_ftp_fopen_connect(wrapper, ZSTR_VAL(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", ZSTR_VAL(resource_from->host));
Expand Down
2 changes: 1 addition & 1 deletion main/php_streams.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ typedef struct _php_stream_wrapper_ops {
int (*unlink)(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context);

/* rename a file */
int (*rename)(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context);
bool (*rename)(php_stream_wrapper *wrapper, const zend_string *url_from, const zend_string *url_to, int options, php_stream_context *context);

/* Create/Remove directory */
int (*stream_mkdir)(php_stream_wrapper *wrapper, const char *url, int mode, int options, php_stream_context *context);
Expand Down
78 changes: 38 additions & 40 deletions main/streams/plain_wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -1266,44 +1266,42 @@ static int php_plain_files_unlink(php_stream_wrapper *wrapper, const char *url,
return 1;
}

static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context)
static bool php_plain_files_rename(php_stream_wrapper *wrapper, const zend_string *url_from, const zend_string *url_to, int options, php_stream_context *context)
{
int ret;

if (!url_from || !url_to) {
return 0;
return false;
}

size_t url_from_len = strlen(url_from);
size_t url_to_len = strlen(url_to);
#ifdef PHP_WIN32
if (!php_win32_check_trailing_space(url_from, url_from_len)) {
php_win32_docref2_from_error(ERROR_INVALID_NAME, url_from, url_to);
return 0;
if (!php_win32_check_trailing_space(ZSTR_VAL(url_from), ZSTR_LEN(url_from))) {
php_win32_docref2_from_error(ERROR_INVALID_NAME, ZSTR_VAL(url_from), ZSTR_VAL(url_to));
return false;
}
if (!php_win32_check_trailing_space(url_to, url_to_len)) {
php_win32_docref2_from_error(ERROR_INVALID_NAME, url_from, url_to);
return 0;
if (!php_win32_check_trailing_space(ZSTR_VAL(url_to), ZSTR_LEN(url_to))) {
php_win32_docref2_from_error(ERROR_INVALID_NAME, ZSTR_VAL(url_from), ZSTR_VAL(url_to));
return false;
}
#endif

if (strncasecmp(url_from, "file://", sizeof("file://") - 1) == 0) {
url_from += sizeof("file://") - 1;
url_from_len -= sizeof("file://");
const char *url_from_ptr = ZSTR_VAL(url_from);
size_t url_from_len = ZSTR_LEN(url_from);
if (zend_string_starts_with_literal_ci(url_from, "file://")) {
url_from_ptr += strlen("file://");
url_from_len -= strlen("file://");
}

if (strncasecmp(url_to, "file://", sizeof("file://") - 1) == 0) {
url_to += sizeof("file://") - 1;
url_to_len -= sizeof("file://");
const char *url_to_ptr = ZSTR_VAL(url_to);
size_t url_to_len = ZSTR_LEN(url_to);
if (zend_string_starts_with_literal_ci(url_to, "file://")) {
url_to_ptr += strlen("file://");
url_to_len -= strlen("file://");
}

if (php_check_open_basedir(url_from) || php_check_open_basedir(url_to)) {
return 0;
if (php_check_open_basedir(url_from_ptr) || php_check_open_basedir(url_to_ptr)) {
return false;
}

ret = VCWD_RENAME(url_from, url_from_len, url_to, url_to_len);

if (ret == -1) {
if (VCWD_RENAME(url_from_ptr, url_from_len, url_to_ptr, url_to_len) == FAILURE) {
#ifndef PHP_WIN32
# ifdef EXDEV
if (errno == EXDEV) {
Expand All @@ -1312,10 +1310,10 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f
/* not sure what to do in ZTS case, umask is not thread-safe */
int oldmask = umask(077);
# endif
int success = 0;
if (php_copy_file(url_from, url_to) == SUCCESS) {
if (VCWD_STAT(url_from, &sb) == 0) {
success = 1;
bool success = false;
if (php_copy_file(url_from_ptr, url_to_ptr) == SUCCESS) {
if (VCWD_STAT(url_from_ptr, &sb) == 0) {
success = true;
# ifndef TSRM_WIN32
/*
* Try to set user and permission info on the target.
Expand All @@ -1324,30 +1322,30 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f
* on the system environment to have proper umask to not allow
* access to the file in the meantime.
*/
if (VCWD_CHOWN(url_to, sb.st_uid, sb.st_gid)) {
php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno));
if (VCWD_CHOWN(url_to_ptr, sb.st_uid, sb.st_gid)) {
php_error_docref2(NULL, ZSTR_VAL(url_from), ZSTR_VAL(url_to), E_WARNING, "%s", strerror(errno));
if (errno != EPERM) {
success = 0;
success = false;
}
}

if (success) {
if (VCWD_CHMOD(url_to, sb.st_mode)) {
php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno));
if (VCWD_CHMOD(url_to_ptr, sb.st_mode)) {
php_error_docref2(NULL, ZSTR_VAL(url_from), ZSTR_VAL(url_to), E_WARNING, "%s", strerror(errno));
if (errno != EPERM) {
success = 0;
success = false;
}
}
}
# endif
if (success) {
VCWD_UNLINK(url_from);
VCWD_UNLINK(url_from_ptr);
}
} else {
php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno));
php_error_docref2(NULL, ZSTR_VAL(url_from), ZSTR_VAL(url_to), E_WARNING, "%s", strerror(errno));
}
} else {
php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno));
php_error_docref2(NULL, ZSTR_VAL(url_from), ZSTR_VAL(url_to), E_WARNING, "%s", strerror(errno));
}
# if !defined(ZTS) && !defined(TSRM_WIN32)
umask(oldmask);
Expand All @@ -1358,17 +1356,17 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f
#endif

#ifdef PHP_WIN32
php_win32_docref2_from_error(GetLastError(), url_from, url_to);
php_win32_docref2_from_error(GetLastError(), ZSTR_VAL(url_from), ZSTR_VAL(url_to));
#else
php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno));
php_error_docref2(NULL, ZSTR_VAL(url_from), ZSTR_VAL(url_to), E_WARNING, "%s", strerror(errno));
#endif
return 0;
return false;
}

/* Clear stat cache (and realpath cache) */
php_clear_stat_cache(1, NULL, 0);

return 1;
return true;
}

static int php_plain_files_mkdir(php_stream_wrapper *wrapper, const char *dir, int mode, int options, php_stream_context *context)
Expand Down
8 changes: 4 additions & 4 deletions main/streams/userspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char *
static int user_wrapper_close(php_stream_wrapper *wrapper, php_stream *stream);
static int user_wrapper_stat_url(php_stream_wrapper *wrapper, const char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context);
static int user_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context);
static int user_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context);
static bool user_wrapper_rename(php_stream_wrapper *wrapper, const zend_string *url_from, const zend_string *url_to, int options, php_stream_context *context);
static int user_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url, int mode, int options, php_stream_context *context);
static int user_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context);
static int user_wrapper_metadata(php_stream_wrapper *wrapper, const char *url, int option, void *value, php_stream_context *context);
Expand Down Expand Up @@ -1067,7 +1067,7 @@ static int user_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int
return ret;
}

static int user_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from, const char *url_to,
static bool user_wrapper_rename(php_stream_wrapper *wrapper, const zend_string *url_from, const zend_string *url_to,
int options, php_stream_context *context)
{
struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract;
Expand All @@ -1084,8 +1084,8 @@ static int user_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from
}

/* call the rename method */
ZVAL_STRING(&args[0], url_from);
ZVAL_STRING(&args[1], url_to);
ZVAL_STRINGL(&args[0], ZSTR_VAL(url_from), ZSTR_LEN(url_from));
ZVAL_STRINGL(&args[1], ZSTR_VAL(url_to), ZSTR_LEN(url_to));

ZVAL_STRING(&zfuncname, USERSTREAM_RENAME);

Expand Down