From 452d30cf7d1ba36d7f8bb8aeff5fb3134376f873 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sat, 4 Jul 2015 21:01:50 -0700 Subject: Fix bug #69958 - Segfault in Phar::convertToData on invalid file --- ext/phar/phar_object.c | 70 ++++++++++++++++++++++--------------------- ext/phar/tests/bug69958.phpt | 14 +++++++++ ext/phar/tests/bug69958.tar | Bin 0 -> 513 bytes 3 files changed, 50 insertions(+), 34 deletions(-) create mode 100644 ext/phar/tests/bug69958.phpt create mode 100644 ext/phar/tests/bug69958.tar diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index add1fa0d5c..1184863de9 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -1269,7 +1269,7 @@ PHP_METHOD(Phar, __construct) INIT_PZVAL(&arg2); ZVAL_LONG(&arg2, flags); - zend_call_method_with_2_params(&zobj, Z_OBJCE_P(zobj), + zend_call_method_with_2_params(&zobj, Z_OBJCE_P(zobj), &spl_ce_RecursiveDirectoryIterator->constructor, "__construct", NULL, &arg1, &arg2); if (!phar_data->is_persistent) { @@ -1293,7 +1293,7 @@ PHP_METHOD(Phar, getSupportedSignatures) if (zend_parse_parameters_none() == FAILURE) { return; } - + array_init(return_value); add_next_index_stringl(return_value, "MD5", 3, 1); @@ -1320,7 +1320,7 @@ PHP_METHOD(Phar, getSupportedCompression) if (zend_parse_parameters_none() == FAILURE) { return; } - + array_init(return_value); phar_request_initialize(TSRMLS_C); @@ -1608,7 +1608,7 @@ phar_spl_fileinfo: } return ZEND_HASH_APPLY_STOP; } - + base = temp; base_len = strlen(base); @@ -1805,7 +1805,7 @@ after_open_fp: /* {{{ proto array Phar::buildFromDirectory(string base_dir[, string regex]) * Construct a phar archive from an existing directory, recursively. * Optional second parameter is a regular expression for filtering directory contents. - * + * * Return value is an array mapping phar index to actual files added. */ PHP_METHOD(Phar, buildFromDirectory) @@ -1845,7 +1845,7 @@ PHP_METHOD(Phar, buildFromDirectory) ZVAL_LONG(&arg2, SPL_FILE_DIR_SKIPDOTS|SPL_FILE_DIR_UNIXPATHS); #endif - zend_call_method_with_2_params(&iter, spl_ce_RecursiveDirectoryIterator, + zend_call_method_with_2_params(&iter, spl_ce_RecursiveDirectoryIterator, &spl_ce_RecursiveDirectoryIterator->constructor, "__construct", NULL, &arg, &arg2); if (EG(exception)) { @@ -1862,7 +1862,7 @@ PHP_METHOD(Phar, buildFromDirectory) RETURN_FALSE; } - zend_call_method_with_1_params(&iteriter, spl_ce_RecursiveIteratorIterator, + zend_call_method_with_1_params(&iteriter, spl_ce_RecursiveIteratorIterator, &spl_ce_RecursiveIteratorIterator->constructor, "__construct", NULL, iter); if (EG(exception)) { @@ -1887,7 +1887,7 @@ PHP_METHOD(Phar, buildFromDirectory) INIT_PZVAL(&arg2); ZVAL_STRINGL(&arg2, regex, regex_len, 0); - zend_call_method_with_2_params(®exiter, spl_ce_RegexIterator, + zend_call_method_with_2_params(®exiter, spl_ce_RegexIterator, &spl_ce_RegexIterator->constructor, "__construct", NULL, iteriter, &arg2); } @@ -2008,7 +2008,7 @@ PHP_METHOD(Phar, buildFromIterator) PHP_METHOD(Phar, count) { PHAR_ARCHIVE_OBJECT(); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -2173,7 +2173,7 @@ static zval *phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool c spprintf(&newname, 0, "%s.%s", strtok(basename, "."), ext); efree(basename); - + basepath = estrndup(oldpath, (strlen(oldpath) - oldname_len)); phar->fname_len = spprintf(&newpath, 0, "%s%s", basepath, newname); @@ -2419,7 +2419,9 @@ no_copy: zend_hash_destroy(&(phar->manifest)); zend_hash_destroy(&(phar->mounted_dirs)); zend_hash_destroy(&(phar->virtual_dirs)); - php_stream_close(phar->fp); + if (phar->fp) { + php_stream_close(phar->fp); + } efree(phar->fname); efree(phar); return NULL; @@ -2639,7 +2641,7 @@ PHP_METHOD(Phar, convertToData) PHP_METHOD(Phar, isCompressed) { PHAR_ARCHIVE_OBJECT(); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -2663,7 +2665,7 @@ PHP_METHOD(Phar, isWritable) { php_stream_statbuf ssb; PHAR_ARCHIVE_OBJECT(); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -2741,7 +2743,7 @@ PHP_METHOD(Phar, delete) PHP_METHOD(Phar, getAlias) { PHAR_ARCHIVE_OBJECT(); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -2758,7 +2760,7 @@ PHP_METHOD(Phar, getAlias) PHP_METHOD(Phar, getPath) { PHAR_ARCHIVE_OBJECT(); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -2874,7 +2876,7 @@ valid_alias: PHP_METHOD(Phar, getVersion) { PHAR_ARCHIVE_OBJECT(); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -2889,7 +2891,7 @@ PHP_METHOD(Phar, getVersion) PHP_METHOD(Phar, startBuffering) { PHAR_ARCHIVE_OBJECT(); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -2904,7 +2906,7 @@ PHP_METHOD(Phar, startBuffering) PHP_METHOD(Phar, isBuffering) { PHAR_ARCHIVE_OBJECT(); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -2921,7 +2923,7 @@ PHP_METHOD(Phar, stopBuffering) char *error; PHAR_ARCHIVE_OBJECT(); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -3156,7 +3158,7 @@ PHP_METHOD(Phar, setSignatureAlgorithm) PHP_METHOD(Phar, getSignature) { PHAR_ARCHIVE_OBJECT(); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -3200,7 +3202,7 @@ PHP_METHOD(Phar, getSignature) PHP_METHOD(Phar, getModified) { PHAR_ARCHIVE_OBJECT(); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -3462,7 +3464,7 @@ PHP_METHOD(Phar, decompressFiles) { char *error; PHAR_ARCHIVE_OBJECT(); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -3983,7 +3985,7 @@ PHP_METHOD(Phar, getStub) phar_entry_info *stub; PHAR_ARCHIVE_OBJECT(); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -4086,7 +4088,7 @@ PHP_METHOD(Phar, hasMetadata) PHP_METHOD(Phar, getMetadata) { PHAR_ARCHIVE_OBJECT(); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -4544,7 +4546,7 @@ PHP_METHOD(PharFileInfo, __construct) INIT_PZVAL(&arg1); ZVAL_STRINGL(&arg1, fname, fname_len, 0); - zend_call_method_with_1_params(&zobj, Z_OBJCE_P(zobj), + zend_call_method_with_1_params(&zobj, Z_OBJCE_P(zobj), &spl_ce_SplFileInfo->constructor, "__construct", NULL, &arg1); } /* }}} */ @@ -4582,7 +4584,7 @@ PHP_METHOD(PharFileInfo, __destruct) PHP_METHOD(PharFileInfo, getCompressedSize) { PHAR_ENTRY_OBJECT(); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -4624,7 +4626,7 @@ PHP_METHOD(PharFileInfo, isCompressed) PHP_METHOD(PharFileInfo, getCRC32) { PHAR_ENTRY_OBJECT(); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -4650,7 +4652,7 @@ PHP_METHOD(PharFileInfo, getCRC32) PHP_METHOD(PharFileInfo, isCRCChecked) { PHAR_ENTRY_OBJECT(); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -4665,7 +4667,7 @@ PHP_METHOD(PharFileInfo, isCRCChecked) PHP_METHOD(PharFileInfo, getPharFlags) { PHAR_ENTRY_OBJECT(); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -4743,7 +4745,7 @@ PHP_METHOD(PharFileInfo, chmod) PHP_METHOD(PharFileInfo, hasMetadata) { PHAR_ENTRY_OBJECT(); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -4758,7 +4760,7 @@ PHP_METHOD(PharFileInfo, hasMetadata) PHP_METHOD(PharFileInfo, getMetadata) { PHAR_ENTRY_OBJECT(); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -4839,7 +4841,7 @@ PHP_METHOD(PharFileInfo, delMetadata) char *error; PHAR_ENTRY_OBJECT(); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -4897,7 +4899,7 @@ PHP_METHOD(PharFileInfo, getContent) phar_entry_info *link; PHAR_ENTRY_OBJECT(); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -5071,7 +5073,7 @@ PHP_METHOD(PharFileInfo, decompress) { char *error; PHAR_ENTRY_OBJECT(); - + if (zend_parse_parameters_none() == FAILURE) { return; } diff --git a/ext/phar/tests/bug69958.phpt b/ext/phar/tests/bug69958.phpt new file mode 100644 index 0000000000..d63b413c29 --- /dev/null +++ b/ext/phar/tests/bug69958.phpt @@ -0,0 +1,14 @@ +--TEST-- +Phar: bug #69958: Segfault in Phar::convertToData on invalid file +--SKIPIF-- + +--FILE-- +convertToData(Phar::TAR); +--EXPECTF-- +Fatal error: Uncaught exception 'BadMethodCallException' with message 'phar "%s/bug69958.tar" exists and must be unlinked prior to conversion' in %s/bug69958.php:%d +Stack trace: +#0 %s/bug69958.php(%d): PharData->convertToData(%d) +#1 {main} + thrown in %s/bug69958.php on line %d diff --git a/ext/phar/tests/bug69958.tar b/ext/phar/tests/bug69958.tar new file mode 100644 index 0000000000..02275248bd Binary files /dev/null and b/ext/phar/tests/bug69958.tar differ -- cgit v1.2.1