diff options
| -rw-r--r-- | ext/curl/streams.c | 4 | ||||
| -rw-r--r-- | ext/standard/file.c | 32 | ||||
| -rw-r--r-- | ext/standard/ftp_fopen_wrapper.c | 3 | ||||
| -rw-r--r-- | ext/standard/http_fopen_wrapper.c | 3 | ||||
| -rw-r--r-- | ext/standard/php_fopen_wrapper.c | 3 | ||||
| -rw-r--r-- | ext/zlib/zlib_fopen_wrapper.c | 3 | ||||
| -rwxr-xr-x | main/php_streams.h | 3 | ||||
| -rw-r--r-- | main/streams/plain_wrapper.c | 36 | ||||
| -rw-r--r-- | main/streams/userspace.c | 3 |
9 files changed, 68 insertions, 22 deletions
diff --git a/ext/curl/streams.c b/ext/curl/streams.c index ad29041ed3..1913672b20 100644 --- a/ext/curl/streams.c +++ b/ext/curl/streams.c @@ -358,7 +358,9 @@ static php_stream_wrapper_ops php_curl_wrapper_ops = { NULL, /* stream_close: curl streams know how to clean themselves up */ NULL, /* stream_stat: curl streams know how to stat themselves */ NULL, /* stat url */ - NULL /* opendir */ + NULL, /* opendir */ + NULL, /* label */ + NULL /* unlink */ }; php_stream_wrapper php_curl_wrapper = { diff --git a/ext/standard/file.c b/ext/standard/file.c index 4da72890f9..096444272a 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -1403,34 +1403,36 @@ PHP_FUNCTION(rename) } /* }}} */ -/* {{{ proto bool unlink(string filename) +/* {{{ proto bool unlink(string filename[, context context]) Delete a file */ PHP_FUNCTION(unlink) { - zval **filename; - int ret; + char *filename; + int filename_len; + php_stream_wrapper *wrapper; + zval *zcontext = NULL; + php_stream_context *context = NULL; - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &filename) == FAILURE) { - WRONG_PARAM_COUNT; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &filename, &filename_len, &zcontext) == FAILURE) { + RETURN_FALSE; } - convert_to_string_ex(filename); - if (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(filename), NULL, CHECKUID_CHECK_FILE_AND_DIR)) { - RETURN_FALSE; + if (zcontext) { + context = zend_fetch_resource(&zcontext TSRMLS_CC, -1, "Stream-Context", NULL, 1, php_le_stream_context()); } - if (php_check_open_basedir(Z_STRVAL_PP(filename) TSRMLS_CC)) { + wrapper = php_stream_locate_url_wrapper(filename, NULL, 0 TSRMLS_CC); + + if (!wrapper || !wrapper->wops) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate stream wrapper"); RETURN_FALSE; } - ret = VCWD_UNLINK(Z_STRVAL_PP(filename)); - if (ret == -1) { - php_error_docref1(NULL TSRMLS_CC, Z_STRVAL_PP(filename), E_WARNING, "%s", strerror(errno)); + if (!wrapper->wops->unlink) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s does not allow unlinking", wrapper->wops->label ? wrapper->wops->label : "Wrapper"); RETURN_FALSE; } - /* Clear stat cache */ - PHP_FN(clearstatcache)(INTERNAL_FUNCTION_PARAM_PASSTHRU); - RETURN_TRUE; + RETURN_BOOL(wrapper->wops->unlink(wrapper, filename, context TSRMLS_CC)); } /* }}} */ diff --git a/ext/standard/ftp_fopen_wrapper.c b/ext/standard/ftp_fopen_wrapper.c index 216b52c1bb..493f5556ae 100644 --- a/ext/standard/ftp_fopen_wrapper.c +++ b/ext/standard/ftp_fopen_wrapper.c @@ -756,7 +756,8 @@ static php_stream_wrapper_ops ftp_stream_wops = { php_stream_ftp_stream_stat, php_stream_ftp_url_stat, /* stat_url */ php_stream_ftp_opendir, /* opendir */ - "FTP" + "FTP", + NULL /* unlink */ }; PHPAPI php_stream_wrapper php_stream_ftp_wrapper = { diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c index 0e53489d1b..7c76c3ef82 100644 --- a/ext/standard/http_fopen_wrapper.c +++ b/ext/standard/http_fopen_wrapper.c @@ -528,7 +528,8 @@ static php_stream_wrapper_ops http_stream_wops = { php_stream_http_stream_stat, NULL, /* stat_url */ NULL, /* opendir */ - "HTTP" + "HTTP", + NULL /* unlink */ }; PHPAPI php_stream_wrapper php_stream_http_wrapper = { diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c index 065005f30f..e163827a5e 100644 --- a/ext/standard/php_fopen_wrapper.c +++ b/ext/standard/php_fopen_wrapper.c @@ -232,7 +232,8 @@ static php_stream_wrapper_ops php_stdio_wops = { NULL, /* fstat */ NULL, /* stat */ NULL, /* opendir */ - "PHP" + "PHP", + NULL /* unlink */ }; php_stream_wrapper php_stream_php_wrapper = { diff --git a/ext/zlib/zlib_fopen_wrapper.c b/ext/zlib/zlib_fopen_wrapper.c index ab3b0d31cc..f49ccbc273 100644 --- a/ext/zlib/zlib_fopen_wrapper.c +++ b/ext/zlib/zlib_fopen_wrapper.c @@ -161,7 +161,8 @@ static php_stream_wrapper_ops gzip_stream_wops = { NULL, /* stat */ NULL, /* stat_url */ NULL, /* opendir */ - "ZLIB" + "ZLIB", + NULL /* unlink */ }; php_stream_wrapper php_stream_gzip_wrapper = { diff --git a/main/php_streams.h b/main/php_streams.h index 9d06932aab..72638379b6 100755 --- a/main/php_streams.h +++ b/main/php_streams.h @@ -145,6 +145,9 @@ typedef struct _php_stream_wrapper_ops { int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); const char *label; + + /* delete a file */ + int (*unlink)(php_stream_wrapper *wrapper, char *url, php_stream_context *context TSRMLS_DC); } php_stream_wrapper_ops; struct _php_stream_wrapper { diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index 67ffc48cf2..d3c36b335f 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -889,13 +889,47 @@ static int php_plain_files_url_stater(php_stream_wrapper *wrapper, char *url, ph return VCWD_STAT(url, &ssb->sb); } +static int php_plain_files_unlink(php_stream_wrapper *wrapper, char *url, php_stream_context *context TSRMLS_DC) +{ + char *p; + int ret; + zval funcname; + zval *retval = NULL; + + if (p = strstr(url, "://")) { + url = p + 3; + } + + if (PG(safe_mode) && !php_checkuid(url, NULL, CHECKUID_CHECK_FILE_AND_DIR)) { + return 0; + } + + if (php_check_open_basedir(url TSRMLS_CC)) { + return 0; + } + + ret = VCWD_UNLINK(url); + if (ret == -1) { + php_error_docref1(NULL TSRMLS_CC, url, E_WARNING, "%s", strerror(errno)); + return 0; + } + /* Clear stat cache */ + ZVAL_STRINGL(&funcname, "clearstatcache", sizeof("clearstatcache")-1, 0); + call_user_function_ex(CG(function_table), NULL, &funcname, &retval, 0, NULL, 0, NULL TSRMLS_CC); + if (retval) { + zval_dtor(retval); + } + return 1; +} + static php_stream_wrapper_ops php_plain_files_wrapper_ops = { php_plain_files_stream_opener, NULL, NULL, php_plain_files_url_stater, php_plain_files_dir_opener, - "plainfile" + "plainfile", + php_plain_files_unlink }; php_stream_wrapper php_plain_files_wrapper = { diff --git a/main/streams/userspace.c b/main/streams/userspace.c index 096eaac841..60e6e03503 100644 --- a/main/streams/userspace.c +++ b/main/streams/userspace.c @@ -42,7 +42,8 @@ static php_stream_wrapper_ops user_stream_wops = { NULL, /* stat - the streams themselves know how */ user_wrapper_stat_url, user_wrapper_opendir, - "user-space" + "user-space", + NULL /* unlink */ }; |
