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);
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip"); ?>
--INI--
-phar.readonly=1
+phar.readonly=0
phar.require_hash=0
--FILE--
<?php
$a->addFile('.phar/alias.txt', 'hio');
$a->mkDir('test');
$a->close();
+ini_set('phar.readonly', 1);
try {
$a = new Phar($fname);
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip"); ?>
--INI--
-phar.readonly=1
+phar.readonly=0
phar.require_hash=0
--FILE--
<?php
$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';
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip"); ?>
--INI--
-phar.readonly=1
+phar.readonly=0
phar.require_hash=0
--FILE--
<?php
$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";
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip"); ?>
--INI--
-phar.readonly=1
+phar.readonly=0
phar.require_hash=0
--FILE--
<?php
$a->addFile($n, $file);
}
$a->close();
+ini_set('phar.readonly', 1);
$fp = fopen($pname . '/b/c.php', 'wb');
fwrite($fp, 'extra');
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip"); ?>
--INI--
-phar.readonly=1
+phar.readonly=0
phar.require_hash=0
--FILE--
<?php
$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";
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip"); ?>
--INI--
-phar.readonly=1
+phar.readonly=0
phar.require_hash=0
--FILE--
<?php
$a->addFile($n, $file);
}
$a->close();
+ini_set('phar.readonly', 1);
$fp = fopen($pname . '/b/new.php', 'wb');
fwrite($fp, 'extra');
*/
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";
}
/**
*/
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;
}
/**
*/
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();
}
/**
*/
function mkdir($dir)
{
- $this->zip->addEmptyDir($dir);
+ if ($dir[strlen($dir)-1] != '/') $dir .= '/';
+ $this->zip[$dir] = '';
}
/**
*/
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);
}
}
\ No newline at end of file
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);
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) {
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;
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);
}
/* 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 */