php_stream_filter *filter;
php_serialize_data_t metadata_hash;
smart_str main_metadata_str = {0};
- int free_user_stub;
+ int free_user_stub, free_fp = 1, free_ufp = 1;
if (error) {
*error = NULL;
/* remove this from the new phar */
continue;
}
+ if (!entry->is_modified && entry->fp_refcount) {
+ /* open file pointers refer to this fp, do not free the stream */
+ switch (entry->fp_type) {
+ case PHAR_FP:
+ free_fp = 0;
+ break;
+ case PHAR_UFP:
+ free_ufp = 0;
+ default:
+ break;
+ }
+ }
/* after excluding deleted files, calculate manifest size in bytes and number of entries */
++new_manifest_count;
/* finally, close the temp file, rename the original phar,
move the temp to the old phar, unlink the old phar, and reload it into memory
*/
- if (phar->fp) {
+ if (phar->fp && free_fp) {
php_stream_close(phar->fp);
}
if (phar->ufp) {
- php_stream_close(phar->ufp);
+ if (free_ufp) {
+ php_stream_close(phar->ufp);
+ }
phar->ufp = NULL;
}
if (closeoldfile) {
struct _phar_pass_tar_info {
php_stream *old;
php_stream *new;
+ int free_fp;
+ int free_ufp;
char **error;
};
memset(padding, 0, 512);
php_stream_write(fp->new, padding, ((entry->uncompressed_filesize +511)&~511) - entry->uncompressed_filesize);
}
+ if (!entry->is_modified && entry->fp_refcount) {
+ /* open file pointers refer to this fp, do not free the stream */
+ switch (entry->fp_type) {
+ case PHAR_FP:
+ fp->free_fp = 0;
+ break;
+ case PHAR_UFP:
+ fp->free_ufp = 0;
+ default:
+ break;
+ }
+ }
entry->is_modified = 0;
if (entry->fp_type == PHAR_MOD && entry->fp != entry->phar->fp && entry->fp != entry->phar->ufp) {
pass.old = oldfile;
pass.new = newfile;
pass.error = error;
+ pass.free_fp = 1;
+ pass.free_ufp = 1;
zend_hash_apply_with_argument(&phar->manifest, (apply_func_arg_t) phar_tar_writeheaders, (void *) &pass TSRMLS_CC);
php_stream_close(newfile);
return EOF;
}
- if (phar->fp) {
+ if (phar->fp && pass.free_fp) {
php_stream_close(phar->fp);
}
if (phar->ufp) {
- php_stream_close(phar->ufp);
+ if (pass.free_ufp) {
+ php_stream_close(phar->ufp);
+ }
phar->ufp = NULL;
}
var_dump(file_get_contents(dirname(__FILE__) . '/extract2/file2.txt'));
var_dump(is_dir(dirname(__FILE__) . '/extract2/one/level'));
try {
-$a->extractTo('whatever', 134);
+$a->extractTo(dirname(__FILE__) . '/whatever', 134);
} catch (Exception $e) {
echo $e->getMessage(), "\n";
}
===DONE===
--CLEAN--
<?php
+@rmdir(dirname(__FILE__) . '/whatever');
@unlink(dirname(__FILE__) . '/oops');
@rmdir(dirname(__FILE__) . '/oops1');
@unlink(dirname(__FILE__) . '/tempmanifest1.phar.php');
php_stream *filefp;
php_stream *centralfp;
php_stream *old;
+ int free_fp;
+ int free_ufp;
char **error;
};
/* perform final modification of zip contents for each file in the manifest before saving */
}
entry->is_modified = 0;
} else {
+ if (entry->fp_refcount) {
+ /* open file pointers refer to this fp, do not free the stream */
+ switch (entry->fp_type) {
+ case PHAR_FP:
+ p->free_fp = 0;
+ break;
+ case PHAR_UFP:
+ p->free_ufp = 0;
+ default:
+ break;
+ }
+ }
if (!entry->is_dir && entry->compressed_filesize && entry->compressed_filesize != php_stream_copy_to_stream(p->old, p->filefp, entry->compressed_filesize)) {
spprintf(p->error, 0, "unable to copy contents of file \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname);
return ZEND_HASH_APPLY_STOP;
}
return EOF;
}
+ pass.free_fp = pass.free_ufp = 1;
memset(&eocd, 0, sizeof(eocd));
strncpy(eocd.signature, "PK\5\6", 4);
}
smart_str_free(&main_metadata_str);
}
- if (phar->fp) {
+ if (phar->fp && pass.free_fp) {
php_stream_close(phar->fp);
}
if (phar->ufp) {
- php_stream_close(phar->ufp);
+ if (pass.free_ufp) {
+ php_stream_close(phar->ufp);
+ }
phar->ufp = NULL;
}
/* re-open */