summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/phar/config.m41
-rw-r--r--ext/phar/config.w322
-rw-r--r--ext/phar/phar.c101
-rw-r--r--ext/phar/tests/003.phpt14
-rw-r--r--ext/phar/tests/015.phpt2
-rwxr-xr-xext/phar/tests/015b.phpt33
-rw-r--r--ext/phar/tests/016.phpt2
-rwxr-xr-xext/phar/tests/016b.phpt2
8 files changed, 123 insertions, 34 deletions
diff --git a/ext/phar/config.m4 b/ext/phar/config.m4
index e62e878cf3..b3e0f70a16 100644
--- a/ext/phar/config.m4
+++ b/ext/phar/config.m4
@@ -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
diff --git a/ext/phar/config.w32 b/ext/phar/config.w32
index c1c427f887..70d6728b0e 100644
--- a/ext/phar/config.w32
+++ b/ext/phar/config.w32
@@ -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);
}
-
diff --git a/ext/phar/phar.c b/ext/phar/phar.c
index ca7c0b530d..9336707a47 100644
--- a/ext/phar/phar.c
+++ b/ext/phar/phar.c
@@ -46,16 +46,22 @@
#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,25 +1428,40 @@ 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();
}
/* }}} */
/* {{{ 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
};
/* }}} */
diff --git a/ext/phar/tests/003.phpt b/ext/phar/tests/003.phpt
index cfbbef6a00..693bfdccd7 100644
--- a/ext/phar/tests/003.phpt
+++ b/ext/phar/tests/003.phpt
@@ -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)
diff --git a/ext/phar/tests/015.phpt b/ext/phar/tests/015.phpt
index 69c9472e64..3e6c673691 100644
--- a/ext/phar/tests/015.phpt
+++ b/ext/phar/tests/015.phpt
@@ -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
index 0000000000..06c0d3065a
--- /dev/null
+++ b/ext/phar/tests/015b.phpt
@@ -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"
diff --git a/ext/phar/tests/016.phpt b/ext/phar/tests/016.phpt
index 3c384ff610..61d784474f 100644
--- a/ext/phar/tests/016.phpt
+++ b/ext/phar/tests/016.phpt
@@ -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
diff --git a/ext/phar/tests/016b.phpt b/ext/phar/tests/016b.phpt
index 00b17a3297..da6d10800a 100755
--- a/ext/phar/tests/016b.phpt
+++ b/ext/phar/tests/016b.phpt
@@ -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