From 266ffce775dc2fc6d2233933fb0ab26590fbe55e Mon Sep 17 00:00:00 2001 From: smiley Date: Tue, 27 Feb 2024 14:18:44 +0100 Subject: [PATCH 1/5] :wrench: QRData::estimateTotalBitLength(): do not substract from the estimated bit length --- src/Data/QRData.php | 6 +++--- tests/Data/QRDataTest.php | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/Data/QRData.php b/src/Data/QRData.php index 7056b63e7..7b1204199 100644 --- a/src/Data/QRData.php +++ b/src/Data/QRData.php @@ -165,9 +165,9 @@ public function estimateTotalBitLength():int{ // it seems that in some cases the estimated total length is not 100% accurate, // so we substract 4 bits from the total when not in mixed mode - if(count($this->dataSegments) <= 1){ - $length -= 4; - } +# if(count($this->dataSegments) <= 1){ +# $length -= 4; +# } // we've got a match! // or let's see if there's a higher version number available diff --git a/tests/Data/QRDataTest.php b/tests/Data/QRDataTest.php index 74ce298d3..2bbc3d2a6 100644 --- a/tests/Data/QRDataTest.php +++ b/tests/Data/QRDataTest.php @@ -11,7 +11,9 @@ namespace chillerlan\QRCodeTest\Data; use chillerlan\QRCode\Common\BitBuffer; +use chillerlan\QRCode\Common\EccLevel; use chillerlan\QRCode\Common\MaskPattern; +use chillerlan\QRCode\Data\Byte; use chillerlan\QRCode\Data\QRData; use chillerlan\QRCode\Output\QRGdImagePNG; use chillerlan\QRCode\QRCode; @@ -63,4 +65,28 @@ public function testSetBitBuffer():void{ $this::assertSame($decodeResult->data, 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s'); } + public function testEstimateTotalBitLength():void{ + + $options = new QROptions([ + 'versionMin' => 10, + 'quietzoneSize' => 2, + 'eccLevel' => EccLevel::H, +# 'outputType' => QROutputInterface::CUSTOM, +# 'outputInterface' => PmaQrCodeSVG::class, + 'outputBase64' => false, + 'cssClass' => 'pma-2fa-qrcode', + 'drawCircularModules' => true, + ]); + + // version 10H has a maximum of 976 bits, which is the exact length of the string below + // QRData::estimateTotalBitLength() used to substract 4 bits for a hypothetical data mode indicator + // we're now going the safe route and do not do that anymore... + $str = 'otpauth://totp/user?secret=P2SXMJFJ7DJGHLVEQYBNH2EYM4FH66CR'. + '&issuer=phpMyAdmin%20%28%29&digits=6&algorithm=SHA1&period=30'; + + $qrData = new QRData($options, [new Byte($str)]); + + $this::assertSame(980, $qrData->estimateTotalBitLength()); + } + } From b2255fe358e326d502f08778cbc36b5cc995e901 Mon Sep 17 00:00:00 2001 From: smiley Date: Tue, 27 Feb 2024 14:41:48 +0100 Subject: [PATCH 2/5] :shower: --- README.md | 2 +- src/Output/QROutputAbstract.php | 8 ++++---- src/QRCode.php | 5 +++++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d2b69dbb4..9aaaaea3c 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ For the QRCode reader, either `ext-gd` or `ext-imagick` is required! ## Installation with [composer](https://getcomposer.org) -See [the installation guide](https://php-qrcode.readthedocs.io/en/v5.0.x/Usage-Installation.html) for more info! +See [the installation guide](https://php-qrcode.readthedocs.io/en/v5.0.x/Usage/Installation.html) for more info! ### Terminal diff --git a/src/Output/QROutputAbstract.php b/src/Output/QROutputAbstract.php index fe6e08611..7ac64fffa 100644 --- a/src/Output/QROutputAbstract.php +++ b/src/Output/QROutputAbstract.php @@ -146,18 +146,18 @@ protected function setModuleValues():void{ } /** - * Prepares the value for the given input () + * Prepares the value for the given input (return value depends on the output class) * * @param mixed $value * - * @return mixed|null return value depends on the output class + * @return mixed|null */ abstract protected function prepareModuleValue($value); /** - * Returns a default value for either dark or light modules + * Returns a default value for either dark or light modules (return value depends on the output class) * - * @return mixed|null return value depends on the output class + * @return mixed|null */ abstract protected function getDefaultModuleValue(bool $isDark); diff --git a/src/QRCode.php b/src/QRCode.php index 8caa1d739..bca6ac584 100755 --- a/src/QRCode.php +++ b/src/QRCode.php @@ -202,6 +202,11 @@ public function setOptions(SettingsContainerInterface $options):self{ /** * Renders a QR Code for the given $data and QROptions, saves $file optionally * + * Note: it is possible to add several data segments before calling this method with a valid $data string + * which will result in a mixed-mode QR Code with the given parameter as last element. + * + * @see https://github.com/chillerlan/php-qrcode/issues/246 + * * @return mixed */ public function render(string $data = null, string $file = null){ From d114a7d5d81b43c1103760e161169dde48a2e0e7 Mon Sep 17 00:00:00 2001 From: smiley Date: Tue, 27 Feb 2024 14:43:33 +0100 Subject: [PATCH 3/5] :octocat: CI update --- .github/workflows/ci.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4668efab9..58134e003 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,7 +33,7 @@ jobs: steps: - name: "Checkout" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "Install PHP" uses: shivammathur/setup-php@v2 @@ -70,7 +70,7 @@ jobs: steps: - name: "Checkout" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "Install PHP with extensions" uses: shivammathur/setup-php@v2 @@ -87,9 +87,10 @@ jobs: run: php vendor/bin/phpunit --colors=always --configuration=phpunit.xml.dist - name: "Send code coverage report to Codecov.io" - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: - files: .build/coverage/clover.xml + token: ${{ secrets.CODECOV_TOKEN }} + files: .build/coverage/clover.xml - name: "Send code coverage report to Codacy" uses: codacy/codacy-coverage-reporter-action@v1 From 537145352581fa446c06fdd8bc7cd97866c7e550 Mon Sep 17 00:00:00 2001 From: smiley Date: Tue, 27 Feb 2024 14:50:38 +0100 Subject: [PATCH 4/5] :shower: --- src/Data/QRData.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/QRData.php b/src/Data/QRData.php index 7b1204199..431a46a0c 100644 --- a/src/Data/QRData.php +++ b/src/Data/QRData.php @@ -12,7 +12,7 @@ use chillerlan\QRCode\Common\{BitBuffer, EccLevel, Mode, Version}; use chillerlan\Settings\SettingsContainerInterface; -use function count, sprintf; +use function sprintf; /** * Processes the binary data and maps it on a QRMatrix which is then being returned From da5bdb82c8755f54de112b271b402aaa8df53269 Mon Sep 17 00:00:00 2001 From: smiley Date: Tue, 27 Feb 2024 15:37:26 +0100 Subject: [PATCH 5/5] :wrench: estimated bit length was correct, add a safety margin instead --- src/Data/QRData.php | 8 ++++---- tests/Data/DataInterfaceTestAbstract.php | 9 ++++++++- tests/Data/QRDataTest.php | 3 ++- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/Data/QRData.php b/src/Data/QRData.php index 431a46a0c..4b2dcf778 100644 --- a/src/Data/QRData.php +++ b/src/Data/QRData.php @@ -165,9 +165,9 @@ public function estimateTotalBitLength():int{ // it seems that in some cases the estimated total length is not 100% accurate, // so we substract 4 bits from the total when not in mixed mode -# if(count($this->dataSegments) <= 1){ -# $length -= 4; -# } + if(count($this->dataSegments) <= 1){ + $length -= 4; + } // we've got a match! // or let's see if there's a higher version number available @@ -195,7 +195,7 @@ public function getMinimumVersion():Version{ // guess the version number within the given range for($version = $this->options->versionMin; $version <= $this->options->versionMax; $version++){ - if($total <= $this->maxBitsForEcc[$version]){ + if($total <= ($this->maxBitsForEcc[$version] - 4)){ return new Version($version); } } diff --git a/tests/Data/DataInterfaceTestAbstract.php b/tests/Data/DataInterfaceTestAbstract.php index 4d4e1d20c..e0bd58efa 100644 --- a/tests/Data/DataInterfaceTestAbstract.php +++ b/tests/Data/DataInterfaceTestAbstract.php @@ -11,6 +11,7 @@ namespace chillerlan\QRCodeTest\Data; use chillerlan\QRCode\Common\{EccLevel, MaskPattern, Mode, Version}; +use PHPUnit\Framework\ExpectationFailedException; use chillerlan\QRCode\Data\{QRCodeDataException, QRData, QRDataModeInterface, QRMatrix}; use chillerlan\QRCode\QROptions; use chillerlan\QRCodeTest\QRMaxLengthTrait; @@ -187,7 +188,13 @@ public function testGetMinimumVersion(Version $version, EccLevel $eccLevel, stri $minimumVersionNumber = $this->QRData->getMinimumVersion()->getVersionNumber(); - $this::assertSame($version->getVersionNumber(), $minimumVersionNumber); + try{ + $this::assertSame($version->getVersionNumber(), $minimumVersionNumber); + } + catch(ExpectationFailedException $e){ + $this::assertSame(($version->getVersionNumber() + 1), $minimumVersionNumber, 'safety margin'); + } + // verify the encoded data $this::assertSame($this->dataMode::DATAMODE, $bitBuffer->read(4)); $this::assertSame($str, $this->dataMode::decodeSegment($bitBuffer, $minimumVersionNumber)); diff --git a/tests/Data/QRDataTest.php b/tests/Data/QRDataTest.php index 2bbc3d2a6..b47bc0f3d 100644 --- a/tests/Data/QRDataTest.php +++ b/tests/Data/QRDataTest.php @@ -86,7 +86,8 @@ public function testEstimateTotalBitLength():void{ $qrData = new QRData($options, [new Byte($str)]); - $this::assertSame(980, $qrData->estimateTotalBitLength()); + $this::assertSame(976, $qrData->estimateTotalBitLength()); + $this::assertSame(11, $qrData->getMinimumVersion()->getVersionNumber()); // version adjusted to 11 } }