Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/wp-admin/includes/file.php
Original file line number Diff line number Diff line change
Expand Up @@ -1880,6 +1880,20 @@ function _unzip_file_ziparchive( $file, $to, $needed_dirs = array() ) {
function _unzip_file_pclzip( $file, $to, $needed_dirs = array() ) {
global $wp_filesystem;

/**
* Filters whether the zlib PHP extension is available for PclZip to extract archives.
*
* PclZip requires `gzopen()`, provided by the zlib extension. Without it, extraction
* cannot proceed.
*
* @since 7.2.0
*
* @param bool $zlib_available Whether the zlib extension is available. Default is the result of `function_exists( 'gzopen' )`.
*/
if ( ! apply_filters( 'unzip_file_pclzip_zlib_available', function_exists( 'gzopen' ) ) ) {
return new WP_Error( 'unzip_file_missing_zlib', __( 'PHP does not have the zlib extension enabled, which is required to extract this archive.' ) );
}

mbstring_binary_safe_encoding();

require_once ABSPATH . 'wp-admin/includes/class-pclzip.php';
Expand Down
15 changes: 15 additions & 0 deletions tests/phpunit/tests/filesystem/unzipFilePclzip.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,19 @@ public function test_should_apply_unzip_file_filters() {
$this->assertSame( 1, $filter->get_call_count(), 'The filter should be called once.' );
$this->assertSame( self::$test_data_dir . 'archive.zip', $filter->get_args()[0][1], 'The $file parameter should be correct.' );
}

/**
* Tests that _unzip_file_pclzip() returns a translatable WP_Error instead of
* fatal-erroring when the zlib extension is unavailable.
*
* @ticket 30963
*/
public function test_should_return_wp_error_when_zlib_extension_is_unavailable() {
add_filter( 'unzip_file_pclzip_zlib_available', '__return_false' );

$result = _unzip_file_pclzip( self::$test_data_dir . 'archive.zip', self::$test_data_dir . 'archive/' );

$this->assertWPError( $result, 'A WP_Error should be returned instead of a fatal error.' );
$this->assertSame( 'unzip_file_missing_zlib', $result->get_error_code(), 'The error code should identify the missing zlib extension.' );
}
}
Loading