diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 8a4599d5f43..027c78a18c9 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -5058,6 +5058,7 @@ PHP_METHOD(PharFileInfo, compress) PHP_METHOD(PharFileInfo, decompress) { char *error; + char *compression_type; PHAR_ENTRY_OBJECT(); if (zend_parse_parameters_none() == FAILURE) { @@ -5108,12 +5109,24 @@ PHP_METHOD(PharFileInfo, decompress) /* re-populate after copy-on-write */ entry_obj->entry = zend_hash_str_find_ptr(&phar->manifest, entry_obj->entry->filename, entry_obj->entry->filename_len); } - if (!entry_obj->entry->fp) { - if (FAILURE == phar_open_archive_fp(entry_obj->entry->phar)) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot decompress entry \"%s\", phar error: Cannot open phar archive \"%s\" for reading", entry_obj->entry->filename, entry_obj->entry->phar->fname); + switch (entry_obj->entry->flags & PHAR_ENT_COMPRESSION_MASK) { + case PHAR_ENT_COMPRESSED_GZ: + compression_type = "gzip"; + break; + case PHAR_ENT_COMPRESSED_BZ2: + compression_type = "bz2"; + break; + default: + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, + "Cannot decompress file compressed with unknown compression type"); RETURN_THROWS(); - } - entry_obj->entry->fp_type = PHAR_FP; + } + /* decompress this file indirectly */ + if (SUCCESS != phar_open_entry_fp(entry_obj->entry, &error, 1)) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, + "Phar error: Cannot decompress %s-compressed file \"%s\" in phar \"%s\": %s", compression_type, entry_obj->entry->filename, entry_obj->entry->phar->fname, error); + efree(error); + return; } entry_obj->entry->old_flags = entry_obj->entry->flags; diff --git a/ext/phar/tests/bug76584.phpt b/ext/phar/tests/bug76584.phpt new file mode 100644 index 00000000000..b37de08c494 --- /dev/null +++ b/ext/phar/tests/bug76584.phpt @@ -0,0 +1,35 @@ +--TEST-- +Bug #76584 (PharFileInfo::decompress not working) +--SKIPIF-- + +--INI-- +phar.readonly=0 +--FILE-- +addFromString('76584.txt', 'This is a test file.'); +$file = $phar['76584.txt']; +var_dump($file->compress(Phar::GZ)); +var_dump($file->isCompressed()); +var_dump($file->decompress()); +var_dump($file->isCompressed()); +mkdir(__DIR__ . '/76584'); +var_dump($phar->extractTo(__DIR__ . '/76584')); +echo file_get_contents(__DIR__ . '/76584/76584.txt'); +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(false) +bool(true) +This is a test file. +--CLEAN-- +