]> granicus.if.org Git - php/commitdiff
A bunch of stuff to do with filename conversion. Hopefully it won't sink the ship.
authorSteph Fox <sfox@php.net>
Sun, 24 Feb 2008 22:29:06 +0000 (22:29 +0000)
committerSteph Fox <sfox@php.net>
Sun, 24 Feb 2008 22:29:06 +0000 (22:29 +0000)
ext/phar/TODO
ext/phar/dirstream.c
ext/phar/phar.c
ext/phar/phar_internal.h
ext/phar/phar_object.c
ext/phar/stream.c
ext/phar/tar.c
ext/phar/util.c
ext/phar/zip.c

index 7130121857bc2946cfd6ccd87439e7a3e6721d1b..32053f265688af6fa97e436797d15826c61c7191 100644 (file)
@@ -78,15 +78,14 @@ Version 2.0.0
    storing sqlite databases, cache, or template files in a location external to the phar.  Copy of the files
    would need to be performed in an installation step, phar would not attempt to do this for performance and
    security reasons.
- * make convertToZip/convertToTar rename files and return the new filename.  Also, convertToPhar() with full
-   file compression should rename to append .gz or .bz
+ X make convertToZip/convertToTar rename files [Steph]
+ X make convertTo*() with full file compression rename to append .gz or .bz2 [Steph]
  * don't automatically add a stub to .zip or .tar files
- * don't allow a stub to be added to a .zip/.tar that does not have ".phar" in the filename somewhere
+ * don't allow a stub to be added to a .zip/.tar that does not have ".phar" in the filename
  * allow read/write on .tar/.zip files that do not contain a stub or alias file
  * prevent manual addition of stub via $a['.phar/stub.php'] = '<?php my stub';
- X make createDefaultStub() setDefaultStub() and have it file format-specific
-    so that zip/tar-based phars do not have a phar-specific stub [Steph]
- * convertTo*() should always use the default stub
+ X make createDefaultStub() setDefaultStub() and have it file format-specific [Steph]
+ X convertTo*() should always use the default stub [Steph]
  X ability to store empty directories [Greg]
  X tar support [Greg]
  X zip support [Greg]
index 22b68906d81bbf33ee1cb4cf9556f56eca53d31f..0819237376c7c6e3fdb82bc222be2767926fa878 100644 (file)
@@ -501,7 +501,7 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, char *url_from, int mode, in
                efree(entry.filename);
                return FAILURE;
        }
-       phar_flush(phar, 0, 0, &error TSRMLS_CC);
+       phar_flush(phar, 0, 0, 0, &error TSRMLS_CC);
        if (error) {
                php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot create directory \"%s\" in phar \"%s\", %s", entry.filename, phar->fname, error);
                zend_hash_del(&phar->manifest, entry.filename, entry.filename_len);
@@ -576,7 +576,7 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_
        /* now for the easy part */
        entry->is_deleted = 1;
        entry->is_modified = 1;
-       phar_flush(phar, 0, 0, &error TSRMLS_CC);
+       phar_flush(phar, 0, 0, 0, &error TSRMLS_CC);
        if (error) {
                php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot create directory \"%s\" in phar \"%s\", %s", entry->filename, phar->fname, error);
                zend_hash_del(&phar->manifest, entry->filename, entry->filename_len);
index 1707259be52a81c1a5b629f145d8bd9f9940e2c3..d4c746e5d097b170ba06914db3917a9c62684aec 100644 (file)
@@ -343,7 +343,7 @@ void phar_entry_remove(phar_entry_data *idata, char **error TSRMLS_DC) /* {{{ */
                phar_entry_delref(idata TSRMLS_CC);
        }
        if (!phar->donotflush) {
-               phar_flush(phar, 0, 0, error TSRMLS_CC);
+               phar_flush(phar, 0, 0, 0, error TSRMLS_CC);
        }
 }
 /* }}} */
