From 4b6161892000cb2b8392dce92a9cf2cabdf2d20e Mon Sep 17 00:00:00 2001 From: Chih-Hsuan Yen Date: Sat, 2 Jul 2022 22:01:51 +0800 Subject: Update php-qrcode and php-settings-container for PHP 8.1 By running the following command after updating composer.json ``` composer update chillerlan/php-qrcode chillerlan/php-settings-container ``` This change fixes a deprecation warning from Preferences -> Personal data / Authentication -> Authenticator (OTP). ``` Return type of chillerlan\Settings\SettingsContainerAbstract::jsonSerialize() should either be compatible with JsonSerializable::jsonSerialize(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice 1. vendor/chillerlan/php-settings-container/src/SettingsContainerAbstract.php(19): ttrss_error_handler(Return type of chillerlan\Settings\SettingsContainerAbstract::jsonSerialize() should either be compatible with JsonSerializable::jsonSerialize(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice, vendor/chillerlan/php-settings-container/src/SettingsContainerAbstract.php) 2. vendor/composer/ClassLoader.php(571): include(/usr/share/webapps/tt-rss/vendor/chillerlan/php-settings-container/src/SettingsContainerAbstract.php) 3. vendor/composer/ClassLoader.php(428): Composer\Autoload\includeFile(/usr/share/webapps/tt-rss/vendor/composer/../chillerlan/php-settings-container/src/SettingsContainerAbstract.php) 4. vendor/chillerlan/php-qrcode/src/QROptions.php(59): loadClass(chillerlan\Settings\SettingsContainerAbstract) 5. vendor/composer/ClassLoader.php(571): include(/usr/share/webapps/tt-rss/vendor/chillerlan/php-qrcode/src/QROptions.php) 6. vendor/composer/ClassLoader.php(428): Composer\Autoload\includeFile(/usr/share/webapps/tt-rss/vendor/composer/../chillerlan/php-qrcode/src/QROptions.php) 7. vendor/chillerlan/php-qrcode/src/QRCode.php(113): loadClass(chillerlan\QRCode\QROptions) 8. classes/pref/prefs.php(958): __construct() 9. classes/pref/prefs.php(469): _get_otp_qrcode_img() 10. classes/pref/prefs.php(541): index_auth_2fa() 11. backend.php(136): index_auth() ``` The issue is fixed in php-settings-container 2.1.1 [1] Here I use the latest php-qrcode version for another PHP 8.1 fix [2]. [1] https://github.com/chillerlan/php-settings-container/commit/68bc5019c8b38956c83906431ef879668366b036#diff-359c7f7a6d32d9935951e1b0742eb116fb654f4a932c8d40328bb5dcab2fa111L162 [2] https://github.com/chillerlan/php-qrcode/issues/97 --- vendor/chillerlan/php-qrcode/src/Data/AlphaNum.php | 29 ++-- vendor/chillerlan/php-qrcode/src/Data/Byte.php | 15 +- vendor/chillerlan/php-qrcode/src/Data/Kanji.php | 23 ++- .../php-qrcode/src/Data/MaskPatternTester.php | 84 +++++------ vendor/chillerlan/php-qrcode/src/Data/Number.php | 35 ++--- .../php-qrcode/src/Data/QRDataAbstract.php | 120 +++++---------- .../php-qrcode/src/Data/QRDataInterface.php | 53 ++++--- vendor/chillerlan/php-qrcode/src/Data/QRMatrix.php | 165 +++++++++++---------- 8 files changed, 245 insertions(+), 279 deletions(-) mode change 100644 => 100755 vendor/chillerlan/php-qrcode/src/Data/QRMatrix.php (limited to 'vendor/chillerlan/php-qrcode/src/Data') diff --git a/vendor/chillerlan/php-qrcode/src/Data/AlphaNum.php b/vendor/chillerlan/php-qrcode/src/Data/AlphaNum.php index c6d34e76f..28d9d7563 100644 --- a/vendor/chillerlan/php-qrcode/src/Data/AlphaNum.php +++ b/vendor/chillerlan/php-qrcode/src/Data/AlphaNum.php @@ -14,22 +14,19 @@ namespace chillerlan\QRCode\Data; use chillerlan\QRCode\QRCode; -use function array_search, ord, sprintf; +use function ord, sprintf; /** * Alphanumeric mode: 0 to 9, A to Z, space, $ % * + - . / : + * + * ISO/IEC 18004:2000 Section 8.3.3 + * ISO/IEC 18004:2000 Section 8.4.3 */ -class AlphaNum extends QRDataAbstract{ +final class AlphaNum extends QRDataAbstract{ - /** - * @inheritdoc - */ - protected $datamode = QRCode::DATA_ALPHANUM; + protected int $datamode = QRCode::DATA_ALPHANUM; - /** - * @inheritdoc - */ - protected $lengthBits = [9, 11, 13]; + protected array $lengthBits = [9, 11, 13]; /** * @inheritdoc @@ -47,19 +44,17 @@ class AlphaNum extends QRDataAbstract{ } /** - * @param string $chr + * get the code for the given character * - * @return int - * @throws \chillerlan\QRCode\Data\QRCodeDataException + * @throws \chillerlan\QRCode\Data\QRCodeDataException on an illegal character occurence */ protected function getCharCode(string $chr):int{ - $i = array_search($chr, $this::ALPHANUM_CHAR_MAP); - if($i !== false){ - return $i; + if(!isset($this::CHAR_MAP_ALPHANUM[$chr])){ + throw new QRCodeDataException(sprintf('illegal char: "%s" [%d]', $chr, ord($chr))); } - throw new QRCodeDataException(sprintf('illegal char: "%s" [%d]', $chr, ord($chr))); + return $this::CHAR_MAP_ALPHANUM[$chr]; } } diff --git a/vendor/chillerlan/php-qrcode/src/Data/Byte.php b/vendor/chillerlan/php-qrcode/src/Data/Byte.php index f1955645a..02e76a639 100644 --- a/vendor/chillerlan/php-qrcode/src/Data/Byte.php +++ b/vendor/chillerlan/php-qrcode/src/Data/Byte.php @@ -18,18 +18,15 @@ use function ord; /** * Byte mode, ISO-8859-1 or UTF-8 + * + * ISO/IEC 18004:2000 Section 8.3.4 + * ISO/IEC 18004:2000 Section 8.4.4 */ -class Byte extends QRDataAbstract{ +final class Byte extends QRDataAbstract{ - /** - * @inheritdoc - */ - protected $datamode = QRCode::DATA_BYTE; + protected int $datamode = QRCode::DATA_BYTE; - /** - * @inheritdoc - */ - protected $lengthBits = [8, 16, 16]; + protected array $lengthBits = [8, 16, 16]; /** * @inheritdoc diff --git a/vendor/chillerlan/php-qrcode/src/Data/Kanji.php b/vendor/chillerlan/php-qrcode/src/Data/Kanji.php index ce600d4ff..e106c50f1 100644 --- a/vendor/chillerlan/php-qrcode/src/Data/Kanji.php +++ b/vendor/chillerlan/php-qrcode/src/Data/Kanji.php @@ -18,18 +18,15 @@ use function mb_strlen, ord, sprintf, strlen; /** * Kanji mode: double-byte characters from the Shift JIS character set + * + * ISO/IEC 18004:2000 Section 8.3.5 + * ISO/IEC 18004:2000 Section 8.4.5 */ -class Kanji extends QRDataAbstract{ +final class Kanji extends QRDataAbstract{ - /** - * @inheritdoc - */ - protected $datamode = QRCode::DATA_KANJI; + protected int $datamode = QRCode::DATA_KANJI; - /** - * @inheritdoc - */ - protected $lengthBits = [8, 10, 12]; + protected array $lengthBits = [8, 10, 12]; /** * @inheritdoc @@ -40,6 +37,8 @@ class Kanji extends QRDataAbstract{ /** * @inheritdoc + * + * @throws \chillerlan\QRCode\Data\QRCodeDataException on an illegal character occurence */ protected function write(string $data):void{ $len = strlen($data); @@ -47,17 +46,17 @@ class Kanji extends QRDataAbstract{ for($i = 0; $i + 1 < $len; $i += 2){ $c = ((0xff & ord($data[$i])) << 8) | (0xff & ord($data[$i + 1])); - if(0x8140 <= $c && $c <= 0x9FFC){ + if($c >= 0x8140 && $c <= 0x9FFC){ $c -= 0x8140; } - elseif(0xE040 <= $c && $c <= 0xEBBF){ + elseif($c >= 0xE040 && $c <= 0xEBBF){ $c -= 0xC140; } else{ throw new QRCodeDataException(sprintf('illegal char at %d [%d]', $i + 1, $c)); } - $this->bitBuffer->put((($c >> 8) & 0xff) * 0xC0 + ($c & 0xff), 13); + $this->bitBuffer->put(((($c >> 8) & 0xff) * 0xC0) + ($c & 0xff), 13); } diff --git a/vendor/chillerlan/php-qrcode/src/Data/MaskPatternTester.php b/vendor/chillerlan/php-qrcode/src/Data/MaskPatternTester.php index 8dfd24180..7874cb53d 100644 --- a/vendor/chillerlan/php-qrcode/src/Data/MaskPatternTester.php +++ b/vendor/chillerlan/php-qrcode/src/Data/MaskPatternTester.php @@ -8,41 +8,51 @@ * @author Smiley * @copyright 2017 Smiley * @license MIT + * + * @noinspection PhpUnused */ namespace chillerlan\QRCode\Data; -use function abs, call_user_func_array; +use function abs, array_search, call_user_func_array, min; /** - * The sole purpose of this class is to receive a QRMatrix object and run the pattern tests on it. + * Receives a QRDataInterface object and runs the mask pattern tests on it. + * + * ISO/IEC 18004:2000 Section 8.8.2 - Evaluation of masking results * - * @link http://www.thonky.com/qr-code-tutorial/data-masking + * @see http://www.thonky.com/qr-code-tutorial/data-masking */ -class MaskPatternTester{ - - /** - * @var \chillerlan\QRCode\Data\QRMatrix - */ - protected $matrix; +final class MaskPatternTester{ /** - * @var int + * The data interface that contains the data matrix to test */ - protected $moduleCount; + protected QRDataInterface $dataInterface; /** - * Receives the matrix an sets the module count + * Receives the QRDataInterface * * @see \chillerlan\QRCode\QROptions::$maskPattern * @see \chillerlan\QRCode\Data\QRMatrix::$maskPattern - * @see \chillerlan\QRCode\QRCode::getBestMaskPattern() + */ + public function __construct(QRDataInterface $dataInterface){ + $this->dataInterface = $dataInterface; + } + + /** + * shoves a QRMatrix through the MaskPatternTester to find the lowest penalty mask pattern * - * @param \chillerlan\QRCode\Data\QRMatrix $matrix + * @see \chillerlan\QRCode\Data\MaskPatternTester */ - public function __construct(QRMatrix $matrix){ - $this->matrix = $matrix; - $this->moduleCount = $this->matrix->size(); + public function getBestMaskPattern():int{ + $penalties = []; + + for($pattern = 0; $pattern < 8; $pattern++){ + $penalties[$pattern] = $this->testPattern($pattern); + } + + return array_search(min($penalties), $penalties, true); } /** @@ -50,15 +60,13 @@ class MaskPatternTester{ * * @see \chillerlan\QRCode\QROptions::$maskPattern * @see \chillerlan\QRCode\Data\QRMatrix::$maskPattern - * @see \chillerlan\QRCode\QRCode::getBestMaskPattern() - * - * @return int */ - public function testPattern():int{ - $penalty = 0; + public function testPattern(int $pattern):int{ + $matrix = $this->dataInterface->initMatrix($pattern, true); + $penalty = 0; for($level = 1; $level <= 4; $level++){ - $penalty += call_user_func_array([$this, 'testLevel'.$level], [$this->matrix->matrix(true)]); + $penalty += call_user_func_array([$this, 'testLevel'.$level], [$matrix->matrix(true), $matrix->size()]); } return (int)$penalty; @@ -66,10 +74,8 @@ class MaskPatternTester{ /** * Checks for each group of five or more same-colored modules in a row (or column) - * - * @return int */ - protected function testLevel1(array $m):int{ + protected function testLevel1(array $m, int $size):int{ $penalty = 0; foreach($m as $y => $row){ @@ -78,13 +84,13 @@ class MaskPatternTester{ for($ry = -1; $ry <= 1; $ry++){ - if($y + $ry < 0 || $this->moduleCount <= $y + $ry){ + if($y + $ry < 0 || $size <= $y + $ry){ continue; } for($rx = -1; $rx <= 1; $rx++){ - if(($ry === 0 && $rx === 0) || (($x + $rx) < 0 || $this->moduleCount <= ($x + $rx))){ + if(($ry === 0 && $rx === 0) || (($x + $rx) < 0 || $size <= ($x + $rx))){ continue; } @@ -107,21 +113,19 @@ class MaskPatternTester{ /** * Checks for each 2x2 area of same-colored modules in the matrix - * - * @return int */ - protected function testLevel2(array $m):int{ + protected function testLevel2(array $m, int $size):int{ $penalty = 0; foreach($m as $y => $row){ - if($y > ($this->moduleCount - 2)){ + if($y > $size - 2){ break; } foreach($row as $x => $val){ - if($x > ($this->moduleCount - 2)){ + if($x > $size - 2){ break; } @@ -140,17 +144,15 @@ class MaskPatternTester{ /** * Checks if there are patterns that look similar to the finder patterns (1:1:3:1:1 ratio) - * - * @return int */ - protected function testLevel3(array $m):int{ + protected function testLevel3(array $m, int $size):int{ $penalties = 0; foreach($m as $y => $row){ foreach($row as $x => $val){ if( - ($x + 6) < $this->moduleCount + $x + 6 < $size && $val && !$m[$y][$x + 1] && $m[$y][$x + 2] @@ -163,7 +165,7 @@ class MaskPatternTester{ } if( - ($y + 6) < $this->moduleCount + $y + 6 < $size && $val && !$m[$y + 1][$x] && $m[$y + 2][$x] @@ -183,10 +185,8 @@ class MaskPatternTester{ /** * Checks if more than half of the modules are dark or light, with a larger penalty for a larger difference - * - * @return float */ - protected function testLevel4(array $m):float{ + protected function testLevel4(array $m, int $size):float{ $count = 0; foreach($m as $y => $row){ @@ -197,7 +197,7 @@ class MaskPatternTester{ } } - return (abs(100 * $count / $this->moduleCount / $this->moduleCount - 50) / 5) * 10; + return (abs(100 * $count / $size / $size - 50) / 5) * 10; } } diff --git a/vendor/chillerlan/php-qrcode/src/Data/Number.php b/vendor/chillerlan/php-qrcode/src/Data/Number.php index 3936d12c3..0a905b13e 100644 --- a/vendor/chillerlan/php-qrcode/src/Data/Number.php +++ b/vendor/chillerlan/php-qrcode/src/Data/Number.php @@ -4,7 +4,7 @@ * * @filesource Number.php * @created 26.11.2015 - * @package QRCode + * @package chillerlan\QRCode\Data * @author Smiley * @copyright 2015 Smiley * @license MIT @@ -14,22 +14,19 @@ namespace chillerlan\QRCode\Data; use chillerlan\QRCode\QRCode; -use function ord, sprintf, substr; +use function ord, sprintf, str_split, substr; /** - * Numeric mode: decimal digits 0 through 9 + * Numeric mode: decimal digits 0 to 9 + * + * ISO/IEC 18004:2000 Section 8.3.2 + * ISO/IEC 18004:2000 Section 8.4.2 */ -class Number extends QRDataAbstract{ +final class Number extends QRDataAbstract{ - /** - * @inheritdoc - */ - protected $datamode = QRCode::DATA_NUMBER; + protected int $datamode = QRCode::DATA_NUMBER; - /** - * @inheritdoc - */ - protected $lengthBits = [10, 12, 14]; + protected array $lengthBits = [10, 12, 14]; /** * @inheritdoc @@ -56,20 +53,18 @@ class Number extends QRDataAbstract{ } /** - * @param string $string + * get the code for the given numeric string * - * @return int - * @throws \chillerlan\QRCode\Data\QRCodeDataException + * @throws \chillerlan\QRCode\Data\QRCodeDataException on an illegal character occurence */ protected function parseInt(string $string):int{ $num = 0; - $len = strlen($string); - for($i = 0; $i < $len; $i++){ - $c = ord($string[$i]); + foreach(str_split($string) as $chr){ + $c = ord($chr); - if(!in_array($string[$i], $this::NUMBER_CHAR_MAP, true)){ - throw new QRCodeDataException(sprintf('illegal char: "%s" [%d]', $string[$i], $c)); + if(!isset($this::CHAR_MAP_NUMBER[$chr])){ + throw new QRCodeDataException(sprintf('illegal char: "%s" [%d]', $chr, $c)); } $c = $c - 48; // ord('0') diff --git a/vendor/chillerlan/php-qrcode/src/Data/QRDataAbstract.php b/vendor/chillerlan/php-qrcode/src/Data/QRDataAbstract.php index f52767e38..72b67b7b9 100644 --- a/vendor/chillerlan/php-qrcode/src/Data/QRDataAbstract.php +++ b/vendor/chillerlan/php-qrcode/src/Data/QRDataAbstract.php @@ -12,7 +12,7 @@ namespace chillerlan\QRCode\Data; -use chillerlan\QRCode\{QRCode, QRCodeException}; +use chillerlan\QRCode\QRCode; use chillerlan\QRCode\Helpers\{BitBuffer, Polynomial}; use chillerlan\Settings\SettingsContainerInterface; @@ -25,68 +25,50 @@ abstract class QRDataAbstract implements QRDataInterface{ /** * the string byte count - * - * @var int */ - protected $strlen; + protected ?int $strlen = null; /** * the current data mode: Num, Alphanum, Kanji, Byte - * - * @var int */ - protected $datamode; + protected int $datamode; /** * mode length bits for the version breakpoints 1-9, 10-26 and 27-40 * - * @var array + * ISO/IEC 18004:2000 Table 3 - Number of bits in Character Count Indicator */ - protected $lengthBits = [0, 0, 0]; + protected array $lengthBits = [0, 0, 0]; /** * current QR Code version - * - * @var int */ - protected $version; - - /** - * the raw data that's being passed to QRMatrix::mapData() - * - * @var array - */ - protected $matrixdata; + protected int $version; /** * ECC temp data - * - * @var array */ - protected $ecdata; + protected array $ecdata; /** * ECC temp data - * - * @var array */ - protected $dcdata; + protected array $dcdata; /** - * @var \chillerlan\QRCode\QROptions + * the options instance + * + * @var \chillerlan\Settings\SettingsContainerInterface|\chillerlan\QRCode\QROptions */ - protected $options; + protected SettingsContainerInterface $options; /** - * @var \chillerlan\QRCode\Helpers\BitBuffer + * a BitBuffer instance */ - protected $bitBuffer; + protected BitBuffer $bitBuffer; /** * QRDataInterface constructor. - * - * @param \chillerlan\Settings\SettingsContainerInterface $options - * @param string|null $data */ public function __construct(SettingsContainerInterface $options, string $data = null){ $this->options = $options; @@ -110,10 +92,7 @@ abstract class QRDataAbstract implements QRDataInterface{ ? $this->getMinimumVersion() : $this->options->version; - $this->matrixdata = $this - ->writeBitBuffer($data) - ->maskECC() - ; + $this->writeBitBuffer($data); return $this; } @@ -123,21 +102,14 @@ abstract class QRDataAbstract implements QRDataInterface{ */ public function initMatrix(int $maskPattern, bool $test = null):QRMatrix{ return (new QRMatrix($this->version, $this->options->eccLevel)) - ->setFinderPattern() - ->setSeparators() - ->setAlignmentPattern() - ->setTimingPattern() - ->setVersionNumber($test) - ->setFormatInfo($maskPattern, $test) - ->setDarkModule() - ->mapData($this->matrixdata, $maskPattern) + ->init($maskPattern, $test) + ->mapData($this->maskECC(), $maskPattern) ; } /** * returns the length bits for the version breakpoints 1-9, 10-26 and 27-40 * - * @return int * @throws \chillerlan\QRCode\Data\QRCodeDataException * @codeCoverageIgnore */ @@ -154,10 +126,6 @@ abstract class QRDataAbstract implements QRDataInterface{ /** * returns the byte count of the $data string - * - * @param string $data - * - * @return int */ protected function getLength(string $data):int{ return strlen($data); @@ -166,15 +134,17 @@ abstract class QRDataAbstract implements QRDataInterface{ /** * returns the minimum version number for the given string * - * @return int * @throws \chillerlan\QRCode\Data\QRCodeDataException */ protected function getMinimumVersion():int{ $maxlength = 0; // guess the version number within the given range + $dataMode = QRCode::DATA_MODES[$this->datamode]; + $eccMode = QRCode::ECC_MODES[$this->options->eccLevel]; + foreach(range($this->options->versionMin, $this->options->versionMax) as $version){ - $maxlength = $this::MAX_LENGTH[$version][QRCode::DATA_MODES[$this->datamode]][QRCode::ECC_MODES[$this->options->eccLevel]]; + $maxlength = $this::MAX_LENGTH[$version][$dataMode][$eccMode]; if($this->strlen <= $maxlength){ return $version; @@ -188,81 +158,72 @@ abstract class QRDataAbstract implements QRDataInterface{ * writes the actual data string to the BitBuffer * * @see \chillerlan\QRCode\Data\QRDataAbstract::writeBitBuffer() - * - * @param string $data - * - * @return void */ abstract protected function write(string $data):void; /** * creates a BitBuffer and writes the string data to it * - * @param string $data - * - * @return \chillerlan\QRCode\Data\QRDataAbstract - * @throws \chillerlan\QRCode\QRCodeException + * @throws \chillerlan\QRCode\QRCodeException on data overflow */ - protected function writeBitBuffer(string $data):QRDataInterface{ + protected function writeBitBuffer(string $data):void{ $this->bitBuffer = new BitBuffer; $MAX_BITS = $this::MAX_BITS[$this->version][QRCode::ECC_MODES[$this->options->eccLevel]]; $this->bitBuffer - ->clear() ->put($this->datamode, 4) ->put($this->strlen, $this->getLengthBits()) ; $this->write($data); - // there was an error writing the BitBuffer data, which is... unlikely. - if($this->bitBuffer->length > $MAX_BITS){ - throw new QRCodeException(sprintf('code length overflow. (%d > %d bit)', $this->bitBuffer->length, $MAX_BITS)); // @codeCoverageIgnore + // overflow, likely caused due to invalid version setting + if($this->bitBuffer->getLength() > $MAX_BITS){ + throw new QRCodeDataException(sprintf('code length overflow. (%d > %d bit)', $this->bitBuffer->getLength(), $MAX_BITS)); } - // end code. - if($this->bitBuffer->length + 4 <= $MAX_BITS){ + // add terminator (ISO/IEC 18004:2000 Table 2) + if($this->bitBuffer->getLength() + 4 <= $MAX_BITS){ $this->bitBuffer->put(0, 4); } // padding - while($this->bitBuffer->length % 8 !== 0){ + while($this->bitBuffer->getLength() % 8 !== 0){ $this->bitBuffer->putBit(false); } // padding while(true){ - if($this->bitBuffer->length >= $MAX_BITS){ + if($this->bitBuffer->getLength() >= $MAX_BITS){ break; } $this->bitBuffer->put(0xEC, 8); - if($this->bitBuffer->length >= $MAX_BITS){ + if($this->bitBuffer->getLength() >= $MAX_BITS){ break; } $this->bitBuffer->put(0x11, 8); } - return $this; } /** * ECC masking * - * @link http://www.thonky.com/qr-code-tutorial/error-correction-coding + * ISO/IEC 18004:2000 Section 8.5 ff * - * @return array + * @see http://www.thonky.com/qr-code-tutorial/error-correction-coding */ protected function maskECC():array{ [$l1, $l2, $b1, $b2] = $this::RSBLOCKS[$this->version][QRCode::ECC_MODES[$this->options->eccLevel]]; $rsBlocks = array_fill(0, $l1, [$b1, $b2]); $rsCount = $l1 + $l2; - $this->ecdata = array_fill(0, $rsCount, null); + $this->ecdata = array_fill(0, $rsCount, []); $this->dcdata = $this->ecdata; if($l2 > 0){ @@ -274,6 +235,8 @@ abstract class QRDataAbstract implements QRDataInterface{ $maxEcCount = 0; $offset = 0; + $bitBuffer = $this->bitBuffer->getBuffer(); + foreach($rsBlocks as $key => $block){ [$rsBlockTotal, $dcCount] = $block; @@ -283,12 +246,12 @@ abstract class QRDataAbstract implements QRDataInterface{ $this->dcdata[$key] = array_fill(0, $dcCount, null); foreach($this->dcdata[$key] as $a => $_z){ - $this->dcdata[$key][$a] = 0xff & $this->bitBuffer->buffer[$a + $offset]; + $this->dcdata[$key][$a] = 0xff & $bitBuffer[$a + $offset]; } [$num, $add] = $this->poly($key, $ecCount); - foreach($this->ecdata[$key] as $c => $_z){ + foreach($this->ecdata[$key] as $c => $_){ $modIndex = $c + $add; $this->ecdata[$key][$c] = $modIndex >= 0 ? $num[$modIndex] : 0; } @@ -300,7 +263,7 @@ abstract class QRDataAbstract implements QRDataInterface{ $data = array_fill(0, $totalCodeCount, null); $index = 0; - $mask = function($arr, $count) use (&$data, &$index, $rsCount){ + $mask = function(array $arr, int $count) use (&$data, &$index, $rsCount):void{ for($x = 0; $x < $count; $x++){ for($y = 0; $y < $rsCount; $y++){ if($x < count($arr[$y])){ @@ -318,10 +281,7 @@ abstract class QRDataAbstract implements QRDataInterface{ } /** - * @param int $key - * @param int $count - * - * @return int[] + * helper method for the polynomial operations */ protected function poly(int $key, int $count):array{ $rsPoly = new Polynomial; diff --git a/vendor/chillerlan/php-qrcode/src/Data/QRDataInterface.php b/vendor/chillerlan/php-qrcode/src/Data/QRDataInterface.php index 653386222..93ad6221d 100644 --- a/vendor/chillerlan/php-qrcode/src/Data/QRDataInterface.php +++ b/vendor/chillerlan/php-qrcode/src/Data/QRDataInterface.php @@ -13,23 +13,38 @@ namespace chillerlan\QRCode\Data; /** - * + * Specifies the methods reqired for the data modules (Number, Alphanum, Byte and Kanji) + * and holds version information in several constants */ interface QRDataInterface{ - const NUMBER_CHAR_MAP = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; + /** + * @var int[] + */ + const CHAR_MAP_NUMBER = [ + '0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, '6' => 6, '7' => 7, '8' => 8, '9' => 9, + ]; - const ALPHANUM_CHAR_MAP = [ - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', - 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', - 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', - 'W', 'X', 'Y', 'Z', ' ', '$', '%', '*', - '+', '-', '.', '/', ':', + /** + * ISO/IEC 18004:2000 Table 5 + * + * @var int[] + */ + const CHAR_MAP_ALPHANUM = [ + '0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, '6' => 6, '7' => 7, + '8' => 8, '9' => 9, 'A' => 10, 'B' => 11, 'C' => 12, 'D' => 13, 'E' => 14, 'F' => 15, + 'G' => 16, 'H' => 17, 'I' => 18, 'J' => 19, 'K' => 20, 'L' => 21, 'M' => 22, 'N' => 23, + 'O' => 24, 'P' => 25, 'Q' => 26, 'R' => 27, 'S' => 28, 'T' => 29, 'U' => 30, 'V' => 31, + 'W' => 32, 'X' => 33, 'Y' => 34, 'Z' => 35, ' ' => 36, '$' => 37, '%' => 38, '*' => 39, + '+' => 40, '-' => 41, '.' => 42, '/' => 43, ':' => 44, ]; /** - * @link http://www.qrcode.com/en/about/version.html + * ISO/IEC 18004:2000 Tables 7-11 - Number of symbol characters and input data capacity for versions 1 to 40 + * + * @see http://www.qrcode.com/en/about/version.html + * + * @var int [][][] */ const MAX_LENGTH =[ // v => [NUMERIC => [L, M, Q, H ], ALPHANUM => [L, M, Q, H], BINARY => [L, M, Q, H ], KANJI => [L, M, Q, H ]] // modules @@ -75,6 +90,11 @@ interface QRDataInterface{ 40 => [[7089, 5596, 3993, 3057], [4296, 3391, 2420, 1852], [2953, 2331, 1663, 1273], [1817, 1435, 1024, 784]], // 177 ]; + /** + * ISO/IEC 18004:2000 Tables 7-11 - Number of symbol characters and input data capacity for versions 1 to 40 + * + * @var int [][] + */ const MAX_BITS = [ // version => [L, M, Q, H ] 1 => [ 152, 128, 104, 72], @@ -120,7 +140,9 @@ interface QRDataInterface{ ]; /** - * @link http://www.thonky.com/qr-code-tutorial/error-correction-table + * @see http://www.thonky.com/qr-code-tutorial/error-correction-table + * + * @var int [][][] */ const RSBLOCKS = [ 1 => [[ 1, 0, 26, 19], [ 1, 0, 26, 16], [ 1, 0, 26, 13], [ 1, 0, 26, 9]], @@ -167,20 +189,11 @@ interface QRDataInterface{ /** * Sets the data string (internally called by the constructor) - * - * @param string $data - * - * @return \chillerlan\QRCode\Data\QRDataInterface */ public function setData(string $data):QRDataInterface; /** * returns a fresh matrix object with the data written for the given $maskPattern - * - * @param int $maskPattern - * @param bool|null $test - * - * @return \chillerlan\QRCode\Data\QRMatrix */ public function initMatrix(int $maskPattern, bool $test = null):QRMatrix; diff --git a/vendor/chillerlan/php-qrcode/src/Data/QRMatrix.php b/vendor/chillerlan/php-qrcode/src/Data/QRMatrix.php old mode 100644 new mode 100755 index 5b4487a40..05c8b9069 --- a/vendor/chillerlan/php-qrcode/src/Data/QRMatrix.php +++ b/vendor/chillerlan/php-qrcode/src/Data/QRMatrix.php @@ -18,29 +18,46 @@ use Closure; use function array_fill, array_key_exists, array_push, array_unshift, count, floor, in_array, max, min, range; /** - * @link http://www.thonky.com/qr-code-tutorial/format-version-information + * Holds a numerical representation of the final QR Code; + * maps the ECC coded binary data and applies the mask pattern + * + * @see http://www.thonky.com/qr-code-tutorial/format-version-information */ -class QRMatrix{ +final class QRMatrix{ + /** @var int */ public const M_NULL = 0x00; + /** @var int */ public const M_DARKMODULE = 0x02; + /** @var int */ public const M_DATA = 0x04; + /** @var int */ public const M_FINDER = 0x06; + /** @var int */ public const M_SEPARATOR = 0x08; + /** @var int */ public const M_ALIGNMENT = 0x0a; + /** @var int */ public const M_TIMING = 0x0c; + /** @var int */ public const M_FORMAT = 0x0e; + /** @var int */ public const M_VERSION = 0x10; + /** @var int */ public const M_QUIETZONE = 0x12; + /** @var int */ public const M_LOGO = 0x14; + /** @var int */ public const M_FINDER_DOT = 0x16; - + /** @var int */ public const M_TEST = 0xff; /** - * @link http://www.thonky.com/qr-code-tutorial/alignment-pattern-locations + * ISO/IEC 18004:2000 Annex E, Table E.1 - Row/column coordinates of center module of Alignment Patterns + * + * version -> pattern * - * version -> pattern + * @var int[][] */ protected const alignmentPattern = [ 1 => [], @@ -86,9 +103,11 @@ class QRMatrix{ ]; /** - * @link http://www.thonky.com/qr-code-tutorial/format-version-tables + * ISO/IEC 18004:2000 Annex D, Table D.1 - Version information bit stream for each version * * no version pattern for QR Codes < 7 + * + * @var int[] */ protected const versionPattern = [ 7 => 0b000111110010010100, @@ -127,7 +146,13 @@ class QRMatrix{ 40 => 0b101000110001101001, ]; - // ECC level -> mask pattern + /** + * ISO/IEC 18004:2000 Section 8.9 - Format Information + * + * ECC level -> mask pattern + * + * @var int[][] + */ protected const formatPattern = [ [ // L 0b111011111000100, @@ -172,36 +197,35 @@ class QRMatrix{ ]; /** - * @var int + * the current QR Code version number */ - protected $version; + protected int $version; /** - * @var int + * the current ECC level */ - protected $eclevel; + protected int $eclevel; /** - * @var int + * the used mask pattern, set via QRMatrix::mapData() */ - protected $maskPattern = QRCode::MASK_PATTERN_AUTO; + protected int $maskPattern = QRCode::MASK_PATTERN_AUTO; /** - * @var int + * the size (side length) of the matrix */ - protected $moduleCount; + protected int $moduleCount; /** - * @var mixed[] + * the actual matrix data array + * + * @var int[][] */ - protected $matrix; + protected array $matrix; /** * QRMatrix constructor. * - * @param int $version - * @param int $eclevel - * * @throws \chillerlan\QRCode\Data\QRCodeDataException */ public function __construct(int $version, int $eclevel){ @@ -220,6 +244,21 @@ class QRMatrix{ $this->matrix = array_fill(0, $this->moduleCount, array_fill(0, $this->moduleCount, $this::M_NULL)); } + /** + * shortcut to initialize the matrix + */ + public function init(int $maskPattern, bool $test = null):QRMatrix{ + return $this + ->setFinderPattern() + ->setSeparators() + ->setAlignmentPattern() + ->setTimingPattern() + ->setVersionNumber($test) + ->setFormatInfo($maskPattern, $test) + ->setDarkModule() + ; + } + /** * Returns the data matrix, returns a pure boolean representation if $boolean is set to true * @@ -245,21 +284,21 @@ class QRMatrix{ } /** - * @return int + * Returns the current version number */ public function version():int{ return $this->version; } /** - * @return int + * Returns the current ECC level */ public function eccLevel():int{ return $this->eclevel; } /** - * @return int + * Returns the current mask pattern */ public function maskPattern():int{ return $this->maskPattern; @@ -269,8 +308,6 @@ class QRMatrix{ * Returns the absoulute size of the matrix, including quiet zone (after setting it). * * size = version * 4 + 17 [ + 2 * quietzone size] - * - * @return int */ public function size():int{ return $this->moduleCount; @@ -278,11 +315,6 @@ class QRMatrix{ /** * Returns the value of the module at position [$x, $y] - * - * @param int $x - * @param int $y - * - * @return int */ public function get(int $x, int $y):int{ return $this->matrix[$y][$x]; @@ -293,13 +325,6 @@ class QRMatrix{ * * true => $M_TYPE << 8 * false => $M_TYPE - * - * @param int $x - * @param int $y - * @param int $M_TYPE - * @param bool $value - * - * @return \chillerlan\QRCode\Data\QRMatrix */ public function set(int $x, int $y, bool $value, int $M_TYPE):QRMatrix{ $this->matrix[$y][$x] = $M_TYPE << ($value ? 8 : 0); @@ -315,21 +340,14 @@ class QRMatrix{ * * false => $value === $M_TYPE * $value >> 8 === 0 - * - * @param int $x - * @param int $y - * - * @return bool */ public function check(int $x, int $y):bool{ - return $this->matrix[$y][$x] >> 8 > 0; + return ($this->matrix[$y][$x] >> 8) > 0; } /** * Sets the "dark module", that is always on the same position 1x1px away from the bottom left finder - * - * @return \chillerlan\QRCode\Data\QRMatrix */ public function setDarkModule():QRMatrix{ $this->set(8, 4 * $this->version + 9, true, $this::M_DARKMODULE); @@ -340,7 +358,7 @@ class QRMatrix{ /** * Draws the 7x7 finder patterns in the corners top left/right and bottom left * - * @return \chillerlan\QRCode\Data\QRMatrix + * ISO/IEC 18004:2000 Section 7.3.2 */ public function setFinderPattern():QRMatrix{ @@ -375,7 +393,7 @@ class QRMatrix{ /** * Draws the separator lines around the finder patterns * - * @return \chillerlan\QRCode\Data\QRMatrix + * ISO/IEC 18004:2000 Section 7.3.3 */ public function setSeparators():QRMatrix{ @@ -405,7 +423,7 @@ class QRMatrix{ /** * Draws the 5x5 alignment patterns * - * @return \chillerlan\QRCode\Data\QRMatrix + * ISO/IEC 18004:2000 Section 7.3.5 */ public function setAlignmentPattern():QRMatrix{ @@ -435,7 +453,7 @@ class QRMatrix{ /** * Draws the timing pattern (h/v checkered line between the finder patterns) * - * @return \chillerlan\QRCode\Data\QRMatrix + * ISO/IEC 18004:2000 Section 7.3.4 */ public function setTimingPattern():QRMatrix{ @@ -457,9 +475,7 @@ class QRMatrix{ /** * Draws the version information, 2x 3x6 pixel * - * @param bool|null $test - * - * @return \chillerlan\QRCode\Data\QRMatrix + * ISO/IEC 18004:2000 Section 8.10 */ public function setVersionNumber(bool $test = null):QRMatrix{ $bits = $this::versionPattern[$this->version] ?? false; @@ -483,10 +499,7 @@ class QRMatrix{ /** * Draws the format info along the finder patterns * - * @param int $maskPattern - * @param bool|null $test - * - * @return \chillerlan\QRCode\Data\QRMatrix + * ISO/IEC 18004:2000 Section 8.9 */ public function setFormatInfo(int $maskPattern, bool $test = null):QRMatrix{ $bits = $this::formatPattern[QRCode::ECC_MODES[$this->eclevel]][$maskPattern] ?? 0; @@ -524,9 +537,8 @@ class QRMatrix{ /** * Draws the "quiet zone" of $size around the matrix * - * @param int|null $size + * ISO/IEC 18004:2000 Section 7.3.7 * - * @return \chillerlan\QRCode\Data\QRMatrix * @throws \chillerlan\QRCode\Data\QRCodeDataException */ public function setQuietZone(int $size = null):QRMatrix{ @@ -574,18 +586,12 @@ class QRMatrix{ * * @link https://github.com/chillerlan/php-qrcode/issues/52 * - * @param int $width - * @param int $height - * @param int|null $startX - * @param int|null $startY - * - * @return \chillerlan\QRCode\Data\QRMatrix * @throws \chillerlan\QRCode\Data\QRCodeDataException */ public function setLogoSpace(int $width, int $height, int $startX = null, int $startY = null):QRMatrix{ // for logos we operate in ECC H (30%) only - if($this->eclevel !== 0b10){ + if($this->eclevel !== QRCode::ECC_H){ throw new QRCodeDataException('ECC level "H" required to add logo space'); } @@ -635,7 +641,8 @@ class QRMatrix{ } /** - * Maps the binary $data array from QRDataInterface::maskECC() on the matrix, using $maskPattern + * Maps the binary $data array from QRDataInterface::maskECC() on the matrix, + * masking the data using $maskPattern (ISO/IEC 18004:2000 Section 8.8) * * @see \chillerlan\QRCode\Data\QRDataAbstract::maskECC() * @@ -647,10 +654,13 @@ class QRMatrix{ public function mapData(array $data, int $maskPattern):QRMatrix{ $this->maskPattern = $maskPattern; $byteCount = count($data); - $size = $this->moduleCount - 1; + $y = $this->moduleCount - 1; + $inc = -1; + $byteIndex = 0; + $bitIndex = 7; $mask = $this->getMask($this->maskPattern); - for($i = $size, $y = $size, $inc = -1, $byteIndex = 0, $bitIndex = 7; $i > 0; $i -= 2){ + for($i = $y; $i > 0; $i -= 2){ if($i === 6){ $i--; @@ -707,9 +717,6 @@ class QRMatrix{ * * @internal * - * @param int $maskPattern - * - * @return \Closure * @throws \chillerlan\QRCode\Data\QRCodeDataException */ protected function getMask(int $maskPattern):Closure{ @@ -719,14 +726,14 @@ class QRMatrix{ } return [ - 0b000 => function($x, $y):int{ return ($x + $y) % 2; }, - 0b001 => function($x, $y):int{ return $y % 2; }, - 0b010 => function($x, $y):int{ return $x % 3; }, - 0b011 => function($x, $y):int{ return ($x + $y) % 3; }, - 0b100 => function($x, $y):int{ return ((int)($y / 2) + (int)($x / 3)) % 2; }, - 0b101 => function($x, $y):int{ return (($x * $y) % 2) + (($x * $y) % 3); }, - 0b110 => function($x, $y):int{ return ((($x * $y) % 2) + (($x * $y) % 3)) % 2; }, - 0b111 => function($x, $y):int{ return ((($x * $y) % 3) + (($x + $y) % 2)) % 2; }, + 0b000 => fn($x, $y):int => ($x + $y) % 2, + 0b001 => fn($x, $y):int => $y % 2, + 0b010 => fn($x, $y):int => $x % 3, + 0b011 => fn($x, $y):int => ($x + $y) % 3, + 0b100 => fn($x, $y):int => ((int)($y / 2) + (int)($x / 3)) % 2, + 0b101 => fn($x, $y):int => (($x * $y) % 2) + (($x * $y) % 3), + 0b110 => fn($x, $y):int => ((($x * $y) % 2) + (($x * $y) % 3)) % 2, + 0b111 => fn($x, $y):int => ((($x * $y) % 3) + (($x + $y) % 2)) % 2, ][$maskPattern]; } -- cgit v1.2.3