Do not allow URL reserved characters in custom slugs

This commit is contained in:
Alejandro Celaya
2023-11-05 10:30:40 +01:00
parent d9d6d5bd9c
commit cfc3d54122
6 changed files with 155 additions and 7 deletions

View File

@@ -62,6 +62,10 @@ class ShortUrlCreationTest extends TestCase
ShortUrlInputFilter::LONG_URL => 'https://foo',
ShortUrlInputFilter::CUSTOM_SLUG => '',
]];
yield [[
ShortUrlInputFilter::LONG_URL => 'https://foo',
ShortUrlInputFilter::CUSTOM_SLUG => 'foo?some=param',
]];
yield [[
ShortUrlInputFilter::LONG_URL => 'https://foo',
ShortUrlInputFilter::CUSTOM_SLUG => ' ',

View File

@@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
namespace ShlinkioTest\Shlink\Core\ShortUrl\Model\Validation;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
use Shlinkio\Shlink\Core\Options\UrlShortenerOptions;
use Shlinkio\Shlink\Core\ShortUrl\Model\Validation\CustomSlugValidator;
use stdClass;
class CustomSlugValidatorTest extends TestCase
{
#[Test]
public function nullIsValid(): void
{
$validator = $this->createValidator();
self::assertTrue($validator->isValid(null));
}
#[Test, DataProvider('provideNonStringValues')]
public function nonStringValuesAreInvalid(mixed $value): void
{
$validator = $this->createValidator();
self::assertFalse($validator->isValid($value));
self::assertEquals(['NOT_STRING' => 'Provided value is not a string.'], $validator->getMessages());
}
public static function provideNonStringValues(): iterable
{
yield [123];
yield [new stdClass()];
yield [true];
}
#[Test]
public function slashesAreAllowedWhenMultiSegmentSlugsAreEnabled(): void
{
$slugWithSlashes = 'foo/bar/baz';
self::assertTrue($this->createValidator(multiSegmentSlugsEnabled: true)->isValid($slugWithSlashes));
self::assertFalse($this->createValidator(multiSegmentSlugsEnabled: false)->isValid($slugWithSlashes));
}
#[Test, DataProvider('provideInvalidValues')]
public function valuesWithReservedCharsAreInvalid(string $value): void
{
$validator = $this->createValidator();
self::assertFalse($validator->isValid($value));
self::assertEquals(
['CONTAINS_URL_CHARACTERS' => 'URL-reserved characters cannot be used in a custom slug.'],
$validator->getMessages(),
);
}
public static function provideInvalidValues(): iterable
{
yield ['foo?bar=baz'];
yield ['some-thing#foo'];
yield ['call()'];
yield ['array[]'];
yield ['email@example.com'];
yield ['wildcard*'];
yield ['$500'];
}
public function createValidator(bool $multiSegmentSlugsEnabled = false): CustomSlugValidator
{
return CustomSlugValidator::forUrlShortenerOptions(
new UrlShortenerOptions(multiSegmentSlugsEnabled: $multiSegmentSlugsEnabled),
);
}
}