eliminate potential double-free of alias

major improvement of zip/tar-based phar stub execution, now __FILE__ says it is the phar, and not phar/.phar/stub.php,
so that the same stub can be used for phar or tar/zip-based phars
ridiculous speedup of rename() within a phar (something like 1000%)
last of the tar-based phar fixes
new tests for tar-based phars, fix existing tests to use new format of __FILE__
This commit is contained in:
Greg Beaver 2008-01-07 22:21:10 +00:00
parent e78819fc01
commit 36efc2a907
20 changed files with 554 additions and 174 deletions

View File

@ -218,6 +218,7 @@ static void phar_destroy_phar_data(phar_archive_data *data TSRMLS_DC) /* {{{ */
}
if (data->fname) {
efree(data->fname);
data->fname = NULL;
}
if (data->signature) {
efree(data->signature);
@ -1070,7 +1071,7 @@ int phar_open_zipfile(char *fname, int fname_len, char *alias, int alias_len, ph
} else {
register_alias = alias ? 1 : 0;
}
mydata->alias = alias ? estrndup(alias, alias_len) : mydata->fname;
mydata->alias = alias ? estrndup(alias, alias_len) : estrndup(mydata->fname, alias_len);
mydata->alias_len = alias ? alias_len : fname_len;
mydata->is_zip = 1;
mydata->zip = zip;
@ -1175,7 +1176,7 @@ int phar_open_zipfile(char *fname, int fname_len, char *alias, int alias_len, ph
/* ignore all errors in loading up manifest */
zip_error_clear(zip);
zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
if (register_alias) {
mydata->is_explicit_alias = 1;
zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
@ -1635,7 +1636,7 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int
phar_unixify_path_separators(mydata->fname, fname_len);
#endif
mydata->fname_len = fname_len;
mydata->alias = alias ? estrndup(alias, alias_len) : mydata->fname;
mydata->alias = alias ? estrndup(alias, alias_len) : estrndup(fname, fname_len);
mydata->alias_len = alias ? alias_len : fname_len;
mydata->sig_flags = sig_flags;
mydata->sig_len = sig_len;
@ -1834,7 +1835,7 @@ int phar_create_or_parse_filename(char *fname, int fname_len, char *alias, int a
#endif
}
mydata->fname_len = fname_len;
mydata->alias = alias ? estrndup(alias, alias_len) : mydata->fname;
mydata->alias = alias ? estrndup(alias, alias_len) : estrndup(mydata->fname, fname_len);
mydata->alias_len = alias ? alias_len : fname_len;
snprintf(mydata->version, sizeof(mydata->version), "%s", PHAR_API_VERSION_STR);
mydata->is_explicit_alias = alias ? 1 : 0;
@ -2313,36 +2314,6 @@ int phar_open_compiled_file(char *alias, int alias_len, char **error TSRMLS_DC)
fname = zend_get_executed_filename(TSRMLS_C);
fname_len = strlen(fname);
if (strstr(fname, "phar://") && strstr(fname, ".phar/stub.php")) {
char *arch, *entry;
int arch_len, entry_len;
phar_archive_data *phar;
if (SUCCESS != phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) {
efree(entry);
efree(arch);
goto regular_error;
}
if (strcmp(entry, "/.phar/stub.php")) {
efree(entry);
efree(arch);
goto regular_error;
}
/* we're running from inside a zip-based phar */
efree(entry);
entry = fname;
fname = arch;
fname_len = arch_len;
if (SUCCESS == phar_open_loaded(fname, fname_len, alias, alias_len, 0, &phar, 0 TSRMLS_CC) && phar && (phar->is_zip || phar->is_tar)) {
efree(arch);
return SUCCESS;
}
/* restore original value for error purpose */
fname = entry;
}
regular_error:
if (phar_open_loaded(fname, fname_len, alias, alias_len, REPORT_ERRORS, NULL, 0 TSRMLS_CC) == SUCCESS) {
return SUCCESS;
}
@ -4444,10 +4415,12 @@ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, char *url, int optio
static int phar_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char *url_to, int options, php_stream_context *context TSRMLS_DC) /* {{{ */
{
php_url *resource_from, *resource_to;
char *from_file, *to_file, *error, *plain_map;
phar_entry_data *fromdata, *todata;
char *error, *plain_map;
phar_archive_data *phar;
phar_entry_info *entry;
uint host_len;
error = NULL;
if (PHAR_G(readonly)) {
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: write operations disabled by INI setting");
return 0;
@ -4502,102 +4475,66 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char
phar_request_initialize(TSRMLS_C);
if (zend_hash_find(&(PHAR_GLOBALS->phar_plain_map), resource_from->host, host_len+1, (void **)&plain_map) == SUCCESS) {
/*TODO:use php_stream_rename() once available*/
php_url_free(resource_from);
php_url_free(resource_to);
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot rename \"%s\" to \"%s\" from extracted phar archive", url_from, url_to);
return 0;
}
/* need to copy to strip leading "/", will get touched again */
from_file = estrdup(resource_from->path + 1);
to_file = estrdup(resource_to->path + 1);
if (FAILURE == phar_get_entry_data(&fromdata, resource_from->host, strlen(resource_from->host), from_file, strlen(from_file), "r", &error TSRMLS_CC)) {
/* constraints of fp refcount were not met */
if (error) {
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, error);
efree(error);
}
efree(from_file);
efree(to_file);
if (SUCCESS != phar_get_archive(&phar, resource_from->host, strlen(resource_from->host), NULL, 0, &error TSRMLS_CC)) {
php_url_free(resource_from);
php_url_free(resource_to);
return 0;
}
if (error) {
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot rename \"%s\" to \"%s\": %s", url_from, url_to, error);
efree(error);
}
if (!fromdata) {
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: \"%s\" is not a file in phar \"%s\", cannot rename", from_file, resource_from->host);
efree(from_file);
efree(to_file);
php_url_free(resource_from);
php_url_free(resource_to);
return 0;
}
if (!(todata = phar_get_or_create_entry_data(resource_to->host, strlen(resource_to->host), to_file, strlen(to_file), "w", &error TSRMLS_CC))) {
/* constraints of fp refcount were not met */
if (error) {
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, error);
efree(error);
}
efree(from_file);
efree(to_file);
php_url_free(resource_from);
php_url_free(resource_to);
return 0;
}
if (error) {
efree(error);
}
if (fromdata->internal_file->fp_refcount > 1) {
/* more than just our fp resource is open for this file */
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: \"%s\" in phar \"%s\", has open file pointers, cannot rename", from_file, resource_from->host);
efree(from_file);
efree(to_file);
php_url_free(resource_from);
php_url_free(resource_to);
phar_entry_delref(fromdata TSRMLS_CC);
phar_entry_delref(todata TSRMLS_CC);
return 0;
}
if (todata->internal_file->fp_refcount > 1) {
/* more than just our fp resource is open for this file */
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: \"%s\" in phar \"%s\", has open file pointers, cannot rename", to_file, resource_to->host);
efree(from_file);
efree(to_file);
php_url_free(resource_from);
php_url_free(resource_to);
phar_entry_delref(fromdata TSRMLS_CC);
phar_entry_delref(todata TSRMLS_CC);
return 0;
}
php_stream_seek(fromdata->internal_file->fp, 0 + fromdata->zero, SEEK_SET);
if (fromdata->internal_file->uncompressed_filesize != php_stream_copy_to_stream(fromdata->internal_file->fp, todata->internal_file->fp, PHP_STREAM_COPY_ALL)) {
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: rename failed \"%s\" to \"%s\"", url_from, url_to);
efree(from_file);
efree(to_file);
php_url_free(resource_from);
php_url_free(resource_to);
phar_entry_delref(fromdata TSRMLS_CC);
phar_entry_delref(todata TSRMLS_CC);
return 0;
if (SUCCESS == zend_hash_find(&(phar->manifest), resource_from->path+1, strlen(resource_from->path)-1, (void **)&entry)) {
phar_entry_info new;
/* perform rename magic */
if (entry->is_deleted) {
php_url_free(resource_from);
php_url_free(resource_to);
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot rename \"%s\" to \"%s\" from extracted phar archive, source has been deleted", url_from, url_to);
return 0;
}
/* transfer all data over to the new entry */
memcpy((void *) &new, (void *) entry, sizeof(phar_entry_info));
/* mark the old one for deletion */
entry->is_deleted = 1;
entry->fp = NULL;
entry->metadata = 0;
entry->link = NULL;
#if HAVE_ZIP
entry->zip = NULL;
#endif
zend_hash_add(&(phar->manifest), resource_to->path+1, strlen(resource_to->path)-1, (void **)&new, sizeof(phar_entry_info), (void **) &entry);
if (!entry->is_modified) {
/* copy file contents into a new temp stream */
if (!phar_open_jit(phar, entry, phar->fp, &error, 1 TSRMLS_CC)) {
php_url_free(resource_from);
php_url_free(resource_to);
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot rename \"%s\" to \"%s\": %s", url_from, url_to, error);
efree(error);
return 0;
}
}
entry->is_modified = 1;
entry->filename = estrdup(resource_to->path+1);
entry->filename_len = strlen(entry->filename);
phar_flush(phar, 0, 0, &error TSRMLS_CC);
if (error) {
php_url_free(resource_from);
php_url_free(resource_to);
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot rename \"%s\" to \"%s\": %s", url_from, url_to, error);
efree(error);
return 0;
}
}
todata->internal_file->uncompressed_filesize = todata->internal_file->compressed_filesize = fromdata->internal_file->uncompressed_filesize;
phar_entry_delref(fromdata TSRMLS_CC);
phar_entry_delref(todata TSRMLS_CC);
if (error) {
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, error);
efree(error);
efree(from_file);
efree(to_file);
php_url_free(resource_from);
php_url_free(resource_to);
return 0;
}
efree(from_file);
efree(to_file);
php_url_free(resource_from);
php_url_free(resource_to);
phar_wrapper_unlink(wrapper, url_from, 0, 0 TSRMLS_CC);
return 1;
}
/* }}} */
@ -4743,13 +4680,18 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type
if (strstr(file_handle->filename, ".phar") && !strstr(file_handle->filename, ":\\")) {
if (SUCCESS == phar_open_filename(file_handle->filename, strlen(file_handle->filename), NULL, 0, 0, &phar, NULL TSRMLS_CC)) {
if (phar->is_zip || phar->is_tar) {
/* zip-based phar */
zend_file_handle f = *file_handle;
/* zip or tar-based phar */
spprintf(&name, 4096, "phar://%s/%s", file_handle->filename, ".phar/stub.php");
file_handle->type = ZEND_HANDLE_FILENAME;
file_handle->free_filename = 1;
file_handle->filename = name;
if (file_handle->opened_path) {
efree(file_handle->opened_path);
if (SUCCESS == zend_stream_open_function((const char *)name, file_handle TSRMLS_CC)) {
efree(name);
name = NULL;
file_handle->filename = f.filename;
file_handle->opened_path = f.opened_path;
file_handle->free_filename = f.free_filename;
} else {
*file_handle = f;
}
goto skip_phar;
}
@ -4774,6 +4716,10 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type
/* auto-convert to phar:// */
spprintf(&name, 4096, "phar://%s/%s", arch, entry);
efree(arch);
if (file_handle->type == ZEND_HANDLE_FP) {
// clean up
fclose(file_handle->handle.fp);
}
file_handle->type = ZEND_HANDLE_FILENAME;
file_handle->free_filename = 1;
file_handle->filename = name;

View File

@ -379,31 +379,6 @@ PHP_METHOD(Phar, webPhar)
fname = zend_get_executed_filename(TSRMLS_C);
fname_len = strlen(fname);
if (strstr(fname, "://")) {
char *arch, *entry;
int arch_len, entry_len;
phar_archive_data *mphar;
/* running within a zip-based phar, acquire the actual name */
if (SUCCESS != phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) {
efree(entry);
efree(arch);
return; /* this, incidentally, should be impossible */
}
efree(entry);
entry = fname;
fname = arch;
fname_len = arch_len;
if (SUCCESS == phar_open_loaded(fname, fname_len, alias, alias_len, 0, &mphar, 0 TSRMLS_CC) && mphar && (mphar->is_zip || mphar->is_tar)) {
efree(arch);
fname = mphar->fname;
fname_len = mphar->fname_len;
} else {
efree(arch);
fname = entry;
}
}
#ifdef PHP_WIN32
fname = estrndup(fname, fname_len);
phar_unixify_path_separators(fname, fname_len);

View File

@ -156,7 +156,7 @@ int phar_open_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, i
size_t pos = 0, read;
tar_header *hdr;
php_uint32 sum1, sum2, size, old;
phar_archive_data *myphar;
phar_archive_data *myphar, **retdata;
if (error) {
*error = NULL;
@ -283,11 +283,13 @@ int phar_open_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, i
myphar->fname_len = fname_len;
myphar->fp = fp;
phar_request_initialize(TSRMLS_C);
zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), myphar->fname, fname_len, (void*)&myphar, sizeof(phar_archive_data*), NULL);
zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len, (void*)&myphar, sizeof(phar_archive_data*), NULL);
if (actual_alias) {
myphar->is_explicit_alias = 1;
zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), actual_alias, myphar->alias_len, (void*)&myphar, sizeof(phar_archive_data*), NULL);
} else {
myphar->alias = estrndup(fname, fname_len);
myphar->alias_len = fname_len;
myphar->is_explicit_alias = 0;
}
if (pphar) {
@ -415,6 +417,7 @@ int phar_tar_flush(phar_archive_data *archive, char *user_stub, long len, char *
entry.flags = PHAR_ENT_PERM_DEF_FILE;
entry.timestamp = time(NULL);
entry.is_modified = 1;
entry.is_crc_checked = 1;
entry.is_tar = 1;
entry.tar_type = '0';
entry.phar = archive;

View File

@ -10,8 +10,8 @@ frontcontroller4.phar.tar
--EXPECTHEADERS--
Content-type: text/html
--EXPECTF--
Fatal error: Uncaught exception 'UnexpectedValueException' with message 'phar rewrite value for "/hi" was not a string' in %sfrontcontroller10.phar.php/.phar/stub.php:2
Fatal error: Uncaught exception 'UnexpectedValueException' with message 'phar rewrite value for "/hi" was not a string' in %sfrontcontroller10.phar.php:2
Stack trace:
#0 %sfrontcontroller10.phar.php/.phar/stub.php(2): Phar::webPhar('whatever', 'index.php', '', Array, Array)
#0 %sfrontcontroller10.phar.php(2): Phar::webPhar('whatever', 'index.php', '', Array, Array)
#1 {main}
thrown in %sfrontcontroller10.phar.php/.phar/stub.php on line 2
thrown in %sfrontcontroller10.phar.php on line 2

View File

@ -10,8 +10,8 @@ frontcontroller5.phar.tar
--EXPECTHEADERS--
Content-type: text/html
--EXPECTF--
Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Key of MIME type overrides array must be a file extension, was "0"' in %sfrontcontroller11.phar.php/.phar/stub.php:2
Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Key of MIME type overrides array must be a file extension, was "0"' in %sfrontcontroller11.phar.php:2
Stack trace:
#0 %sfrontcontroller11.phar.php/.phar/stub.php(2): Phar::webPhar('whatever', 'index.php', '', Array)
#0 %sfrontcontroller11.phar.php(2): Phar::webPhar('whatever', 'index.php', '', Array)
#1 {main}
thrown in %sfrontcontroller11.phar.php/.phar/stub.php on line 2
thrown in %sfrontcontroller11.phar.php on line 2

View File

@ -10,8 +10,8 @@ frontcontroller6.phar.tar
--EXPECTHEADERS--
Content-type: text/html
--EXPECTF--
Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Unknown mime type specifier used, only Phar::PHP, Phar::PHPS and a mime type string are allowed' in %sfrontcontroller12.phar.php/.phar/stub.php:2
Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Unknown mime type specifier used, only Phar::PHP, Phar::PHPS and a mime type string are allowed' in %sfrontcontroller12.phar.php:2
Stack trace:
#0 %sfrontcontroller12.phar.php/.phar/stub.php(2): Phar::webPhar('whatever', 'index.php', '', Array)
#0 %sfrontcontroller12.phar.php(2): Phar::webPhar('whatever', 'index.php', '', Array)
#1 {main}
thrown in %sfrontcontroller12.phar.php/.phar/stub.php on line 2
thrown in %sfrontcontroller12.phar.php on line 2

View File

@ -10,8 +10,8 @@ frontcontroller7.phar.tar
--EXPECTHEADERS--
Content-type: text/html
--EXPECTF--
Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Unknown mime type specifier used (not a string or int), only Phar::PHP, Phar::PHPS and a mime type string are allowed' in %sfrontcontroller13.phar.php/.phar/stub.php:2
Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Unknown mime type specifier used (not a string or int), only Phar::PHP, Phar::PHPS and a mime type string are allowed' in %sfrontcontroller13.phar.php:2
Stack trace:
#0 %sfrontcontroller13.phar.php/.phar/stub.php(2): Phar::webPhar('whatever', 'index.php', '', Array)
#0 %sfrontcontroller13.phar.php(2): Phar::webPhar('whatever', 'index.php', '', Array)
#1 {main}
thrown in %sfrontcontroller13.phar.php/.phar/stub.php on line 2
thrown in %sfrontcontroller13.phar.php on line 2

View File

@ -8,8 +8,8 @@ REQUEST_URI=/frontcontroller18.phar.php/fronk.gronk
--FILE_EXTERNAL--
frontcontroller9.phar.tar
--EXPECTF--
Fatal error: Uncaught exception 'UnexpectedValueException' with message 'No values passed to Phar::mungServer(), expecting an array of any of these strings: PHP_SELF, REQUEST_URI, SCRIPT_FILENAME, SCRIPT_NAME' in %sfrontcontroller18.phar.php/.phar/stub.php:2
Fatal error: Uncaught exception 'UnexpectedValueException' with message 'No values passed to Phar::mungServer(), expecting an array of any of these strings: PHP_SELF, REQUEST_URI, SCRIPT_FILENAME, SCRIPT_NAME' in %sfrontcontroller18.phar.php:2
Stack trace:
#0 %sfrontcontroller18.phar.php/.phar/stub.php(2): Phar::mungServer(Array)
#0 %sfrontcontroller18.phar.php(2): Phar::mungServer(Array)
#1 {main}
thrown in %sfrontcontroller18.phar.php/.phar/stub.php on line 2
thrown in %sfrontcontroller18.phar.php on line 2

View File

@ -8,8 +8,8 @@ REQUEST_URI=/frontcontroller19.phar.php/
--FILE_EXTERNAL--
frontcontroller10.phar.tar
--EXPECTF--
Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Too many values passed to Phar::mungServer(), expecting an array of any of these strings: PHP_SELF, REQUEST_URI, SCRIPT_FILENAME, SCRIPT_NAME' in %sfrontcontroller19.phar.php/.phar/stub.php:2
Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Too many values passed to Phar::mungServer(), expecting an array of any of these strings: PHP_SELF, REQUEST_URI, SCRIPT_FILENAME, SCRIPT_NAME' in %sfrontcontroller19.phar.php:2
Stack trace:
#0 %sfrontcontroller19.phar.php/.phar/stub.php(2): Phar::mungServer(Array)
#0 %sfrontcontroller19.phar.php(2): Phar::mungServer(Array)
#1 {main}
thrown in %sfrontcontroller19.phar.php/.phar/stub.php on line 2
thrown in %sfrontcontroller19.phar.php on line 2

View File

@ -8,8 +8,8 @@ REQUEST_URI=/frontcontroller20.phar.php/
--FILE_EXTERNAL--
frontcontroller11.phar.tar
--EXPECTF--
Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Non-string value passed to Phar::mungServer(), expecting an array of any of these strings: PHP_SELF, REQUEST_URI, SCRIPT_FILENAME, SCRIPT_NAME' in %sfrontcontroller20.phar.php/.phar/stub.php:2
Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Non-string value passed to Phar::mungServer(), expecting an array of any of these strings: PHP_SELF, REQUEST_URI, SCRIPT_FILENAME, SCRIPT_NAME' in %sfrontcontroller20.phar.php:2
Stack trace:
#0 %sfrontcontroller20.phar.php/.phar/stub.php(2): Phar::mungServer(Array)
#0 %sfrontcontroller20.phar.php(2): Phar::mungServer(Array)
#1 {main}
thrown in %sfrontcontroller20.phar.php/.phar/stub.php on line 2
thrown in %sfrontcontroller20.phar.php on line 2

View File

@ -0,0 +1,44 @@
--TEST--
Phar::setStub()/stopBuffering() tar-based
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip"); ?>
--INI--
phar.require_hash=0
phar.readonly=0
--FILE--
<?php
$p = new Phar(dirname(__FILE__) . '/brandnewphar.phar.tar', 0, 'brandnewphar.phar');
$p['file1.txt'] = 'hi';
$p->stopBuffering();
var_dump($p->getStub());
$p->setStub("<?php
function __autoload(\$class)
{
include 'phar://' . str_replace('_', '/', \$class);
}
Phar::mapPhar('brandnewphar.phar');
include 'phar://brandnewphar.phar/startup.php';
__HALT_COMPILER();
?>");
var_dump($p->getStub());
var_dump($p->isTar());
?>
===DONE===
--CLEAN--
<?php
unlink(dirname(__FILE__) . '/brandnewphar.phar.tar');
?>
--EXPECT--
string(60) "<?php // tar-based phar archive stub file
__HALT_COMPILER();"
string(200) "<?php
function __autoload($class)
{
include 'phar://' . str_replace('_', '/', $class);
}
Phar::mapPhar('brandnewphar.phar');
include 'phar://brandnewphar.phar/startup.php';
__HALT_COMPILER(); ?>
"
bool(true)
===DONE===

View File

@ -0,0 +1,56 @@
--TEST--
Phar: copy() tar-based
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip"); ?>
<?php if (!extension_loaded("spl")) die("skip SPL not available"); ?>
<?php if (!extension_loaded("zlib")) die("skip zlib not available"); ?>
--INI--
phar.readonly=0
phar.require_hash=1
--FILE--
<?php
$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.tar.php';
$fname2 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '2.phar.php';
$pname = 'phar://'.$fname;
$iname = '/file.txt';
$ename = '/error/';
$p = new Phar($fname);
try
{
$p['a'] = 'hi';
$p->startBuffering();
$p->copy('a', 'b');
echo file_get_contents($p['b']->getPathName());
$p->copy('b', 'c');
$p->stopBuffering();
echo file_get_contents($p['c']->getPathName());
copy($fname, $fname2);
var_dump($p->isTar());
$p->copy('a', $ename);
}
catch(Exception $e)
{
echo $e->getMessage() . "\n";
}
ini_set('phar.readonly',1);
$p2 = new Phar($fname2);
var_dump($p2->isTar());
echo "\n";
echo 'a: ' , file_get_contents($p2['a']->getPathName());
echo 'b: ' ,file_get_contents($p2['b']->getPathName());
echo 'c: ' ,file_get_contents($p2['c']->getPathName());
?>
===DONE===
--CLEAN--
<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.tar.php'); ?>
<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '2.phar.php'); ?>
--EXPECTF--
hihibool(true)
file "/error/" contains invalid characters empty directory, cannot be copied from "a" in phar %s
bool(true)
a: hib: hic: hi===DONE===

View File

@ -0,0 +1,32 @@
--TEST--
Phar: include/fopen magic tar-based
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip"); ?>
--INI--
phar.require_hash=0
phar.readonly=0
--FILE--
<?php
$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.tar.php';
$p = new Phar($fname);
var_dump($p->isTar());
$p['a'] = '<?php include "b/c.php";' . "\n";
$p['b/c.php'] = '<?php echo "in b\n";$a = fopen("a", "r", true);echo stream_get_contents($a);fclose($a);include dirname(__FILE__) . "/../d";';
$p['d'] = "in d\n";
$p->setStub('<?php
include "phar://" . __FILE__ . "/a";
__HALT_COMPILER();');
include $fname;
?>
===DONE===
--CLEAN--
<?php
unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.tar.php');
__HALT_COMPILER();
?>
--EXPECTF--
bool(true)
in b
<?php include "b/c.php";
in d
===DONE===

View File

@ -0,0 +1,42 @@
--TEST--
Phar::setAlias() tar-based
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip"); ?>
--INI--
phar.require_hash=0
phar.readonly=0
--FILE--
<?php
include dirname(__FILE__) . '/tarmaker.php.inc';
$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
$pname = 'phar://' . $fname;
$a = new tarmaker($fname, 'none');
$a->init();
$a->addFile('.phar/stub.php', '<?php echo "first stub\n"; __HALT_COMPILER(); ?>');
$files = array();
$files['a'] = 'a';
$files['b'] = 'b';
$files['c'] = 'c';
$files['.phar/alias.txt'] = 'hio';
foreach ($files as $n => $file) {
$a->addFile($n, $file);
}
$a->close();
$phar = new Phar($fname);
echo $phar->getAlias() . "\n";
$phar->setAlias('test');
echo $phar->getAlias() . "\n";
?>
===DONE===
--CLEAN--
<?php
unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php');
unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phartmp.php');
__HALT_COMPILER();
?>
--EXPECT--
hio
test
===DONE===

View File

@ -0,0 +1,50 @@
--TEST--
Phar::setAlias() error tar-based
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip"); ?>
--INI--
phar.require_hash=0
phar.readonly=0
--FILE--
<?php
include dirname(__FILE__) . '/tarmaker.php.inc';
$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
$pname = 'phar://' . $fname;
$a = new tarmaker($fname, 'none');
$a->init();
$a->addFile('.phar/stub.php', '<?php echo "first stub\n"; __HALT_COMPILER(); ?>');
$files = array();
$files['a'] = 'a';
$files['b'] = 'b';
$files['c'] = 'c';
$files['.phar/alias.txt'] = 'hio';
foreach ($files as $n => $file) {
$a->addFile($n, $file);
}
$a->close();
$phar = new Phar($fname);
echo $phar->getAlias() . "\n";
$phar->setAlias('test');
echo $phar->getAlias() . "\n";
$phar = new Phar(dirname(__FILE__) . '/notphar.phar');
try {
$phar->setAlias('test');
} catch (Exception $e) {
echo $e->getMessage() . "\n";
}
?>
===DONE===
--CLEAN--
<?php
unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php');
unlink(dirname(__FILE__) . '/notphar.phar');
unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phartmp.php');
__HALT_COMPILER();
?>
--EXPECTF--
hio
test
alias "test" is already used for archive "%sphar_setalias2.phar.php" and cannot be used for other archives
===DONE===

View File

@ -0,0 +1,61 @@
--TEST--
Phar::setStub()/getStub()
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip"); ?>
--INI--
phar.require_hash=0
phar.readonly=0
--FILE--
<?php
include dirname(__FILE__) . '/tarmaker.php.inc';
$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
$pname = 'phar://' . $fname;
$a = new tarmaker($fname, 'none');
$a->init();
$a->addFile('.phar/stub.php', $stub = '<?php echo "first stub\n"; __HALT_COMPILER(); ?>');
$files = array();
$files['a'] = 'a';
$files['.phar/alias.txt'] = 'hio';
foreach ($files as $n => $file) {
$a->addFile($n, $file);
}
$a->close();
$phar = new Phar($fname);
var_dump($stub);
var_dump($phar->getStub());
var_dump($phar->getStub() == $stub);
$newstub = '<?php echo "second stub\n"; _x_HALT_COMPILER(); ?>';
try
{
$phar->setStub($newstub);
}
catch(exception $e)
{
echo 'Exception: ' . $e->getMessage() . "\n";
}
var_dump($phar->getStub());
var_dump($phar->getStub() == $stub);
$phar->stopBuffering();
var_dump($phar->getStub());
var_dump($phar->getStub() == $stub);
?>
===DONE===
--CLEAN--
<?php
unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php');
__HALT_COMPILER();
?>
--EXPECTF--
string(48) "<?php echo "first stub\n"; __HALT_COMPILER(); ?>"
string(48) "<?php echo "first stub\n"; __HALT_COMPILER(); ?>"
bool(true)
Exception: illegal stub for tar-based phar "%sphar_stub_error.phar.php"
string(48) "<?php echo "first stub\n"; __HALT_COMPILER(); ?>"
bool(true)
string(48) "<?php echo "first stub\n"; __HALT_COMPILER(); ?>"
bool(true)
===DONE===

View File

@ -0,0 +1,70 @@
--TEST--
Phar: test that refcounting avoids problems with deleting a file tar-based
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip"); ?>
<?php if (!extension_loaded("spl")) die("skip SPL not available"); ?>
<?php if (version_compare(PHP_VERSION, "5.3", "<")) die("skip requires 5.3 or later"); ?>
--INI--
phar.readonly=0
phar.require_hash=0
--FILE--
<?php
include dirname(__FILE__) . '/tarmaker.php.inc';
$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
$pname = 'phar://' . $fname;
$a = new tarmaker($fname, 'none');
$a->init();
$a->addFile('.phar/stub.php', "<?php __HALT_COMPILER(); ?>");
$files = array();
$files['a.php'] = '<?php echo "This is a\n"; ?>';
$files['b.php'] = '<?php echo "This is b\n"; ?>';
$files['b/c.php'] = '<?php echo "This is b/c\n"; ?>';
$files['.phar/alias.txt'] = 'hio';
foreach ($files as $n => $file) {
$a->addFile($n, $file);
}
$a->close();
$fp = fopen($pname . '/b/c.php', 'wb');
fwrite($fp, "extra");
fclose($fp);
echo "===CLOSE===\n";
$p = new Phar($fname);
$b = fopen($pname . '/b/c.php', 'rb');
$a = $p['b/c.php'];
var_dump($a);
var_dump(fread($b, 20));
rewind($b);
echo "===UNLINK===\n";
unlink($pname . '/b/c.php');
var_dump($a);
var_dump(fread($b, 20));
include $pname . '/b/c.php';
?>
===DONE===
--CLEAN--
<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php'); ?>
--EXPECTF--
===CLOSE===
object(PharFileInfo)#%d (2) {
["pathName":"SplFileInfo":private]=>
string(%d) "phar://%srefcount1.phar.php/b"
["fileName":"SplFileInfo":private]=>
string(%d) "phar://%srefcount1.phar.php/b/c.php"
}
string(5) "extra"
===UNLINK===
Warning: unlink(): phar error: "b/c.php" in phar "%srefcount1.phar.php", has open file pointers, cannot unlink in %srefcount1.php on line %d
object(PharFileInfo)#%d (2) {
["pathName":"SplFileInfo":private]=>
string(%d) "phar://%srefcount1.phar.php/b"
["fileName":"SplFileInfo":private]=>
string(%s) "phar://%srefcount1.phar.php/b/c.php"
}
string(5) "extra"
extra
===DONE===

View File

@ -0,0 +1,62 @@
--TEST--
Phar: test that refcounting avoids problems with deleting a file tar-based
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip"); ?>
<?php if (!extension_loaded("spl")) die("skip SPL not available"); ?>
<?php if (version_compare(PHP_VERSION, "5.2", ">")) die("skip requires 5.2 or earlier"); ?>
--INI--
phar.readonly=0
phar.require_hash=0
--FILE--
<?php
include dirname(__FILE__) . '/tarmaker.php.inc';
$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
$pname = 'phar://' . $fname;
$a = new tarmaker($fname, 'none');
$a->init();
$a->addFile('.phar/stub.php', "<?php __HALT_COMPILER(); ?>");
$files = array();
$files['a.php'] = '<?php echo "This is a\n"; ?>';
$files['b.php'] = '<?php echo "This is b\n"; ?>';
$files['b/c.php'] = '<?php echo "This is b/c\n"; ?>';
$files['.phar/alias.txt'] = 'hio';
foreach ($files as $n => $file) {
$a->addFile($n, $file);
}
$a->close();
$fp = fopen($pname . '/b/c.php', 'wb');
fwrite($fp, "extra");
fclose($fp);
echo "===CLOSE===\n";
$p = new Phar($fname);
$b = fopen($pname . '/b/c.php', 'rb');
$a = $p['b/c.php'];
var_dump($a);
var_dump(fread($b, 20));
rewind($b);
echo "===UNLINK===\n";
unlink($pname . '/b/c.php');
var_dump($a);
var_dump(fread($b, 20));
include $pname . '/b/c.php';
?>
===DONE===
--CLEAN--
<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php'); ?>
--EXPECTF--
===CLOSE===
object(PharFileInfo)#%d (0) {
}
string(5) "extra"
===UNLINK===
Warning: unlink(): phar error: "b/c.php" in phar "%sefcount1.phar.php", has open file pointers, cannot unlink in %sefcount1.php on line %d
object(PharFileInfo)#%d (0) {
}
string(5) "extra"
extra
===DONE===