@@ -1749,7 +1749,7 @@ char *phar_create_default_stub(const char *index_php, const char *web_index, siz
  * user_stub contains either a string, or a resource pointer, if len is a negative length.
  * user_stub and len should be both 0 if the default or existing stub should be used
  */
-int phar_flush(phar_archive_data *phar, char *user_stub, long len, char **error TSRMLS_DC) /* {{{ */
+int phar_flush(phar_archive_data *phar, char *user_stub, long len, int convert, char **error TSRMLS_DC) /* {{{ */
 {
 /*     static const char newstub[] = "<?php __HALT_COMPILER(); ?>\r\n"; */
        char *newstub;
@@ -1777,11 +1777,12 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, char **error
        }
 
        if (phar->is_zip) {
-               return phar_zip_flush(phar, user_stub, len, error TSRMLS_CC);
+               return phar_zip_flush(phar, user_stub, len, convert, error TSRMLS_CC);
        }
        if (phar->is_tar) {
-               return phar_tar_flush(phar, user_stub, len, error TSRMLS_CC);
+               return phar_tar_flush(phar, user_stub, len, convert, error TSRMLS_CC);
        }
+
        if (phar->fp && !phar->is_brandnew) {
                oldfile = phar->fp;
                closeoldfile = 0;
@@ -1868,8 +1869,8 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, char **error
                        efree(user_stub);
                }
        } else {
-               if (phar->halt_offset && oldfile && !phar->is_brandnew) {
-                       if (phar->halt_offset != php_stream_copy_to_stream(oldfile, newfile, phar->halt_offset)) {      
+               if (!user_stub && phar->halt_offset && oldfile && !phar->is_brandnew) {
+                       if (phar->halt_offset != php_stream_copy_to_stream(oldfile, newfile, phar->halt_offset)) {
                                if (closeoldfile) {
                                        php_stream_close(oldfile);
                                }
@@ -1880,7 +1881,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, char **error
                                return EOF;
                        }
                } else {
-                       /* this is a brand new phar */
+                       /* this is either a brand new phar or a default stub overwrite */
                        newstub = phar_create_default_stub(NULL, NULL, &(phar->halt_offset), NULL TSRMLS_CC);
                        if (phar->halt_offset != php_stream_write(newfile, newstub, phar->halt_offset)) {
                                efree(newstub);
index 7d18be8a0b0bb8bf3813de9df5ec971429712b85..ae01d5b3505b4f0ad20418bd444ea5ce4e2e9836 100755 (executable)
@@ -392,14 +392,13 @@ int phar_open_archive_fp(phar_archive_data *phar TSRMLS_DC);
 /* tar functions in tar.c */
 int phar_is_tar(char *buf);
 int phar_open_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, php_uint32 compression, char **error TSRMLS_DC);
-int phar_flush(phar_archive_data *archive, char *user_stub, long len, char **error TSRMLS_DC);
 int phar_open_or_create_tar(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
-int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, char **error TSRMLS_DC);
+int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defaultstub, char **error TSRMLS_DC);
 
 /* zip functions in zip.c */
 int phar_open_zipfile(php_stream *fp, char *fname, int fname_len, char *alias, int alias_len, phar_archive_data** pphar, char **error TSRMLS_DC);
 int phar_open_or_create_zip(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
-int phar_zip_flush(phar_archive_data *archive, char *user_stub, long len, char **error TSRMLS_DC);
+int phar_zip_flush(phar_archive_data *archive, char *user_stub, long len, int defaultstub, char **error TSRMLS_DC);
 
 #ifdef PHAR_MAIN
 static int phar_open_fp(php_stream* fp, char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
@@ -413,7 +412,7 @@ phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, int pa
 phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, int path_len, char dir, char **error TSRMLS_DC);
 phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char *path, int path_len, char *mode, char allow_dir, char **error TSRMLS_DC);
 int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len, char *path, int path_len, char *mode, char allow_dir, char **error TSRMLS_DC);
-int phar_flush(phar_archive_data *archive, char *user_stub, long len, char **error TSRMLS_DC);
+int phar_flush(phar_archive_data *archive, char *user_stub, long len, int convert, char **error TSRMLS_DC);
 int phar_detect_phar_fname_ext(const char *filename, int check_length, char **ext_str, int *ext_len);
 int phar_split_fname(char *filename, int filename_len, char **arch, int *arch_len, char **entry, int *entry_len TSRMLS_DC);
 
index 1b40ce5bc44b517b888b183067b2f63fca04ca67..4f49241b0701c95fc26aaf682959462efa270675 100755 (executable)
@@ -1452,7 +1452,7 @@ PHP_METHOD(Phar, buildFromIterator)
        pass.ret = return_value;
 
        if (SUCCESS == spl_iterator_apply(obj, (spl_iterator_apply_func_t) phar_build, (void *) &pass TSRMLS_CC)) {
-               phar_flush(phar_obj->arc.archive, 0, 0, &error TSRMLS_CC);
+               phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC);
                if (error) {
                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
                        efree(error);
@@ -1560,13 +1560,10 @@ static int phar_restore_apply(void *data TSRMLS_DC) /* {{{ */
 }
 /* }}} */
 
-static void phar_convert_to_other(phar_archive_data *source, int convert, php_uint32 flags TSRMLS_DC) /* {{{ */
+static void phar_convert_to_other(phar_archive_data *source, int convert, char *ext, php_uint32 flags TSRMLS_DC) /* {{{ */
 {
        phar_archive_data phar = {0};
        char *error;
-       zval *userz;
-       long tmp;
-       php_stream *fp;
        phar_entry_info *entry, newentry;
 
        /* set whole-archive compression from parameter */
@@ -1596,17 +1593,6 @@ static void phar_convert_to_other(phar_archive_data *source, int convert, php_ui
                        zend_hash_apply(&source->manifest, phar_restore_apply TSRMLS_CC);
                        return;
                }
-               if (!convert) {
-                       /* converting to Phar */
-                       if (entry->filename_len == sizeof(".phar/stub.php")-1 && !strncmp(entry->filename, ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
-                               /* do not copy stub file */
-                               continue;
-                       }
-                       if (entry->filename_len == sizeof(".phar/alias.txt")-1 && !strncmp(entry->filename, ".phar/alias.txt", sizeof(".phar/alias.txt")-1)) {
-                               /* do not copy alias file */
-                               continue;
-                       }
-               }
                if (entry->fp_refcount > 0) {
                        zend_hash_destroy(&(phar.manifest));
                        php_stream_close(phar.fp);
@@ -1651,41 +1637,7 @@ static void phar_convert_to_other(phar_archive_data *source, int convert, php_ui
                zend_hash_add(&(phar.manifest), newentry.filename, newentry.filename_len, (void*)&newentry, sizeof(phar_entry_info), NULL);
        }
 
-       /* next copy the stub and flush */
-
-       if (source->is_tar || source->is_zip) {
-               if (FAILURE == (zend_hash_find(&source->manifest, ".phar/stub.php", sizeof(".phar/stub.php")-1, (void **)&entry))) {
-                       /* use default stub - the existing one in the manifest will be used if present */
-                       phar_flush(&phar, NULL, 0, &error TSRMLS_CC);
-                       goto finalize;
-               }
-               fp = php_stream_open_wrapper(source->fname, "rb", IGNORE_URL|STREAM_MUST_SEEK|0, NULL);
-               php_stream_seek(fp, entry->offset, SEEK_SET);
-               /* use this unused value to set the stub size */
-               source->internal_file_start = entry->uncompressed_filesize;
-       } else {
-               fp = php_stream_open_wrapper(source->fname, "rb", IGNORE_URL|STREAM_MUST_SEEK|0, NULL);
-       }
-       /* copy the other phar's stub */
-       ALLOC_ZVAL(userz);
-       php_stream_to_zval(fp, userz);
-       tmp = source->internal_file_start;
-       source->internal_file_start = 0;
-       phar_flush(&phar, (char *) &userz, -tmp, &error TSRMLS_CC);
-       php_stream_close(fp);
-       efree(userz);
-
-       if (error) {
-               zend_hash_destroy(&(phar.manifest));
-               zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
-                       "Cannot convert phar archive \"%s\": %s", source->fname, error);
-               efree(error);
-               php_stream_close(phar.fp);
-               return;
-       }
-
-finalize:
-       /* third, update the old phar's manifest */
+       /* 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)) {
@@ -1696,32 +1648,6 @@ finalize:
                        return;
                }
                if (FAILURE == zend_hash_find(&source->manifest, entry->filename, entry->filename_len, (void **) &mine)) {
-                       if (phar.is_tar || phar.is_zip) {
-                               if (entry->filename_len == sizeof(".phar/stub.php")-1 && !strncmp(entry->filename, ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
-                                       /* a little hack to prevent destruction of data */
-                                       dtor_func_t save;
-
-                                       entry->phar = source;
-                                       save = phar.manifest.pDestructor;
-                                       phar.manifest.pDestructor = NULL;
-                                       zend_hash_add(&source->manifest, ".phar/stub.php", sizeof(".phar/stub.php")-1, (void*)entry, sizeof(phar_entry_info), NULL);
-                                       zend_hash_del(&(phar.manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1);
-                                       phar.manifest.pDestructor = save;
-                                       continue;
-                               }
-                               if (entry->filename_len == sizeof(".phar/alias.txt")-1 && !strncmp(entry->filename, ".phar/alias.txt", sizeof(".phar/alias.txt")-1)) {
-                                       /* a little hack to prevent destruction of data */
-                                       dtor_func_t save;
-
-                                       entry->phar = source;
-                                       save = phar.manifest.pDestructor;
-                                       phar.manifest.pDestructor = NULL;
-                                       zend_hash_add(&source->manifest, ".phar/alias.txt", sizeof(".phar/alias.txt")-1, (void*)entry, sizeof(phar_entry_info), NULL);
-                                       zend_hash_del(&(phar.manifest), ".phar/alias.txt", sizeof(".phar/alias.txt")-1);
-                                       phar.manifest.pDestructor = save;
-                                       continue;
-                               }
-                       }
                        zend_hash_destroy(&(phar.manifest));
                        php_stream_close(phar.fp);
                        /* we can't throw an exception or bad crap will happen */
@@ -1748,10 +1674,10 @@ finalize:
        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;
        }
-       source->is_tar = phar.is_tar;
        if (source->signature) {
                efree(source->signature);
        }
@@ -1760,21 +1686,34 @@ finalize:
        } else {
                source->signature = 0;
        }
+       if (source->alias) {
+               efree(source->alias);
+       }
+       source->alias = NULL;
+       source->alias_len = 0;
+       source->is_temporary_alias = 0;
+       source->flags = phar.flags;
+
+       phar_rename_archive(source, ext TSRMLS_CC);
+       phar_flush(source, 0, 0, convert, &error TSRMLS_CC);
 }
 /* }}} */
 
