From 90e8582d6605b00b8b02df2fe9bfef13c213314c Mon Sep 17 00:00:00 2001 From: Tomasz Sita Date: Wed, 2 Sep 2015 08:51:56 +0100 Subject: [PATCH 1/3] Input sanitization and a bit of celanup --- lib/ManualImageCrop.php | 93 +++++++++++++++++++---------- lib/ManualImageCropEditorWindow.php | 28 ++++----- lib/ManualImageCropSettingsPage.php | 5 +- 3 files changed, 79 insertions(+), 47 deletions(-) diff --git a/lib/ManualImageCrop.php b/lib/ManualImageCrop.php index a4d9cb4..a7b9466 100644 --- a/lib/ManualImageCrop.php +++ b/lib/ManualImageCrop.php @@ -140,14 +140,45 @@ public function addAfterUploadAttachementEditLink() { filter_var($_POST['attachmentId'], FILTER_SANITIZE_NUMBER_INT), + 'editedSize' => in_array($_POST['editedSize'], $imageSizes) ? $_POST['editedSize'] : null, + 'select' => array( + 'x' => filter_var($_POST['select']['x'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION), + 'y' => filter_var($_POST['select']['y'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION), + 'w' => filter_var($_POST['select']['w'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION), + 'h' => filter_var($_POST['select']['h'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION), + ), + 'previewScale' => filter_var($_POST['previewScale'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) + + ); + + if (isset($_POST['mic_quality'])) { + $data['mic_quality'] = filter_var($_POST['mic_quality'], FILTER_SANITIZE_NUMBER_INT); + } else { + $data['mic_quality'] = 60; + } + + if (isset($_POST['make2x'])) { + $data['make2x'] = filter_var($_POST['make2x'], FILTER_VALIDATE_BOOLEAN); + } + + return $data; + } /** * Crops the image based on params passed in $_POST array */ public function cropImage() { global $_wp_additional_image_sizes; + + $data = $this->filterPostData(); - $dst_file_url = wp_get_attachment_image_src($_POST['attachmentId'], $_POST['editedSize']); + $dst_file_url = wp_get_attachment_image_src($data['attachmentId'], $data['editedSize']); if (!$dst_file_url) { exit; @@ -163,10 +194,10 @@ public function cropImage() { if ( function_exists( '_load_image_to_edit_path' ) ) { // this function is consider as private, but it return proper image path. Notice it is in function_exists condition - $src_file = _load_image_to_edit_path( $_POST['attachmentId'], 'full' ); - $dst_file = _load_image_to_edit_path( $_POST['attachmentId'], $_POST['editedSize'] ); + $src_file = _load_image_to_edit_path( $data['attachmentId'], 'full' ); + $dst_file = _load_image_to_edit_path( $data['attachmentId'], $data['editedSize'] ); } else { - $src_file_url = wp_get_attachment_image_src( $_POST['attachmentId'], 'full' ); + $src_file_url = wp_get_attachment_image_src( $data['attachmentId'], 'full' ); if ( ! $src_file_url ) { echo json_encode( array( 'status' => 'error', 'message' => 'wrong attachment' ) ); @@ -179,31 +210,31 @@ public function cropImage() { //checks if the destination image file is present (if it's not, we want to create a new file, as the WordPress returns the original image instead of specific one) if ($dst_file == $src_file) { - $attachmentData = wp_generate_attachment_metadata( $_POST['attachmentId'], $dst_file ); + $attachmentData = wp_generate_attachment_metadata( $data['attachmentId'], $dst_file ); //overwrite with previous values - $prevAttachmentData = wp_get_attachment_metadata($_POST['attachmentId']); + $prevAttachmentData = wp_get_attachment_metadata($data['attachmentId']); if (isset($prevAttachmentData['micSelectedArea'])) { $attachmentData['micSelectedArea'] = $prevAttachmentData['micSelectedArea']; } //saves new path to the image size in the database - wp_update_attachment_metadata( $_POST['attachmentId'], $attachmentData ); + wp_update_attachment_metadata( $data['attachmentId'], $attachmentData ); //new destination file path - replaces original file name with the correct one - $dst_file = str_replace( basename($attachmentData['file']), $attachmentData['sizes'][ $_POST['editedSize'] ]['file'], $dst_file); + $dst_file = str_replace( basename($attachmentData['file']), $attachmentData['sizes'][ $data['editedSize'] ]['file'], $dst_file); //retrieves the new url to file (needet to refresh the preview) - $dst_file_url = wp_get_attachment_image_src($_POST['attachmentId'], $_POST['editedSize']); + $dst_file_url = wp_get_attachment_image_src($data['attachmentId'], $data['editedSize']); } //sets the destination image dimensions - if (isset($_wp_additional_image_sizes[$_POST['editedSize']])) { - $dst_w = min(intval($_wp_additional_image_sizes[$_POST['editedSize']]['width']), $_POST['select']['w'] * $_POST['previewScale']); - $dst_h = min(intval($_wp_additional_image_sizes[$_POST['editedSize']]['height']), $_POST['select']['h'] * $_POST['previewScale']); + if (isset($_wp_additional_image_sizes[$data['editedSize']])) { + $dst_w = min(intval($_wp_additional_image_sizes[$data['editedSize']]['width']), $data['select']['w'] * $data['previewScale']); + $dst_h = min(intval($_wp_additional_image_sizes[$data['editedSize']]['height']), $data['select']['h'] * $data['previewScale']); } else { - $dst_w = min(get_option($_POST['editedSize'].'_size_w'), $_POST['select']['w'] * $_POST['previewScale']); - $dst_h = min(get_option($_POST['editedSize'].'_size_h'), $_POST['select']['h'] * $_POST['previewScale']); + $dst_w = min(get_option($data['editedSize'].'_size_w'), $data['select']['w'] * $data['previewScale']); + $dst_h = min(get_option($data['editedSize'].'_size_h'), $data['select']['h'] * $data['previewScale']); } if (!$dst_w || !$dst_h) { @@ -214,10 +245,10 @@ public function cropImage() { //prepares coordinates that will be passed to cropping function $dst_x = 0; $dst_y = 0; - $src_x = max(0, $_POST['select']['x']) * $_POST['previewScale']; - $src_y = max(0, $_POST['select']['y']) * $_POST['previewScale']; - $src_w = max(0, $_POST['select']['w']) * $_POST['previewScale']; - $src_h = max(0, $_POST['select']['h']) * $_POST['previewScale']; + $src_x = max(0, $data['select']['x']) * $data['previewScale']; + $src_y = max(0, $data['select']['y']) * $data['previewScale']; + $src_w = max(0, $data['select']['w']) * $data['previewScale']; + $src_h = max(0, $data['select']['h']) * $data['previewScale']; $size = wp_get_image_editor( $src_file )->get_size(); @@ -238,17 +269,15 @@ public function cropImage() { } //saves the selected area - $imageMetadata = wp_get_attachment_metadata($_POST['attachmentId']); - $imageMetadata['micSelectedArea'][$_POST['editedSize']] = array( - 'x' => $_POST['select']['x'], - 'y' => $_POST['select']['y'], - 'w' => $_POST['select']['w'], - 'h' => $_POST['select']['h'], - 'scale' => $_POST['previewScale'], + $imageMetadata = wp_get_attachment_metadata($data['attachmentId']); + $imageMetadata['micSelectedArea'][$data['editedSize']] = array( + 'x' => $data['select']['x'], + 'y' => $data['select']['y'], + 'w' => $data['select']['w'], + 'h' => $data['select']['h'], + 'scale' => $data['previewScale'], ); - wp_update_attachment_metadata($_POST['attachmentId'], $imageMetadata); - - $quality = isset($_POST['mic_quality']) ? intval($_POST['mic_quality']) : 60; + wp_update_attachment_metadata($data['attachmentId'], $imageMetadata); if ( function_exists('wp_get_image_editor') ) { $img = wp_get_image_editor( $src_file ); @@ -256,7 +285,7 @@ public function cropImage() { if ( ! is_wp_error( $img ) ) { $img->crop( $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h, false ); - $img->set_quality( $quality ); + $img->set_quality( $data['mic_quality'] ); $saveStatus = $img->save( $dst_file ); if ( is_wp_error( $saveStatus ) ) { @@ -307,7 +336,7 @@ public function cropImage() { } // Generate Retina Image - if( isset( $_POST['make2x'] ) && $_POST['make2x'] === 'true' ) { + if( isset( $data['make2x'] ) && $data['make2x'] === 'true' ) { $dst_w2x = $dst_w * 2; $dst_h2x = $dst_h * 2; @@ -352,8 +381,8 @@ public function cropImage() { } } // update 'mic_make2x' option status to persist choice - if( isset( $_POST['make2x'] ) && $_POST['make2x'] !== get_option('mic_make2x') ) { - update_option('mic_make2x', $_POST['make2x']); + if( isset( $data['make2x'] ) && $data['make2x'] !== get_option('mic_make2x') ) { + update_option('mic_make2x', $data['make2x']); } //returns the url to the generated image (to allow refreshing the preview) diff --git a/lib/ManualImageCropEditorWindow.php b/lib/ManualImageCropEditorWindow.php index 5688755..812d8ce 100644 --- a/lib/ManualImageCropEditorWindow.php +++ b/lib/ManualImageCropEditorWindow.php @@ -36,8 +36,10 @@ public function renderWindow() { $imageSizes = get_intermediate_image_sizes(); - $editedSize = isset( $_GET['size'] ) ? $_GET['size'] : null; + $editedSize = in_array($_GET['size'], $imageSizes) ? $_GET['size'] : null; + $postId = filter_var($_GET['postId'], FILTER_SANITIZE_NUMBER_INT); + $sizeLabels = apply_filters( 'image_size_names_choose', array( 'thumbnail' => __('Thumbnail'), 'medium' => __('Medium'), @@ -74,7 +76,7 @@ public function renderWindow() { // Get user defined label for the size or just cleanup a bit $label = isset($sizeLabels[$s]) ? $sizeLabels[$s] : ucfirst( str_replace( '-', ' ', $s ) ); $label = $sizesSettings[$s]['label'] ? $sizesSettings[$s]['label'] : $label; - echo '' . $label . ''; + echo '' . $label . ''; } ?> @@ -93,9 +95,9 @@ public function renderWindow() { $uploadsDir = wp_upload_dir(); - $metaData = wp_get_attachment_metadata($_GET['postId']); + $metaData = wp_get_attachment_metadata($postId); - $src_file_url = wp_get_attachment_image_src($_GET['postId'], 'full'); + $src_file_url = wp_get_attachment_image_src($postId, 'full'); if (!$src_file_url) { echo json_encode (array('status' => 'error', 'message' => 'wrong attachement' ) ); exit; @@ -127,12 +129,11 @@ public function renderWindow() { $minWidth = min($width / $previewRatio, $previewWidth); $minHeight = min($height / $previewRatio, $previewHeight); - if ($cropMethod == 1) { + if ($cropMethod != 0) { $aspectRatio = ($width / $height); - // if ($aspectRatio * $minWidth > $sizes[0]) { - // die('a'); - // $aspectRatio = ($previewWidth / $minHeight); - // } + // if ($aspectRatio * $minWidth > $sizes[0]) { + // $aspectRatio = ($previewWidth / $minHeight); + // } if (1 / $aspectRatio * $minHeight > $sizes[1]) { $aspectRatio = ($minWidth / $previewHeight); @@ -157,7 +158,7 @@ public function renderWindow() { ?>
- +
@@ -181,13 +182,13 @@ public function renderWindow() {
+ src="">
@@ -237,7 +238,7 @@ public function renderWindow() {
'; - $sizesSettings = self::getSettings() || array(); + $sizesSettings = self::getSettings(); + if (!is_array($sizesSettings)) { + $sizesSettings = array(); + } foreach ($imageSizes as $s) { $label = isset($sizeLabels[$s]) ? $sizeLabels[$s] : ucfirst( str_replace( '-', ' ', $s ) ); From de5112b93084f6f525d72b6238ec0bb1ff4eff3b Mon Sep 17 00:00:00 2001 From: Tomasz Sita Date: Wed, 2 Sep 2015 08:52:16 +0100 Subject: [PATCH 2/3] updated readme.txt --- readme.txt | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/readme.txt b/readme.txt index e2c1786..cd1175c 100644 --- a/readme.txt +++ b/readme.txt @@ -1,16 +1,15 @@ === Manual Image Crop === Contributors: tomasz.sita Tags: crop, cropping, thumbnail, featured image, gallery, images, picture, image, image area -Tested up to: 4.2.1 +Tested up to: 4.3 Requires at least: 3.5 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WB5ZQWGUM7T96 -Stable tag: 1.09 +Stable tag: 1.12 Plugin allows you to manually crop all the image sizes registered in your WordPress theme (in particular featured image). - == Description == Plugin allows you to manually crop all the image sizes registered in your WordPress theme (in particular featured image). Simply click on the "Crop" link next to any image in your media library. @@ -21,32 +20,49 @@ Apart from media library list, the plugin adds links in few more places: * Below featured image box ("Crop featured image") * In the media insert modal window (once you select an image) -GitHub Repository: += Enjoying using Manual Image Crop? = +[Donate the plugin here](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WB5ZQWGUM7T96 "Donate") + +Thank you! + += GitHub Repository = https://github.com/tomaszsita/wp-manual-image-crop -Translations: += Translations = * Dutch (Bernardo Hulsman) * French (Gabriel FĂ©ron) * German (Bertram Greenhough) +* Hungarian (Roland Kal) * Italian (Alessandro Curci) * Polish (myself) * Russian (Andrey Hohlov) * Spanish (Andrew Kurtis) +* Swedish (Karl Oskar Mattsson) Please contact me if you want to add a translation (or submit a pull request on GitHub) - == Installation == -Manually: -* Upload `manual-image-crop` to the `/wp-content/plugins/` directory -* Activate the plugin through the 'Plugins' menu in WordPress += Manually: = +* Upload `manual-image-crop` to the `/wp-content/plugins/` directory +* Activate the plugin through the 'Plugins' menu in WordPress -Automatically: -* Navigate to the 'Plugins' menu inside of the wordpress wp-admin dashboard, and select AD NEW -* Search for 'Manual Imag Crop', and click install -* When the plugin has been installed, Click 'Activate' += Automatically: = +* Navigate to the 'Plugins' menu inside of the wordpress wp-admin dashboard, and select AD NEW +* Search for 'Manual Imag Crop', and click install +* When the plugin has been installed, Click 'Activate' == Changelog == += 1.12 = +* Fixed 'streched images' issue + += 1.11 = +* Hungarian translation added +* Swedish translation added +* Security improvements + += 1.10 = +* Fixed handling of array $crop param + = 1.09 = * Dutch translation added * Better error handling From 623bfa9e8de063462bb79739dcab0438d016ec6f Mon Sep 17 00:00:00 2001 From: Tomasz Sita Date: Wed, 2 Sep 2015 08:52:27 +0100 Subject: [PATCH 3/3] v1.12 --- manual-image-crop.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/manual-image-crop.php b/manual-image-crop.php index 63eb8ac..0b7f6da 100644 --- a/manual-image-crop.php +++ b/manual-image-crop.php @@ -1,9 +1,9 @@