Skip to content

Commit

Permalink
Add option to only allow certain mime types for DataUri rule
Browse files Browse the repository at this point in the history
  • Loading branch information
olivervogel committed Dec 10, 2023
1 parent b9b685c commit c701529
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ The field under validation must be a valid [creditcard number](https://en.wikipe

The field under validation must be a valid [Data URI](https://en.wikipedia.org/wiki/Data_URI_scheme).

public Intervention\Validation\Rules\DataUri::__construct()
public Intervention\Validation\Rules\DataUri::__construct(?array $media_types = null)

### Domain name

Expand Down
63 changes: 61 additions & 2 deletions src/Rules/DataUri.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@

class DataUri extends AbstractRule
{
/**
* Create new instance with allowed media types or null for all valid media types
*
* @param null|array $media_types
* @return void
*/
public function __construct(protected ?array $media_types = null)
{
}

/**
* Determine if the validation rule passes.
*
Expand All @@ -15,26 +25,75 @@ class DataUri extends AbstractRule
public function isValid(mixed $value): bool
{
$info = $this->dataUriInfo($value);
if (! $info->isValid()) {
if (!$info->isValid()) {
return false;
}

if ($info->hasMediaType() && !$this->isValidMimeType($info->mediaType())) {
return false;
}

if ($this->expectsMediaType() && !$info->hasMediaType()) {
return false;
}

if ($this->expectsMediaType() && !$this->isAllowedMimeType($info->mediaType())) {
return false;
}

if ($info->isBase64Encoded()) {
return $this->isValidBase64EncodedValue($info->data());
}

return true;
}

/**
* Determine if the rule expects a set mime type in the data url
*
* @return bool
*/
protected function expectsMediaType(): bool
{
return is_array($this->media_types);
}

/**
* Check for validity of given mime type
*
* @param mixed $value
* @return bool
*/
protected function isValidMimeType(mixed $value): bool
{
return (new MimeType())->isValid($value);
}

/**
* Check if give mime type is allowed
*
* @param mixed $type
* @return bool
*/
protected function isAllowedMimeType(mixed $type): bool
{
if (is_null($this->media_types)) {
return true;
}

if (count($this->media_types) === 0) {
return false;
}

foreach ($this->media_types as $allowed) {
if ($type === $allowed) {
return true;
}
}

return false;
}

protected function isValidBase64EncodedValue(mixed $value): bool
{
return (new Base64())->isValid($value);
Expand All @@ -50,7 +109,7 @@ protected function dataUriInfo($value): object
$pattern = "/^data:(?P<mediatype>\w+\/[-+.\w]+)?(?P<parameters>(;[-\w]+=[-\w]+)*)(?P<base64>;base64)?,(?P<data>.*)/";
$result = preg_match($pattern, $value, $matches);

return new class ($matches, $result)
return new class($matches, $result)
{
private $matches;
private $result;
Expand Down
38 changes: 38 additions & 0 deletions tests/Rules/DataUriTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ public function testValidation($result, $value)
$this->assertEquals($result, $valid);
}

/**
* @dataProvider dataProviderImages
*/
public function testValidationWithMimeTypes($result, $value)
{
$valid = (new DataUri(['image/jpeg', 'image/png']))->isValid($value);
$this->assertEquals($result, $valid);
}

public function dataProvider()
{
return [
Expand Down Expand Up @@ -44,4 +53,33 @@ public function dataProvider()
[false, 'data:text;base64,SGVsbG8sIFdvcmxkIQ=='],
];
}

public function dataProviderImages()
{
return [
[false, 'data:,'],
[false, 'data:,foo'],
[false, 'data:;base64,Zm9v'],
[false, 'data:,foo%20bar'],
[true, 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='],
[false, 'data:text/vnd-example+xyz;foo=bar;base64,R0lGODdh'],
[false, 'data:text/vnd-example+xyz;foo=bar;bar-baz=false;base64,R0lGODdh'],
[false, 'data:text/plain;charset=UTF-8;page=21,the%20data:1234,5678'],
[false, 'data:text/plain;charset=US-ASCII,foobar'],
[false, 'data:text/plain,foobar'],
[false, 'data:,VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy='],
[false, 'data:,Hello%2C%20World%21'],
[false, 'data:text/plain;base64,SGVsbG8sIFdvcmxkIQ=='],
[false, 'data:text/html,<script>alert(\'hi\');</script>'],
[false, 'foo'],
[false, 'bar'],
[false, 'data:'],
[false, 'data:;base64,foo'],
[false, 'data:foo/plain,foobar'],
[false, 'data:;base64,VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy='],
[false, 'data:image/jpeg;base64,VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy='],
[false, 'VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4='],
[false, 'data:text;base64,SGVsbG8sIFdvcmxkIQ=='],
];
}
}

0 comments on commit c701529

Please sign in to comment.