-/* {{{ proto bool Phar::convertToTar([int compression])
- * Convert the phar archive to the tar file format.  The optional parameter can be one of Phar::GZ
- * or Phar::BZ2 to specify whole-file compression
+/* {{{ proto bool Phar::convertToTar([int compression, [string extension]])
+ * Convert the phar 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 filename extension
+ * (default is phar.tar). Both parameters are optional.
  */
 PHP_METHOD(Phar, convertToTar)
 {
-       char *error;
+       char *error, *ext = NULL;
        php_uint32 flags;
        long method = 0;
+       int ext_len = 0;
        PHAR_ARCHIVE_OBJECT();
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &method) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ls", &method, &ext, &ext_len) == FAILURE) {
                return;
        }
 
@@ -1814,26 +1753,13 @@ PHP_METHOD(Phar, convertToTar)
                return;
        }
 
-       if (!zend_hash_num_elements(&phar_obj->arc.archive->manifest)) {
-               /* nothing need be done specially, this has no files in it */
-               phar_obj->arc.archive->is_tar = 1;
-               phar_obj->arc.archive->is_modified = 1;
-               RETURN_TRUE;
-       }
-
        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;
        }
 
-       phar_flush(phar_obj->arc.archive, NULL, 0, &error TSRMLS_CC);
-       if (error) {
-               zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
-               efree(error);
-               return;
-       }
-       phar_convert_to_other(phar_obj->arc.archive, 1, flags TSRMLS_CC);
+       phar_convert_to_other(phar_obj->arc.archive, 1, ext, flags TSRMLS_CC);
        RETURN_TRUE;
 }
 /* }}} */
