diff --git a/module/Core/src/Action/QrCodeAction.php b/module/Core/src/Action/QrCodeAction.php index b39159fd..3209d651 100644 --- a/module/Core/src/Action/QrCodeAction.php +++ b/module/Core/src/Action/QrCodeAction.php @@ -50,12 +50,9 @@ class QrCodeAction implements MiddlewareInterface } $query = $request->getQueryParams(); - // Size attribute is deprecated - $size = $this->normalizeSize((int) $request->getAttribute('size', $query['size'] ?? self::DEFAULT_SIZE)); - $qrCode = new QrCode($this->stringifier->stringify($shortUrl)); - $qrCode->setSize($size); - $qrCode->setMargin(0); + $qrCode->setSize($this->resolveSize($request, $query)); + $qrCode->setMargin($this->resolveMargin($query)); $format = $query['format'] ?? 'png'; if ($format === 'svg') { @@ -65,12 +62,29 @@ class QrCodeAction implements MiddlewareInterface return new QrCodeResponse($qrCode); } - private function normalizeSize(int $size): int + private function resolveSize(Request $request, array $query): int { + // Size attribute is deprecated. After v3.0.0, always use the query param instead + $size = (int) $request->getAttribute('size', $query['size'] ?? self::DEFAULT_SIZE); if ($size < self::MIN_SIZE) { return self::MIN_SIZE; } return $size > self::MAX_SIZE ? self::MAX_SIZE : $size; } + + private function resolveMargin(array $query): int + { + if (! isset($query['margin'])) { + return 0; + } + + $margin = $query['margin']; + $intMargin = (int) $margin; + if ($margin !== (string) $intMargin) { + return 0; + } + + return $intMargin < 0 ? 0 : $intMargin; + } } diff --git a/module/Core/test/Action/QrCodeActionTest.php b/module/Core/test/Action/QrCodeActionTest.php index 245ac6de..aeaec13f 100644 --- a/module/Core/test/Action/QrCodeActionTest.php +++ b/module/Core/test/Action/QrCodeActionTest.php @@ -133,5 +133,20 @@ class QrCodeActionTest extends TestCase ServerRequestFactory::fromGlobals()->withAttribute('size', '350')->withQueryParams(['size' => '123']), 350, ]; + yield 'margin' => [ServerRequestFactory::fromGlobals()->withQueryParams(['margin' => '35']), 370]; + yield 'margin and size' => [ + ServerRequestFactory::fromGlobals()->withQueryParams(['margin' => '100', 'size' => '200']), + 400, + ]; + yield 'negative margin' => [ServerRequestFactory::fromGlobals()->withQueryParams(['margin' => '-50']), 300]; + yield 'non-numeric margin' => [ServerRequestFactory::fromGlobals()->withQueryParams(['margin' => 'foo']), 300]; + yield 'negative margin and size' => [ + ServerRequestFactory::fromGlobals()->withQueryParams(['margin' => '-1', 'size' => '150']), + 150, + ]; + yield 'non-numeric margin and size' => [ + ServerRequestFactory::fromGlobals()->withQueryParams(['margin' => 'foo', 'size' => '538']), + 538, + ]; } }