mirror of
https://github.com/php/php-src.git
synced 2024-12-14 20:33:36 +08:00
fix PharFileInfo->setAlias (was wildly broken)
fix directory creation in zip archives update zip tests to use phar to create the zip, and then copy to a new file
This commit is contained in:
parent
18c8e6501b
commit
f4e4ad0cd1
@ -1818,28 +1818,28 @@ PHP_METHOD(Phar, setAlias)
|
||||
if (alias_len == phar_obj->arc.archive->alias_len && memcmp(phar_obj->arc.archive->alias, alias, alias_len) == 0) {
|
||||
RETURN_TRUE;
|
||||
}
|
||||
if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void**)&fd_ptr)) {
|
||||
if (alias_len && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void**)&fd_ptr)) {
|
||||
spprintf(&error, 0, "alias \"%s\" is already used for archive \"%s\" and cannot be used for other archives", alias, (*fd_ptr)->fname);
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
|
||||
efree(error);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), phar_obj->arc.archive->alias, phar_obj->arc.archive->alias_len, (void**)&fd_ptr)) {
|
||||
zend_hash_del(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len);
|
||||
if (phar_obj->arc.archive->alias_len && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), phar_obj->arc.archive->alias, phar_obj->arc.archive->alias_len, (void**)&fd_ptr)) {
|
||||
zend_hash_del(&(PHAR_GLOBALS->phar_alias_map), phar_obj->arc.archive->alias, phar_obj->arc.archive->alias_len);
|
||||
fd = *fd_ptr;
|
||||
if (alias && alias_len) {
|
||||
zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&fd, sizeof(phar_archive_data*), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
efree(phar_obj->arc.archive->alias);
|
||||
if (phar_obj->arc.archive->alias) {
|
||||
efree(phar_obj->arc.archive->alias);
|
||||
}
|
||||
if (alias_len) {
|
||||
phar_obj->arc.archive->alias = estrndup(alias, alias_len);
|
||||
} else {
|
||||
phar_obj->arc.archive->alias = NULL;
|
||||
}
|
||||
phar_obj->arc.archive->alias_len = alias_len;
|
||||
phar_obj->arc.archive->is_explicit_alias = 0;
|
||||
phar_obj->arc.archive->is_explicit_alias = 1;
|
||||
|
||||
phar_flush(phar_obj->arc.archive, NULL, 0, &error TSRMLS_CC);
|
||||
if (error) {
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
|
||||
|
@ -3,7 +3,7 @@ Phar::chmod zip-based
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("phar")) die("skip"); ?>
|
||||
--INI--
|
||||
phar.readonly=1
|
||||
phar.readonly=0
|
||||
phar.require_hash=0
|
||||
--FILE--
|
||||
<?php
|
||||
@ -17,6 +17,7 @@ $a->addFile('a.php', '<?php echo "This is a\n"; include "'.$pname.'/b.php"; ?>')
|
||||
$a->addFile('.phar/alias.txt', 'hio');
|
||||
$a->mkDir('test');
|
||||
$a->close();
|
||||
ini_set('phar.readonly', 1);
|
||||
|
||||
try {
|
||||
$a = new Phar($fname);
|
||||
|
@ -3,7 +3,7 @@ Phar: delete a file within a zip-based .phar
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("phar")) die("skip"); ?>
|
||||
--INI--
|
||||
phar.readonly=1
|
||||
phar.readonly=0
|
||||
phar.require_hash=0
|
||||
--FILE--
|
||||
<?php
|
||||
@ -18,6 +18,7 @@ $a->addFile('b.php', '<?php echo "This is b\n"; ?>');
|
||||
$a->addFile('b/c.php', '<?php echo "This is b/c\n"; ?>');
|
||||
$a->addFile('.phar/stub.php', '<?php __HALT_COMPILER(); ?>');
|
||||
$a->close();
|
||||
ini_set('phar.readonly', 1);
|
||||
|
||||
include $pname . '/a.php';
|
||||
include $pname . '/b.php';
|
||||
|
@ -3,7 +3,7 @@ Phar: fopen a .phar for writing (existing file) zip-based
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("phar")) die("skip"); ?>
|
||||
--INI--
|
||||
phar.readonly=1
|
||||
phar.readonly=0
|
||||
phar.require_hash=0
|
||||
--FILE--
|
||||
<?php
|
||||
@ -22,6 +22,7 @@ foreach ($files as $n => $file) {
|
||||
$a->addFile($n, $file);
|
||||
}
|
||||
$a->close();
|
||||
ini_set('phar.readonly', 1);
|
||||
|
||||
function err_handler($errno, $errstr, $errfile, $errline) {
|
||||
echo "Catchable fatal error: $errstr in $errfile on line $errline\n";
|
||||
|
@ -3,7 +3,7 @@ Phar: fopen a .phar for writing (existing file) tar-based
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("phar")) die("skip"); ?>
|
||||
--INI--
|
||||
phar.readonly=1
|
||||
phar.readonly=0
|
||||
phar.require_hash=0
|
||||
--FILE--
|
||||
<?php
|
||||
@ -22,6 +22,7 @@ foreach ($files as $n => $file) {
|
||||
$a->addFile($n, $file);
|
||||
}
|
||||
$a->close();
|
||||
ini_set('phar.readonly', 1);
|
||||
|
||||
$fp = fopen($pname . '/b/c.php', 'wb');
|
||||
fwrite($fp, 'extra');
|
||||
|
@ -3,7 +3,7 @@ Phar: fopen a .phar for writing (new file) zip-based
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("phar")) die("skip"); ?>
|
||||
--INI--
|
||||
phar.readonly=1
|
||||
phar.readonly=0
|
||||
phar.require_hash=0
|
||||
--FILE--
|
||||
<?php
|
||||
@ -22,6 +22,7 @@ foreach ($files as $n => $file) {
|
||||
$a->addFile($n, $file);
|
||||
}
|
||||
$a->close();
|
||||
ini_set('phar.readonly', 1);
|
||||
|
||||
function err_handler($errno, $errstr, $errfile, $errline) {
|
||||
echo "Catchable fatal error: $errstr in $errfile on line $errline\n";
|
||||
|
@ -3,7 +3,7 @@ Phar: fopen a .phar for writing (new file) zip-based
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("phar")) die("skip"); ?>
|
||||
--INI--
|
||||
phar.readonly=1
|
||||
phar.readonly=0
|
||||
phar.require_hash=0
|
||||
--FILE--
|
||||
<?php
|
||||
@ -22,6 +22,7 @@ foreach ($files as $n => $file) {
|
||||
$a->addFile($n, $file);
|
||||
}
|
||||
$a->close();
|
||||
ini_set('phar.readonly', 1);
|
||||
|
||||
$fp = fopen($pname . '/b/new.php', 'wb');
|
||||
fwrite($fp, 'extra');
|
||||
|
@ -9,17 +9,19 @@ class tarmaker
|
||||
*/
|
||||
protected $archive;
|
||||
/**
|
||||
* @var ZIPArchive
|
||||
* @var Phar
|
||||
*/
|
||||
protected $zip;
|
||||
protected $path;
|
||||
/**
|
||||
* this is the location we'll create the phar, then we'll copy() it to $path
|
||||
* @var string
|
||||
*/
|
||||
protected $tmppath;
|
||||
function __construct($path)
|
||||
{
|
||||
if (!class_exists('ZIPArchive')) {
|
||||
throw new Exception(
|
||||
'Zip extension is not available');
|
||||
}
|
||||
$this->path = $path;
|
||||
$this->tmppath = dirname($path) . "/.tmp.thingy.phar";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -29,11 +31,12 @@ class tarmaker
|
||||
*/
|
||||
function addFile($path, $fileOrStream)
|
||||
{
|
||||
if (is_resource($fileOrStream)) {
|
||||
$this->zip->addFromString($path, stream_get_contents($fileOrStream));
|
||||
} else {
|
||||
$this->zip->addFromString($path, $fileOrStream);
|
||||
if ($path == '.phar/stub.php') {
|
||||
$this->zip->setStub($fileOrStream);
|
||||
} elseif ($path == '.phar/alias.txt') {
|
||||
$this->zip->setAlias($fileOrStream);
|
||||
}
|
||||
$this->zip[$path] = $fileOrStream;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -41,12 +44,8 @@ class tarmaker
|
||||
*/
|
||||
function init()
|
||||
{
|
||||
$this->zip = new ZipArchive;
|
||||
if (true !== $this->zip->open($this->path, ZIPARCHIVE::CREATE)) {
|
||||
throw new Exception(
|
||||
'Cannot open ZIP archive ' . $this->path
|
||||
);
|
||||
}
|
||||
$this->zip = new Phar($this->tmppath);
|
||||
$this->zip->convertToZip();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,7 +56,8 @@ class tarmaker
|
||||
*/
|
||||
function mkdir($dir)
|
||||
{
|
||||
$this->zip->addEmptyDir($dir);
|
||||
if ($dir[strlen($dir)-1] != '/') $dir .= '/';
|
||||
$this->zip[$dir] = '';
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,6 +65,14 @@ class tarmaker
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
$this->zip->close();
|
||||
$this->zip->stopBuffering();
|
||||
copy($this->tmppath, $this->path);
|
||||
$this->zip->setAlias('not.to.be.used'); // for preventing alias conflict
|
||||
$this->zip->stopBuffering();
|
||||
}
|
||||
|
||||
function __destruct()
|
||||
{
|
||||
unlink($this->tmppath);
|
||||
}
|
||||
}
|
@ -245,7 +245,12 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char
|
||||
etemp.is_tar = phar->is_tar;
|
||||
etemp.tar_type = TAR_FILE;
|
||||
}
|
||||
zend_hash_add(&phar->manifest, etemp.filename, path_len, (void*)&etemp, sizeof(phar_entry_info), (void **) &entry);
|
||||
if (FAILURE == zend_hash_add(&phar->manifest, etemp.filename, path_len, (void*)&etemp, sizeof(phar_entry_info), (void **) &entry)) {
|
||||
if (error) {
|
||||
spprintf(error, 0, "phar error: unable to add new entry \"%s\" to phar \"%s\"", etemp.filename, phar->fname);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!entry) {
|
||||
php_stream_close(etemp.fp);
|
||||
|
@ -448,7 +448,7 @@ static int phar_zip_changed_apply(void *data, void *arg TSRMLS_DC) /* {{{ */
|
||||
phar_zip_u2d_time(entry->timestamp, &local.timestamp, &local.datestamp);
|
||||
central.timestamp = local.timestamp;
|
||||
central.datestamp = local.datestamp;
|
||||
central.filename_len = local.filename_len = entry->filename_len;
|
||||
central.filename_len = local.filename_len = entry->filename_len + (entry->is_dir ? 1 : 0);
|
||||
central.offset = php_stream_tell(p->filefp);
|
||||
/* do extra field for perms later */
|
||||
if (entry->is_modified) {
|
||||
@ -549,7 +549,7 @@ continue_dir:
|
||||
central.comment_len = entry->metadata_str.len;
|
||||
}
|
||||
entry->header_offset = php_stream_tell(p->filefp);
|
||||
offset = entry->header_offset + sizeof(local) + entry->filename_len + sizeof(perms);
|
||||
offset = entry->header_offset + sizeof(local) + entry->filename_len + (entry->is_dir ? 1 : 0) + sizeof(perms);
|
||||
if (sizeof(local) != php_stream_write(p->filefp, (char *)&local, sizeof(local))) {
|
||||
spprintf(p->error, 0, "unable to write local file header of file \"%s\" to zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
@ -558,13 +558,32 @@ continue_dir:
|
||||
spprintf(p->error, 0, "unable to write central directory entry for file \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
if (entry->filename_len != php_stream_write(p->filefp, entry->filename, entry->filename_len)) {
|
||||
spprintf(p->error, 0, "unable to write filename to local directory entry for file \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
if (entry->filename_len != php_stream_write(p->centralfp, entry->filename, entry->filename_len)) {
|
||||
spprintf(p->error, 0, "unable to write filename to central directory entry for file \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
if (entry->is_dir) {
|
||||
if (entry->filename_len != php_stream_write(p->filefp, entry->filename, entry->filename_len)) {
|
||||
spprintf(p->error, 0, "unable to write filename to local directory entry for directory \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
if (1 != php_stream_write(p->filefp, "/", 1)) {
|
||||
spprintf(p->error, 0, "unable to write filename to local directory entry for directory \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
if (entry->filename_len != php_stream_write(p->centralfp, entry->filename, entry->filename_len)) {
|
||||
spprintf(p->error, 0, "unable to write filename to central directory entry for directory \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
if (1 != php_stream_write(p->centralfp, "/", 1)) {
|
||||
spprintf(p->error, 0, "unable to write filename to central directory entry for directory \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
} else {
|
||||
if (entry->filename_len != php_stream_write(p->filefp, entry->filename, entry->filename_len)) {
|
||||
spprintf(p->error, 0, "unable to write filename to local directory entry for file \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
if (entry->filename_len != php_stream_write(p->centralfp, entry->filename, entry->filename_len)) {
|
||||
spprintf(p->error, 0, "unable to write filename to central directory entry for file \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
}
|
||||
}
|
||||
if (sizeof(perms) != php_stream_write(p->filefp, (char *)&perms, sizeof(perms))) {
|
||||
spprintf(p->error, 0, "unable to write local extra permissions file header of file \"%s\" to zip-based phar \"%s\"", entry->filename, entry->phar->fname);
|
||||
@ -660,7 +679,9 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, char **er
|
||||
}
|
||||
/* register alias */
|
||||
if (phar->alias_len) {
|
||||
phar_get_archive(&phar, phar->fname, phar->fname_len, phar->alias, phar->alias_len, NULL TSRMLS_CC);
|
||||
if (FAILURE == phar_get_archive(&phar, phar->fname, phar->fname_len, phar->alias, phar->alias_len, error TSRMLS_CC)) {
|
||||
return EOF;
|
||||
}
|
||||
}
|
||||
|
||||
/* set stub */
|
||||
|
Loading…
Reference in New Issue
Block a user