summaryrefslogtreecommitdiff
path: root/ext/phar
diff options
context:
space:
mode:
Diffstat (limited to 'ext/phar')
-rwxr-xr-xext/phar/phar_internal.h5
-rwxr-xr-xext/phar/phar_object.c523
-rw-r--r--ext/phar/tests/phar_convert_repeated_b.phpt24
-rw-r--r--ext/phar/util.c104
4 files changed, 346 insertions, 310 deletions
diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h
index ebab7fdd26..369fab3d87 100755
--- a/ext/phar/phar_internal.h
+++ b/ext/phar/phar_internal.h
@@ -376,10 +376,9 @@ int phar_open_loaded(char *fname, int fname_len, char *alias, int alias_len, int
/* utility functions */
char *phar_create_default_stub(const char *index_php, const char *web_index, size_t *len, char **error TSRMLS_DC);
-char * phar_decompress_filter(phar_entry_info * entry, int return_unknown);
-char * phar_compress_filter(phar_entry_info * entry, int return_unknown);
+char *phar_decompress_filter(phar_entry_info * entry, int return_unknown);
+char *phar_compress_filter(phar_entry_info * entry, int return_unknown);
-void phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool compress TSRMLS_DC);
int phar_mount_entry(phar_archive_data *phar, char *filename, int filename_len, char *path, int path_len TSRMLS_DC);
char *phar_find_in_include_path(char *file, int file_len, phar_archive_data **pphar TSRMLS_DC);
char *phar_fix_filepath(char *path, int *new_len, int use_cwd TSRMLS_DC);
diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c
index 9f8fc01781..317980bb0d 100755
--- a/ext/phar/phar_object.c
+++ b/ext/phar/phar_object.c
@@ -1605,73 +1605,174 @@ static int phar_copy_file_contents(phar_entry_info *entry, php_stream *fp TSRMLS
}
/* }}} */
-static int phar_restore_apply(void *data TSRMLS_DC) /* {{{ */
+static zval *phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool compress TSRMLS_DC)
{
- phar_entry_info *entry = (phar_entry_info *)data;
+ char *oldname = NULL, *oldpath = NULL;
+ char *basename = NULL, *basepath = NULL;
+ char *newname = NULL, *newpath = NULL;
+ zval *ret, arg1;
+ zend_class_entry *ce;
+ char *error;
+
+ if (!ext) {
+ if (phar->is_zip) {
+ if (phar->is_data) {
+ ext = "zip";
+ } else {
+ ext = "phar.zip";
+ }
+ } else if (phar->is_tar) {
+ switch (phar->flags) {
+ case PHAR_FILE_COMPRESSED_GZ:
+ if (phar->is_data) {
+ ext = "tar.gz";
+ } else {
+ ext = "phar.tar.gz";
+ }
+ break;
+ case PHAR_FILE_COMPRESSED_BZ2:
+ if (phar->is_data) {
+ ext = "tar.bz2";
+ } else {
+ ext = "phar.tar.bz2";
+ }
+ break;
+ default:
+ if (phar->is_data) {
+ ext = "tar";
+ } else {
+ ext = "phar.tar";
+ }
+ }
+ } else {
+ switch (phar->flags) {
+ case PHAR_FILE_COMPRESSED_GZ:
+ ext = "phar.gz";
+ break;
+ case PHAR_FILE_COMPRESSED_BZ2:
+ ext = "phar.bz2";
+ break;
+ default:
+ ext = "phar";
+ }
+ }
+ }
+
+ if (ext[0] == '.') {
+ ++ext;
+ }
+
+ oldpath = estrndup(phar->fname, phar->fname_len);
+ oldname = strrchr(phar->fname, '/');
+ ++oldname;
- if (entry->cfp) {
- entry->fp_type = PHAR_MOD;
- entry->fp = entry->cfp;
- entry->cfp = NULL;
- entry->offset = 0;
+ basename = estrndup(oldname, strlen(oldname));
+ spprintf(&newname, 0, "%s.%s", strtok(basename, "."), ext);
+ efree(basename);
+
+ basepath = estrndup(oldpath, strlen(oldpath) - strlen(oldname));
+ phar->fname_len = spprintf(&newpath, 0, "%s%s", basepath, newname);
+ phar->fname = newpath;
+ efree(basepath);
+ efree(newname);
+
+ if (zend_hash_exists(&(PHAR_GLOBALS->phar_fname_map), newpath, phar->fname_len)) {
+ zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Unable to add newly converted phar \"%s\" to the list of phars, a phar with that name already exists", phar->fname);
+ return NULL;
+ }
+ if (SUCCESS != zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), newpath, phar->fname_len, (void*)&phar, sizeof(phar_archive_data*), NULL)) {
+ zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Unable to add newly converted phar \"%s\" to the list of phars", phar->fname);
+ return NULL;
+ }
+
+ if (!phar->is_data) {
+ if (phar->alias) {
+ efree(phar->alias);
+ phar->alias = estrndup(newpath, strlen(newpath));
+ phar->alias_len = strlen(newpath);
+ phar->is_temporary_alias = 1;
+ zend_hash_update(&(PHAR_GLOBALS->phar_alias_map), newpath, phar->fname_len, (void*)&phar, sizeof(phar_archive_data*), NULL);
+ }
+ }
+
+
+ phar_flush(phar, 0, 0, 1, &error TSRMLS_CC);
+ if (error) {
+ zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, error);
+ efree(error);
+ return NULL;
+ }
+
+ efree(oldpath);
+
+ if (phar->is_data) {
+ ce = phar_ce_data;
} else {
- entry->fp_type = PHAR_FP;
- entry->fp = NULL;
- entry->offset = entry->offset_abs;
+ ce = phar_ce_archive;
}
- return ZEND_HASH_APPLY_KEEP;
+
+ MAKE_STD_ZVAL(ret);
+ if (SUCCESS != object_init_ex(ret, ce)) {
+ zval_dtor(ret);
+ zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Unable to instantiate phar object when converting archive \"%s\"", phar->fname);
+ return NULL;
+ }
+ INIT_PZVAL(&arg1);
+ ZVAL_STRINGL(&arg1, phar->fname, phar->fname_len, 0);
+
+ zend_call_method_with_1_params(&ret, ce, &ce->constructor, "__construct", NULL, &arg1);
+
+ return ret;
}
-/* }}} */
-static void phar_convert_to_other(phar_archive_data *source, int convert, char *ext, php_uint32 flags TSRMLS_DC) /* {{{ */
+static zval *phar_convert_to_other(phar_archive_data *source, int convert, char *ext, php_uint32 flags TSRMLS_DC) /* {{{ */
{
- phar_archive_data phar = {0};
- char *error;
+ phar_archive_data *phar;
phar_entry_info *entry, newentry;
+ zval *ret;
+ phar = (phar_archive_data *) ecalloc(1, sizeof(phar_archive_data));
/* set whole-archive compression and type from parameter */
- phar.flags = flags;
+ phar->flags = flags;
+ phar->is_data = source->is_data;
switch (convert) {
case 1 :
- phar.is_tar = 1;
+ phar->is_tar = 1;
break;
case 2 :
- phar.is_zip = 1;
+ phar->is_zip = 1;
+ break;
+ default :
+ phar->is_data = 0;
break;
}
- zend_hash_init(&(phar.manifest), sizeof(phar_entry_info),
+ zend_hash_init(&(phar->manifest), sizeof(phar_entry_info),
zend_get_hash_value, destroy_phar_manifest_entry, 0);
- phar.fp = php_stream_fopen_tmpfile();
- phar.fname = source->fname;
+ phar->fp = php_stream_fopen_tmpfile();
+ phar->fname = source->fname;
+ phar->fname_len = source->fname_len;
+ phar->is_temporary_alias = source->is_temporary_alias;
/* first copy each file's uncompressed contents to a temporary file and set per-file flags */
for (zend_hash_internal_pointer_reset(&source->manifest); SUCCESS == zend_hash_has_more_elements(&source->manifest); zend_hash_move_forward(&source->manifest)) {
if (FAILURE == zend_hash_get_current_data(&source->manifest, (void **) &entry)) {
- zend_hash_destroy(&(phar.manifest));
- php_stream_close(phar.fp);
+ zend_hash_destroy(&(phar->manifest));
+ php_stream_close(phar->fp);
+ efree(phar);
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
"Cannot convert phar archive \"%s\"", source->fname);
- zend_hash_apply(&source->manifest, phar_restore_apply TSRMLS_CC);
- return;
- }
- if (entry->fp_refcount > 0) {
- zend_hash_destroy(&(phar.manifest));
- php_stream_close(phar.fp);
- zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
- "Cannot convert phar archive \"%s\", open file pointers for entry \"%s\"", source->fname, entry->filename);
- zend_hash_apply(&source->manifest, phar_restore_apply TSRMLS_CC);
- return;
+ return NULL;
}
newentry = *entry;
- if (FAILURE == phar_copy_file_contents(&newentry, phar.fp TSRMLS_CC)) {
- zend_hash_destroy(&(phar.manifest));
- php_stream_close(phar.fp);
+ if (FAILURE == phar_copy_file_contents(&newentry, phar->fp TSRMLS_CC)) {
+ zend_hash_destroy(&(phar->manifest));
+ php_stream_close(phar->fp);
+ efree(phar);
/* exception already thrown */
- zend_hash_apply(&source->manifest, phar_restore_apply TSRMLS_CC);
- return;
+ return NULL;
}
newentry.filename = estrndup(newentry.filename, newentry.filename_len);
if (newentry.metadata) {
@@ -1690,82 +1791,30 @@ static void phar_convert_to_other(phar_archive_data *source, int convert, char *
newentry.metadata_str.c = NULL;
newentry.metadata_str.len = 0;
}
- newentry.is_zip = phar.is_zip;
- newentry.is_tar = phar.is_tar;
+ newentry.is_zip = phar->is_zip;
+ newentry.is_tar = phar->is_tar;
if (newentry.is_tar) {
newentry.tar_type = (entry->is_dir ? TAR_DIR : TAR_FILE);
}
newentry.is_modified = 1;
- newentry.phar = &phar;
+ newentry.phar = phar;
newentry.old_flags = newentry.flags & ~PHAR_ENT_COMPRESSION_MASK; /* remove compression from old_flags */
- zend_hash_add(&(phar.manifest), newentry.filename, newentry.filename_len, (void*)&newentry, sizeof(phar_entry_info), NULL);
- }
-
- /* update the original manifest */
- for (zend_hash_internal_pointer_reset(&(phar.manifest)); SUCCESS == zend_hash_has_more_elements(&(phar.manifest)); zend_hash_move_forward(&(phar.manifest))) {
- phar_entry_info *entry, *mine;
- if (FAILURE == zend_hash_get_current_data(&(phar.manifest), (void **) &entry)) {
- zend_hash_destroy(&(phar.manifest));
- php_stream_close(phar.fp);
- /* we can't throw an exception or bad crap will happen */
- zend_error(E_ERROR, "Error: could not convert phar archive \"%s\", phar is in unstable state, shutting down", source->fname);
- return;
- }
- if (FAILURE == zend_hash_find(&source->manifest, entry->filename, entry->filename_len, (void **) &mine)) {
- zend_hash_destroy(&(phar.manifest));
- php_stream_close(phar.fp);
- /* we can't throw an exception or bad crap will happen */
- zend_error(E_ERROR, "Error: could not convert phar archive \"%s\", phar is in unstable state, shutting down", source->fname);
- return;
- }
- /* now, replace the manifest entry with the new guy */
- efree(mine->filename);
- if (mine->metadata) {
- zval_dtor(mine->metadata);
- efree(mine->metadata);
- }
- if (mine->fp_type == PHAR_MOD && mine->fp != source->fp && mine->fp != source->ufp) {
- php_stream_close(mine->fp);
- }
- *mine = *entry;
- mine->phar = source;
- }
- if (source->fp && source->refcount == 1) {
- php_stream_close(source->fp);
+ zend_hash_add(&(phar->manifest), newentry.filename, newentry.filename_len, (void*)&newentry, sizeof(phar_entry_info), NULL);
}
- source->fp = phar.fp;
- /* don't free stuff */
- phar.manifest.pDestructor = NULL;
- zend_hash_destroy(&(phar.manifest));
- source->is_zip = phar.is_zip;
- source->is_tar = phar.is_tar;
-
- if (phar.is_zip || phar.is_tar) {
- source->internal_file_start = source->halt_offset = 0;
- }
- if (source->signature) {
- efree(source->signature);
- }
- if (phar.signature) {
- source->signature = phar.signature;
+ if ((ret = phar_rename_archive(phar, ext, 0 TSRMLS_CC))) {
+ return ret;
} else {
- source->signature = 0;
- }
- if (source->alias) {
- efree(source->alias);
+ zend_hash_destroy(&(phar->manifest));
+ php_stream_close(phar->fp);
+ efree(phar->fname);
+ efree(phar);
+ return NULL;
}
- source->alias = NULL;
- source->alias_len = 0;
- source->is_temporary_alias = 0;
- source->flags = phar.flags;
-
- phar_rename_archive(source, ext, 0 TSRMLS_CC);
- phar_flush(source, 0, 0, convert, &error TSRMLS_CC);
}
/* }}} */
-/* {{{ proto bool Phar::convertToTar([int compression, [string file_ext]])
+/* {{{ proto object Phar::convertToTar([string file_ext])
* Convert a phar or phar.zip archive to the tar file format. The first
* parameter can be one of Phar::GZ or Phar::BZ2 to specify whole-file
* compression. The second parameter allows the user to determine the new
@@ -1775,63 +1824,33 @@ static void phar_convert_to_other(phar_archive_data *source, int convert, char *
PHP_METHOD(Phar, convertToTar)
{
char *ext = NULL;
- php_uint32 flags;
- long method = 0;
int ext_len = 0;
+ zval *ret;
PHAR_ARCHIVE_OBJECT();
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ls", &method, &ext, &ext_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &ext, &ext_len) == FAILURE) {
return;
}
if (phar_obj->arc.archive->is_tar) {
RETURN_TRUE;
}
-
- switch (method) {
- case 0:
- flags = PHAR_FILE_COMPRESSED_NONE;
- break;
- case PHAR_ENT_COMPRESSED_GZ:
- if (!phar_has_zlib) {
- zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
- "Cannot compress entire archive with gzip, enable ext/zlib in php.ini");
- return;
- }
- flags = PHAR_FILE_COMPRESSED_GZ;
- break;
-
- case PHAR_ENT_COMPRESSED_BZ2:
- if (!phar_has_bz2) {
- zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
- "Cannot compress entire archive with bz2, enable ext/bz2 in php.ini");
- return;
- }
- flags = PHAR_FILE_COMPRESSED_BZ2;
- break;
- default:
- zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
- "Unknown compression specified, please pass one of Phar::GZ or Phar::BZ2");
- return;
- }
if (PHAR_G(readonly)) {
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
"Cannot write out phar archive, phar is read-only");
return;
}
- if (phar_obj->arc.archive->donotflush) {
- zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
- "Cannot convert phar archive to tar format, call stopBuffering() first");
- return;
+ ret = phar_convert_to_other(phar_obj->arc.archive, 1, ext, phar_obj->arc.archive->flags TSRMLS_CC);
+ if (ret) {
+ RETURN_ZVAL(ret, 1, 1);
+ } else {
+ RETURN_NULL();
}
-
- phar_convert_to_other(phar_obj->arc.archive, 1, ext, flags TSRMLS_CC);
- RETURN_TRUE;
}
/* }}} */
-/* {{{ proto bool Phar::convertToZip([string file_ext])
+/* {{{ proto object Phar::convertToZip([string file_ext])
* Convert a phar or phar.tar archive to the zip file format. The single
* optional argument allows the user to determine the new filename extension
* (default is phar.zip).
@@ -1840,20 +1859,13 @@ PHP_METHOD(Phar, convertToZip)
{
char *ext = NULL;
int ext_len = 0;
+ zval *ret;
PHAR_ARCHIVE_OBJECT();
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &ext, &ext_len) == FAILURE) {
return;
}
- if (ext_len) {
- if (strncmp(ext, "Phar::GZ", 8) || strncmp(ext, "Phar::BZ2", 9)) {
- zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
- "Cannot compress a zip-based archive with gz or bz2");
- return;
- }
- }
-
if (phar_obj->arc.archive->is_zip) {
RETURN_TRUE;
}
@@ -1864,43 +1876,40 @@ PHP_METHOD(Phar, convertToZip)
return;
}
- if (phar_obj->arc.archive->donotflush) {
- zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
- "Cannot convert phar archive to zip format, call stopBuffering() first");
- return;
+ ret = phar_convert_to_other(phar_obj->arc.archive, 2, ext, PHAR_FILE_COMPRESSED_NONE TSRMLS_CC);
+ if (ret) {
+ RETURN_ZVAL(ret, 1, 1);
+ } else {
+ RETURN_NULL();
}
-
- phar_convert_to_other(phar_obj->arc.archive, 2, ext, 0 TSRMLS_CC);
- RETURN_TRUE;
}
/* }}} */
-/* {{{ proto bool Phar::convertToPhar([int compression, [string file_ext]])
- * Convert a phar.tar or phar.zip archive to the phar file format. The first
- * parameter can be one of Phar::GZ or Phar::BZ2 to specify whole-file
- * compression. The second parameter allows the user to determine the new
- * filename extension (default is phar/phar.bz2/phar.gz).
- * Both parameters are optional.
+/* {{{ proto object Phar::compress(int method)
+ * Compress a .tar, or .phar.tar with whole-file compression
+ * The parameter can be one of Phar::GZ or Phar::BZ2 to specify
+ * the kind of compression desired
*/
-PHP_METHOD(Phar, convertToPhar)
+PHP_METHOD(Phar, compress)
{
- char *ext = NULL;
- php_uint32 flags;
long method = 0;
- int ext_len = 0;
+ php_uint32 flags;
+ zval *ret;
PHAR_ARCHIVE_OBJECT();
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ls", &method, &ext, &ext_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &method) == FAILURE) {
return;
}
- if (!phar_obj->arc.archive->is_tar && !phar_obj->arc.archive->is_zip) {
- RETURN_TRUE;
+ if (PHAR_G(readonly) && !phar_obj->arc.archive->is_data) {
+ zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
+ "Cannot compress phar archive, phar is read-only");
+ return;
}
- if (PHAR_G(readonly)) { /* Don't override this one for is_data */
+ if (phar_obj->arc.archive->is_zip) {
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
- "Cannot write out phar archive, phar is read-only");
+ "Cannot compress zip-based archives with whole-archive compression");
return;
}
@@ -1931,14 +1940,137 @@ PHP_METHOD(Phar, convertToPhar)
return;
}
- if (phar_obj->arc.archive->donotflush) {
- zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
- "Cannot convert archive to phar format, call stopBuffering() first");
+ if (phar_obj->arc.archive->is_tar) {
+ ret = phar_convert_to_other(phar_obj->arc.archive, 1, NULL, flags TSRMLS_CC);
+ } else {
+ ret = phar_convert_to_other(phar_obj->arc.archive, 0, NULL, flags TSRMLS_CC);
+ }
+ if (ret) {
+ RETURN_ZVAL(ret, 1, 1);
+ } else {
+ RETURN_NULL();
+ }
+}
+/* }}} */
+
+/* {{{ proto object Phar::convertToPhar([string file_ext])
+ * Convert a phar.tar or phar.zip archive to the phar file format. The
+ * optional parameter allows the user to determine the new
+ * filename extension (default is phar).
+ */
+PHP_METHOD(Phar, convertToPhar)
+{
+ char *ext = NULL;
+ int ext_len = 0;
+ zval *ret;
+ PHAR_ARCHIVE_OBJECT();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &ext, &ext_len) == FAILURE) {
return;
}
- phar_convert_to_other(phar_obj->arc.archive, 0, ext, flags TSRMLS_CC);
- RETURN_TRUE;
+ if (!phar_obj->arc.archive->is_tar && !phar_obj->arc.archive->is_zip) {
+ RETURN_TRUE;
+ }
+
+ if (PHAR_G(readonly)) { /* Don't override this one for is_data */
+ zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
+ "Cannot write out phar archive, phar is read-only");
+ return;
+ }
+
+ ret = phar_convert_to_other(phar_obj->arc.archive, 0, ext, phar_obj->arc.archive->flags TSRMLS_CC);
+ if (ret) {
+ RETURN_ZVAL(ret, 1, 1);
+ } else {
+ RETURN_NULL();
+ }
+}
+/* }}} */
+
+/* {{{ proto object Phar::convertToExecutable([string file_ext])
+ * Convert a .tar or .zip archive to an executable .phar.tar or .phar.zip.
+ * The optional parameter allows the user to determine the new
+ * filename extension (default is phar.zip or phar.tar).
+ */
+PHP_METHOD(Phar, convertToExecutable)
+{
+ char *ext = NULL;
+ int ext_len = 0;
+ zval *ret;
+ PHAR_ARCHIVE_OBJECT();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &ext, &ext_len) == FAILURE) {
+ return;
+ }
+
+ if (!phar_obj->arc.archive->is_tar && !phar_obj->arc.archive->is_zip) {
+ RETURN_TRUE;
+ }
+ if (!phar_obj->arc.archive->is_data) {
+ RETURN_TRUE;
+ }
+
+ if (PHAR_G(readonly)) { /* Don't override this one for is_data */
+ zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
+ "Cannot convert phar archive to executable format, phar is read-only");
+ return;
+ }
+
+ phar_obj->arc.archive->is_data = 0;
+ if (phar_obj->arc.archive->is_tar) {
+ ret = phar_convert_to_other(phar_obj->arc.archive, 1, ext, phar_obj->arc.archive->flags TSRMLS_CC);
+ } else {
+ ret = phar_convert_to_other(phar_obj->arc.archive, 2, ext, phar_obj->arc.archive->flags TSRMLS_CC);
+ }
+ if (ret) {
+ RETURN_ZVAL(ret, 1, 1);
+ } else {
+ RETURN_NULL();
+ }
+}
+/* }}} */
+
+/* {{{ proto object Phar::convertToData([string file_ext])
+ * Convert a phar.tar or phar.zip archive to a non-executable .tar or .zip.
+ * The optional parameter allows the user to determine the new
+ * filename extension (default is .zip or .tar).
+ */
+PHP_METHOD(Phar, convertToData)
+{
+ char *ext = NULL;
+ int ext_len = 0;
+ zval *ret;
+ PHAR_ARCHIVE_OBJECT();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &ext, &ext_len) == FAILURE) {
+ return;
+ }
+
+ if (!phar_obj->arc.archive->is_tar && !phar_obj->arc.archive->is_zip) {
+ RETURN_TRUE;
+ }
+ if (!phar_obj->arc.archive->is_data) {
+ RETURN_TRUE;
+ }
+
+ if (PHAR_G(readonly)) { /* Don't override this one for is_data */
+ zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
+ "Cannot convert phar archive to executable format, phar is read-only");
+ return;
+ }
+
+ phar_obj->arc.archive->is_data = 1;
+ if (phar_obj->arc.archive->is_tar) {
+ ret = phar_convert_to_other(phar_obj->arc.archive, 1, ext, phar_obj->arc.archive->flags TSRMLS_CC);
+ } else {
+ ret = phar_convert_to_other(phar_obj->arc.archive, 2, ext, phar_obj->arc.archive->flags TSRMLS_CC);
+ }
+ if (ret) {
+ RETURN_ZVAL(ret, 1, 1);
+ } else {
+ RETURN_NULL();
+ }
}
/* }}} */
@@ -2458,20 +2590,19 @@ PHP_METHOD(Phar, compressAllFilesGZ)
"Cannot compress with Gzip compression, zlib extension is not enabled");
return;
}
+ if (phar_obj->arc.archive->is_tar) {
+ zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
+ "Cannot compress with Gzip compression, tar archives cannot compress individual files, use compress() to compress the whole archive");
+ return;
+ }
if (!pharobj_cancompress(&phar_obj->arc.archive->manifest TSRMLS_CC)) {
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
"Cannot compress all files as Gzip, some are compressed as bzip2 and cannot be uncompressed");
return;
}
- if (phar_obj->arc.archive->is_tar) {
- phar_obj->arc.archive->flags &= ~PHAR_FILE_COMPRESSION_MASK;
- phar_obj->arc.archive->flags |= PHAR_FILE_COMPRESSED_GZ;
- } else {
- pharobj_set_compression(&phar_obj->arc.archive->manifest, PHAR_ENT_COMPRESSED_GZ TSRMLS_CC);
- }
+ pharobj_set_compression(&phar_obj->arc.archive->manifest, PHAR_ENT_COMPRESSED_GZ TSRMLS_CC);
phar_obj->arc.archive->is_modified = 1;
- phar_rename_archive(phar_obj->arc.archive, NULL, 1 TSRMLS_CC);
phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC);
if (error) {
@@ -2499,20 +2630,19 @@ PHP_METHOD(Phar, compressAllFilesBZIP2)
"Cannot compress with Bzip2 compression, bz2 extension is not enabled");
return;
}
+ if (phar_obj->arc.archive->is_tar) {
+ zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
+ "Cannot compress with Bzip2 compression, tar archives cannot compress individual files, use compress() to compress the whole archive");
+ return;
+ }
if (!pharobj_cancompress(&phar_obj->arc.archive->manifest TSRMLS_CC)) {
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
"Cannot compress all files as Bzip2, some are compressed as gzip and cannot be uncompressed");
return;
}
- if (phar_obj->arc.archive->is_tar) {
- phar_obj->arc.archive->flags &= ~PHAR_FILE_COMPRESSION_MASK;
- phar_obj->arc.archive->flags |= PHAR_FILE_COMPRESSED_BZ2;
- } else {
- pharobj_set_compression(&phar_obj->arc.archive->manifest, PHAR_ENT_COMPRESSED_BZ2 TSRMLS_CC);
- }
+ pharobj_set_compression(&phar_obj->arc.archive->manifest, PHAR_ENT_COMPRESSED_BZ2 TSRMLS_CC);
phar_obj->arc.archive->is_modified = 1;
- phar_rename_archive(phar_obj->arc.archive, NULL, 1 TSRMLS_CC);
phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC);
if (error) {
@@ -2541,19 +2671,19 @@ PHP_METHOD(Phar, uncompressAllFiles)
return;
}
if (phar_obj->arc.archive->is_tar) {
- phar_obj->arc.archive->flags &= ~PHAR_FILE_COMPRESSION_MASK;
+ RETURN_TRUE;
} else {
pharobj_set_compression(&phar_obj->arc.archive->manifest, PHAR_ENT_COMPRESSED_NONE TSRMLS_CC);
}
phar_obj->arc.archive->is_modified = 1;
- phar_rename_archive(phar_obj->arc.archive, NULL, 0 TSRMLS_CC);
phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC);
if (error) {
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, error);
efree(error);
}
+ RETURN_TRUE;
}
/* }}} */
@@ -3534,13 +3664,12 @@ ZEND_END_ARG_INFO();
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_conv, 0, 0, 0)
- ZEND_ARG_INFO(0, compression_type)
ZEND_ARG_INFO(0, file_ext)
ZEND_END_ARG_INFO();
static
-ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_convz, 0, 0, 0)
- ZEND_ARG_INFO(0, file_ext)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_comp, 0, 0, 1)
+ ZEND_ARG_INFO(0, compression_type)
ZEND_END_ARG_INFO();
static
@@ -3599,11 +3728,12 @@ zend_function_entry php_archive_methods[] = {
#else
PHP_ME(Phar, __construct, arginfo_phar___construct, ZEND_ACC_PUBLIC)
PHP_ME(Phar, buildFromIterator, arginfo_phar_build, ZEND_ACC_PUBLIC)
+ PHP_ME(Phar, compress, arginfo_phar_comp, ZEND_ACC_PUBLIC)
PHP_ME(Phar, compressAllFilesBZIP2, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Phar, compressAllFilesGZ, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Phar, convertToPhar, arginfo_phar_conv, ZEND_ACC_PUBLIC)
PHP_ME(Phar, convertToTar, arginfo_phar_conv, ZEND_ACC_PUBLIC)
- PHP_ME(Phar, convertToZip, arginfo_phar_convz, ZEND_ACC_PUBLIC)
+ PHP_ME(Phar, convertToZip, arginfo_phar_conv, ZEND_ACC_PUBLIC)
PHP_ME(Phar, copy, arginfo_phar_copy, ZEND_ACC_PUBLIC)
PHP_ME(Phar, count, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Phar, delete, arginfo_phar_delete, ZEND_ACC_PUBLIC)
@@ -3621,6 +3751,8 @@ zend_function_entry php_archive_methods[] = {
PHP_ME(Phar, isPhar, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Phar, isTar, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Phar, isZip, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Phar, convertToExecutable, arginfo_phar_conv, ZEND_ACC_PUBLIC)
+ PHP_ME(Phar, convertToData, arginfo_phar_conv, ZEND_ACC_PUBLIC)
PHP_ME(Phar, offsetExists, arginfo_phar_offsetExists, ZEND_ACC_PUBLIC)
PHP_ME(Phar, offsetGet, arginfo_phar_offsetExists, ZEND_ACC_PUBLIC)
PHP_ME(Phar, offsetSet, arginfo_phar_offsetSet, ZEND_ACC_PUBLIC)
@@ -3732,6 +3864,7 @@ void phar_object_init(TSRMLS_D) /* {{{ */
REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "BZ2", PHAR_ENT_COMPRESSED_BZ2)
REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "GZ", PHAR_ENT_COMPRESSED_GZ)
+ REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "NONE", PHAR_ENT_COMPRESSED_NONE)
REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "COMPRESSED", PHAR_ENT_COMPRESSION_MASK)
REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "PHP", PHAR_MIME_PHP)
REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "PHPS", PHAR_MIME_PHPS)
diff --git a/ext/phar/tests/phar_convert_repeated_b.phpt b/ext/phar/tests/phar_convert_repeated_b.phpt
index 9e5b403cc9..229d654a0d 100644
--- a/ext/phar/tests/phar_convert_repeated_b.phpt
+++ b/ext/phar/tests/phar_convert_repeated_b.phpt
@@ -3,7 +3,6 @@ PharData::convertToZip|Tar|Phar() repeated (phardata_based archives)
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip"); ?>
--INI--
-phar.require_hash=0
phar.readonly=0
--FILE--
<?php
@@ -24,7 +23,7 @@ var_dump($phar->getAlias());
echo "================= convertToTar() =====================\n";
-$phar->convertToTar(Phar::GZ);
+$phar = $phar->convertToTar();
var_dump($phar->isPhar());
var_dump($phar->isTar());
var_dump($phar->isZip());
@@ -33,7 +32,7 @@ var_dump($phar->getAlias());
echo "================= convertToZip() =====================\n";
-$phar->convertToZip();
+$phar = $phar->convertToZip('.1.zip');
var_dump($phar->isPhar());
var_dump($phar->isTar());
var_dump($phar->isZip());
@@ -43,7 +42,7 @@ var_dump($phar->getAlias());
echo "================= convertToPhar() ====================\n";
try {
- $phar->convertToPhar();
+ $phar = $phar->convertToPhar();
var_dump($phar->isPhar());
var_dump($phar->isTar());
var_dump($phar->isZip());
@@ -55,7 +54,7 @@ try {
echo "================ convertToTar(GZ) ====================\n";
-$phar->convertToTar(Phar::GZ);
+$phar = $phar->convertToTar()->compress(Phar::GZ);
var_dump($phar->isPhar());
var_dump($phar->isTar());
var_dump($phar->isZip());
@@ -65,7 +64,7 @@ var_dump($phar->getAlias());
echo "================= convertToPhar() ====================\n";
try {
- $phar->convertToPhar();
+ $phar = $phar->convertToPhar();
var_dump($phar->isPhar());
var_dump($phar->isTar());
var_dump($phar->isZip());
@@ -80,8 +79,15 @@ try {
--CLEAN--
<?php
unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar');
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.tar');
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.tar.gz');
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.gz');
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.tar.gz');
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.tar');
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.zip');
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.1.zip');
?>
---EXPECT--
+--EXPECTF--
=================== new PharData() ==================
bool(false)
bool(false)
@@ -110,7 +116,8 @@ NULL
bool(false)
bool(true)
bool(false)
-string(0) ""
+string(60) "<?php // tar-based phar archive stub file
+__HALT_COMPILER();"
NULL
================= convertToPhar() ====================
bool(true)
@@ -119,3 +126,4 @@ bool(false)
int(6651)
NULL
===DONE===
+
diff --git a/ext/phar/util.c b/ext/phar/util.c
index aa3801ae0f..d3f198c9be 100644
--- a/ext/phar/util.c
+++ b/ext/phar/util.c
@@ -75,110 +75,6 @@ int phar_seek_efp(phar_entry_info *entry, off_t offset, int whence, off_t positi
return php_stream_seek(fp, temp, SEEK_SET);
}
-void phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool compress TSRMLS_DC)
-{
- char *oldname = NULL, *oldpath = NULL;
- char *basename = NULL, *basepath = NULL;
- char *newname = NULL, *newpath = NULL;
- dtor_func_t save;
-
- if (phar->flags && compress) {
- char *error;
-
- phar_flush(phar, 0, 0, 0, &error TSRMLS_CC);
- if (error) {
- zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, error);
- efree(error);
- }
- }
-
- if (!ext) {
- if (phar->is_zip) {
- if (phar->is_data) {
- ext = "zip";
- } else {
- ext = "phar.zip";
- }
- } else if (phar->is_tar) {
- switch (phar->flags) {
- case PHAR_FILE_COMPRESSED_GZ:
- if (phar->is_data) {
- ext = "tar.gz";
- } else {
- ext = "phar.tar.gz";
- }
- break;
- case PHAR_FILE_COMPRESSED_BZ2:
- if (phar->is_data) {
- ext = "tar.bz2";
- } else {
- ext = "phar.tar.bz2";
- }
- break;
- default:
- if (phar->is_data) {
- ext = "tar";
- } else {
- ext = "phar.tar";
- }
- }
- } else {
- switch (phar->flags) {
- case PHAR_FILE_COMPRESSED_GZ:
- ext = "phar.gz";
- break;
- case PHAR_FILE_COMPRESSED_BZ2:
- ext = "phar.bz2";
- break;
- default:
- ext = "phar";
- }
- }
- }
-
- if (ext[0] == '.') {
- ++ext;
- }
-
- oldpath = estrndup(phar->fname, phar->fname_len);
- oldname = strrchr(phar->fname, '/');
- ++oldname;
-
- basename = estrndup(oldname, strlen(oldname));
- spprintf(&newname, 0, "%s.%s", strtok(basename, "."), ext);
- efree(basename);
-
- basepath = estrndup(oldpath, strlen(oldpath) - strlen(oldname));
- spprintf(&newpath, 0, "%s%s", basepath, newname);
- efree(basepath);
- efree(newname);
-
- if (!phar->is_data) {
- if (phar->alias) {
- efree(phar->alias);
- }
- phar->alias = estrndup(newpath, strlen(newpath));
- phar->alias_len = strlen(newpath);
- zend_hash_update(&(PHAR_GLOBALS->phar_alias_map), newpath, strlen(newpath), (void*)&phar, sizeof(phar_archive_data*), NULL);
- }
-
- /* remove old guy, add new guy */
- save = PHAR_GLOBALS->phar_fname_map.pDestructor;
- /* don't destruct, we are only renaming */
- PHAR_GLOBALS->phar_fname_map.pDestructor = NULL;
- zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), oldpath, phar->fname_len);
- PHAR_GLOBALS->phar_fname_map.pDestructor = save;
- zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), newpath, strlen(newpath), (void*)&phar, sizeof(phar_archive_data*), NULL);
-
- efree(phar->fname);
-
- phar->fname = newpath;
- phar->fname_len = strlen(newpath);
-
- unlink(oldpath);
- efree(oldpath);
-}
-
/* mount an absolute path or uri to a path internal to the phar archive */
int phar_mount_entry(phar_archive_data *phar, char *filename, int filename_len, char *path, int path_len TSRMLS_DC)
{