diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ba90574..e81dc273 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,20 +8,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this ### Added * [#1274](https://github.com/shlinkio/shlink/issues/1274) Added support to filter short URLs lists by all provided tags. - The `GET /short-urls` endpoint now accepts a `tagsMode=all` param which will make only short URLs matching **all** the tags in the `tags[]` query param, to be returned. + The `GET /short-urls` endpoint now accepts a `tagsMode=all` param which will make only short URLs matching **all** the tags in the `tags[]` query param, to be returned. - The `short-urls:list` command now accepts a `-i`/`--including-all-tags` flag which behaves the same. + The `short-urls:list` command now accepts a `-i`/`--including-all-tags` flag which behaves the same. * [#1273](https://github.com/shlinkio/shlink/issues/1273) Added support for pagination in tags lists, allowing to improve performance by loading subsets of tags. - For backwards compatibility, lists continue returning all items by default, but the `GET /tags` endpoint now supports `page` and `itemsPerPage` query params, to make sure only a subset of the tags is returned. + For backwards compatibility, lists continue returning all items by default, but the `GET /tags` endpoint now supports `page` and `itemsPerPage` query params, to make sure only a subset of the tags is returned. - This is supported both when invoking the endpoint with and without `withStats=true` query param. + This is supported both when invoking the endpoint with and without `withStats=true` query param. - Additionally, the endpoint also supports filtering by `searchTerm` query param. When provided, only tags matching it will be returned. + Additionally, the endpoint also supports filtering by `searchTerm` query param. When provided, only tags matching it will be returned. ### Changed -* [#1277](https://github.com/shlinkio/shlink/issues/1277) Reduced docker image size to 45% the original size. +* [#1277](https://github.com/shlinkio/shlink/issues/1277) Reduced docker image size to 45% of the original size. * [#1268](https://github.com/shlinkio/shlink/issues/1268) Updated dependencies, including symfony/console 6 and mezzio/mezzio-swoole 4. * [#1283](https://github.com/shlinkio/shlink/issues/1283) Changed behavior of `DELETE_SHORT_URL_THRESHOLD` env var, disabling the feature if a value was not provided. * [#1300](https://github.com/shlinkio/shlink/issues/1300) Changed default ordering for short URLs list, returning always from newest to oldest. @@ -38,6 +38,25 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this * *Nothing* +## [2.10.2] - 2022-01-07 +### Added +* *Nothing* + +### Changed +* *Nothing* + +### Deprecated +* *Nothing* + +### Removed +* *Nothing* + +### Fixed +* [#1293](https://github.com/shlinkio/shlink/issues/1293) Fixed error when trying to create/import short URLs with a too long title. +* [#1306](https://github.com/shlinkio/shlink/issues/1306) Ensured remote IP address is not logged when using swoole/openswoole. +* [#1308](https://github.com/shlinkio/shlink/issues/1308) Fixed memory leak when using redis due to the amount of non-expiring keys created by doctrine. Now they have a 24h expiration by default. + + ## [2.10.1] - 2021-12-21 ### Added * *Nothing* diff --git a/composer.json b/composer.json index 3b79c514..a5ca2bd1 100644 --- a/composer.json +++ b/composer.json @@ -48,7 +48,7 @@ "predis/predis": "^1.1", "pugx/shortid-php": "^1.0", "ramsey/uuid": "^4.2", - "shlinkio/shlink-common": "dev-main#0d476fd as 4.3", + "shlinkio/shlink-common": "^4.3", "shlinkio/shlink-config": "^1.5", "shlinkio/shlink-event-dispatcher": "^2.3", "shlinkio/shlink-importer": "^2.5", diff --git a/config/autoload/entity-manager.local.php.dist b/config/autoload/entity-manager.local.php.dist index ef5cabf8..0624aa51 100644 --- a/config/autoload/entity-manager.local.php.dist +++ b/config/autoload/entity-manager.local.php.dist @@ -11,7 +11,6 @@ return [ 'driver' => 'pdo_mysql', 'host' => 'shlink_db_mysql', 'dbname' => 'shlink', - 'charset' => 'utf8', ], ], diff --git a/config/autoload/logger.global.php b/config/autoload/logger.global.php index 7c0e4f00..e6fcd43c 100644 --- a/config/autoload/logger.global.php +++ b/config/autoload/logger.global.php @@ -82,7 +82,7 @@ return [ 'swoole-http-server' => [ 'logger' => [ 'logger-name' => 'Logger_Access', - 'format' => '%h %l %u "%r" %>s %b', + 'format' => '%u "%r" %>s %B', ], ], ], diff --git a/config/autoload/redis.global.php b/config/autoload/redis.global.php index 871ac531..7af209d6 100644 --- a/config/autoload/redis.global.php +++ b/config/autoload/redis.global.php @@ -11,6 +11,7 @@ return (static function (): array { null => [], default => [ 'cache' => [ + 'default_lifetime' => 86400, // 24h 'redis' => [ 'servers' => $redisServers, 'sentinel_service' => env('REDIS_SENTINEL_SERVICE'), diff --git a/config/test/test_config.global.php b/config/test/test_config.global.php index 41320c89..fff7e00a 100644 --- a/config/test/test_config.global.php +++ b/config/test/test_config.global.php @@ -55,7 +55,6 @@ $buildDbConnection = static function (): array { 'user' => 'postgres', 'password' => 'root', 'dbname' => 'shlink_test', - 'charset' => 'utf8', ], 'mssql' => [ 'driver' => 'pdo_sqlsrv', @@ -71,7 +70,6 @@ $buildDbConnection = static function (): array { 'user' => 'root', 'password' => 'root', 'dbname' => 'shlink_test', - 'charset' => 'utf8', ], }; }; diff --git a/module/Core/src/Validation/ShortUrlInputFilter.php b/module/Core/src/Validation/ShortUrlInputFilter.php index 47f6f8ac..2497f85d 100644 --- a/module/Core/src/Validation/ShortUrlInputFilter.php +++ b/module/Core/src/Validation/ShortUrlInputFilter.php @@ -6,6 +6,7 @@ namespace Shlinkio\Shlink\Core\Validation; use Cocur\Slugify\Slugify; use DateTime; +use Laminas\Filter; use Laminas\InputFilter\Input; use Laminas\InputFilter\InputFilter; use Laminas\Validator; @@ -13,6 +14,8 @@ use Shlinkio\Shlink\Common\Validation; use Shlinkio\Shlink\Core\Util\CocurSymfonySluggerBridge; use Shlinkio\Shlink\Rest\Entity\ApiKey; +use function substr; + use const Shlinkio\Shlink\CUSTOM_SLUGS_REGEXP; use const Shlinkio\Shlink\MIN_SHORT_CODES_LENGTH; @@ -107,7 +110,11 @@ class ShortUrlInputFilter extends InputFilter $this->add($this->createTagsInput(self::TAGS, false)); - $this->add($this->createInput(self::TITLE, false)); + $title = $this->createInput(self::TITLE, false); + $title->getFilterChain()->attach(new Filter\Callback( + static fn (?string $value) => $value === null ? $value : substr($value, 0, 512), + )); + $this->add($title); $this->add($this->createBooleanInput(self::CRAWLABLE, false)); } diff --git a/module/Core/test/Model/ShortUrlMetaTest.php b/module/Core/test/Model/ShortUrlMetaTest.php index 2b57987b..9a5eac72 100644 --- a/module/Core/test/Model/ShortUrlMetaTest.php +++ b/module/Core/test/Model/ShortUrlMetaTest.php @@ -11,6 +11,10 @@ use Shlinkio\Shlink\Core\Model\ShortUrlMeta; use Shlinkio\Shlink\Core\Validation\ShortUrlInputFilter; use stdClass; +use function str_pad; + +use const STR_PAD_BOTH; + class ShortUrlMetaTest extends TestCase { /** @@ -99,4 +103,30 @@ class ShortUrlMetaTest extends TestCase yield ['谷歌', '谷歌']; yield ['гугл', 'гугл']; } + + /** + * @test + * @dataProvider provideTitles + */ + public function titleIsCroppedIfTooLong(?string $title, ?string $expectedTitle): void + { + $meta = ShortUrlMeta::fromRawData([ + 'title' => $title, + 'longUrl' => '', + ]); + + self::assertEquals($expectedTitle, $meta->getTitle()); + } + + public function provideTitles(): iterable + { + yield [null, null]; + yield ['foo', 'foo']; + yield [str_pad('bar', 600, ' ', STR_PAD_BOTH), 'bar']; + yield [str_pad('', 511, 'a'), str_pad('', 511, 'a')]; + yield [str_pad('', 512, 'b'), str_pad('', 512, 'b')]; + yield [str_pad('', 513, 'c'), str_pad('', 512, 'c')]; + yield [str_pad('', 600, 'd'), str_pad('', 512, 'd')]; + yield [str_pad('', 800, 'e'), str_pad('', 512, 'e')]; + } }