]> granicus.if.org Git - php/commitdiff
fix tar-based phars creation and loading
authorGreg Beaver <cellog@php.net>
Thu, 3 Jan 2008 18:13:27 +0000 (18:13 +0000)
committerGreg Beaver <cellog@php.net>
Thu, 3 Jan 2008 18:13:27 +0000 (18:13 +0000)
ext/phar/phar.c
ext/phar/tar.c
ext/phar/tar.h

index e54ba6d21384c3ea93d2b3c2b5e0c6459909cc25..a2de17bd700677419244aabaf9356a17f6613bbf 100644 (file)
@@ -328,9 +328,9 @@ void destroy_phar_manifest(void *pDest) /* {{{ */
                entry->zip = 0;
        }
 #endif
-       if (entry->linkname) {
-               efree(entry->linkname);
-               entry->linkname = 0;
+       if (entry->link) {
+               efree(entry->link);
+               entry->link = 0;
        }
 }
 /* }}} */
@@ -703,7 +703,7 @@ int phar_entry_delref(phar_entry_data *idata TSRMLS_DC) /* {{{ */
        int ret = 0;
 
        if (idata->internal_file) {
-               if (--idata->internal_file->fp_refcount <= 0) {
+               if (--idata->internal_file->fp_refcount < 0) {
                        idata->internal_file->fp_refcount = 0;
                }
                if (idata->fp && idata->fp != idata->internal_file->fp) {
@@ -824,6 +824,8 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char
                }
                etemp.filename = estrndup(etemp.filename, strlen(etemp.filename));
        } else {
+               etemp.is_tar = phar->is_tar;
+               etemp.tar_type = '0';
                etemp.filename = estrndup(path, path_len);
        }
 #else
@@ -842,6 +844,8 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char
        ret->fp = entry->fp;
        ret->position = 0;
        ret->for_write = 1;
+       ret->is_zip = entry->is_zip;
+       ret->is_tar = entry->is_tar;
        ret->internal_file = entry;
        return ret;
 }
@@ -2515,7 +2519,7 @@ phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry,
                                                if (error) {
                                                        spprintf(error, 4096, "phar error: could not copy full zip file contents of entry \"%s\"", entry->filename);
                                                }
-                                               fclose(fp);
+                                               php_stream_close(fp);
                                                entry->fp = NULL;
                                                zip_fclose(entry->zip);
                                                entry->zip = NULL;
@@ -2527,12 +2531,12 @@ phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry,
 
                                /* now use a decompression filter to inflate into our temp file */
                                if ((filter_name = phar_decompress_filter(entry, 0)) != NULL) {
-                                       filter = php_stream_filter_create(phar_decompress_filter(phar, 0), NULL, php_stream_is_persistent(fp) TSRMLS_CC);
+                                       filter = php_stream_filter_create(filter_name, NULL, php_stream_is_persistent(fp) TSRMLS_CC);
                                } else {
                                        filter = NULL;
                                }
                                if (!filter) {
-                                       spprintf(error, 0, "phar error: unable to read phar \"%s\" (cannot create %s filter while decompressing file \"%s\")", phar->phar->fname, phar_decompress_filter(entry, 1), entry->filename);
+                                       spprintf(error, 0, "phar error: unable to read phar \"%s\" (cannot create %s filter while decompressing file \"%s\")", entry->phar->fname, phar_decompress_filter(entry, 1), entry->filename);
                                        return NULL;                    
                                }
 
@@ -4711,7 +4715,7 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type
                goto skip_phar;
        }
        if (strstr(file_handle->filename, ".phar.tar") && !strstr(file_handle->filename, ":\\")) {
-               /* zip-based phar */
+               /* tar-based phar */
                spprintf(&name, 4096, "phar://%s/%s", file_handle->filename, ".phar/stub.php");
                file_handle->type = ZEND_HANDLE_FILENAME;
                file_handle->free_filename = 1;
index 30c6fd2e4c94345c895ea0407e3a1ab98f0233b6..795afd3a1db7d8b092a9ac70c9cdff179b5784d1 100644 (file)
@@ -276,6 +276,7 @@ int phar_open_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, i
        } while (read != 0);
        myphar->fname = estrndup(fname, fname_len);
        myphar->fname_len = fname_len;
