From: Greg Beaver Date: Thu, 3 Jan 2008 18:13:27 +0000 (+0000) Subject: fix tar-based phars creation and loading X-Git-Tag: RELEASE_2_0_0a1~1043 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f58985509380afe3f010f26dcf759b852a1cb121;p=php fix tar-based phars creation and loading --- diff --git a/ext/phar/phar.c b/ext/phar/phar.c index e54ba6d213..a2de17bd70 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -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; diff --git a/ext/phar/tar.c b/ext/phar/tar.c index 30c6fd2e4c..795afd3a1d 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -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); } diff --git a/ext/phar/tar.h b/ext/phar/tar.h index 3938518905..3757da805c 100644 --- a/ext/phar/tar.h +++ b/ext/phar/tar.h @@ -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; /* }}} */