diff --git a/classes/emr-plugin.php b/classes/emr-plugin.php index ad2fcd2..05577d6 100644 --- a/classes/emr-plugin.php +++ b/classes/emr-plugin.php @@ -69,6 +69,12 @@ public function uiHelper() public function useFeature($name) { + // If for some obscure reason, it's called earlier or out of admin, still load the features. + if (count($this->features) === 0) + { + $this->adminInit(); + } + switch($name) { case 'background': diff --git a/classes/replacer.php b/classes/replacer.php index cf8ab87..d19b417 100644 --- a/classes/replacer.php +++ b/classes/replacer.php @@ -45,11 +45,17 @@ public function __construct($post_id) if (function_exists('wp_get_original_image_path')) // WP 5.3+ { $source_file = wp_get_original_image_path($post_id); + if ($source_file === false) // if it's not an image, returns false, use the old way. + { $source_file = trim(get_attached_file($post_id, apply_filters( 'emr_unfiltered_get_attached_file', true ))); + } + else { + $this->source_is_scaled = true; + } } else - $source_file = trim(get_attached_file($post_id, apply_filters( 'emr_unfiltered_get_attached_file', true ))); + $source_file = trim(get_attached_file($post_id, apply_filters( 'emr_unfiltered_get_attached_file', true ))); /* It happens that the SourceFile returns relative / incomplete when something messes up get_upload_dir with an error something. This case shoudl be detected here and create a non-relative path anyhow.. @@ -78,8 +84,7 @@ public function __construct($post_id) } else $this->source_url = wp_get_attachment_url($post_id); - // $this->ThumbnailUpdater = new \ThumbnailUpdater($post_id); - //$this->ThumbnailUpdater->setOldMetadata($this->source_metadata); + } private function fs() @@ -139,8 +144,15 @@ public function replaceWith($file, $fileName) if (false === $result_moved) { - $ex = sprintf( esc_html__('The uploaded file could not be moved to %1$s. This is most likely an issue with permissions, or upload failed.', "enable-media-replace"), $targetFile ); - throw new \RuntimeException($ex); + if ($targetFileObj->exists()) + { + Log::addDebug('Could remove file from tmp directory?'); + } + else { + $ex = sprintf( esc_html__('The uploaded file could not be moved to %1$s. This is most likely an issue with permissions, or upload failed.', "enable-media-replace"), $targetFile ); + throw new \RuntimeException($ex); + } + } // init targetFile. @@ -513,10 +525,11 @@ protected function doSearchReplace($args = array()) // get relurls of both source and target. $urls = $this->getRelativeURLS(); - if ($args['thumbnails_only']) { - foreach($urls as $side => $data) +// if (isset($urls['source']['file']) && $urls['source']) + + /*foreach($urls as $side => $data) { if (isset($data['base'])) { @@ -526,7 +539,7 @@ protected function doSearchReplace($args = array()) { unset($urls[$side]['file']); } - } + } */ } $search_urls = $urls['source']; @@ -543,8 +556,18 @@ protected function doSearchReplace($args = array()) } } - Log::addDebug('Source', $this->source_metadata); - Log::addDebug('Target', $this->target_metadata); + // Original can be unbalanced + if (isset($search_urls['original'])) + { + if (! isset($replace_urls['original'])) + { + $replace_urls['original'] = $replace_urls['file']; + } + } + + + Log::addDebug('Source', $search_urls); + Log::addDebug('Target', $replace_urls); /* If on the other hand, some sizes are available in source, but not in target, try to replace them with something closeby. */ foreach($search_urls as $size => $url) { @@ -563,6 +586,11 @@ protected function doSearchReplace($args = array()) Log::addDebug('Unset size ' . $size . ' - no closest found in source'); } } + elseif ($url === $replace_urls[$size]) { // identical + unset($replace_urls[$size]); + unset($search_urls[$size]); + Log::addDebug('Unset size ' . $size . ' - search and replace identical'); + } } /* If source and target are the same, remove them from replace. This happens when replacing a file with same name, and +/- same dimensions generated. @@ -707,7 +735,6 @@ private function handleMetaData($url, $search_urls, $replace_urls) } $sql = $wpdb->prepare($sql, $prepare); - Log::addTemp('Handle MEta SQL ' . $sql); if ($wpdb->last_error) Log::addWarn('Error' . $wpdb->last_error, $wpdb->last_query); @@ -828,6 +855,10 @@ private function getFilesFromMetadata($meta) $fileArray = array(); if (isset($meta['file'])) $fileArray['file'] = $meta['file']; + if (isset($meta['original_image'])) + { + $fileArray['original'] = $meta['original_image']; + } if (isset($meta['sizes'])) { @@ -839,6 +870,8 @@ private function getFilesFromMetadata($meta) } } } + + // scaled return $fileArray; } @@ -860,9 +893,6 @@ private function getRelativeURLS() 'target' => array('url' => $this->target_url, 'metadata' => $this->getFilesFromMetadata($this->target_metadata) ), ); - // Log::addDebug('Source Metadata', $this->source_metadata); - // Log::addDebug('Target Metadata', $this->target_metadata); - $result = array(); foreach($dataArray as $index => $item) @@ -880,7 +910,7 @@ private function getRelativeURLS() } } - // Log::addDebug('Relative URLS', $result); + Log::addDebug('Relative URLS', $result); return $result; } diff --git a/classes/uihelper.php b/classes/uihelper.php index 0943983..c609189 100644 --- a/classes/uihelper.php +++ b/classes/uihelper.php @@ -82,7 +82,6 @@ public function getSuccesRedirect($post_id) } $url = apply_filters('emr_returnurl', $url); - Log::addDebug('Success URL- ' . $url); return $url; @@ -100,7 +99,6 @@ public function getFailedRedirect($attach_id) ); $url = apply_filters('emr_returnurl_failed', $url); - Log::addDebug('Failed URL- ' . $url); return $url; } diff --git a/enable-media-replace.php b/enable-media-replace.php index 36fd520..c09e968 100644 --- a/enable-media-replace.php +++ b/enable-media-replace.php @@ -3,7 +3,7 @@ * Plugin Name: Enable Media Replace * Plugin URI: https://wordpress.org/plugins/enable-media-replace/ * Description: Enable replacing media files by uploading a new file in the "Edit Media" section of the WordPress Media Library. - * Version: 4.0.1 + * Version: 4.0.2 * Author: ShortPixel * Author URI: https://shortpixel.com * GitHub Plugin URI: https://github.com/short-pixel-optimizer/enable-media-replace @@ -27,7 +27,7 @@ namespace EnableMediaReplace; -define( 'EMR_VERSION', '4.0.1' ); +define( 'EMR_VERSION', '4.0.2' ); if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. diff --git a/readme.txt b/readme.txt index 572fc7f..f7ed9f0 100644 --- a/readme.txt +++ b/readme.txt @@ -5,7 +5,7 @@ Tags: replace, attachment, media, files, replace image, remove background, repla Requires at least: 4.9.7 Tested up to: 6.1 Requires PHP: 5.6 -Stable tag: 4.0.1 +Stable tag: 4.0.2 Easily replace any attached image/file by simply uploading a new file in the Media Library edit view - a real time saver! @@ -61,6 +61,14 @@ If you want more control over the format in which the time is shown, you can use == Changelog == += 4.0.2 = + +Release date: January 13, 2023 +* Fix: patched a security vulnerability that could allow loading an unauthorized file during the replace operation; +* Fix: finish the replace operation even if the tmp file cannot be removed due to file permissions issues; +* Fix: when replacing a scaled file with a non-scaled file, some links were broken; +* Fix: under certain conditions a PHP warning about an undefined array key was displayed. + = 4.0.1 = Release date: November 23, 2022 diff --git a/views/upload.php b/views/upload.php index 6c15342..decf5bc 100644 --- a/views/upload.php +++ b/views/upload.php @@ -74,7 +74,6 @@ $custom_minute = str_pad($_POST['custom_minute'], 2, 0, STR_PAD_LEFT); // create a mysql time representation from what we have. - Log::addDebug($_POST); Log::addDebug('Custom Date - ' . $custom_date . ' ' . $custom_hour . ':' . $custom_minute); $custom_date = \DateTime::createFromFormat('Y-m-d G:i', $custom_date . ' ' . $custom_hour . ':' . $custom_minute); if ($custom_date === false) { @@ -115,8 +114,7 @@ $replacer->setTimeMode($timestamp_replace, $datetime); /** Check if file is uploaded properly **/ -// @todo Post remove Bg should be removed. -if (is_uploaded_file($_FILES["userfile"]["tmp_name"]) || isset($_POST["remove_bg"])) { +if (is_uploaded_file($_FILES["userfile"]["tmp_name"])) { Log::addDebug($_FILES['userfile']); // New method for validating that the uploaded file is allowed, using WP:s internal wp_check_filetype_and_ext() function. @@ -131,7 +129,8 @@ } - if ($filedata["ext"] == false && ! current_user_can('unfiltered_upload') && ! isset($_POST["remove_bg"])) { + if ($filedata["ext"] == false && ! current_user_can('unfiltered_upload')) { + Log::addWarn('Uploaded File type does not meet security guidelines, aborting'); Notices::addError(esc_html__("File type does not meet security guidelines. Try another.", 'enable-media-replace')); wp_safe_redirect($redirect_error); exit(); @@ -139,7 +138,6 @@ // Here we have the uploaded file $new_filename = $_FILES["userfile"]["name"]; - //$new_filesize = $_FILES["userfile"]["size"]; // Seems not to be in use. $new_filetype = $filedata["type"] ? $filedata["type"] : $_FILES['userfile']['type']; // Gather all functions that both options do. @@ -153,7 +151,7 @@ } */ try { - $result = $replacer->replaceWith($_FILES["userfile"]["tmp_name"], $new_filename , isset($_POST["remove_bg"])); + $result = $replacer->replaceWith($_FILES["userfile"]["tmp_name"], $new_filename); } catch (\RunTimeException $e) { var_dump($e->getMessage()); die; @@ -168,7 +166,7 @@ // Execute hook actions - thanks rubious for the suggestion! } else { - //TODO Better error handling when no file is selected. + //@TODO Better error handling when no file is selected. //For now just go back to media management //$returnurl = admin_url("upload.php"); Log::addInfo('Failed. Redirecting - '. $redirect_error);