+       myphar->fp = fp;
        phar_request_initialize(TSRMLS_C);
        zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), myphar->fname, fname_len, (void*)&myphar, sizeof(phar_archive_data*),  NULL);
        if (actual_alias) {
@@ -287,7 +288,6 @@ int phar_open_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, i
        if (pphar) {
                *pphar = myphar;
        }
-       php_stream_close(fp);
        return SUCCESS;
 }
 /* }}} */
@@ -305,6 +305,7 @@ int phar_tar_writeheaders(void *pDest, void *argument TSRMLS_DC)
        phar_entry_info *entry = (phar_entry_info *) pDest;
        struct _phar_pass_tar_info *fp = (struct _phar_pass_tar_info *)argument;
        php_stream *file;
+       char padding[512];
 
        if (entry->is_deleted) {
                return ZEND_HASH_APPLY_REMOVE;
@@ -377,6 +378,9 @@ int phar_tar_writeheaders(void *pDest, void *argument TSRMLS_DC)
                return ZEND_HASH_APPLY_STOP;
        }
 
+       memset(padding, 0, 512);
+       php_stream_write(fp->new, padding, ((entry->uncompressed_filesize +511)&~511) - entry->uncompressed_filesize);
+
        if (entry->fp) {
                php_stream_close(entry->fp);
                entry->fp = NULL;
@@ -394,6 +398,7 @@ int phar_tar_flush(phar_archive_data *archive, char *user_stub, long len, char *
        php_stream *oldfile, *newfile, *stubfile;
        int closeoldfile, free_user_stub;
        struct _phar_pass_tar_info pass;
+       char *buf;
 
        entry.flags = PHAR_ENT_PERM_DEF_FILE;
        entry.timestamp = time(NULL);
@@ -408,7 +413,7 @@ int phar_tar_flush(phar_archive_data *archive, char *user_stub, long len, char *
                entry.crc32 = phar_tar_checksum(archive->alias, archive->alias_len);
                php_stream_write(entry.fp, archive->alias, archive->alias_len);
                entry.uncompressed_filesize = archive->alias_len;
-               zend_hash_add(&archive->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL);
+               zend_hash_update(&archive->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL);
        }
 
        /* set stub */
@@ -465,7 +470,7 @@ int phar_tar_flush(phar_archive_data *archive, char *user_stub, long len, char *
                }
                entry.filename = estrndup(".phar/stub.php", sizeof(".phar/stub.php")-1);
                entry.filename_len = sizeof(".phar/stub.php")-1;
-               zend_hash_add(&archive->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL);
+               zend_hash_update(&archive->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL);
                if (free_user_stub) {
                        efree(user_stub);
                }
@@ -511,6 +516,11 @@ int phar_tar_flush(phar_archive_data *archive, char *user_stub, long len, char *
 
        zend_hash_apply_with_argument(&archive->manifest, (apply_func_arg_t) phar_tar_writeheaders, (void *) &pass TSRMLS_CC);
 
+       /* add final zero blocks */
+       buf = (char *) ecalloc(1024, 1);
+       php_stream_write(newfile, buf, 1024);
+       efree(buf);
+
        if (closeoldfile) {
                php_stream_close(oldfile);
        }
index 39385189051fc7b6392e3282be44a125e42b06cd..3757da805c9201da1019fde6f33a98a1dff7cc17 100644 (file)
@@ -73,6 +73,7 @@ typedef struct _tar_header {  /* {{{ */
                               the value of the prefix field, if non-null,
                               is prefixed to the name field to allow names
                               longer then 100 characters */
+       char padding[12];   /* unused zeroed bytes */
 } tar_header;
 /* }}} */