summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/curl/streams.c4
-rw-r--r--ext/standard/file.c32
-rw-r--r--ext/standard/ftp_fopen_wrapper.c3
-rw-r--r--ext/standard/http_fopen_wrapper.c3
-rw-r--r--ext/standard/php_fopen_wrapper.c3
-rw-r--r--ext/zlib/zlib_fopen_wrapper.c3
-rwxr-xr-xmain/php_streams.h3
-rw-r--r--main/streams/plain_wrapper.c36
-rw-r--r--main/streams/userspace.c3
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 */
};