Skip to content

Commit 6eda6f0

Browse files
committed
Media: Prevent scaling up of images in the Image Editor.
Previously, when scaling an image larger than the source size in the image edit states the image would silently fail the scaling action. This patch provides an error when someone attempts to scale an image larger than the source size while also disabling the button to initiate the action. Props brookedot, joedolson, markoheijnen, mikeschroder, desrosj, Mista-Flo, costdev. Fixes #26381. git-svn-id: https://develop.svn.wordpress.org/trunk@55859 602fd350-edb4-49c9-b593-d223f7449a82
1 parent ad57ef6 commit 6eda6f0

File tree

4 files changed

+58
-17
lines changed

4 files changed

+58
-17
lines changed

src/js/_enqueues/lib/image-edit.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,8 @@
226226
*/
227227
scaleChanged : function( postid, x, el ) {
228228
var w = $('#imgedit-scale-width-' + postid), h = $('#imgedit-scale-height-' + postid),
229-
warn = $('#imgedit-scale-warn-' + postid), w1 = '', h1 = '';
229+
warn = $('#imgedit-scale-warn-' + postid), w1 = '', h1 = '',
230+
scaleBtn = $('#imgedit-scale-button');
230231

231232
if ( false === this.validateNumeric( el ) ) {
232233
return;
@@ -242,8 +243,10 @@
242243

243244
if ( ( h1 && h1 > this.hold.oh ) || ( w1 && w1 > this.hold.ow ) ) {
244245
warn.css('visibility', 'visible');
246+
scaleBtn.prop('disabled', true);
245247
} else {
246248
warn.css('visibility', 'hidden');
249+
scaleBtn.prop('disabled', false);
247250
}
248251
},
249252

src/wp-admin/css/media.css

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,8 +1154,11 @@ border color while dragging a file over the uploader drop area */
11541154
}
11551155

