When using download_url(), if the resource supplies a Content-MD5 header, verify the downloaded file against it. Fixes #20074

Built from https://develop.svn.wordpress.org/trunk@25541


git-svn-id: http://core.svn.wordpress.org/trunk@25461 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Dion Hulse 2013-09-21 06:54:09 +00:00
parent 6737d0a202
commit a82b463610
1 changed files with 34 additions and 0 deletions

View File

@ -485,9 +485,43 @@ function download_url( $url, $timeout = 300 ) {
return new WP_Error( 'http_404', trim( wp_remote_retrieve_response_message( $response ) ) ); return new WP_Error( 'http_404', trim( wp_remote_retrieve_response_message( $response ) ) );
} }
$content_md5 = wp_remote_retrieve_header( $response, 'content-md5' );
if ( $content_md5 ) {
$md5_check = verify_file_md5( $tmpfname, $content_md5 );
if ( is_wp_error( $md5_check ) ) {
unlink( $tmpfname );
return $md5_check;
}
}
return $tmpfname; return $tmpfname;
} }
/**
* Calculates and compares the MD5 of a file to it's expected value.
*
* @since 3.7.0
*
* @param string $filename The filename to check the MD5 of.
* @param string $expected_md5 The expected MD5 of the file, either a base64 encoded raw md5, or a hex-encoded md5
* @return bool|object WP_Error on failure, true on success, false when the MD5 format is unknown/unexpected
*/
function verify_file_md5( $filename, $expected_md5 ) {
if ( 32 == strlen( $expected_md5 ) )
$expected_raw_md5 = pack( 'H*', $expected_md5 );
elseif ( 24 == strlen( $expected_md5 ) )
$expected_raw_md5 = base64_decode( $expected_md5 );
else
return false; // unknown format
$file_md5 = md5_file( $filename, true );
if ( $file_md5 === $expected_raw_md5 )
return true;
return new WP_Error( 'md5_mismatch', sprintf( __( 'The checksum of the file (%1$s) does not match the expected checksum value (%2$s).' ), bin2hex( $file_md5 ), bin2hex( $expected_raw_md5 ) ) );
}
/** /**
* Unzips a specified ZIP file to a location on the Filesystem via the WordPress Filesystem Abstraction. * Unzips a specified ZIP file to a location on the Filesystem via the WordPress Filesystem Abstraction.
* Assumes that WP_Filesystem() has already been called and set up. Does not extract a root-level __MACOSX directory, if present. * Assumes that WP_Filesystem() has already been called and set up. Does not extract a root-level __MACOSX directory, if present.