From: Greg Beaver Date: Mon, 22 Jan 2007 00:13:20 +0000 (+0000) Subject: add setUncompressed(), setCompressedGZ(), setCompressedBZ2() to PharFileInfo, and... X-Git-Tag: RELEASE_1_0_0RC1~167 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=27f4a3ad30c96ec6092f6ff0e965ae9f803f7d96;p=php add setUncompressed(), setCompressedGZ(), setCompressedBZ2() to PharFileInfo, and a failing test (due to bug in streams + bug in phar) --- diff --git a/ext/phar/TODO b/ext/phar/TODO index 432e754e84..a35e195a36 100644 --- a/ext/phar/TODO +++ b/ext/phar/TODO @@ -15,8 +15,8 @@ Version 1.0.0 X stream context for specifying compression of a file [Marcus] * stream context for specifying meta-data X Phar->setStub() for specifying a new stub to the phar [Greg] - * add setUncompressed(), setCompressedGZ() and setCompressedBZ2() to - PharFileInfo class + X add setUncompressed(), setCompressedGZ() and setCompressedBZ2() to + PharFileInfo class [Greg] * add uncompressAllFiles(), compressAllFilesGZ() and compressAllFilesBZ2() to Phar class X add PharFileInfo::setMetaData($metadata) [Marcus] diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 4e7d9e292a..900f4e8364 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -291,6 +291,7 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char etemp.offset_within_phar = -1; etemp.is_crc_checked = 1; etemp.flags = PHAR_ENT_PERM_DEF_FILE; + etemp.phar = phar; zend_hash_add(&phar->manifest, etemp.filename, path_len, (void*)&etemp, sizeof(phar_entry_info), NULL); /* retrieve the phar manifest copy */ entry = phar_get_entry_info(phar, path, path_len TSRMLS_CC); @@ -722,6 +723,7 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int manifest_flags |= (entry.flags & PHAR_ENT_COMPRESSION_MASK); entry.is_crc_checked = 0; entry.fp = NULL; + entry.phar = mydata; zend_hash_add(&mydata->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL); } diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 53f1343e35..b1e9d2c53d 100755 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -134,6 +134,7 @@ typedef union _phar_archive_object phar_archive_object; typedef union _phar_entry_object phar_entry_object; #endif +typedef struct _phar_archive_data phar_archive_data; /* entry for one file in a phar file */ typedef struct _phar_entry_info { /* first bytes are exactly as in file */ @@ -152,10 +153,11 @@ typedef struct _phar_entry_info { int is_crc_checked:1; int is_modified:1; int is_deleted:1; + phar_archive_data *phar; } phar_entry_info; /* information about a phar file (the archive itself) */ -typedef struct _phar_archive_data { +struct _phar_archive_data { char *fname; int fname_len; char *alias; @@ -175,7 +177,7 @@ typedef struct _phar_archive_data { int is_explicit_alias:1; int is_modified:1; int is_writeable:1; -} phar_archive_data; +}; /* stream access data for one file entry in a phar file */ typedef struct _phar_entry_data { diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index eae4a83fb4..bfde05a3db 100755 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -598,6 +598,181 @@ PHP_METHOD(PharFileInfo, setMetadata) } /* }}} */ +/* {{{ proto int PharFileInfo::setCompressedGZ() + * Instructs the Phar class to compress the current file using zlib + */ +PHP_METHOD(PharFileInfo, setCompressedGZ) +{ +#if HAVE_ZLIB + php_stream *stream, *parent; + phar_entry_data *idata; + char *fname; + int fname_len; + PHAR_ENTRY_OBJECT(); + + if (entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSED_GZ) { + RETURN_TRUE; + return; + } + if (PHAR_G(readonly)) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, + "Phar is readonly, cannot change compression"); + } + if (entry_obj->ent.entry->is_deleted) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, + "Cannot compress deleted file"); + } + stream = php_stream_fopen_tmpfile(); + if (!entry_obj->ent.entry->temp_file) { + fname_len = spprintf(&fname, 0, "phar://%s/%s", entry_obj->ent.entry->phar->fname, entry_obj->ent.entry->filename); + parent = php_stream_open_wrapper_ex(fname, "rb", 0, 0, 0); + efree(fname); + php_stream_copy_to_stream(parent, stream, PHP_STREAM_COPY_ALL); + entry_obj->ent.entry->temp_file = stream; + php_stream_close(parent); + } + if (entry_obj->ent.entry->fp) { + php_stream_close(entry_obj->ent.entry->fp); + entry_obj->ent.entry->fp = 0; + } + entry_obj->ent.entry->flags &= ~PHAR_ENT_COMPRESSION_MASK; + entry_obj->ent.entry->flags |= PHAR_ENT_COMPRESSED_GZ; + entry_obj->ent.entry->phar->is_modified = 1; + entry_obj->ent.entry->is_modified = 1; + + idata = (phar_entry_data *) emalloc(sizeof(phar_entry_data)); + idata->fp = 0; + idata->internal_file = 0; + idata->phar = entry_obj->ent.entry->phar; + phar_flush(idata, 0, 0 TSRMLS_CC); + efree(idata); + RETURN_TRUE; +#else + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, + "Cannot compress with Gzip compression, zlib extension is not enabled"); +#endif +} +/* }}} */ + +/* {{{ proto int PharFileInfo::setCompressedBZIP2() + * Instructs the Phar class to compress the current file using bzip2 + */ +PHP_METHOD(PharFileInfo, setCompressedBZIP2) +{ +#if HAVE_BZ2 + php_stream *stream, *parent; + phar_entry_data *idata; + char *fname; + int fname_len; + PHAR_ENTRY_OBJECT(); + + if (entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSED_BZ2) { + RETURN_TRUE; + return; + } + if (PHAR_G(readonly)) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, + "Phar is readonly, cannot change compression"); + } + if (entry_obj->ent.entry->is_deleted) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, + "Cannot compress deleted file"); + } + stream = php_stream_fopen_tmpfile(); + if (!entry_obj->ent.entry->temp_file) { + fname_len = spprintf(&fname, 0, "phar://%s/%s", entry_obj->ent.entry->phar->fname, entry_obj->ent.entry->filename); + parent = php_stream_open_wrapper_ex(fname, "rb", 0, 0, 0); + efree(fname); + php_stream_copy_to_stream(parent, stream, PHP_STREAM_COPY_ALL); + entry_obj->ent.entry->temp_file = stream; + php_stream_close(parent); + } + if (entry_obj->ent.entry->fp) { + php_stream_close(entry_obj->ent.entry->fp); + entry_obj->ent.entry->fp = 0; + } + entry_obj->ent.entry->flags &= ~PHAR_ENT_COMPRESSION_MASK; + entry_obj->ent.entry->flags |= PHAR_ENT_COMPRESSED_BZ2; + entry_obj->ent.entry->phar->is_modified = 1; + entry_obj->ent.entry->is_modified = 1; + + idata = (phar_entry_data *) emalloc(sizeof(phar_entry_data)); + idata->fp = 0; + idata->internal_file = 0; + idata->phar = entry_obj->ent.entry->phar; + phar_flush(idata, 0, 0 TSRMLS_CC); + efree(idata); + RETURN_TRUE; +#else + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, + "Cannot compress with Bzip2 compression, bzip2 extension is not enabled"); +#endif +} +/* }}} */ + +/* {{{ proto int PharFileInfo::setUncompressed() + * Instructs the Phar class to uncompress the current file + */ +PHP_METHOD(PharFileInfo, setUncompressed) +{ + php_stream *stream, *parent; + phar_entry_data *idata; + char *fname; + int fname_len; + PHAR_ENTRY_OBJECT(); + + if ((entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSION_MASK) == 0) { + RETURN_TRUE; + return; + } + if (PHAR_G(readonly)) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, + "Phar is readonly, cannot change compression"); + } + if (entry_obj->ent.entry->is_deleted) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, + "Cannot compress deleted file"); + } +#if !HAVE_ZLIB + if (entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSED_GZ) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, + "Cannot uncompress Gzip-compressed file, zlib extension is not enabled"); + } +#endif +#if !HAVE_BZ2 + if (entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSED_BZ2) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, + "Cannot uncompress Bzip2-compressed file, bzip2 extension is not enabled"); + } +#endif + stream = php_stream_fopen_tmpfile(); + if (!entry_obj->ent.entry->temp_file) { + fname_len = spprintf(&fname, 0, "phar://%s/%s", entry_obj->ent.entry->phar->fname, entry_obj->ent.entry->filename); + parent = php_stream_open_wrapper_ex(fname, "rb", 0, 0, 0); + efree(fname); + php_stream_copy_to_stream(parent, stream, PHP_STREAM_COPY_ALL); + entry_obj->ent.entry->compressed_filesize = entry_obj->ent.entry->uncompressed_filesize; + entry_obj->ent.entry->temp_file = stream; + php_stream_close(parent); + } + if (entry_obj->ent.entry->fp) { + php_stream_close(entry_obj->ent.entry->fp); + entry_obj->ent.entry->fp = 0; + } + entry_obj->ent.entry->flags &= ~PHAR_ENT_COMPRESSION_MASK; + entry_obj->ent.entry->phar->is_modified = 1; + entry_obj->ent.entry->is_modified = 1; + + idata = (phar_entry_data *) emalloc(sizeof(phar_entry_data)); + idata->fp = 0; + idata->internal_file = 0; + idata->phar = entry_obj->ent.entry->phar; + phar_flush(idata, 0, 0 TSRMLS_CC); + efree(idata); + RETURN_TRUE; +} +/* }}} */ + #endif /* HAVE_SPL */ /* {{{ phar methods */ @@ -680,6 +855,9 @@ zend_function_entry php_entry_methods[] = { PHP_ME(PharFileInfo, isCompressed, NULL, 0) PHP_ME(PharFileInfo, isCompressedGZ, NULL, 0) PHP_ME(PharFileInfo, isCompressedBZIP2, NULL, 0) + PHP_ME(PharFileInfo, setUncompressed, NULL, 0) + PHP_ME(PharFileInfo, setCompressedGZ, NULL, 0) + PHP_ME(PharFileInfo, setCompressedBZIP2, NULL, 0) PHP_ME(PharFileInfo, getCRC32, NULL, 0) PHP_ME(PharFileInfo, isCRCChecked, NULL, 0) PHP_ME(PharFileInfo, getPharFlags, NULL, 0) diff --git a/ext/phar/tests/phar_oo_compressed_001.phpt b/ext/phar/tests/phar_oo_compressed_001.phpt new file mode 100644 index 0000000000..6809eb98c3 --- /dev/null +++ b/ext/phar/tests/phar_oo_compressed_001.phpt @@ -0,0 +1,69 @@ +--TEST-- +Phar context +--SKIPIF-- + + +--INI-- +phar.require_hash=0 +--FILE-- +'; + +$files = array(); +$files['a'] = 'a'; +$files['b'] = 'b'; +$files['c'] = 'c'; + +include 'phar_test.inc'; + +$phar = new Phar($fname); + +var_dump(file_get_contents($pname . '/a')); +var_dump($phar['a']->isCompressed()); +var_dump(file_get_contents($pname . '/b')); +var_dump($phar['b']->isCompressed()); +var_dump(file_get_contents($pname . '/c')); +var_dump($phar['c']->isCompressed()); + +$context = stream_context_create(array('phar'=>array('compress'=>Phar::GZ))); + +$phar['a'] = 'new a'; +$phar['a']->setUncompressed(); +$phar['b'] = 'new b'; +$phar['b']->setCompressedGZ(); +$phar['d'] = 'new d'; + +$phar = new Phar($fname); +var_dump(file_get_contents($pname . '/a')); +var_dump($phar['a']->isCompressed()); +var_dump(file_get_contents($pname . '/b')); +var_dump($phar['b']->isCompressed()); +var_dump(file_get_contents($pname . '/c')); +var_dump($phar['c']->isCompressed()); +var_dump(file_get_contents($pname . '/d')); +var_dump($phar['d']->isCompressed()); + +?> +===DONE=== +--CLEAN-- + +--EXPECTF-- +string(1) "a" +bool(false) +string(1) "b" +bool(false) +string(1) "c" +bool(false) +string(4) "new a" +bool(false) +string(4) "new b" +bool(true) +string(1) "c" +bool(false) +string(4) "new d" +bool(true) +===DONE===