11561156
span.imgedit-scale-warn {
1157-
color: #d63638;
1158-
font-size: 20px;
1157+
display: flex;
1158+
align-items: center;
1159+
margin: 4px;
1160+
gap: 4px;
1161+
color: #b32d2e;
11591162
font-style: normal;
11601163
visibility: hidden;
11611164
vertical-align: middle;

src/wp-admin/includes/image-edit.php

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -143,18 +143,19 @@ function wp_image_editor( $post_id, $msg = false ) {
143143
_e( 'scale width' );
144144
?>
145145
</label>
146-
<input type="text" id="imgedit-scale-width-<?php echo $post_id; ?>" onkeyup="imageEdit.scaleChanged(<?php echo $post_id; ?>, 1, this)" onblur="imageEdit.scaleChanged(<?php echo $post_id; ?>, 1, this)" value="<?php echo isset( $meta['width'] ) ? $meta['width'] : 0; ?>" />
146+
<input type="number" aria-describedby="imgedit-scale-warn-<?php echo $post_id; ?>" min="1" max="<?php echo isset( $meta['width'] ) ? $meta['width'] : ''; ?>" step="1" id="imgedit-scale-width-<?php echo $post_id; ?>" onkeyup="imageEdit.scaleChanged(<?php echo $post_id; ?>, 1, this)" onchange="imageEdit.scaleChanged(<?php echo $post_id; ?>, 0, this)" onblur="imageEdit.scaleChanged(<?php echo $post_id; ?>, 1, this)" value="<?php echo isset( $meta['width'] ) ? $meta['width'] : 0; ?>" />
147147
<span class="imgedit-separator" aria-hidden="true">&times;</span>
148148
<label for="imgedit-scale-height-<?php echo $post_id; ?>" class="screen-reader-text">
149149
<?php
150150
/* translators: Hidden accessibility text. */
151151
_e( 'scale height' );
152152
?>
153153
</label>
154-
<input type="text" id="imgedit-scale-height-<?php echo $post_id; ?>" onkeyup="imageEdit.scaleChanged(<?php echo $post_id; ?>, 0, this)" onblur="imageEdit.scaleChanged(<?php echo $post_id; ?>, 0, this)" value="<?php echo isset( $meta['height'] ) ? $meta['height'] : 0; ?>" />
155-
<span class="imgedit-scale-warn" id="imgedit-scale-warn-<?php echo $post_id; ?>">!</span>
154+
<input type="number" aria-describedby="imgedit-scale-warn-<?php echo $post_id; ?>" min="1" max="<?php echo isset( $meta['height'] ) ? $meta['height'] : ''; ?>" step="1" id="imgedit-scale-height-<?php echo $post_id; ?>" onkeyup="imageEdit.scaleChanged(<?php echo $post_id; ?>, 0, this)" onchange="imageEdit.scaleChanged(<?php echo $post_id; ?>, 0, this)" onblur="imageEdit.scaleChanged(<?php echo $post_id; ?>, 0, this)" value="<?php echo isset( $meta['height'] ) ? $meta['height'] : 0; ?>" />
156155
<div class="imgedit-scale-button-wrapper"><input id="imgedit-scale-button" type="button" onclick="imageEdit.action(<?php echo "$post_id, '$nonce'"; ?>, 'scale')" class="button button-primary" value="<?php esc_attr_e( 'Scale' ); ?>" /></div>
157156
</div>
157+
<span class="imgedit-scale-warn" id="imgedit-scale-warn-<?php echo $post_id; ?>"><span class="dashicons dashicons-warning" aria-hidden="true"></span><?php esc_html_e( 'Images cannot be scaled to a size larger than the original.' ); ?></span>
158+
158159
</fieldset>
159160

160161
</div>
@@ -893,23 +894,30 @@ function wp_save_image( $post_id ) {
893894
$target = ! empty( $_REQUEST['target'] ) ? preg_replace( '/[^a-z0-9_-]+/i', '', $_REQUEST['target'] ) : '';
894895
$scale = ! empty( $_REQUEST['do'] ) && 'scale' === $_REQUEST['do'];
895896

896-
if ( $scale && $fwidth > 0 && $fheight > 0 ) {
897+
if ( $scale ) {
897898
$size = $img->get_size();
898899
$sX = $size['width'];
899900
$sY = $size['height'];
900901

901-
// Check if it has roughly the same w / h ratio.
902-
$diff = round( $sX / $sY, 2 ) - round( $fwidth / $fheight, 2 );
903-
if ( -0.1 < $diff && $diff < 0.1 ) {
904-
// Scale the full size image.
905-
if ( $img->resize( $fwidth, $fheight ) ) {
906-
$scaled = true;
907-
}
902+
if ( $sX < $fwidth || $sY < $fheight ) {
903+
$return->error = esc_js( __( 'Images cannot be scaled to a size larger than the original.' ) );
904+
return $return;
908905
}
909906

910-
if ( ! $scaled ) {
911-
$return->error = esc_js( __( 'Error while saving the scaled image. Please reload the page and try again.' ) );
912-
return $return;
907+
if ( $fwidth > 0 && $fheight > 0 ) {
908+
// Check if it has roughly the same w / h ratio.
909+
$diff = round( $sX / $sY, 2 ) - round( $fwidth / $fheight, 2 );
910+
if ( -0.1 < $diff && $diff < 0.1 ) {
911+
// Scale the full size image.
912+
if ( $img->resize( $fwidth, $fheight ) ) {
913+
$scaled = true;
914+
}
915+
}
916+
917+
if ( ! $scaled ) {
918+
$return->error = esc_js( __( 'Error while saving the scaled image. Please reload the page and try again.' ) );
919+
return $return;
920+
}
913921
}
914922
} elseif ( ! empty( $_REQUEST['history'] ) ) {
915923
$changes = json_decode( wp_unslash( $_REQUEST['history'] ) );

tests/phpunit/tests/ajax/wpAjaxImageEditor.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,33 @@ public function testCropImageThumbnail() {
6161
$this->assertArrayHasKey( 'medium', $media_meta['sizes'], 'cropped attachment should have data for medium size' );
6262
}
6363

64+
/**
65+
* @ticket 26381
66+
* @requires function imagejpeg
67+
*
68+
* @covers ::wp_save_image
69+
*/
70+
public function testCropImageIntoLargerOne() {
71+
require_once ABSPATH . 'wp-admin/includes/image-edit.php';
72+
73+
$filename = DIR_TESTDATA . '/images/canola.jpg';
74+
$contents = file_get_contents( $filename );
75+
76+
$upload = wp_upload_bits( wp_basename( $filename ), null, $contents );
77+
$id = $this->_make_attachment( $upload );
78+
79+
$_REQUEST['action'] = 'image-editor';
80+
$_REQUEST['postid'] = $id;
81+
$_REQUEST['do'] = 'scale';
82+
$_REQUEST['fwidth'] = 700;
83+
$_REQUEST['fheight'] = 500;
84+
85+
$ret = wp_save_image( $id );
86+
87+
$this->assertObjectHasAttribute( 'error', $ret );
88+
$this->assertEquals( 'Images cannot be scaled to a size larger than the original.', $ret->error );
89+
}
90+
6491
/**
6592
* @ticket 32171
6693
* @requires function imagejpeg

0 commit comments

Comments
 (0)