@@ -1843,8 +1769,13 @@ PHP_METHOD(Phar, convertToTar)
  */
 PHP_METHOD(Phar, convertToZip)
 {
-       char *error;
+       char *error, *ext = NULL;
+       int ext_len = 0;
        PHAR_ARCHIVE_OBJECT();
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &ext) == FAILURE) {
+               return;
+       }
        
        if (phar_obj->arc.archive->is_zip) {
                RETURN_TRUE;
@@ -1861,29 +1792,26 @@ PHP_METHOD(Phar, convertToZip)
                return;
        }
 
-       phar_flush(phar_obj->arc.archive, NULL, 0, &error TSRMLS_CC);
-       if (error) {
-               zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
-               efree(error);
-               return;
-       }
-       phar_convert_to_other(phar_obj->arc.archive, 2, 0 TSRMLS_CC);
+       phar_convert_to_other(phar_obj->arc.archive, 2, ext, 0 TSRMLS_CC);
        RETURN_TRUE;
 }
 /* }}} */
 
-/* {{{ proto bool Phar::convertToPhar([int compression])
- * Convert the phar archive to the phar file format.  The optional parameter can be one of Phar::GZ
- * or Phar::BZ2 to specify whole-file compression
+/* {{{ proto bool Phar::convertToPhar([int compression, [bool rename]])
+ * Convert the phar 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 determines whether the filename should be changed to
+ * reflect the new type (on by default). Both parameters are optional.
  */
 PHP_METHOD(Phar, convertToPhar)
 {
-       char *error;
+       char *error, *ext = NULL;
        php_uint32 flags;
        long method = 0;
+       int ext_len = 0;
        PHAR_ARCHIVE_OBJECT();
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &method) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ls", &method, &ext, &ext_len) == FAILURE) {
                return;
        }
 
