From bf701fe74f82bd096ccbc0adce52c653316daeef Mon Sep 17 00:00:00 2001 From: Greg Beaver Date: Mon, 14 Apr 2008 17:54:38 +0000 Subject: [PATCH] disallow unlink() on extracted phars (the idea is that it is a read-only for execute thing), add tests for unlink edge cases --- ext/phar/stream.c | 13 ++++--------- ext/phar/tests/fopen_edgecases.phpt | 28 +++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/ext/phar/stream.c b/ext/phar/stream.c index b2df01ed89..08da8911e4 100644 --- a/ext/phar/stream.c +++ b/ext/phar/stream.c @@ -569,7 +569,7 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags, } if (!phar->manifest.arBuckets) { php_url_free(resource); - return SUCCESS; + return FAILURE; } internal_file_len = strlen(internal_file); /* search through the manifest of files, and if we have an exact match, it's a file */ @@ -660,9 +660,9 @@ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, char *url, int optio phar_entry_data *idata; phar_archive_data **pphar; uint host_len; - int retval; if ((resource = phar_open_url(wrapper, url, "rb", options TSRMLS_CC)) == NULL) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: unlink failed"); return 0; } @@ -682,14 +682,9 @@ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, char *url, int optio host_len = strlen(resource->host); phar_request_initialize(TSRMLS_C); if (zend_hash_find(&(PHAR_GLOBALS->phar_plain_map), resource->host, host_len+1, (void **)&plain_map) == SUCCESS) { - spprintf(&internal_file, 0, "%s%s", plain_map, resource->path); - retval = php_stream_unlink(internal_file, options, context); - if (!retval) { - php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: file \"%s\" extracted from \"%s\" could not be opened", internal_file, resource->host); - } + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: \"%s\" cannot be unlinked, phar is extracted in plain map", url); php_url_free(resource); - efree(internal_file); - return retval; + return 0; } if (FAILURE == zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), resource->host, strlen(resource->host), (void **) &pphar)) { diff --git a/ext/phar/tests/fopen_edgecases.phpt b/ext/phar/tests/fopen_edgecases.phpt index 46595fbf67..a868b71059 100644 --- a/ext/phar/tests/fopen_edgecases.phpt +++ b/ext/phar/tests/fopen_edgecases.phpt @@ -1,5 +1,5 @@ --TEST-- -Phar: fopen/stat/fseek edge cases +Phar: fopen/stat/fseek/unlink edge cases --SKIPIF-- --INI-- @@ -9,8 +9,10 @@ phar.require_hash=0 ===DONE=== @@ -74,5 +85,20 @@ bool(false) bool(true) bool(true) bool(false) +bool(false) + +Warning: unlink(): internal corruption of phar "%sfopen_edgecases.2.phar.php" (truncated manifest at stub end) in %sfopen_edgecases.php on line %d + +Warning: unlink(): phar error: unlink failed in %sfopen_edgecases.php on line %d + +Warning: unlink(): phar error: no directory in "phar://", must have at least phar:/// for root directory (always use full path to a new phar) in %sfopen_edgecases.php on line %d + +Warning: unlink(): phar error: unlink failed in %sfopen_edgecases.php on line %d + +Warning: unlink(): unable to open phar for reading "foo.phar" in %sfopen_edgecases.php on line %d + +Warning: unlink(): phar error: unlink failed in %sfopen_edgecases.php on line %d + +Warning: unlink(): phar error: "phar://test.phar/fopen_edgecases.php" cannot be unlinked, phar is extracted in plain map in %sfopen_edgecases.php on line %d ===DONE=== \ No newline at end of file -- 2.50.1