disallow unlink() on extracted phars (the idea is that it is a read-only for execute thing), add tests for unlink edge cases

This commit is contained in:
Greg Beaver 2008-04-14 17:54:38 +00:00
parent d376f209d4
commit bf701fe74f
2 changed files with 31 additions and 10 deletions

View File

@ -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)) {

View File

@ -1,5 +1,5 @@
--TEST--
Phar: fopen/stat/fseek edge cases
Phar: fopen/stat/fseek/unlink edge cases
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip"); ?>
--INI--
@ -9,8 +9,10 @@ phar.require_hash=0
<?php
$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
$fname2 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.2.phar.php';
$fname3 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.3.phar.php';
$pname = 'phar://' . $fname;
$pname2 = 'phar://' . $fname2;
$pname3 = 'phar://' . $fname3;
// append
$a = fopen($pname . '/b/c.php', 'a');
@ -42,6 +44,15 @@ var_dump(is_dir($pname));
ini_set('phar.extract_list', 'test.phar=' . dirname(__FILE__));
var_dump(file_exists('phar://test.phar/' . basename(__FILE__)));
var_dump(file_exists('phar://test.phar/@#$^&*%$#'));
// this tests coverage of the case where the phar exists and has no files
$phar = new Phar($fname3);
var_dump(file_exists($pname3 . '/test'));
unlink($pname2 . '/hi');
unlink('phar://');
unlink('phar://foo.phar');
unlink('phar://test.phar/' . basename(__FILE__));
?>
===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===