Skip to content

Commit 7b6a96e

Browse files
committed
Add corrupted images validation
1 parent caae21c commit 7b6a96e

File tree

4 files changed

+135
-2
lines changed

4 files changed

+135
-2
lines changed

src/Symfony/Component/Validator/Constraints/Image.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class Image extends File
3030
const SQUARE_NOT_ALLOWED_ERROR = '5d41425b-facb-47f7-a55a-de9fbe45cb46';
3131
const LANDSCAPE_NOT_ALLOWED_ERROR = '6f895685-7cf2-4d65-b3da-9029c5581d88';
3232
const PORTRAIT_NOT_ALLOWED_ERROR = '65608156-77da-4c79-a88c-02ef6d18c782';
33+
const CORRUPTED_IMAGE_ERROR = '5d4163f3-648f-4e39-87fd-cc5ea7aad2d1';
3334

3435
// Include the mapping from the base class
3536

@@ -49,6 +50,7 @@ class Image extends File
4950
self::SQUARE_NOT_ALLOWED_ERROR => 'SQUARE_NOT_ALLOWED_ERROR',
5051
self::LANDSCAPE_NOT_ALLOWED_ERROR => 'LANDSCAPE_NOT_ALLOWED_ERROR',
5152
self::PORTRAIT_NOT_ALLOWED_ERROR => 'PORTRAIT_NOT_ALLOWED_ERROR',
53+
self::CORRUPTED_IMAGE_ERROR => 'CORRUPTED_IMAGE_ERROR',
5254
);
5355

5456
public $mimeTypes = 'image/*';
@@ -61,6 +63,7 @@ class Image extends File
6163
public $allowSquare = true;
6264
public $allowLandscape = true;
6365
public $allowPortrait = true;
66+
public $detectCorrupted = false;
6467

6568
// The constant for a wrong MIME type is taken from the parent class.
6669
public $mimeTypesMessage = 'This file is not a valid image.';
@@ -74,4 +77,5 @@ class Image extends File
7477
public $allowSquareMessage = 'The image is square ({{ width }}x{{ height }}px). Square images are not allowed.';
7578
public $allowLandscapeMessage = 'The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.';
7679
public $allowPortraitMessage = 'The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.';
80+
public $corruptedMessage = 'The image file is corrupted.';
7781
}

src/Symfony/Component/Validator/Constraints/ImageValidator.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\Validator\Constraint;
1515
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
16+
use Symfony\Component\Validator\Exception\RuntimeException;
1617
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
1718

1819
/**
@@ -46,7 +47,8 @@ public function validate($value, Constraint $constraint)
4647
if (null === $constraint->minWidth && null === $constraint->maxWidth
4748
&& null === $constraint->minHeight && null === $constraint->maxHeight
4849
&& null === $constraint->minRatio && null === $constraint->maxRatio
49-
&& $constraint->allowSquare && $constraint->allowLandscape && $constraint->allowPortrait) {
50+
&& $constraint->allowSquare && $constraint->allowLandscape && $constraint->allowPortrait
51+
&& !$constraint->detectCorrupted) {
5052
return;
5153
}
5254

@@ -178,5 +180,23 @@ public function validate($value, Constraint $constraint)
178180
->setCode(Image::PORTRAIT_NOT_ALLOWED_ERROR)
179181
->addViolation();
180182
}
183+
184+
if ($constraint->detectCorrupted) {
185+
if (!function_exists('imagecreatefromstring')) {
186+
throw new RuntimeException('Corrupted images detection requires installed and enabled GD extension');
187+
}
188+
189+
$resource = @imagecreatefromstring(file_get_contents($value));
190+
191+
if (false === $resource) {
192+
$this->context->buildViolation($constraint->corruptedMessage)
193+
->setCode(Image::CORRUPTED_IMAGE_ERROR)
194+
->addViolation();
195+
196+
return;
197+
}
198+
199+
imagedestroy($resource);
200+
}
181201
}
182202
}

0 commit comments

Comments
 (0)