mirror of
https://github.com/php/php-src.git
synced 2024-09-22 02:17:32 +00:00
- Change to use streams filters which simplifies decompression a lot and
easily allows to use other compression algos too
This commit is contained in:
parent
ae81cb9a1c
commit
8166072ea3
@ -4,27 +4,7 @@ dnl config.m4 for extension phar
|
||||
PHP_ARG_ENABLE(phar, for phar support/phar zlib support,
|
||||
[ --enable-phar Enable phar support, use --with-zlib-dir if zlib detection fails])
|
||||
|
||||
if test -z "$PHP_ZLIB_DIR"; then
|
||||
PHP_ARG_WITH(zlib-dir, for the location of libz,
|
||||
[ --with-zlib-dir[=DIR] PHAR: Set the path to libz install prefix], no, no)
|
||||
fi
|
||||
|
||||
if test "$PHP_PHAR" != "no"; then
|
||||
PHP_NEW_EXTENSION(phar, phar.c, $ext_shared)
|
||||
PHP_SUBST(ZLIB_SHARED_LIBADD)
|
||||
|
||||
if test "$PHP_ZLIB_DIR" != "no"; then
|
||||
PHP_CHECK_LIBRARY(z, gzgets, [
|
||||
AC_DEFINE(HAVE_PHAR_ZLIB,1,[ ])
|
||||
AC_MSG_CHECKING(whether phar uses zlib)
|
||||
AC_MSG_RESULT(yes)
|
||||
PHP_ADD_LIBRARY_WITH_PATH(z, $PHP_ZLIB_DIR, PHAR_SHARED_LIBADD)
|
||||
AC_DEFINE(HAVE_PHAR_ZLIB,1,[ ])
|
||||
],[
|
||||
AC_MSG_CHECKING(whether phar uses zlib)
|
||||
AC_MSG_RESULT(no, PHAR extension requires zlib >= 1.0.9)
|
||||
],[
|
||||
$ac_extra
|
||||
])
|
||||
fi
|
||||
PHP_ADD_EXTENSION_DEP(phar, zlib, true)
|
||||
fi
|
||||
|
@ -4,19 +4,7 @@
|
||||
ARG_ENABLE("phar", "enable phar support", "no");
|
||||
|
||||
if (PHP_PHAR != "no") {
|
||||
if (PHP_ZLIB != "no") {
|
||||
EXTENSION("phar", "phar.c");
|
||||
if (!PHP_ZLIB_SHARED) {
|
||||
AC_DEFINE("HAVE_PHAR_ZLIB", 1, "ZLIB support in phar");
|
||||
}
|
||||
} else {
|
||||
EXTENSION("phar", "phar.c", null, "/D ZLIB_EXPORTS");
|
||||
AC_DEFINE("HAVE_PHAR_ZLIB", 1, "ZLIB support in phar");
|
||||
CHECK_LIB("zlib.lib", "zlib", PHP_ZLIB);
|
||||
CHECK_HEADER_ADD_INCLUDE("zlib.h", "CFLAGS", "..\\zlib;" + php_usual_include_suspects);
|
||||
if (!PHP_ZLIB_SHARED) {
|
||||
ADD_DEF_FILE("ext\\zlib\\php_zlib.def");
|
||||
}
|
||||
}
|
||||
EXTENSION("phar", "phar.c");
|
||||
ADD_EXTENSION_DEP('phar', 'zlib', true);
|
||||
}
|
||||
|
||||
|
140
ext/phar/phar.c
140
ext/phar/phar.c
@ -42,10 +42,6 @@
|
||||
# define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PHAR_ZLIB
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
#ifndef E_RECOVERABLE_ERROR
|
||||
#define E_RECOVERABLE_ERROR E_ERROR
|
||||
#endif
|
||||
@ -227,7 +223,7 @@ PHP_METHOD(Phar, apiVersion)
|
||||
* Returns whether phar extension supports compression using zlib */
|
||||
PHP_METHOD(Phar, canCompress)
|
||||
{
|
||||
#ifdef HAVE_PHAR_ZLIB
|
||||
#if HAVE_ZLIB
|
||||
RETURN_TRUE;
|
||||
#else
|
||||
RETURN_FALSE;
|
||||
@ -413,7 +409,7 @@ static int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alia
|
||||
offset += entry.compressed_filesize;
|
||||
entry.flags = *buffer++;
|
||||
if (entry.flags & PHAR_COMPRESSED_GZ) {
|
||||
#ifndef HAVE_PHAR_ZLIB
|
||||
#if !HAVE_ZLIB
|
||||
if (!compressed) {
|
||||
MAPPHAR_FAIL("zlib extension is required for gz compressed .phar file \"%s\"");
|
||||
}
|
||||
@ -688,21 +684,13 @@ static int phar_postprocess_file(php_stream_wrapper *wrapper, int options, phar_
|
||||
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;
|
||||
php_stream *stream = NULL;
|
||||
char *internal_file;
|
||||
char *buffer;
|
||||
char *filedata;
|
||||
char tmpbuf[8];
|
||||
php_url *resource = NULL;
|
||||
php_stream *fp;
|
||||
int status;
|
||||
#ifdef HAVE_PHAR_ZLIB
|
||||
char *savebuf;
|
||||
/* borrowed from zlib.c gzinflate() function */
|
||||
php_stream *fp, *fpf;
|
||||
php_stream_filter *filter;
|
||||
php_uint32 offset;
|
||||
char *s1=NULL;
|
||||
z_stream zstream;
|
||||
#endif
|
||||
|
||||
resource = php_url_parse(path);
|
||||
|
||||
@ -748,9 +736,9 @@ static php_stream * php_stream_phar_url_wrapper(php_stream_wrapper *wrapper, cha
|
||||
|
||||
/* do we have the data already? */
|
||||
if (idata->fp) {
|
||||
stream = php_stream_alloc(&phar_ops, idata, NULL, mode);
|
||||
fpf = php_stream_alloc(&phar_ops, idata, NULL, mode);
|
||||
efree(internal_file);
|
||||
return stream;
|
||||
return fpf;
|
||||
}
|
||||
|
||||
if (PG(safe_mode) && (!php_checkuid(idata->phar->fname, NULL, CHECKUID_ALLOW_ONLY_FILE))) {
|
||||
@ -785,82 +773,30 @@ static php_stream * php_stream_phar_url_wrapper(php_stream_wrapper *wrapper, cha
|
||||
}
|
||||
|
||||
if (idata->internal_file->flags & PHAR_COMPRESSED_GZ) {
|
||||
#ifdef HAVE_PHAR_ZLIB
|
||||
buffer = (char *) emalloc(idata->internal_file->compressed_filesize);
|
||||
if (idata->internal_file->compressed_filesize !=
|
||||
php_stream_read(fp, buffer, idata->internal_file->compressed_filesize)) {
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: internal corruption of phar \"%s\" (filesize mismatch on file \"%s\")", idata->phar->fname, internal_file);
|
||||
filter = php_stream_filter_create("zlib.inflate", NULL, php_stream_is_persistent(fp) TSRMLS_CC);
|
||||
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);
|
||||
efree(idata);
|
||||
efree(internal_file);
|
||||
return NULL;
|
||||
}
|
||||
php_stream_filter_append(&fp->readfilters, filter);
|
||||
|
||||
idata->fp = php_stream_temp_new();
|
||||
if (php_stream_copy_to_stream(fp, idata->fp, idata->internal_file->uncompressed_filesize) != idata->internal_file->uncompressed_filesize) {
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: internal corruption of phar \"%s\" (actual filesize mismatch on file \"%s\")", idata->phar->fname, internal_file);
|
||||
php_stream_close(idata->fp);
|
||||
efree(idata);
|
||||
efree(internal_file);
|
||||
efree(buffer);
|
||||
return NULL;
|
||||
}
|
||||
savebuf = buffer;
|
||||
|
||||
/* borrowed from zlib.c gzinflate() function */
|
||||
zstream.zalloc = (alloc_func) Z_NULL;
|
||||
zstream.zfree = (free_func) Z_NULL;
|
||||
|
||||
do {
|
||||
filedata = (char *) erealloc(s1, idata->internal_file->uncompressed_filesize);
|
||||
|
||||
if (!filedata && s1) {
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: internal corruption of phar \"%s\" (corrupted zlib compression of file \"%s\")", idata->phar->fname, internal_file);
|
||||
efree(s1);
|
||||
efree(savebuf);
|
||||
efree(idata);
|
||||
efree(internal_file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
zstream.next_in = (Bytef *) buffer;
|
||||
zstream.avail_in = (uInt) idata->internal_file->compressed_filesize;
|
||||
|
||||
zstream.next_out = filedata;
|
||||
zstream.avail_out = (uInt) idata->internal_file->uncompressed_filesize;
|
||||
|
||||
/* init with -MAX_WBITS disables the zlib internal headers */
|
||||
status = inflateInit2(&zstream, -MAX_WBITS);
|
||||
if (status == Z_OK) {
|
||||
status = inflate(&zstream, Z_FINISH);
|
||||
if (status != Z_STREAM_END) {
|
||||
inflateEnd(&zstream);
|
||||
if (status == Z_OK) {
|
||||
status = Z_BUF_ERROR;
|
||||
}
|
||||
} else {
|
||||
status = inflateEnd(&zstream);
|
||||
}
|
||||
}
|
||||
s1 = filedata;
|
||||
|
||||
} while (status == Z_BUF_ERROR);
|
||||
|
||||
if (status != Z_OK) {
|
||||
efree(savebuf);
|
||||
efree(filedata);
|
||||
efree(idata);
|
||||
efree(internal_file);
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: decompression failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
efree(savebuf);
|
||||
/* need to copy filedata to stream now */
|
||||
idata->fp = php_stream_temp_open(0, PHP_STREAM_MAX_MEM, filedata, idata->internal_file->uncompressed_filesize);
|
||||
efree(filedata);
|
||||
/* check crc32/filesize */
|
||||
if (!idata->internal_file->crc_checked
|
||||
&& phar_postprocess_file(wrapper, options, idata, idata->internal_file->crc32 TSRMLS_CC) != SUCCESS) {
|
||||
efree(idata);
|
||||
efree(internal_file);
|
||||
}
|
||||
idata->internal_file->crc_checked = 1;
|
||||
#else
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "zlib extension must be enabled for compressed .phar files");
|
||||
efree(internal_file);
|
||||
return NULL;
|
||||
#endif
|
||||
php_stream_filter_flush(filter, 1);
|
||||
php_stream_filter_remove(filter, 1 TSRMLS_CC);
|
||||
/* Nnfortunatley 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. Correct the stream pos anyway. */
|
||||
php_stream_seek(fp, offset + idata->internal_file->compressed_filesize, SEEK_SET);
|
||||
} else { /* from here is for non-compressed */
|
||||
buffer = &tmpbuf[0];
|
||||
/* bypass to temp stream */
|
||||
@ -872,20 +808,20 @@ static php_stream * php_stream_phar_url_wrapper(php_stream_wrapper *wrapper, cha
|
||||
efree(internal_file);
|
||||
return NULL;
|
||||
}
|
||||
/* check length, crc32 */
|
||||
if (!idata->internal_file->crc_checked
|
||||
&& phar_postprocess_file(wrapper, options, idata, idata->internal_file->crc32 TSRMLS_CC) != SUCCESS) {
|
||||
php_stream_close(idata->fp);
|
||||
efree(idata);
|
||||
efree(internal_file);
|
||||
return NULL;
|
||||
}
|
||||
idata->internal_file->crc_checked = 1;
|
||||
}
|
||||
|
||||
stream = php_stream_alloc(&phar_ops, idata, NULL, mode);
|
||||
/* check length, crc32 */
|
||||
if (phar_postprocess_file(wrapper, options, idata, idata->internal_file->crc32 TSRMLS_CC) != SUCCESS) {
|
||||
php_stream_close(idata->fp);
|
||||
efree(idata);
|
||||
efree(internal_file);
|
||||
return NULL;
|
||||
}
|
||||
idata->internal_file->crc_checked = 1;
|
||||
|
||||
fpf = php_stream_alloc(&phar_ops, idata, NULL, mode);
|
||||
efree(internal_file);
|
||||
return stream;
|
||||
return fpf;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -1445,7 +1381,7 @@ PHP_MINFO_FUNCTION(phar)
|
||||
php_info_print_table_row(2, "phar API version", "0.8.0");
|
||||
php_info_print_table_row(2, "CVS revision", "$Revision$");
|
||||
php_info_print_table_row(2, "compressed phar support",
|
||||
#ifdef HAVE_PHAR_ZLIB
|
||||
#if HAVE_ZLIB
|
||||
"enabled");
|
||||
#else
|
||||
"disabled");
|
||||
|
@ -15,7 +15,7 @@ $files['a'] = 'a';
|
||||
$manifest = '';
|
||||
foreach($files as $name => $cont) {
|
||||
$len = strlen($cont);
|
||||
$manifest .= pack('V', strlen($name)) . $name . pack('VVVVC', $len, time(), 3, crc32($cont), 0x01);
|
||||
$manifest .= pack('V', strlen($name)) . $name . pack('VVVVC', $len, time(), 1, crc32($cont), 0x01);
|
||||
}
|
||||
$alias = 'hio';
|
||||
$manifest = pack('VnV', count($files), 0x0800, strlen($alias)) . $alias . $manifest;
|
||||
|
Loading…
Reference in New Issue
Block a user