]> granicus.if.org Git - php/commitdiff
- Add bzip2 decompression support
authorMarcus Boerger <helly@php.net>
Thu, 12 Jan 2006 21:16:29 +0000 (21:16 +0000)
committerMarcus Boerger <helly@php.net>
Thu, 12 Jan 2006 21:16:29 +0000 (21:16 +0000)
ext/phar/config.m4
ext/phar/config.w32
ext/phar/phar.c
ext/phar/tests/003.phpt
ext/phar/tests/015.phpt
ext/phar/tests/015b.phpt [new file with mode: 0755]
ext/phar/tests/016.phpt
ext/phar/tests/016b.phpt

index e62e878cf34e7ef4fe6a23fffe2fbb0b49aef443..b3e0f70a169bc7a5a953d79ca6e372baa9cf3ef8 100644 (file)
@@ -7,4 +7,5 @@ PHP_ARG_ENABLE(phar, for phar support/phar zlib support,
 if test "$PHP_PHAR" != "no"; then
   PHP_NEW_EXTENSION(phar, phar.c, $ext_shared)
   PHP_ADD_EXTENSION_DEP(phar, zlib, true)
+  PHP_ADD_EXTENSION_DEP(phar, bz2, true)
 fi
index c1c427f887389f51a0e3ae7b6dfb12fe34face44..70d6728b0ec1bd45beab1df49acf7643cb8bfdad 100644 (file)
@@ -6,5 +6,5 @@ ARG_ENABLE("phar", "enable phar support", "no");
 if (PHP_PHAR != "no") {
        EXTENSION("phar", "phar.c");
        ADD_EXTENSION_DEP('phar', 'zlib', true);
+       ADD_EXTENSION_DEP('phar', 'bz2', true);
 }
-
index ca7c0b530db32c77a8c7ca449fb0cf9d717db5e2..9336707a47de43e76faf45d93e68832ad211da35 100644 (file)
 #define E_RECOVERABLE_ERROR E_ERROR
 #endif
 
+#define PHAR_VERSION_STR          "0.8.0"
 /* x.y.z maps to 0xyz0 */
-#define PHAR_API_VERSION       0x0800
-#define PHAR_API_MAJORVERSION  0x0000
-#define PHAR_API_MAJORVER_MASK 0xF000
-#define PHAR_API_VER_MASK      0xFFF0
+#define PHAR_API_VERSION          0x0800
+#define PHAR_API_MAJORVERSION     0x0000
+#define PHAR_API_MAJORVER_MASK    0xF000
+#define PHAR_API_VER_MASK         0xFFF0
+
+#define PHAR_HDR_ANY_COMPRESSED   0x0001
+#define PHAR_HDR_SIGNATURE        0x0008
 
 /* flags byte for each file adheres to these bitmasks.
    All unused values are reserved */
-#define PHAR_COMPRESSED_GZ     0x0001
-#define PHAR_SIGNATURE         0x0002
+#define PHAR_ENT_COMPRESSION_MASK 0x0F
+#define PHAR_ENT_COMPRESSED_NONE  0x00
+#define PHAR_ENT_COMPRESSED_GZ    0x01
+#define PHAR_ENT_COMPRESSED_BZ2   0x02
 
 
 ZEND_BEGIN_MODULE_GLOBALS(phar)
@@ -215,7 +221,7 @@ static phar_internal_file_data *phar_get_file_entry(char *fname, char *path TSRM
  * Returns the api version */
 PHP_METHOD(Phar, apiVersion)
 {
-       RETURN_STRINGL("0.8.0", sizeof("0.8.0")-1, 1);
+       RETURN_STRINGL(PHAR_VERSION_STR, sizeof(PHAR_VERSION_STR)-1, 1);
 }
 /* }}}*/
 
@@ -223,7 +229,7 @@ PHP_METHOD(Phar, apiVersion)
  * Returns whether phar extension supports compression using zlib */
 PHP_METHOD(Phar, canCompress)
 {
-#if HAVE_ZLIB
+#if HAVE_ZLIB || HAVE_BZ2
        RETURN_TRUE;
 #else
        RETURN_FALSE;
@@ -346,6 +352,8 @@ static int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alia
                efree(savebuf);
                return FAILURE;
        }
+       /* The lowest nibble contains the phar wide flags. The any compressed can */
+       /* be ignored on reading because it is being generated anyways. */
 
        /* extract alias */
        PHAR_GET_32(buffer, tmp_len);
@@ -408,15 +416,28 @@ static int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alia
                entry.offset_within_phar = offset;
                offset += entry.compressed_filesize;
                entry.flags = *buffer++;
-               if (entry.flags & PHAR_COMPRESSED_GZ) {
+               switch (entry.flags & PHAR_ENT_COMPRESSION_MASK) {
+               case PHAR_ENT_COMPRESSED_GZ:
 #if !HAVE_ZLIB
                        if (!compressed) {
                                MAPPHAR_FAIL("zlib extension is required for gz compressed .phar file \"%s\"");
                        }
 #endif
                        compressed = 1;
-               } else if (entry.uncompressed_filesize != entry.compressed_filesize) {
-                       MAPPHAR_FAIL("internal corruption of phar \"%s\" (compressed and uncompressed size does not match for uncompressed entry)");
+                       break;
+               case PHAR_ENT_COMPRESSED_BZ2:
+#if !HAVE_BZ2
+                       if (!compressed) {
+                               MAPPHAR_FAIL("bz2 extension is required for bzip2 compressed .phar file \"%s\"");
+                       }
+#endif
+                       compressed = 1;
+                       break;
+               default:
+                       if (entry.uncompressed_filesize != entry.compressed_filesize) {
+                               MAPPHAR_FAIL("internal corruption of phar \"%s\" (compressed and uncompressed size does not match for uncompressed entry)");
+                       }
+                       break;
                }
                entry.crc_checked = 0;
                entry.fp = NULL;
@@ -681,11 +702,25 @@ static int phar_postprocess_file(php_stream_wrapper *wrapper, int options, phar_
 }
 /* }}} */
 
+static char * phar_decompress_filter(phar_manifest_entry * entry, int return_unknow) /* {{{ */
+{
+       switch (entry->flags & PHAR_ENT_COMPRESSION_MASK) {
+       case PHAR_ENT_COMPRESSED_GZ:
+               return "zlib.inflate";
+       case PHAR_ENT_COMPRESSED_BZ2:
+               return "bzip2.decompress";
+       default:
+               return return_unknow ? "unknown" : NULL;
+       }
+}
+/* }}} */
+
 static php_stream * php_stream_phar_url_wrapper(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) /* {{{ */
 {
        phar_internal_file_data *idata;
        char *internal_file;
        char *buffer;
+       char *filter_name;
        char tmpbuf[8];
        php_url *resource = NULL;
        php_stream *fp, *fpf;
@@ -772,15 +807,20 @@ static php_stream * php_stream_phar_url_wrapper(php_stream_wrapper *wrapper, cha
                return NULL;
        }
 
-       if (idata->internal_file->flags & PHAR_COMPRESSED_GZ) {
-               filter = php_stream_filter_create("zlib.inflate", NULL, php_stream_is_persistent(fp) TSRMLS_CC);
+       if ((idata->internal_file->flags & PHAR_ENT_COMPRESSION_MASK) != 0) {
+               ;
+               if ((filter_name = phar_decompress_filter(idata->internal_file, 0)) != NULL) {
+                       filter = php_stream_filter_create(phar_decompress_filter(idata->internal_file, 0), NULL, php_stream_is_persistent(fp) TSRMLS_CC);
+               } else {
+                       filter = NULL;
+               }
                if (!filter) {
-                       php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: unable to read phar \"%s\" (cannot create zlib.inflate filter while decompressing file \"%s\")", idata->phar->fname, internal_file);
+                       php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: unable to read phar \"%s\" (cannot create %s filter while decompressing file \"%s\")", idata->phar->fname, phar_decompress_filter(idata->internal_file, 1), internal_file);
                        efree(idata);
                        efree(internal_file);
                        return NULL;                    
                }
-               /* Nnfortunatley we cannot check the read position of fp after getting */
+               /* Unfortunatley we cannot check the read position of fp after getting */
                /* uncompressed data because the new stream posiition is being changed */
                /* by the number of bytes read throughthe filter not by the raw number */
                /* bytes being consumed on the stream. Therefor use a consumed filter. */ 
@@ -1388,14 +1428,20 @@ PHP_RSHUTDOWN_FUNCTION(phar)
 PHP_MINFO_FUNCTION(phar)
 {
        php_info_print_table_start();
-       php_info_print_table_header(2, "phar PHP Archive support", "enabled");
-       php_info_print_table_row(2, "phar API version", "0.8.0");
+       php_info_print_table_header(2, "Phar: PHP Archive support", "enabled");
+       php_info_print_table_row(2, "Phar API version", PHAR_VERSION_STR);
        php_info_print_table_row(2, "CVS revision", "$Revision$");
-       php_info_print_table_row(2, "compressed phar support", 
+       php_info_print_table_row(2, "gzip compression", 
 #if HAVE_ZLIB
                "enabled");
 #else
                "disabled");
+#endif
+       php_info_print_table_row(2, "bzip2 compression", 
+#if HAVE_BZ2
+               "enabled");
+#else
+               "disabled");
 #endif
        php_info_print_table_end();
 }
@@ -1403,10 +1449,19 @@ PHP_MINFO_FUNCTION(phar)
 
 /* {{{ phar_module_entry
  */
-zend_module_entry phar_module_entry = {
-#if ZEND_MODULE_API_NO >= 20010901
-       STANDARD_MODULE_HEADER,
+static zend_module_dep phar_deps[] = {
+#if HAVE_ZLIB
+       ZEND_MOD_REQUIRED("zlib")
+#endif
+#if HAVE_BZ2
+       ZEND_MOD_REQUIRED("bz2")
 #endif
+       {NULL, NULL, NULL}
+};
+
+zend_module_entry phar_module_entry = {
+       STANDARD_MODULE_HEADER_EX, NULL,
+       phar_deps,
        "Phar",
        phar_functions,
        PHP_MINIT(phar),
@@ -1414,9 +1469,7 @@ zend_module_entry phar_module_entry = {
        PHP_RINIT(phar),
        PHP_RSHUTDOWN(phar),
        PHP_MINFO(phar),
-#if ZEND_MODULE_API_NO >= 20010901
-       "0.1.0", /* Replace with version number for your extension */
-#endif
+       PHAR_VERSION_STR,
        STANDARD_MODULE_PROPERTIES
 };
 /* }}} */
index cfbbef6a00e6054e6216a8d3c9d12f6b446eb835..693bfdccd7de3de5531b9137c1b3abb690f2c8a9 100644 (file)
@@ -1,11 +1,13 @@
 --TEST--
-Phar::mapPhar zlib is loaded
+Phar::canCompress
 --SKIPIF--
-<?php if (!extension_loaded("phar")) print "skip zlib is present"; ?>
+<?php if (!extension_loaded("phar")) print "skip"; ?>
 --FILE--
 <?php
-/* check this works and actually returns a boolean value */
-var_dump(Phar::canCompress());
+/* check this works and actually returns the boolean value */
+var_dump(Phar::canCompress() == (
+       extension_loaded("zlib") || extension_loaded("bz2")
+       ));
 ?>
---EXPECTF--
-bool(%s)
+--EXPECT--
+bool(true)
index 69c9472e6487002cd55ae9473f4536f77995bd8c..3e6c673691a088a278c564571d516ac5674637fc 100644 (file)
@@ -2,7 +2,7 @@
 Phar::mapPhar valid file (gzipped)
 --SKIPIF--
 <?php if (!extension_loaded("phar")) print "skip";
-if (!Phar::canCompress()) print "skip"; ?>
+if (!extension_loaded("zlib")) print "skip zlib not present"; ?>
 --FILE--
 <?php
 $file = "<?php
diff --git a/ext/phar/tests/015b.phpt b/ext/phar/tests/015b.phpt
new file mode 100755 (executable)
index 0000000..06c0d30
--- /dev/null
@@ -0,0 +1,33 @@
+--TEST--
+Phar::mapPhar valid file (bzip2)
+--SKIPIF--
+<?php if (!extension_loaded("phar")) print "skip";
+if (!extension_loaded("bz2")) print "skip bz2 not present"; ?>
+--FILE--
+<?php
+$file = "<?php
+Phar::mapPhar('hio');
+__HALT_COMPILER(); ?>";
+
+$files = array();
+$files['a'] = array('Hello World', pack('H*', '425a6839314159265359d872012f00000157800010400000400080060490002000220686d420c988c769e8281f8bb9229c28486c39009780'));
+$manifest = '';
+foreach($files as $name => $cont) {
+       $manifest .= pack('V', strlen($name)) . $name . pack('VVVVC', strlen($cont[0]), time(), strlen($cont[1]), crc32($cont[0]), 0x02);
+}
+$alias = 'hio';
+$manifest = pack('VnV', count($files), 0x0800, strlen($alias)) . $alias . $manifest;
+$file .= pack('V', strlen($manifest)) . $manifest;
+foreach($files as $cont)
+{
+       $file .= $cont[1];
+}
+
+file_put_contents(dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php', $file);
+include dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
+var_dump(file_get_contents('phar://hio/a'));
+?>
+--CLEAN--
+<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php'); ?>
+--EXPECT--
+string(11) "Hello World"
index 3c384ff6108032d70e57c0bba97f3017e44b9b78..61d784474fd89fbe80c922d8ce758324236f16fe 100644 (file)
@@ -2,7 +2,7 @@
 Phar::mapPhar invalid file (gzipped file length is too short)
 --SKIPIF--
 <?php if (!extension_loaded("phar")) print "skip";
-if (!Phar::canCompress()) print "skip"; ?>
+if (!extension_loaded("zlib")) print "skip zlib not present"; ?>
 --FILE--
 <?php
 $file = "<?php
index 00b17a3297fa6119fa351512193d5a10b3a9ad83..da6d10800a2c159a2a62f76d65e9a0f625df5c86 100755 (executable)
@@ -2,7 +2,7 @@
 Phar::mapPhar invalid file (gzipped file length is too short)
 --SKIPIF--
 <?php if (!extension_loaded("phar")) print "skip";
-if (!Phar::canCompress()) print "skip"; ?>
+if (!extension_loaded("zlib")) print "skip zlib not present"; ?>
 --FILE--
 <?php
 $file = "<?php