@@ -1929,28 +1857,7 @@ PHP_METHOD(Phar, convertToPhar)
                return;
        }
 
-       if (!zend_hash_num_elements(&phar_obj->arc.archive->manifest)) {
-               /* nothing need be done specially, this has no files in it */
-               phar_obj->arc.archive->is_tar = 0;
-               phar_obj->arc.archive->is_zip = 0;
-               phar_obj->arc.archive->is_modified = 1;
-               RETURN_TRUE;
-       }
-
-       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;
-       }
-
-       phar_flush(phar_obj->arc.archive, NULL, 0, &error TSRMLS_CC);
-       if (error) {
-               zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
-               efree(error);
-               return;
-       }
-               
-       phar_convert_to_other(phar_obj->arc.archive, 0, flags TSRMLS_CC);
+       phar_convert_to_other(phar_obj->arc.archive, 0, ext, flags TSRMLS_CC);
        RETURN_TRUE;
 }
 /* }}} */
@@ -2009,7 +1916,7 @@ PHP_METHOD(Phar, delete)
                RETURN_FALSE;
        }
 
-       phar_flush(phar_obj->arc.archive, NULL, 0, &error TSRMLS_CC);
+       phar_flush(phar_obj->arc.archive, NULL, 0, 0, &error TSRMLS_CC);
        if (error) {
                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
                efree(error);
@@ -2074,7 +1981,7 @@ PHP_METHOD(Phar, setAlias)
                phar_obj->arc.archive->alias_len = alias_len;
                phar_obj->arc.archive->is_temporary_alias = 0;
 
-               phar_flush(phar_obj->arc.archive, NULL, 0, &error TSRMLS_CC);
+               phar_flush(phar_obj->arc.archive, NULL, 0, 0, &error TSRMLS_CC);
                if (error) {
                        phar_obj->arc.archive->alias = oldalias;
                        phar_obj->arc.archive->alias_len = oldalias_len;
@@ -2146,7 +2053,7 @@ PHP_METHOD(Phar, stopBuffering)
 
        phar_obj->arc.archive->donotflush = 0;
 
-       phar_flush(phar_obj->arc.archive, 0, 0, &error TSRMLS_CC);
+       phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC);
        if (error) {
                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
                efree(error);
@@ -2179,7 +2086,7 @@ PHP_METHOD(Phar, setStub)
                        } else {
                                len = -1;
                        }
-                       phar_flush(phar_obj->arc.archive, (char *) &zstub, len, &error TSRMLS_CC);
+                       phar_flush(phar_obj->arc.archive, (char *) &zstub, len, 0, &error TSRMLS_CC);
                        if (error) {
                                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
                                efree(error);
@@ -2190,7 +2097,7 @@ PHP_METHOD(Phar, setStub)
                                "Cannot change stub, unable to read from input stream");
                }
        } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &stub, &stub_len) == SUCCESS) {
-               phar_flush(phar_obj->arc.archive, stub, stub_len, &error TSRMLS_CC);
+               phar_flush(phar_obj->arc.archive, stub, stub_len, 0, &error TSRMLS_CC);
                if (error) {
                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
                        efree(error);
@@ -2210,8 +2117,7 @@ PHP_METHOD(Phar, setStub)
  */
  PHP_METHOD(Phar, setDefaultStub)
 {
-       char *index = NULL, *webindex = NULL, *error = NULL;
-       char *stub = "dummy";
+       char *index = NULL, *webindex = NULL, *error = NULL, *stub = NULL;
        int index_len = 0, webindex_len = 0, created_stub = 0;
        size_t stub_len = 0;
        PHAR_ARCHIVE_OBJECT();
@@ -2232,6 +2138,7 @@ PHP_METHOD(Phar, setStub)
        }
 
        if (!phar_obj->arc.archive->is_tar && !phar_obj->arc.archive->is_zip) {
+
                stub = phar_create_default_stub(index, webindex, &stub_len, &error TSRMLS_CC);
 
                if (error) {
@@ -2245,7 +2152,8 @@ PHP_METHOD(Phar, setStub)
                created_stub = 1;
        }
 
-       phar_flush(phar_obj->arc.archive, stub, stub_len, &error TSRMLS_CC);
+       phar_flush(phar_obj->arc.archive, stub, stub_len, 1, &error TSRMLS_CC);
+
        if (created_stub) {
                efree(stub);
        }
@@ -2306,7 +2214,7 @@ PHP_METHOD(Phar, setSignatureAlgorithm)
                        phar_obj->arc.archive->sig_flags = algo;
                        phar_obj->arc.archive->is_modified = 1;
 
-                       phar_flush(phar_obj->arc.archive, 0, 0, &error TSRMLS_CC);
+                       phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC);
                        if (error) {
                                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
                                efree(error);
@@ -2443,7 +2351,7 @@ PHP_METHOD(Phar, compressAllFilesGZ)
        }
        phar_obj->arc.archive->is_modified = 1;
        
-       phar_flush(phar_obj->arc.archive, 0, 0, &error 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);
@@ -2482,7 +2390,7 @@ PHP_METHOD(Phar, compressAllFilesBZIP2)
        }
        phar_obj->arc.archive->is_modified = 1;
        
-       phar_flush(phar_obj->arc.archive, 0, 0, &error 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);
@@ -2515,7 +2423,7 @@ PHP_METHOD(Phar, uncompressAllFiles)
        }
        phar_obj->arc.archive->is_modified = 1;
        