View File

@ -0,0 +1,39 @@
--TEST--
Phar: rename test
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip"); ?>
--INI--
phar.readonly=0
phar.require_hash=0
--FILE--
<?php
include dirname(__FILE__) . '/tarmaker.php.inc';
$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
$pname = 'phar://' . $fname;
$a = new tarmaker($fname, 'none');
$a->init();
$a->addFile('.phar/stub.php', "<?php
Phar::mapPhar('hio');
__HALT_COMPILER(); ?>");
$files = array();
$files['a'] = 'a';
foreach ($files as $n => $file) {
$a->addFile($n, $file);
}
$a->close();
include $fname;
echo file_get_contents($pname . '/a') . "\n";
rename($pname . '/a', $pname . '/b');
echo file_get_contents($pname . '/b') . "\n";
echo file_get_contents($pname . '/a') . "\n";
?>
--CLEAN--
<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php'); ?>
--EXPECTF--
a
a
Warning: file_get_contents(phar://%srename.phar.php/a): failed to open stream: phar error: "a" is not a file in phar "%srename.phar.php" in %srename.php on line %d

View File

@ -20,7 +20,7 @@ $a->mkDir('dir');
$a->addFile('.phar/stub.php', '<?php
Phar::mapPhar();
var_dump("it worked");
include "tar_004.php";
include "phar://" . __FILE__ . "/tar_004.php";
');
$a->close();