-       phar_flush(phar_obj->arc.archive, 0, 0, &error 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);
@@ -2604,7 +2512,7 @@ PHP_METHOD(Phar, copy)
        zend_hash_add(&oldentry->phar->manifest, newfile, newfile_len, (void*)&newentry, sizeof(phar_entry_info), NULL);
        phar_obj->arc.archive->is_modified = 1;
 
-       phar_flush(phar_obj->arc.archive, 0, 0, &error TSRMLS_CC);
+       phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC);
        if (error) {
                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
                efree(error);
@@ -2721,7 +2629,7 @@ PHP_METHOD(Phar, offsetSet)
                        data->internal_file->compressed_filesize = data->internal_file->uncompressed_filesize = contents_len;
                }
                phar_entry_delref(data TSRMLS_CC);
-               phar_flush(phar_obj->arc.archive, 0, 0, &error TSRMLS_CC);
+               phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC);
                if (error) {
                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
                        efree(error);
@@ -2758,7 +2666,7 @@ PHP_METHOD(Phar, offsetUnset)
                        entry->is_modified = 0;
                        entry->is_deleted = 1;
                        /* we need to "flush" the stream to save the newly deleted file on disk */
-                       phar_flush(phar_obj->arc.archive, 0, 0, &error TSRMLS_CC);
+                       phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC);
                        if (error) {
                                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
                                efree(error);
@@ -2912,7 +2820,7 @@ PHP_METHOD(Phar, setMetadata)
        MAKE_STD_ZVAL(phar_obj->arc.archive->metadata);
        ZVAL_ZVAL(phar_obj->arc.archive->metadata, metadata, 1, 0);
 
-       phar_flush(phar_obj->arc.archive, 0, 0, &error TSRMLS_CC);
+       phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC);
        if (error) {
                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
                efree(error);
@@ -2936,7 +2844,7 @@ PHP_METHOD(Phar, delMetadata)
                zval_ptr_dtor(&phar_obj->arc.archive->metadata);
                phar_obj->arc.archive->metadata = NULL;
 
-               phar_flush(phar_obj->arc.archive, 0, 0, &error TSRMLS_CC);
+               phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC);
                if (error) {
                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
                        efree(error);
@@ -3168,7 +3076,7 @@ PHP_METHOD(PharFileInfo, chmod)
        BG(CurrentLStatFile) = NULL;
        BG(CurrentStatFile) = NULL;
 
-       phar_flush(entry_obj->ent.entry->phar, 0, 0, &error TSRMLS_CC);
+       phar_flush(entry_obj->ent.entry->phar, 0, 0, 0, &error TSRMLS_CC);
        if (error) {
                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
                efree(error);
@@ -3235,7 +3143,7 @@ PHP_METHOD(PharFileInfo, setMetadata)
        MAKE_STD_ZVAL(entry_obj->ent.entry->metadata);
        ZVAL_ZVAL(entry_obj->ent.entry->metadata, metadata, 1, 0);
 
-       phar_flush(entry_obj->ent.entry->phar, 0, 0, &error TSRMLS_CC);
+       phar_flush(entry_obj->ent.entry->phar, 0, 0, 0, &error TSRMLS_CC);
        if (error) {
                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
                efree(error);
@@ -3262,7 +3170,7 @@ PHP_METHOD(PharFileInfo, delMetadata)
                zval_ptr_dtor(&entry_obj->ent.entry->metadata);
                entry_obj->ent.entry->metadata = NULL;
 
-               phar_flush(entry_obj->ent.entry->phar, 0, 0, &error TSRMLS_CC);
+               phar_flush(entry_obj->ent.entry->phar, 0, 0, 0, &error TSRMLS_CC);
                if (error) {
                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
                        efree(error);
@@ -3319,7 +3227,7 @@ PHP_METHOD(PharFileInfo, setCompressedGZ)
        entry_obj->ent.entry->phar->is_modified = 1;
        entry_obj->ent.entry->is_modified = 1;
 
-       phar_flush(entry_obj->ent.entry->phar, 0, 0, &error TSRMLS_CC);
+       phar_flush(entry_obj->ent.entry->phar, 0, 0, 0, &error TSRMLS_CC);
        if (error) {
                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
                efree(error);
@@ -3375,7 +3283,7 @@ PHP_METHOD(PharFileInfo, setCompressedBZIP2)
        entry_obj->ent.entry->phar->is_modified = 1;
        entry_obj->ent.entry->is_modified = 1;
 
-       phar_flush(entry_obj->ent.entry->phar, 0, 0, &error TSRMLS_CC);
+       phar_flush(entry_obj->ent.entry->phar, 0, 0, 0, &error TSRMLS_CC);
        if (error) {
                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
                efree(error);
@@ -3432,7 +3340,7 @@ PHP_METHOD(PharFileInfo, setUncompressed)
        entry_obj->ent.entry->phar->is_modified = 1;
        entry_obj->ent.entry->is_modified = 1;
 
-       phar_flush(entry_obj->ent.entry->phar, 0, 0, &error TSRMLS_CC);
+       phar_flush(entry_obj->ent.entry->phar, 0, 0, 0, &error TSRMLS_CC);
        if (error) {
                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
                efree(error);
index ac6aacef90f5d5d0dd5b91bb2c71ad0fcb2e915a..deeb968e6e73d6e8ce811ce02e4e4d1b7fdbf179 100644 (file)
@@ -393,7 +393,7 @@ static int phar_stream_flush(php_stream *stream TSRMLS_DC) /* {{{ */
        char *error;
        int ret;
        if (stream->mode[0] == 'w' || (stream->mode[0] == 'r' && stream->mode[1] == '+')) {
-               ret = phar_flush(((phar_entry_data *)stream->abstract)->phar, 0, 0, &error TSRMLS_CC);
+               ret = phar_flush(((phar_entry_data *)stream->abstract)->phar, 0, 0, 0, &error TSRMLS_CC);
                if (error) {
                        php_stream_wrapper_log_error(stream->wrapper, REPORT_ERRORS TSRMLS_CC, error);
                        efree(error);
@@ -803,7 +803,7 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char
                }
                entry->is_modified = 1;
                entry->filename_len = strlen(entry->filename);
-               phar_flush(phar, 0, 0, &error TSRMLS_CC);
+               phar_flush(phar, 0, 0, 0, &error TSRMLS_CC);
                if (error) {
                        php_url_free(resource_from);
                        php_url_free(resource_to);
index 10cd0655d852a713d9d887d198c6214ef6dfd472..52ab15cc3e04dda82b0535daad7a5495dd80d12b 100644 (file)
@@ -442,7 +442,7 @@ int phar_tar_writeheaders(void *pDest, void *argument TSRMLS_DC)
        return ZEND_HASH_APPLY_KEEP;
 }
 
-int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, char **error TSRMLS_DC) /* {{{ */
+int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defaultstub, char **error TSRMLS_DC) /* {{{ */
 {
        phar_entry_info entry = {0};
        static const char newstub[] = "<?php // tar-based phar archive stub file\n__HALT_COMPILER();";
@@ -460,7 +460,6 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, char **er
        entry.phar = phar;
        entry.fp_type = PHAR_MOD;
 
-
        /* set alias */
        if (!phar->is_temporary_alias && phar->alias_len) {
                entry.filename = estrndup(".phar/alias.txt", sizeof(".phar/alias.txt")-1);
@@ -485,7 +484,7 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, char **er
        }
 
        /* set stub */
-       if (user_stub && len) {
+       if (user_stub && !defaultstub) {
                char *pos;
                if (len < 0) {
                        /* resource passed in */
@@ -543,8 +542,9 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, char **er
                        efree(user_stub);
                }
        } else {
-               /* Either this is a brand new phar (add the stub), or setDefaultStub() is the caller (overwrite the stub) */
+               /* Either this is a brand new phar (add the stub), or the default stub is required (overwrite the stub) */
                entry.fp = php_stream_fopen_tmpfile();
+
                if (sizeof(newstub)-1 != php_stream_write(entry.fp, newstub, sizeof(newstub)-1)) {
                        php_stream_close(entry.fp);
                        if (error) {
@@ -552,11 +552,12 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, char **er
                        }
                        return EOF;
                }
+
                entry.uncompressed_filesize = entry.compressed_filesize = sizeof(newstub) - 1;
                entry.filename = estrndup(".phar/stub.php", sizeof(".phar/stub.php")-1);
                entry.filename_len = sizeof(".phar/stub.php")-1;
 
-               if (!user_stub) {
+               if (!defaultstub) {
                        if (!zend_hash_exists(&phar->manifest, ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
                                if (SUCCESS != zend_hash_add(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {
                                        php_stream_close(entry.fp);
index 92227ffe79606847f3a9daf4177b98eee9312fd1..50c3371f463ee90523d6f6190c2e1f7a9f79e781 100644 (file)
@@ -72,6 +72,74 @@ 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 TSRMLS_DC) {
+
+       char *oldname = NULL, *oldpath = NULL;
+       char *basename = NULL, *basepath = NULL;
+       char *newname = NULL, *newpath = NULL;
+
+       if (!ext) {
+               if (phar->is_zip) {
+                       ext = "phar.zip";
+               } else if (phar->is_tar) {
+                       switch (phar->flags) {
+                               case PHAR_FILE_COMPRESSED_GZ:
+                                       ext = "phar.tar.gz";
+                                       break;
+                               case PHAR_FILE_COMPRESSED_BZ2:
+                                       ext = "phar.tar.bz2";
+                                       break;
+                               default:
+                                       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_zip && !phar->is_tar) {
+               phar->alias = estrndup(newpath, strlen(newpath));
+               phar->alias_len = strlen(newpath);
+               zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), newpath, strlen(newpath), (void*)&phar, sizeof(phar_archive_data*), NULL);
+       }
+
+       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)
 {
index 7ae5a8626136d66e6ffc67cbed01e5dd023d16f6..166fd2ae7c6307c060beb93d58329a30bb9553b2 100644 (file)
@@ -641,7 +641,7 @@ continue_dir:
 }
 /* }}} */
 
-int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, char **error TSRMLS_DC) /* {{{ */
+int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defaultstub, char **error TSRMLS_DC) /* {{{ */
 {
        char *pos;
        smart_str main_metadata_str = {0};
@@ -691,7 +691,7 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, char **er
        }
 
        /* set stub */
-       if (user_stub && len) {
+       if (user_stub && !defaultstub) {
                if (len < 0) {
                        /* resource passed in */
                        if (!(php_stream_from_zval_no_verify(stubfile, (zval **)user_stub))) {
@@ -756,8 +756,9 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, char **er
                        efree(user_stub);
                }
        } else {
-               /* Either this is a brand new phar (add the stub), or setDefaultStub() is the caller (overwrite the stub) */
+               /* Either this is a brand new phar (add the stub), or the default stub is required (overwrite the stub) */
                entry.fp = php_stream_fopen_tmpfile();
+
                if (sizeof(newstub)-1 != php_stream_write(entry.fp, newstub, sizeof(newstub)-1)) {
                        php_stream_close(entry.fp);
                        if (error) {
@@ -765,11 +766,12 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, char **er
                        }
                        return EOF;
                }
+
                entry.uncompressed_filesize = entry.compressed_filesize = sizeof(newstub) - 1;
                entry.filename = estrndup(".phar/stub.php", sizeof(".phar/stub.php")-1);
                entry.filename_len = sizeof(".phar/stub.php")-1;
 
-               if (!user_stub) {
+               if (!defaultstub) {
                        if (!zend_hash_exists(&phar->manifest, ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
                                if (SUCCESS != zend_hash_add(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {
                                        php_stream_close(entry.fp);