From 5dbc4b0013b89d15afdb68bae6c7adfe1bf1dad0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2024 11:57:21 +0000 Subject: [PATCH 1/2] chore(deps): Bump web-auth/webauthn-lib from 3.3.9 to 3.3.12 Bumps [web-auth/webauthn-lib](https://github.com/web-auth/webauthn-lib) from 3.3.9 to 3.3.12. - [Commits](https://github.com/web-auth/webauthn-lib/compare/v3.3.9...v3.3.12) --- updated-dependencies: - dependency-name: web-auth/webauthn-lib dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- composer.lock | 433 +++++++++++++++++++++++++++++++------------------- 1 file changed, 269 insertions(+), 164 deletions(-) diff --git a/composer.lock b/composer.lock index 168016fec..a5ce56772 100644 --- a/composer.lock +++ b/composer.lock @@ -186,16 +186,16 @@ }, { "name": "beberlei/assert", - "version": "v3.3.1", + "version": "v3.3.2", "source": { "type": "git", "url": "https://github.com/beberlei/assert.git", - "reference": "5e721d7e937ca3ba2cdec1e1adf195f9e5188372" + "reference": "cb70015c04be1baee6f5f5c953703347c0ac1655" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/beberlei/assert/zipball/5e721d7e937ca3ba2cdec1e1adf195f9e5188372", - "reference": "5e721d7e937ca3ba2cdec1e1adf195f9e5188372", + "url": "https://api.github.com/repos/beberlei/assert/zipball/cb70015c04be1baee6f5f5c953703347c0ac1655", + "reference": "cb70015c04be1baee6f5f5c953703347c0ac1655", "shasum": "" }, "require": { @@ -247,22 +247,22 @@ ], "support": { "issues": "https://github.com/beberlei/assert/issues", - "source": "https://github.com/beberlei/assert/tree/v3.3.1" + "source": "https://github.com/beberlei/assert/tree/v3.3.2" }, - "time": "2021-04-18T20:11:03+00:00" + "time": "2021-12-16T21:41:27+00:00" }, { "name": "brick/math", - "version": "0.9.2", + "version": "0.9.3", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "dff976c2f3487d42c1db75a3b180e2b9f0e72ce0" + "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/dff976c2f3487d42c1db75a3b180e2b9f0e72ce0", - "reference": "dff976c2f3487d42c1db75a3b180e2b9f0e72ce0", + "url": "https://api.github.com/repos/brick/math/zipball/ca57d18f028f84f777b2168cd1911b0dee2343ae", + "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae", "shasum": "" }, "require": { @@ -272,7 +272,7 @@ "require-dev": { "php-coveralls/php-coveralls": "^2.2", "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0", - "vimeo/psalm": "4.3.2" + "vimeo/psalm": "4.9.2" }, "type": "library", "autoload": { @@ -297,15 +297,19 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.9.2" + "source": "https://github.com/brick/math/tree/0.9.3" }, "funding": [ + { + "url": "https://github.com/BenMorel", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/brick/math", "type": "tidelift" } ], - "time": "2021-01-20T22:51:39+00:00" + "time": "2021-08-15T20:50:18+00:00" }, { "name": "cweagans/composer-patches", @@ -980,24 +984,24 @@ }, { "name": "fgrosse/phpasn1", - "version": "v2.3.0", + "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/fgrosse/PHPASN1.git", - "reference": "20299033c35f4300eb656e7e8e88cf52d1d6694e" + "reference": "42060ed45344789fb9f21f9f1864fc47b9e3507b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fgrosse/PHPASN1/zipball/20299033c35f4300eb656e7e8e88cf52d1d6694e", - "reference": "20299033c35f4300eb656e7e8e88cf52d1d6694e", + "url": "https://api.github.com/repos/fgrosse/PHPASN1/zipball/42060ed45344789fb9f21f9f1864fc47b9e3507b", + "reference": "42060ed45344789fb9f21f9f1864fc47b9e3507b", "shasum": "" }, "require": { - "php": ">=7.0.0" + "php": "^7.1 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "~6.3", - "satooshi/php-coveralls": "~2.0" + "php-coveralls/php-coveralls": "~2.0", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "suggest": { "ext-bcmath": "BCmath is the fallback extension for big integer calculations", @@ -1049,10 +1053,10 @@ ], "support": { "issues": "https://github.com/fgrosse/PHPASN1/issues", - "source": "https://github.com/fgrosse/PHPASN1/tree/v2.3.0" + "source": "https://github.com/fgrosse/PHPASN1/tree/v2.5.0" }, "abandoned": true, - "time": "2021-04-24T19:01:55+00:00" + "time": "2022-12-19T11:08:26+00:00" }, { "name": "fusonic/linq", @@ -1902,33 +1906,36 @@ }, { "name": "league/uri", - "version": "6.4.0", + "version": "6.7.2", "source": { "type": "git", "url": "https://github.com/thephpleague/uri.git", - "reference": "09da64118eaf4c5d52f9923a1e6a5be1da52fd9a" + "reference": "d3b50812dd51f3fbf176344cc2981db03d10fe06" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri/zipball/09da64118eaf4c5d52f9923a1e6a5be1da52fd9a", - "reference": "09da64118eaf4c5d52f9923a1e6a5be1da52fd9a", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/d3b50812dd51f3fbf176344cc2981db03d10fe06", + "reference": "d3b50812dd51f3fbf176344cc2981db03d10fe06", "shasum": "" }, "require": { "ext-json": "*", - "league/uri-interfaces": "^2.1", - "php": ">=7.2", + "league/uri-interfaces": "^2.3", + "php": "^7.4 || ^8.0", "psr/http-message": "^1.0" }, "conflict": { "league/uri-schemes": "^1.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^2.16", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpstan/phpstan-strict-rules": "^0.12", - "phpunit/phpunit": "^8.0 || ^9.0", + "friendsofphp/php-cs-fixer": "^v3.3.2", + "nyholm/psr7": "^1.5", + "php-http/psr7-integration-tests": "^1.1", + "phpstan/phpstan": "^1.2.0", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0.0", + "phpstan/phpstan-strict-rules": "^1.1.0", + "phpunit/phpunit": "^9.5.10", "psr/http-factory": "^1.0" }, "suggest": { @@ -1960,7 +1967,7 @@ } ], "description": "URI manipulation library", - "homepage": "http://uri.thephpleague.com", + "homepage": "https://uri.thephpleague.com", "keywords": [ "data-uri", "file-uri", @@ -1986,7 +1993,7 @@ "docs": "https://uri.thephpleague.com", "forum": "https://thephpleague.slack.com", "issues": "https://github.com/thephpleague/uri/issues", - "source": "https://github.com/thephpleague/uri/tree/6.4.0" + "source": "https://github.com/thephpleague/uri/tree/6.7.2" }, "funding": [ { @@ -1994,31 +2001,36 @@ "type": "github" } ], - "time": "2020-11-22T14:29:11+00:00" + "time": "2022-09-13T19:50:42+00:00" }, { "name": "league/uri-interfaces", - "version": "2.2.0", + "version": "2.3.0", "source": { "type": "git", "url": "https://github.com/thephpleague/uri-interfaces.git", - "reference": "667f150e589d65d79c89ffe662e426704f84224f" + "reference": "00e7e2943f76d8cb50c7dfdc2f6dee356e15e383" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/667f150e589d65d79c89ffe662e426704f84224f", - "reference": "667f150e589d65d79c89ffe662e426704f84224f", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/00e7e2943f76d8cb50c7dfdc2f6dee356e15e383", + "reference": "00e7e2943f76d8cb50c7dfdc2f6dee356e15e383", "shasum": "" }, "require": { "ext-json": "*", - "php": "^7.1 || ^8.0" + "php": "^7.2 || ^8.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^2.0", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpstan/phpstan-strict-rules": "^0.12" + "friendsofphp/php-cs-fixer": "^2.19", + "phpstan/phpstan": "^0.12.90", + "phpstan/phpstan-phpunit": "^0.12.19", + "phpstan/phpstan-strict-rules": "^0.12.9", + "phpunit/phpunit": "^8.5.15 || ^9.5" + }, + "suggest": { + "ext-intl": "to use the IDNA feature", + "symfony/intl": "to use the IDNA feature via Symfony Polyfill" }, "type": "library", "extra": { @@ -2052,7 +2064,7 @@ ], "support": { "issues": "https://github.com/thephpleague/uri-interfaces/issues", - "source": "https://github.com/thephpleague/uri-interfaces/tree/2.2.0" + "source": "https://github.com/thephpleague/uri-interfaces/tree/2.3.0" }, "funding": [ { @@ -2060,7 +2072,7 @@ "type": "github" } ], - "time": "2020-10-31T13:45:51+00:00" + "time": "2021-06-28T04:27:21+00:00" }, { "name": "mexitek/phpcolors", @@ -3308,20 +3320,20 @@ }, { "name": "psr/http-factory", - "version": "1.0.2", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/php-fig/http-factory.git", - "reference": "e616d01114759c4c489f93b099585439f795fe35" + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", - "reference": "e616d01114759c4c489f93b099585439f795fe35", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", "shasum": "" }, "require": { - "php": ">=7.0.0", + "php": ">=7.1", "psr/http-message": "^1.0 || ^2.0" }, "type": "library", @@ -3345,7 +3357,7 @@ "homepage": "https://www.php-fig.org/" } ], - "description": "Common interfaces for PSR-7 HTTP message factories", + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", "keywords": [ "factory", "http", @@ -3357,9 +3369,9 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-factory/tree/1.0.2" + "source": "https://github.com/php-fig/http-factory" }, - "time": "2023-04-10T20:10:41+00:00" + "time": "2024-04-15T12:06:14+00:00" }, { "name": "psr/http-message", @@ -3597,40 +3609,53 @@ }, { "name": "ramsey/collection", - "version": "1.1.3", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/ramsey/collection.git", - "reference": "28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1" + "reference": "ad7475d1c9e70b190ecffc58f2d989416af339b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/collection/zipball/28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1", - "reference": "28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1", + "url": "https://api.github.com/repos/ramsey/collection/zipball/ad7475d1c9e70b190ecffc58f2d989416af339b4", + "reference": "ad7475d1c9e70b190ecffc58f2d989416af339b4", "shasum": "" }, "require": { - "php": "^7.2 || ^8" + "php": "^7.4 || ^8.0", + "symfony/polyfill-php81": "^1.23" }, "require-dev": { - "captainhook/captainhook": "^5.3", - "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", - "ergebnis/composer-normalize": "^2.6", - "fakerphp/faker": "^1.5", - "hamcrest/hamcrest-php": "^2", - "jangregor/phpstan-prophecy": "^0.8", - "mockery/mockery": "^1.3", - "phpstan/extension-installer": "^1", - "phpstan/phpstan": "^0.12.32", - "phpstan/phpstan-mockery": "^0.12.5", - "phpstan/phpstan-phpunit": "^0.12.11", - "phpunit/phpunit": "^8.5 || ^9", - "psy/psysh": "^0.10.4", - "slevomat/coding-standard": "^6.3", - "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "^4.4" + "captainhook/plugin-composer": "^5.3", + "ergebnis/composer-normalize": "^2.28.3", + "fakerphp/faker": "^1.21", + "hamcrest/hamcrest-php": "^2.0", + "jangregor/phpstan-prophecy": "^1.0", + "mockery/mockery": "^1.5", + "php-parallel-lint/php-console-highlighter": "^1.0", + "php-parallel-lint/php-parallel-lint": "^1.3", + "phpcsstandards/phpcsutils": "^1.0.0-rc1", + "phpspec/prophecy-phpunit": "^2.0", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.9", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5", + "psalm/plugin-mockery": "^1.1", + "psalm/plugin-phpunit": "^0.18.4", + "ramsey/coding-standard": "^2.0.3", + "ramsey/conventional-commits": "^1.3", + "vimeo/psalm": "^5.4" }, "type": "library", + "extra": { + "captainhook": { + "force-install": true + }, + "ramsey/conventional-commits": { + "configFile": "conventional-commits.json" + } + }, "autoload": { "psr-4": { "Ramsey\\Collection\\": "src/" @@ -3647,7 +3672,7 @@ "homepage": "https://benramsey.com" } ], - "description": "A PHP 7.2+ library for representing and manipulating collections.", + "description": "A PHP library for representing and manipulating collections.", "keywords": [ "array", "collection", @@ -3658,7 +3683,7 @@ ], "support": { "issues": "https://github.com/ramsey/collection/issues", - "source": "https://github.com/ramsey/collection/tree/1.1.3" + "source": "https://github.com/ramsey/collection/tree/1.3.0" }, "funding": [ { @@ -3670,57 +3695,55 @@ "type": "tidelift" } ], - "time": "2021-01-21T17:40:04+00:00" + "time": "2022-12-27T19:12:24+00:00" }, { "name": "ramsey/uuid", - "version": "4.1.1", + "version": "4.7.6", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "cd4032040a750077205918c86049aa0f43d22947" + "reference": "91039bc1faa45ba123c4328958e620d382ec7088" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/cd4032040a750077205918c86049aa0f43d22947", - "reference": "cd4032040a750077205918c86049aa0f43d22947", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/91039bc1faa45ba123c4328958e620d382ec7088", + "reference": "91039bc1faa45ba123c4328958e620d382ec7088", "shasum": "" }, "require": { - "brick/math": "^0.8 || ^0.9", + "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12", "ext-json": "*", - "php": "^7.2 || ^8", - "ramsey/collection": "^1.0", - "symfony/polyfill-ctype": "^1.8" + "php": "^8.0", + "ramsey/collection": "^1.2 || ^2.0" }, "replace": { "rhumsaa/uuid": "self.version" }, "require-dev": { - "codeception/aspect-mock": "^3", - "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7.0", + "captainhook/captainhook": "^5.10", + "captainhook/plugin-composer": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "doctrine/annotations": "^1.8", - "goaop/framework": "^2", + "ergebnis/composer-normalize": "^2.15", "mockery/mockery": "^1.3", - "moontoast/math": "^1.1", "paragonie/random-lib": "^2", + "php-mock/php-mock": "^2.2", "php-mock/php-mock-mockery": "^1.3", - "php-mock/php-mock-phpunit": "^2.5", "php-parallel-lint/php-parallel-lint": "^1.1", - "phpbench/phpbench": "^0.17.1", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-mockery": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^8.5", - "psy/psysh": "^0.10.0", - "slevomat/coding-standard": "^6.0", + "phpbench/phpbench": "^1.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^8.5 || ^9", + "ramsey/composer-repl": "^1.4", + "slevomat/coding-standard": "^8.4", "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "3.9.4" + "vimeo/psalm": "^4.9" }, "suggest": { "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", - "ext-ctype": "Enables faster processing of character classification using ctype functions.", "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", @@ -3728,8 +3751,8 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "4.x-dev" + "captainhook": { + "force-install": true } }, "autoload": { @@ -3745,7 +3768,6 @@ "MIT" ], "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", - "homepage": "https://github.com/ramsey/uuid", "keywords": [ "guid", "identifier", @@ -3753,8 +3775,7 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "rss": "https://github.com/ramsey/uuid/releases.atom", - "source": "https://github.com/ramsey/uuid" + "source": "https://github.com/ramsey/uuid/tree/4.7.6" }, "funding": [ { @@ -3766,7 +3787,7 @@ "type": "tidelift" } ], - "time": "2020-08-18T17:17:46+00:00" + "time": "2024-04-27T21:32:50+00:00" }, { "name": "sabre/dav", @@ -4360,28 +4381,37 @@ }, { "name": "spomky-labs/cbor-php", - "version": "v2.0.1", + "version": "v2.1.0", "source": { "type": "git", "url": "https://github.com/Spomky-Labs/cbor-php.git", - "reference": "9776578000be884cd7864eeb7c37a4ac92d8c995" + "reference": "28e2712cfc0b48fae661a48ffc6896d7abe83684" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Spomky-Labs/cbor-php/zipball/9776578000be884cd7864eeb7c37a4ac92d8c995", - "reference": "9776578000be884cd7864eeb7c37a4ac92d8c995", + "url": "https://api.github.com/repos/Spomky-Labs/cbor-php/zipball/28e2712cfc0b48fae661a48ffc6896d7abe83684", + "reference": "28e2712cfc0b48fae661a48ffc6896d7abe83684", "shasum": "" }, "require": { "brick/math": "^0.8.15|^0.9.0", + "ext-mbstring": "*", "php": ">=7.3" }, "require-dev": { - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-beberlei-assert": "^0.12", - "phpstan/phpstan-deprecation-rules": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpstan/phpstan-strict-rules": "^0.12" + "ekino/phpstan-banned-code": "^1.0", + "ext-json": "*", + "infection/infection": "^0.18|^0.25", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-beberlei-assert": "^1.0", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.12", + "roave/security-advisories": "dev-latest", + "symplify/easy-coding-standard": "^10.0" }, "suggest": { "ext-bcmath": "GMP or BCMath extensions will drastically improve the library performance. BCMath extension needed to handle the Big Float and Decimal Fraction Tags", @@ -4415,15 +4445,19 @@ ], "support": { "issues": "https://github.com/Spomky-Labs/cbor-php/issues", - "source": "https://github.com/Spomky-Labs/cbor-php/tree/v2.0.1" + "source": "https://github.com/Spomky-Labs/cbor-php/tree/v2.1.0" }, "funding": [ + { + "url": "https://github.com/Spomky", + "type": "github" + }, { "url": "https://www.patreon.com/FlorentMorselli", "type": "patreon" } ], - "time": "2020-08-31T20:08:03+00:00" + "time": "2021-12-13T12:46:26+00:00" }, { "name": "stecman/symfony-console-completion", @@ -5183,20 +5217,20 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.28.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", - "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-ctype": "*" @@ -5206,9 +5240,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -5245,7 +5276,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" }, "funding": [ { @@ -5261,7 +5292,7 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:26:14+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-grapheme", @@ -5755,26 +5786,23 @@ }, { "name": "symfony/polyfill-php80", - "version": "v1.28.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", - "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -5818,7 +5846,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" }, "funding": [ { @@ -5834,20 +5862,96 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:26:14+00:00" + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/process", - "version": "v5.4.34", + "version": "v5.4.44", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "8fa22178dfc368911dbd513b431cd9b06f9afe7a" + "reference": "1b9fa82b5c62cd49da8c9e3952dd8531ada65096" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/8fa22178dfc368911dbd513b431cd9b06f9afe7a", - "reference": "8fa22178dfc368911dbd513b431cd9b06f9afe7a", + "url": "https://api.github.com/repos/symfony/process/zipball/1b9fa82b5c62cd49da8c9e3952dd8531ada65096", + "reference": "1b9fa82b5c62cd49da8c9e3952dd8531ada65096", "shasum": "" }, "require": { @@ -5880,7 +5984,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.4.34" + "source": "https://github.com/symfony/process/tree/v5.4.44" }, "funding": [ { @@ -5896,7 +6000,7 @@ "type": "tidelift" } ], - "time": "2023-12-02T08:41:43+00:00" + "time": "2024-09-17T12:46:43+00:00" }, { "name": "symfony/routing", @@ -6517,16 +6621,16 @@ }, { "name": "web-auth/cose-lib", - "version": "v3.3.9", + "version": "v3.3.12", "source": { "type": "git", "url": "https://github.com/web-auth/cose-lib.git", - "reference": "ed172d2dc1a6b87b5c644c07c118cd30c1b3819b" + "reference": "efa6ec2ba4e840bc1316a493973c9916028afeeb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/web-auth/cose-lib/zipball/ed172d2dc1a6b87b5c644c07c118cd30c1b3819b", - "reference": "ed172d2dc1a6b87b5c644c07c118cd30c1b3819b", + "url": "https://api.github.com/repos/web-auth/cose-lib/zipball/efa6ec2ba4e840bc1316a493973c9916028afeeb", + "reference": "efa6ec2ba4e840bc1316a493973c9916028afeeb", "shasum": "" }, "require": { @@ -6564,7 +6668,7 @@ "RFC8152" ], "support": { - "source": "https://github.com/web-auth/cose-lib/tree/v3.3.9" + "source": "https://github.com/web-auth/cose-lib/tree/v3.3.12" }, "funding": [ { @@ -6576,20 +6680,20 @@ "type": "patreon" } ], - "time": "2021-05-02T19:57:09+00:00" + "time": "2021-12-04T12:13:35+00:00" }, { "name": "web-auth/metadata-service", - "version": "v3.3.9", + "version": "v3.3.12", "source": { "type": "git", "url": "https://github.com/web-auth/webauthn-metadata-service.git", - "reference": "8488d3a832a38cc81c670fce05de1e515c6e64b1" + "reference": "ef40d2b7b68c4964247d13fab52e2fa8dbd65246" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/web-auth/webauthn-metadata-service/zipball/8488d3a832a38cc81c670fce05de1e515c6e64b1", - "reference": "8488d3a832a38cc81c670fce05de1e515c6e64b1", + "url": "https://api.github.com/repos/web-auth/webauthn-metadata-service/zipball/ef40d2b7b68c4964247d13fab52e2fa8dbd65246", + "reference": "ef40d2b7b68c4964247d13fab52e2fa8dbd65246", "shasum": "" }, "require": { @@ -6633,7 +6737,7 @@ "webauthn" ], "support": { - "source": "https://github.com/web-auth/webauthn-metadata-service/tree/v3.3.9" + "source": "https://github.com/web-auth/webauthn-metadata-service/tree/v3.3.12" }, "funding": [ { @@ -6645,20 +6749,21 @@ "type": "patreon" } ], - "time": "2021-01-09T13:31:01+00:00" + "abandoned": "web-auth/webauthn-lib", + "time": "2021-11-21T11:14:31+00:00" }, { "name": "web-auth/webauthn-lib", - "version": "v3.3.9", + "version": "v3.3.12", "source": { "type": "git", "url": "https://github.com/web-auth/webauthn-lib.git", - "reference": "04b98ee3d39cb79dad68a7c15c297c085bf66bfe" + "reference": "5ef9b21c8e9f8a817e524ac93290d08a9f065b33" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/web-auth/webauthn-lib/zipball/04b98ee3d39cb79dad68a7c15c297c085bf66bfe", - "reference": "04b98ee3d39cb79dad68a7c15c297c085bf66bfe", + "url": "https://api.github.com/repos/web-auth/webauthn-lib/zipball/5ef9b21c8e9f8a817e524ac93290d08a9f065b33", + "reference": "5ef9b21c8e9f8a817e524ac93290d08a9f065b33", "shasum": "" }, "require": { @@ -6674,7 +6779,7 @@ "psr/log": "^1.1", "ramsey/uuid": "^3.8|^4.0", "spomky-labs/base64url": "^2.0", - "spomky-labs/cbor-php": "^1.1|^2.0", + "spomky-labs/cbor-php": "^1.0|^2.0", "symfony/process": "^3.0|^4.0|^5.0", "thecodingmachine/safe": "^1.1", "web-auth/cose-lib": "self.version", @@ -6715,7 +6820,7 @@ "webauthn" ], "support": { - "source": "https://github.com/web-auth/webauthn-lib/tree/v3.3.9" + "source": "https://github.com/web-auth/webauthn-lib/tree/v3.3.12" }, "funding": [ { @@ -6727,7 +6832,7 @@ "type": "patreon" } ], - "time": "2021-04-19T20:22:20+00:00" + "time": "2022-02-18T07:13:44+00:00" } ], "packages-dev": [], From 2cbacf9626d64c92a8e9f0926cf17329f31cc4eb Mon Sep 17 00:00:00 2001 From: nextcloud-command Date: Tue, 24 Sep 2024 12:09:10 +0000 Subject: [PATCH 2/2] chore(autoloader): Dump autoloader Signed-off-by: nextcloud-command --- beberlei/assert/lib/Assert/Assertion.php | 15 +- beberlei/assert/lib/Assert/AssertionChain.php | 21 +- brick/math/src/BigDecimal.php | 36 +- brick/math/src/BigInteger.php | 33 + brick/math/src/BigRational.php | 34 + brick/math/src/Internal/Calculator.php | 5 +- .../Internal/Calculator/NativeCalculator.php | 2 +- composer/autoload_classmap.php | 37 + composer/autoload_files.php | 3 +- composer/autoload_psr4.php | 1 + composer/autoload_static.php | 45 +- composer/installed.json | 526 ++++++----- composer/installed.php | 105 ++- fgrosse/phpasn1/lib/ASN1/AbstractTime.php | 2 +- fgrosse/phpasn1/lib/ASN1/Construct.php | 13 +- fgrosse/phpasn1/lib/ASN1/OID.php | 824 ++++++++++++++++++ .../src/Exceptions/IdnaConversionFailed.php | 46 + league/uri-interfaces/src/Idna/Idna.php | 212 +++++ league/uri-interfaces/src/Idna/IdnaInfo.php | 113 +++ .../Exceptions/TemplateCanNotBeExpanded.php | 3 +- league/uri/src/Http.php | 30 +- league/uri/src/Uri.php | 276 ++---- league/uri/src/UriInfo.php | 34 +- league/uri/src/UriResolver.php | 9 +- league/uri/src/UriString.php | 118 +-- league/uri/src/UriTemplate.php | 30 +- league/uri/src/UriTemplate/Expression.php | 64 +- league/uri/src/UriTemplate/Template.php | 24 +- league/uri/src/UriTemplate/VarSpecifier.php | 17 +- league/uri/src/UriTemplate/VariableBag.php | 14 +- .../src/UploadedFileFactoryInterface.php | 12 +- ramsey/collection/LICENSE | 2 +- ramsey/collection/conventional-commits.json | 22 + ramsey/collection/src/AbstractArray.php | 35 +- ramsey/collection/src/AbstractCollection.php | 60 +- ramsey/collection/src/AbstractSet.php | 2 +- ramsey/collection/src/ArrayInterface.php | 2 + ramsey/collection/src/Collection.php | 6 +- ramsey/collection/src/CollectionInterface.php | 3 +- ramsey/collection/src/DoubleEndedQueue.php | 14 +- .../src/DoubleEndedQueueInterface.php | 7 +- .../Exception/CollectionMismatchException.php | 4 +- .../Exception/InvalidSortOrderException.php | 4 +- .../src/Exception/NoSuchElementException.php | 4 +- .../UnsupportedOperationException.php | 4 +- .../Exception/ValueExtractionException.php | 4 +- ramsey/collection/src/GenericArray.php | 2 +- ramsey/collection/src/Map/AbstractMap.php | 7 +- .../collection/src/Map/AbstractTypedMap.php | 17 +- .../src/Map/AssociativeArrayMap.php | 2 +- ramsey/collection/src/Map/MapInterface.php | 2 +- .../collection/src/Map/NamedParameterMap.php | 11 +- ramsey/collection/src/Map/TypedMap.php | 16 +- .../collection/src/Map/TypedMapInterface.php | 2 +- ramsey/collection/src/Queue.php | 20 +- ramsey/collection/src/QueueInterface.php | 5 +- ramsey/collection/src/Set.php | 6 +- ramsey/collection/src/Tool/TypeTrait.php | 1 + .../src/Tool/ValueExtractorTrait.php | 5 +- .../src/Tool/ValueToStringTrait.php | 4 + ramsey/uuid/LICENSE | 4 +- ramsey/uuid/src/Builder/BuilderCollection.php | 20 +- .../uuid/src/Builder/DefaultUuidBuilder.php | 2 +- .../uuid/src/Builder/DegradedUuidBuilder.php | 13 +- ramsey/uuid/src/Builder/FallbackBuilder.php | 11 +- ramsey/uuid/src/Codec/GuidStringCodec.php | 21 + ramsey/uuid/src/Codec/OrderedTimeCodec.php | 1 + ramsey/uuid/src/Codec/StringCodec.php | 36 +- .../src/Codec/TimestampFirstCombCodec.php | 1 + .../Converter/Number/BigNumberConverter.php | 5 +- .../Number/GenericNumberConverter.php | 11 +- .../Converter/Time/BigNumberTimeConverter.php | 5 +- .../Converter/Time/GenericTimeConverter.php | 8 +- .../src/Converter/Time/PhpTimeConverter.php | 23 +- .../src/Converter/Time/UnixTimeConverter.php | 90 ++ ramsey/uuid/src/DeprecatedUuidInterface.php | 9 +- .../uuid/src/DeprecatedUuidMethodsTrait.php | 132 ++- .../Exception/BuilderNotFoundException.php | 2 +- .../uuid/src/Exception/DateTimeException.php | 2 +- .../src/Exception/DceSecurityException.php | 2 +- .../Exception/InvalidArgumentException.php | 2 +- .../src/Exception/InvalidBytesException.php | 2 +- .../Exception/InvalidUuidStringException.php | 2 +- ramsey/uuid/src/Exception/NameException.php | 2 +- ramsey/uuid/src/Exception/NodeException.php | 2 +- .../src/Exception/RandomSourceException.php | 2 +- .../src/Exception/TimeSourceException.php | 2 +- .../Exception/UnableToBuildUuidException.php | 2 +- .../UnsupportedOperationException.php | 2 +- .../src/Exception/UuidExceptionInterface.php | 21 + ramsey/uuid/src/FeatureSet.php | 147 +--- .../src/Fields/SerializableFieldsTrait.php | 39 +- ramsey/uuid/src/Generator/CombGenerator.php | 24 +- .../src/Generator/DceSecurityGenerator.php | 30 +- .../src/Generator/DefaultNameGenerator.php | 9 +- .../src/Generator/DefaultTimeGenerator.php | 32 +- .../src/Generator/PeclUuidNameGenerator.php | 23 +- .../src/Generator/PeclUuidRandomGenerator.php | 3 + .../src/Generator/PeclUuidTimeGenerator.php | 3 + .../src/Generator/RandomBytesGenerator.php | 3 +- .../Generator/RandomGeneratorInterface.php | 2 +- .../uuid/src/Generator/RandomLibAdapter.php | 9 +- .../src/Generator/TimeGeneratorFactory.php | 24 +- .../uuid/src/Generator/UnixTimeGenerator.php | 169 ++++ ramsey/uuid/src/Guid/Fields.php | 31 +- ramsey/uuid/src/Guid/Guid.php | 3 +- ramsey/uuid/src/Guid/GuidBuilder.php | 16 +- ramsey/uuid/src/Lazy/LazyUuidFromString.php | 58 +- ramsey/uuid/src/Math/BrickMathCalculator.php | 6 +- ramsey/uuid/src/Nonstandard/Fields.php | 18 +- ramsey/uuid/src/Nonstandard/Uuid.php | 3 +- ramsey/uuid/src/Nonstandard/UuidBuilder.php | 16 +- ramsey/uuid/src/Nonstandard/UuidV6.php | 54 +- .../Dce/SystemDceSecurityProvider.php | 48 +- .../Provider/Node/FallbackNodeProvider.php | 13 +- .../Provider/Node/NodeProviderCollection.php | 20 +- .../src/Provider/Node/RandomNodeProvider.php | 3 +- .../src/Provider/Node/StaticNodeProvider.php | 5 +- .../src/Provider/Node/SystemNodeProvider.php | 36 +- .../src/Provider/Time/FixedTimeProvider.php | 16 +- ramsey/uuid/src/Rfc4122/Fields.php | 84 +- ramsey/uuid/src/Rfc4122/FieldsInterface.php | 4 +- ramsey/uuid/src/Rfc4122/MaxTrait.php | 41 + ramsey/uuid/src/Rfc4122/MaxUuid.php | 27 + ramsey/uuid/src/Rfc4122/TimeTrait.php | 55 ++ ramsey/uuid/src/Rfc4122/UuidBuilder.php | 49 +- ramsey/uuid/src/Rfc4122/UuidInterface.php | 7 - ramsey/uuid/src/Rfc4122/UuidV1.php | 40 +- ramsey/uuid/src/Rfc4122/UuidV2.php | 56 +- ramsey/uuid/src/Rfc4122/UuidV6.php | 29 + ramsey/uuid/src/Rfc4122/UuidV7.php | 62 ++ ramsey/uuid/src/Rfc4122/UuidV8.php | 65 ++ ramsey/uuid/src/Rfc4122/Validator.php | 5 +- ramsey/uuid/src/Rfc4122/VariantTrait.php | 23 +- ramsey/uuid/src/Rfc4122/VersionTrait.php | 27 +- ramsey/uuid/src/Type/Decimal.php | 55 +- ramsey/uuid/src/Type/Hexadecimal.php | 76 +- ramsey/uuid/src/Type/Integer.php | 132 ++- ramsey/uuid/src/Type/Time.php | 65 +- ramsey/uuid/src/Uuid.php | 243 ++++-- ramsey/uuid/src/UuidFactory.php | 146 ++-- ramsey/uuid/src/UuidFactoryInterface.php | 114 +-- ramsey/uuid/src/UuidInterface.php | 14 +- ramsey/uuid/src/functions.php | 61 +- spomky-labs/cbor-php/infection.json.dist | 11 - .../cbor-php/src/AbstractCBORObject.php | 1 + spomky-labs/cbor-php/src/ByteStringObject.php | 26 +- .../src/ByteStringWithChunkObject.php | 74 +- spomky-labs/cbor-php/src/CBORObject.php | 82 ++ spomky-labs/cbor-php/src/Decoder.php | 244 ++++-- spomky-labs/cbor-php/src/DecoderInterface.php | 19 + .../src/IndefiniteLengthByteStringObject.php | 106 +++ .../src/IndefiniteLengthListObject.php | 167 ++++ .../src/IndefiniteLengthMapObject.php | 201 +++++ .../src/IndefiniteLengthTextStringObject.php | 106 +++ .../cbor-php/src/InfiniteListObject.php | 61 +- .../cbor-php/src/InfiniteMapObject.php | 65 +- spomky-labs/cbor-php/src/LengthCalculator.php | 40 +- spomky-labs/cbor-php/src/ListObject.php | 114 ++- spomky-labs/cbor-php/src/MapItem.php | 5 + spomky-labs/cbor-php/src/MapObject.php | 156 +++- .../cbor-php/src/NegativeIntegerObject.php | 136 +++ spomky-labs/cbor-php/src/Normalizable.php | 22 + spomky-labs/cbor-php/src/OtherObject.php | 9 +- .../cbor-php/src/OtherObject/BreakObject.php | 12 +- .../DoublePrecisionFloatObject.php | 39 +- .../cbor-php/src/OtherObject/FalseObject.php | 22 +- .../src/OtherObject/GenericObject.php | 9 + .../OtherObject/HalfPrecisionFloatObject.php | 39 +- .../cbor-php/src/OtherObject/NullObject.php | 21 +- .../src/OtherObject/OtherObjectManager.php | 14 +- .../OtherObjectManagerInterface.php | 21 + .../cbor-php/src/OtherObject/SimpleObject.php | 37 +- .../SinglePrecisionFloatObject.php | 38 +- .../cbor-php/src/OtherObject/TrueObject.php | 22 +- .../src/OtherObject/UndefinedObject.php | 14 +- .../cbor-php/src/SignedIntegerObject.php | 107 +-- spomky-labs/cbor-php/src/StringStream.php | 43 +- spomky-labs/cbor-php/src/Tag.php | 99 +++ .../cbor-php/src/Tag/Base16EncodingTag.php | 26 +- .../cbor-php/src/Tag/Base64EncodingTag.php | 27 +- spomky-labs/cbor-php/src/Tag/Base64Tag.php | 57 ++ .../cbor-php/src/Tag/Base64UrlEncodingTag.php | 26 +- spomky-labs/cbor-php/src/Tag/Base64UrlTag.php | 57 ++ spomky-labs/cbor-php/src/Tag/BigFloatTag.php | 92 +- .../cbor-php/src/Tag/CBOREncodingTag.php | 57 ++ spomky-labs/cbor-php/src/Tag/CBORTag.php | 54 ++ spomky-labs/cbor-php/src/Tag/DatetimeTag.php | 84 ++ .../cbor-php/src/Tag/DecimalFractionTag.php | 77 +- spomky-labs/cbor-php/src/Tag/EpochTag.php | 32 +- spomky-labs/cbor-php/src/Tag/GenericTag.php | 9 +- spomky-labs/cbor-php/src/Tag/MimeTag.php | 66 ++ .../src/Tag/NegativeBigIntegerTag.php | 48 +- .../src/Tag/PositiveBigIntegerTag.php | 42 +- spomky-labs/cbor-php/src/Tag/TagManager.php | 64 ++ .../cbor-php/src/Tag/TagManagerInterface.php | 22 + .../cbor-php/src/Tag/TagObjectManager.php | 41 +- spomky-labs/cbor-php/src/Tag/TimestampTag.php | 70 +- .../src/Tag/UnsignedBigIntegerTag.php | 78 ++ spomky-labs/cbor-php/src/Tag/UriTag.php | 66 ++ spomky-labs/cbor-php/src/TagObject.php | 43 +- spomky-labs/cbor-php/src/TextStringObject.php | 26 +- .../src/TextStringWithChunkObject.php | 74 +- .../cbor-php/src/UnsignedIntegerObject.php | 38 +- spomky-labs/cbor-php/src/Utils.php | 14 +- symfony/polyfill-php81/LICENSE | 19 + symfony/polyfill-php81/Php81.php | 37 + .../Resources/stubs/CURLStringFile.php | 51 ++ .../Resources/stubs/ReturnTypeWillChange.php | 20 + symfony/polyfill-php81/bootstrap.php | 28 + symfony/process/ExecutableFinder.php | 34 +- symfony/process/InputStream.php | 2 +- symfony/process/PhpExecutableFinder.php | 4 +- symfony/process/PhpProcess.php | 6 +- symfony/process/Process.php | 37 +- web-auth/cose-lib/src/Algorithm/Algorithm.php | 2 +- web-auth/cose-lib/src/Algorithm/Mac/HS256.php | 2 +- .../src/Algorithm/Mac/HS256Truncated64.php | 2 +- web-auth/cose-lib/src/Algorithm/Mac/HS384.php | 2 +- web-auth/cose-lib/src/Algorithm/Mac/HS512.php | 2 +- web-auth/cose-lib/src/Algorithm/Mac/Hmac.php | 4 +- web-auth/cose-lib/src/Algorithm/Mac/Mac.php | 2 +- web-auth/cose-lib/src/Algorithm/Manager.php | 2 +- .../cose-lib/src/Algorithm/ManagerFactory.php | 2 +- .../src/Algorithm/Signature/ECDSA/ECDSA.php | 2 +- .../Algorithm/Signature/ECDSA/ECSignature.php | 4 +- .../src/Algorithm/Signature/ECDSA/ES256.php | 2 +- .../src/Algorithm/Signature/ECDSA/ES256K.php | 2 +- .../src/Algorithm/Signature/ECDSA/ES384.php | 2 +- .../src/Algorithm/Signature/ECDSA/ES512.php | 2 +- .../src/Algorithm/Signature/EdDSA/ED256.php | 2 +- .../src/Algorithm/Signature/EdDSA/ED512.php | 2 +- .../src/Algorithm/Signature/EdDSA/Ed25519.php | 2 +- .../src/Algorithm/Signature/EdDSA/EdDSA.php | 2 +- .../src/Algorithm/Signature/RSA/PS256.php | 4 +- .../src/Algorithm/Signature/RSA/PS384.php | 4 +- .../src/Algorithm/Signature/RSA/PS512.php | 4 +- .../src/Algorithm/Signature/RSA/PSSRSA.php | 12 +- .../src/Algorithm/Signature/RSA/RS1.php | 2 +- .../src/Algorithm/Signature/RSA/RS256.php | 2 +- .../src/Algorithm/Signature/RSA/RS384.php | 2 +- .../src/Algorithm/Signature/RSA/RS512.php | 2 +- .../src/Algorithm/Signature/RSA/RSA.php | 2 +- .../src/Algorithm/Signature/Signature.php | 2 +- web-auth/cose-lib/src/Algorithms.php | 2 +- web-auth/cose-lib/src/BigInteger.php | 154 ++++ web-auth/cose-lib/src/Hash.php | 103 +++ web-auth/cose-lib/src/Key/Ec2Key.php | 2 +- web-auth/cose-lib/src/Key/Key.php | 2 +- web-auth/cose-lib/src/Key/OkpKey.php | 2 +- web-auth/cose-lib/src/Key/RsaKey.php | 2 +- web-auth/cose-lib/src/Key/SymmetricKey.php | 2 +- web-auth/cose-lib/src/Verifier.php | 2 +- .../src/AbstractDescriptor.php | 2 +- .../src/AuthenticatorStatus.php | 2 +- .../src/BiometricAccuracyDescriptor.php | 2 +- .../src/BiometricStatusReport.php | 2 +- .../src/CodeAccuracyDescriptor.php | 2 +- .../DisplayPNGCharacteristicsDescriptor.php | 2 +- .../src/DistantSingleMetadata.php | 2 +- .../metadata-service/src/EcdaaTrustAnchor.php | 2 +- .../src/ExtensionDescriptor.php | 2 +- .../metadata-service/src/MetadataService.php | 2 +- .../src/MetadataStatement.php | 2 +- .../src/MetadataStatementFetcher.php | 2 +- .../src/MetadataStatementRepository.php | 2 +- .../src/MetadataTOCPayload.php | 2 +- .../src/MetadataTOCPayloadEntry.php | 2 +- .../src/PatternAccuracyDescriptor.php | 2 +- .../metadata-service/src/RgbPaletteEntry.php | 2 +- .../metadata-service/src/RogueListEntry.php | 2 +- .../metadata-service/src/SingleMetadata.php | 2 +- .../metadata-service/src/StatusReport.php | 2 +- web-auth/metadata-service/src/Utils.php | 2 +- .../src/VerificationMethodANDCombinations.php | 2 +- .../src/VerificationMethodDescriptor.php | 2 +- web-auth/metadata-service/src/Version.php | 2 +- .../AndroidKeyAttestationStatementSupport.php | 2 +- ...idSafetyNetAttestationStatementSupport.php | 6 +- .../AppleAttestationStatementSupport.php | 3 +- .../AttestationObject.php | 2 +- .../AttestationObjectLoader.php | 2 +- .../AttestationStatement.php | 2 +- .../AttestationStatementSupport.php | 2 +- .../AttestationStatementSupportManager.php | 2 +- .../FidoU2FAttestationStatementSupport.php | 2 +- .../NoneAttestationStatementSupport.php | 2 +- .../PackedAttestationStatementSupport.php | 2 +- .../TPMAttestationStatementSupport.php | 2 +- .../src/AttestedCredentialData.php | 2 +- .../AuthenticationExtension.php | 2 +- .../AuthenticationExtensionsClientInputs.php | 2 +- .../AuthenticationExtensionsClientOutputs.php | 2 +- ...nticationExtensionsClientOutputsLoader.php | 2 +- .../ExtensionOutputChecker.php | 2 +- .../ExtensionOutputCheckerHandler.php | 2 +- .../ExtensionOutputError.php | 2 +- .../src/AuthenticatorAssertionResponse.php | 2 +- ...uthenticatorAssertionResponseValidator.php | 38 +- .../src/AuthenticatorAttestationResponse.php | 2 +- ...henticatorAttestationResponseValidator.php | 28 +- .../webauthn-lib/src/AuthenticatorData.php | 2 +- .../src/AuthenticatorResponse.php | 2 +- .../src/AuthenticatorSelectionCriteria.php | 2 +- .../CertificateChainChecker.php | 2 +- .../OpenSSLCertificateChainChecker.php | 2 +- .../webauthn-lib/src/CertificateToolbox.php | 2 +- .../webauthn-lib/src/CollectedClientData.php | 2 +- .../src/Counter/CounterChecker.php | 2 +- .../src/Counter/ThrowExceptionIfInvalid.php | 2 +- web-auth/webauthn-lib/src/Credential.php | 2 +- .../webauthn-lib/src/PublicKeyCredential.php | 2 +- .../PublicKeyCredentialCreationOptions.php | 15 +- .../src/PublicKeyCredentialDescriptor.php | 2 +- ...ublicKeyCredentialDescriptorCollection.php | 2 +- .../src/PublicKeyCredentialEntity.php | 2 +- .../src/PublicKeyCredentialLoader.php | 2 +- .../src/PublicKeyCredentialOptions.php | 2 +- .../src/PublicKeyCredentialParameters.php | 2 +- .../src/PublicKeyCredentialRequestOptions.php | 2 +- .../src/PublicKeyCredentialRpEntity.php | 2 +- .../src/PublicKeyCredentialSource.php | 2 +- .../PublicKeyCredentialSourceRepository.php | 2 +- .../src/PublicKeyCredentialUserEntity.php | 2 +- web-auth/webauthn-lib/src/Server.php | 28 +- web-auth/webauthn-lib/src/StringStream.php | 2 +- .../IgnoreTokenBindingHandler.php | 2 +- .../TokenBinding/SecTokenBindingHandler.php | 2 +- .../src/TokenBinding/TokenBinding.php | 2 +- .../src/TokenBinding/TokenBindingHandler.php | 2 +- .../TokenBindingNotSupportedHandler.php | 2 +- .../src/TrustPath/CertificateTrustPath.php | 2 +- .../src/TrustPath/EcdaaKeyIdTrustPath.php | 2 +- .../src/TrustPath/EmptyTrustPath.php | 2 +- .../webauthn-lib/src/TrustPath/TrustPath.php | 2 +- .../src/TrustPath/TrustPathLoader.php | 2 +- web-auth/webauthn-lib/src/U2FPublicKey.php | 46 + .../src/Util/CoseSignatureFixer.php | 2 +- 338 files changed, 7155 insertions(+), 2981 deletions(-) create mode 100644 league/uri-interfaces/src/Exceptions/IdnaConversionFailed.php create mode 100644 league/uri-interfaces/src/Idna/Idna.php create mode 100644 league/uri-interfaces/src/Idna/IdnaInfo.php create mode 100644 ramsey/collection/conventional-commits.json create mode 100644 ramsey/uuid/src/Converter/Time/UnixTimeConverter.php create mode 100644 ramsey/uuid/src/Exception/UuidExceptionInterface.php create mode 100644 ramsey/uuid/src/Generator/UnixTimeGenerator.php create mode 100644 ramsey/uuid/src/Rfc4122/MaxTrait.php create mode 100644 ramsey/uuid/src/Rfc4122/MaxUuid.php create mode 100644 ramsey/uuid/src/Rfc4122/TimeTrait.php create mode 100644 ramsey/uuid/src/Rfc4122/UuidV6.php create mode 100644 ramsey/uuid/src/Rfc4122/UuidV7.php create mode 100644 ramsey/uuid/src/Rfc4122/UuidV8.php delete mode 100644 spomky-labs/cbor-php/infection.json.dist create mode 100644 spomky-labs/cbor-php/src/DecoderInterface.php create mode 100644 spomky-labs/cbor-php/src/IndefiniteLengthByteStringObject.php create mode 100644 spomky-labs/cbor-php/src/IndefiniteLengthListObject.php create mode 100644 spomky-labs/cbor-php/src/IndefiniteLengthMapObject.php create mode 100644 spomky-labs/cbor-php/src/IndefiniteLengthTextStringObject.php create mode 100644 spomky-labs/cbor-php/src/NegativeIntegerObject.php create mode 100644 spomky-labs/cbor-php/src/Normalizable.php create mode 100644 spomky-labs/cbor-php/src/OtherObject/OtherObjectManagerInterface.php create mode 100644 spomky-labs/cbor-php/src/Tag.php create mode 100644 spomky-labs/cbor-php/src/Tag/Base64Tag.php create mode 100644 spomky-labs/cbor-php/src/Tag/Base64UrlTag.php create mode 100644 spomky-labs/cbor-php/src/Tag/CBOREncodingTag.php create mode 100644 spomky-labs/cbor-php/src/Tag/CBORTag.php create mode 100644 spomky-labs/cbor-php/src/Tag/DatetimeTag.php create mode 100644 spomky-labs/cbor-php/src/Tag/MimeTag.php create mode 100644 spomky-labs/cbor-php/src/Tag/TagManager.php create mode 100644 spomky-labs/cbor-php/src/Tag/TagManagerInterface.php create mode 100644 spomky-labs/cbor-php/src/Tag/UnsignedBigIntegerTag.php create mode 100644 spomky-labs/cbor-php/src/Tag/UriTag.php create mode 100644 symfony/polyfill-php81/LICENSE create mode 100644 symfony/polyfill-php81/Php81.php create mode 100644 symfony/polyfill-php81/Resources/stubs/CURLStringFile.php create mode 100644 symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php create mode 100644 symfony/polyfill-php81/bootstrap.php create mode 100644 web-auth/cose-lib/src/BigInteger.php create mode 100644 web-auth/cose-lib/src/Hash.php create mode 100644 web-auth/webauthn-lib/src/U2FPublicKey.php diff --git a/beberlei/assert/lib/Assert/Assertion.php b/beberlei/assert/lib/Assert/Assertion.php index 31382e5dc..243e64d28 100644 --- a/beberlei/assert/lib/Assert/Assertion.php +++ b/beberlei/assert/lib/Assert/Assertion.php @@ -953,7 +953,7 @@ public static function startsWith($string, $needle, $message = null, string $pro { static::string($string, $message, $propertyPath); - if (0 !== \mb_strpos($string, $needle, null, $encoding)) { + if (0 !== \mb_strpos($string, $needle, 0, $encoding)) { $message = \sprintf( static::generateMessage($message ?: 'Value "%s" does not start with "%s".'), static::stringify($string), @@ -987,7 +987,7 @@ public static function endsWith($string, $needle, $message = null, string $prope $stringPosition = \mb_strlen($string, $encoding) - \mb_strlen($needle, $encoding); - if (\mb_strripos($string, $needle, null, $encoding) !== $stringPosition) { + if (\mb_strripos($string, $needle, 0, $encoding) !== $stringPosition) { $message = \sprintf( static::generateMessage($message ?: 'Value "%s" does not end with "%s".'), static::stringify($string), @@ -1019,7 +1019,7 @@ public static function contains($string, $needle, $message = null, string $prope { static::string($string, $message, $propertyPath); - if (false === \mb_strpos($string, $needle, null, $encoding)) { + if (false === \mb_strpos($string, $needle, 0, $encoding)) { $message = \sprintf( static::generateMessage($message ?: 'Value "%s" does not contain "%s".'), static::stringify($string), @@ -1051,7 +1051,7 @@ public static function notContains($string, $needle, $message = null, string $pr { static::string($string, $message, $propertyPath); - if (false !== \mb_strpos($string, $needle, null, $encoding)) { + if (false !== \mb_strpos($string, $needle, 0, $encoding)) { $message = \sprintf( static::generateMessage($message ?: 'Value "%s" contains "%s".'), static::stringify($string), @@ -2620,7 +2620,12 @@ public static function satisfy($value, $callback, $message = null, string $prope public static function ip($value, $flag = null, $message = null, string $propertyPath = null): bool { static::string($value, $message, $propertyPath); - if (!\filter_var($value, FILTER_VALIDATE_IP, $flag)) { + if ($flag === null) { + $filterVarResult = \filter_var($value, FILTER_VALIDATE_IP); + } else { + $filterVarResult = \filter_var($value, FILTER_VALIDATE_IP, $flag); + } + if (!$filterVarResult) { $message = \sprintf( static::generateMessage($message ?: 'Value "%s" was expected to be a valid IP address.'), static::stringify($value) diff --git a/beberlei/assert/lib/Assert/AssertionChain.php b/beberlei/assert/lib/Assert/AssertionChain.php index b3f8fa5ea..4c444350f 100644 --- a/beberlei/assert/lib/Assert/AssertionChain.php +++ b/beberlei/assert/lib/Assert/AssertionChain.php @@ -15,7 +15,6 @@ namespace Assert; use LogicException; -use ReflectionClass; /** * Chaining builder for assertions. @@ -171,13 +170,12 @@ public function __call($methodName, $args): AssertionChain return $this; } - if (!\method_exists($this->assertionClassName, $methodName)) { + try { + $method = new \ReflectionMethod($this->assertionClassName, $methodName); + } catch (\ReflectionException $exception) { throw new \RuntimeException("Assertion '".$methodName."' does not exist."); } - $reflClass = new ReflectionClass($this->assertionClassName); - $method = $reflClass->getMethod($methodName); - \array_unshift($args, $this->value); $params = $method->getParameters(); @@ -186,12 +184,13 @@ public function __call($methodName, $args): AssertionChain continue; } - if ('message' == $param->getName()) { - $args[$idx] = $this->defaultMessage; - } - - if ('propertyPath' == $param->getName()) { - $args[$idx] = $this->defaultPropertyPath; + switch ($param->getName()) { + case 'message': + $args[$idx] = $this->defaultMessage; + break; + case 'propertyPath': + $args[$idx] = $this->defaultPropertyPath; + break; } } diff --git a/brick/math/src/BigDecimal.php b/brick/math/src/BigDecimal.php index 7707b166e..78246500c 100644 --- a/brick/math/src/BigDecimal.php +++ b/brick/math/src/BigDecimal.php @@ -752,6 +752,40 @@ public function __toString() : string return \substr($value, 0, -$this->scale) . '.' . \substr($value, -$this->scale); } + /** + * This method is required for serializing the object and SHOULD NOT be accessed directly. + * + * @internal + * + * @return array{value: string, scale: int} + */ + public function __serialize(): array + { + return ['value' => $this->value, 'scale' => $this->scale]; + } + + /** + * This method is only here to allow unserializing the object and cannot be accessed directly. + * + * @internal + * @psalm-suppress RedundantPropertyInitializationCheck + * + * @param array{value: string, scale: int} $data + * + * @return void + * + * @throws \LogicException + */ + public function __unserialize(array $data): void + { + if (isset($this->value)) { + throw new \LogicException('__unserialize() is an internal function, it must not be called directly.'); + } + + $this->value = $data['value']; + $this->scale = $data['scale']; + } + /** * This method is required by interface Serializable and SHOULD NOT be accessed directly. * @@ -794,7 +828,7 @@ public function unserialize($value) : void * @param BigDecimal $x The first decimal number. * @param BigDecimal $y The second decimal number. * - * @return array{0: string, 1: string} The scaled integer values of $x and $y. + * @return array{string, string} The scaled integer values of $x and $y. */ private function scaleValues(BigDecimal $x, BigDecimal $y) : array { diff --git a/brick/math/src/BigInteger.php b/brick/math/src/BigInteger.php index 0dcc8f3b3..f213fbedb 100644 --- a/brick/math/src/BigInteger.php +++ b/brick/math/src/BigInteger.php @@ -1116,6 +1116,39 @@ public function __toString() : string return $this->value; } + /** + * This method is required for serializing the object and SHOULD NOT be accessed directly. + * + * @internal + * + * @return array{value: string} + */ + public function __serialize(): array + { + return ['value' => $this->value]; + } + + /** + * This method is only here to allow unserializing the object and cannot be accessed directly. + * + * @internal + * @psalm-suppress RedundantPropertyInitializationCheck + * + * @param array{value: string} $data + * + * @return void + * + * @throws \LogicException + */ + public function __unserialize(array $data): void + { + if (isset($this->value)) { + throw new \LogicException('__unserialize() is an internal function, it must not be called directly.'); + } + + $this->value = $data['value']; + } + /** * This method is required by interface Serializable and SHOULD NOT be accessed directly. * diff --git a/brick/math/src/BigRational.php b/brick/math/src/BigRational.php index 7fbabd7f1..bee094f73 100644 --- a/brick/math/src/BigRational.php +++ b/brick/math/src/BigRational.php @@ -451,6 +451,40 @@ public function __toString() : string return $this->numerator . '/' . $this->denominator; } + /** + * This method is required for serializing the object and SHOULD NOT be accessed directly. + * + * @internal + * + * @return array{numerator: BigInteger, denominator: BigInteger} + */ + public function __serialize(): array + { + return ['numerator' => $this->numerator, 'denominator' => $this->denominator]; + } + + /** + * This method is only here to allow unserializing the object and cannot be accessed directly. + * + * @internal + * @psalm-suppress RedundantPropertyInitializationCheck + * + * @param array{numerator: BigInteger, denominator: BigInteger} $data + * + * @return void + * + * @throws \LogicException + */ + public function __unserialize(array $data): void + { + if (isset($this->numerator)) { + throw new \LogicException('__unserialize() is an internal function, it must not be called directly.'); + } + + $this->numerator = $data['numerator']; + $this->denominator = $data['denominator']; + } + /** * This method is required by interface Serializable and SHOULD NOT be accessed directly. * diff --git a/brick/math/src/Internal/Calculator.php b/brick/math/src/Internal/Calculator.php index 99b478193..a6eac799f 100644 --- a/brick/math/src/Internal/Calculator.php +++ b/brick/math/src/Internal/Calculator.php @@ -99,7 +99,7 @@ private static function detect() : Calculator * @param string $a The first operand. * @param string $b The second operand. * - * @return array{0: bool, 1: bool, 2: string, 3: string} Whether $a and $b are negative, followed by their digits. + * @return array{bool, bool, string, string} Whether $a and $b are negative, followed by their digits. */ final protected function init(string $a, string $b) : array { @@ -677,9 +677,6 @@ private function bitwise(string $operator, string $a, string $b) : string } /** - * @psalm-suppress InvalidOperand - * @see https://github.com/vimeo/psalm/issues/4456 - * * @param string $number A positive, binary number. * * @return string diff --git a/brick/math/src/Internal/Calculator/NativeCalculator.php b/brick/math/src/Internal/Calculator/NativeCalculator.php index a5f8a9b48..020a6338b 100644 --- a/brick/math/src/Internal/Calculator/NativeCalculator.php +++ b/brick/math/src/Internal/Calculator/NativeCalculator.php @@ -610,7 +610,7 @@ private function doCmp(string $a, string $b) : int * @param string $a The first operand. * @param string $b The second operand. * - * @return array{0: string, 1: string, 2: int} + * @return array{string, string, int} */ private function pad(string $a, string $b) : array { diff --git a/composer/autoload_classmap.php b/composer/autoload_classmap.php index 19834d353..f008752ff 100644 --- a/composer/autoload_classmap.php +++ b/composer/autoload_classmap.php @@ -963,12 +963,19 @@ 'CBOR\\ByteStringWithChunkObject' => $vendorDir . '/spomky-labs/cbor-php/src/ByteStringWithChunkObject.php', 'CBOR\\CBORObject' => $vendorDir . '/spomky-labs/cbor-php/src/CBORObject.php', 'CBOR\\Decoder' => $vendorDir . '/spomky-labs/cbor-php/src/Decoder.php', + 'CBOR\\DecoderInterface' => $vendorDir . '/spomky-labs/cbor-php/src/DecoderInterface.php', + 'CBOR\\IndefiniteLengthByteStringObject' => $vendorDir . '/spomky-labs/cbor-php/src/IndefiniteLengthByteStringObject.php', + 'CBOR\\IndefiniteLengthListObject' => $vendorDir . '/spomky-labs/cbor-php/src/IndefiniteLengthListObject.php', + 'CBOR\\IndefiniteLengthMapObject' => $vendorDir . '/spomky-labs/cbor-php/src/IndefiniteLengthMapObject.php', + 'CBOR\\IndefiniteLengthTextStringObject' => $vendorDir . '/spomky-labs/cbor-php/src/IndefiniteLengthTextStringObject.php', 'CBOR\\InfiniteListObject' => $vendorDir . '/spomky-labs/cbor-php/src/InfiniteListObject.php', 'CBOR\\InfiniteMapObject' => $vendorDir . '/spomky-labs/cbor-php/src/InfiniteMapObject.php', 'CBOR\\LengthCalculator' => $vendorDir . '/spomky-labs/cbor-php/src/LengthCalculator.php', 'CBOR\\ListObject' => $vendorDir . '/spomky-labs/cbor-php/src/ListObject.php', 'CBOR\\MapItem' => $vendorDir . '/spomky-labs/cbor-php/src/MapItem.php', 'CBOR\\MapObject' => $vendorDir . '/spomky-labs/cbor-php/src/MapObject.php', + 'CBOR\\NegativeIntegerObject' => $vendorDir . '/spomky-labs/cbor-php/src/NegativeIntegerObject.php', + 'CBOR\\Normalizable' => $vendorDir . '/spomky-labs/cbor-php/src/Normalizable.php', 'CBOR\\OtherObject' => $vendorDir . '/spomky-labs/cbor-php/src/OtherObject.php', 'CBOR\\OtherObject\\BreakObject' => $vendorDir . '/spomky-labs/cbor-php/src/OtherObject/BreakObject.php', 'CBOR\\OtherObject\\DoublePrecisionFloatObject' => $vendorDir . '/spomky-labs/cbor-php/src/OtherObject/DoublePrecisionFloatObject.php', @@ -977,6 +984,7 @@ 'CBOR\\OtherObject\\HalfPrecisionFloatObject' => $vendorDir . '/spomky-labs/cbor-php/src/OtherObject/HalfPrecisionFloatObject.php', 'CBOR\\OtherObject\\NullObject' => $vendorDir . '/spomky-labs/cbor-php/src/OtherObject/NullObject.php', 'CBOR\\OtherObject\\OtherObjectManager' => $vendorDir . '/spomky-labs/cbor-php/src/OtherObject/OtherObjectManager.php', + 'CBOR\\OtherObject\\OtherObjectManagerInterface' => $vendorDir . '/spomky-labs/cbor-php/src/OtherObject/OtherObjectManagerInterface.php', 'CBOR\\OtherObject\\SimpleObject' => $vendorDir . '/spomky-labs/cbor-php/src/OtherObject/SimpleObject.php', 'CBOR\\OtherObject\\SinglePrecisionFloatObject' => $vendorDir . '/spomky-labs/cbor-php/src/OtherObject/SinglePrecisionFloatObject.php', 'CBOR\\OtherObject\\TrueObject' => $vendorDir . '/spomky-labs/cbor-php/src/OtherObject/TrueObject.php', @@ -984,22 +992,34 @@ 'CBOR\\SignedIntegerObject' => $vendorDir . '/spomky-labs/cbor-php/src/SignedIntegerObject.php', 'CBOR\\Stream' => $vendorDir . '/spomky-labs/cbor-php/src/Stream.php', 'CBOR\\StringStream' => $vendorDir . '/spomky-labs/cbor-php/src/StringStream.php', + 'CBOR\\Tag' => $vendorDir . '/spomky-labs/cbor-php/src/Tag.php', 'CBOR\\TagObject' => $vendorDir . '/spomky-labs/cbor-php/src/TagObject.php', 'CBOR\\Tag\\Base16EncodingTag' => $vendorDir . '/spomky-labs/cbor-php/src/Tag/Base16EncodingTag.php', 'CBOR\\Tag\\Base64EncodingTag' => $vendorDir . '/spomky-labs/cbor-php/src/Tag/Base64EncodingTag.php', + 'CBOR\\Tag\\Base64Tag' => $vendorDir . '/spomky-labs/cbor-php/src/Tag/Base64Tag.php', 'CBOR\\Tag\\Base64UrlEncodingTag' => $vendorDir . '/spomky-labs/cbor-php/src/Tag/Base64UrlEncodingTag.php', + 'CBOR\\Tag\\Base64UrlTag' => $vendorDir . '/spomky-labs/cbor-php/src/Tag/Base64UrlTag.php', 'CBOR\\Tag\\BigFloatTag' => $vendorDir . '/spomky-labs/cbor-php/src/Tag/BigFloatTag.php', + 'CBOR\\Tag\\CBOREncodingTag' => $vendorDir . '/spomky-labs/cbor-php/src/Tag/CBOREncodingTag.php', + 'CBOR\\Tag\\CBORTag' => $vendorDir . '/spomky-labs/cbor-php/src/Tag/CBORTag.php', + 'CBOR\\Tag\\DatetimeTag' => $vendorDir . '/spomky-labs/cbor-php/src/Tag/DatetimeTag.php', 'CBOR\\Tag\\DecimalFractionTag' => $vendorDir . '/spomky-labs/cbor-php/src/Tag/DecimalFractionTag.php', 'CBOR\\Tag\\EpochTag' => $vendorDir . '/spomky-labs/cbor-php/src/Tag/EpochTag.php', 'CBOR\\Tag\\GenericTag' => $vendorDir . '/spomky-labs/cbor-php/src/Tag/GenericTag.php', + 'CBOR\\Tag\\MimeTag' => $vendorDir . '/spomky-labs/cbor-php/src/Tag/MimeTag.php', 'CBOR\\Tag\\NegativeBigIntegerTag' => $vendorDir . '/spomky-labs/cbor-php/src/Tag/NegativeBigIntegerTag.php', 'CBOR\\Tag\\PositiveBigIntegerTag' => $vendorDir . '/spomky-labs/cbor-php/src/Tag/PositiveBigIntegerTag.php', + 'CBOR\\Tag\\TagManager' => $vendorDir . '/spomky-labs/cbor-php/src/Tag/TagManager.php', + 'CBOR\\Tag\\TagManagerInterface' => $vendorDir . '/spomky-labs/cbor-php/src/Tag/TagManagerInterface.php', 'CBOR\\Tag\\TagObjectManager' => $vendorDir . '/spomky-labs/cbor-php/src/Tag/TagObjectManager.php', 'CBOR\\Tag\\TimestampTag' => $vendorDir . '/spomky-labs/cbor-php/src/Tag/TimestampTag.php', + 'CBOR\\Tag\\UnsignedBigIntegerTag' => $vendorDir . '/spomky-labs/cbor-php/src/Tag/UnsignedBigIntegerTag.php', + 'CBOR\\Tag\\UriTag' => $vendorDir . '/spomky-labs/cbor-php/src/Tag/UriTag.php', 'CBOR\\TextStringObject' => $vendorDir . '/spomky-labs/cbor-php/src/TextStringObject.php', 'CBOR\\TextStringWithChunkObject' => $vendorDir . '/spomky-labs/cbor-php/src/TextStringWithChunkObject.php', 'CBOR\\UnsignedIntegerObject' => $vendorDir . '/spomky-labs/cbor-php/src/UnsignedIntegerObject.php', 'CBOR\\Utils' => $vendorDir . '/spomky-labs/cbor-php/src/Utils.php', + 'CURLStringFile' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php', 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', 'Console_Getopt' => $vendorDir . '/pear/console_getopt/Console/Getopt.php', 'Cose\\Algorithm\\Algorithm' => $vendorDir . '/web-auth/cose-lib/src/Algorithm/Algorithm.php', @@ -1032,6 +1052,8 @@ 'Cose\\Algorithm\\Signature\\RSA\\RSA' => $vendorDir . '/web-auth/cose-lib/src/Algorithm/Signature/RSA/RSA.php', 'Cose\\Algorithm\\Signature\\Signature' => $vendorDir . '/web-auth/cose-lib/src/Algorithm/Signature/Signature.php', 'Cose\\Algorithms' => $vendorDir . '/web-auth/cose-lib/src/Algorithms.php', + 'Cose\\BigInteger' => $vendorDir . '/web-auth/cose-lib/src/BigInteger.php', + 'Cose\\Hash' => $vendorDir . '/web-auth/cose-lib/src/Hash.php', 'Cose\\Key\\Ec2Key' => $vendorDir . '/web-auth/cose-lib/src/Key/Ec2Key.php', 'Cose\\Key\\Key' => $vendorDir . '/web-auth/cose-lib/src/Key/Key.php', 'Cose\\Key\\OkpKey' => $vendorDir . '/web-auth/cose-lib/src/Key/OkpKey.php', @@ -1780,10 +1802,13 @@ 'League\\Uri\\Contracts\\UserInfoInterface' => $vendorDir . '/league/uri-interfaces/src/Contracts/UserInfoInterface.php', 'League\\Uri\\Exceptions\\FileinfoSupportMissing' => $vendorDir . '/league/uri-interfaces/src/Exceptions/FileinfoSupportMissing.php', 'League\\Uri\\Exceptions\\IdnSupportMissing' => $vendorDir . '/league/uri-interfaces/src/Exceptions/IdnSupportMissing.php', + 'League\\Uri\\Exceptions\\IdnaConversionFailed' => $vendorDir . '/league/uri-interfaces/src/Exceptions/IdnaConversionFailed.php', 'League\\Uri\\Exceptions\\SyntaxError' => $vendorDir . '/league/uri-interfaces/src/Exceptions/SyntaxError.php', 'League\\Uri\\Exceptions\\TemplateCanNotBeExpanded' => $vendorDir . '/league/uri/src/Exceptions/TemplateCanNotBeExpanded.php', 'League\\Uri\\Http' => $vendorDir . '/league/uri/src/Http.php', 'League\\Uri\\HttpFactory' => $vendorDir . '/league/uri/src/HttpFactory.php', + 'League\\Uri\\Idna\\Idna' => $vendorDir . '/league/uri-interfaces/src/Idna/Idna.php', + 'League\\Uri\\Idna\\IdnaInfo' => $vendorDir . '/league/uri-interfaces/src/Idna/IdnaInfo.php', 'League\\Uri\\Uri' => $vendorDir . '/league/uri/src/Uri.php', 'League\\Uri\\UriInfo' => $vendorDir . '/league/uri/src/UriInfo.php', 'League\\Uri\\UriResolver' => $vendorDir . '/league/uri/src/UriResolver.php', @@ -2172,6 +2197,7 @@ 'Ramsey\\Uuid\\Converter\\Time\\DegradedTimeConverter' => $vendorDir . '/ramsey/uuid/src/Converter/Time/DegradedTimeConverter.php', 'Ramsey\\Uuid\\Converter\\Time\\GenericTimeConverter' => $vendorDir . '/ramsey/uuid/src/Converter/Time/GenericTimeConverter.php', 'Ramsey\\Uuid\\Converter\\Time\\PhpTimeConverter' => $vendorDir . '/ramsey/uuid/src/Converter/Time/PhpTimeConverter.php', + 'Ramsey\\Uuid\\Converter\\Time\\UnixTimeConverter' => $vendorDir . '/ramsey/uuid/src/Converter/Time/UnixTimeConverter.php', 'Ramsey\\Uuid\\DegradedUuid' => $vendorDir . '/ramsey/uuid/src/DegradedUuid.php', 'Ramsey\\Uuid\\DeprecatedUuidInterface' => $vendorDir . '/ramsey/uuid/src/DeprecatedUuidInterface.php', 'Ramsey\\Uuid\\DeprecatedUuidMethodsTrait' => $vendorDir . '/ramsey/uuid/src/DeprecatedUuidMethodsTrait.php', @@ -2187,6 +2213,7 @@ 'Ramsey\\Uuid\\Exception\\TimeSourceException' => $vendorDir . '/ramsey/uuid/src/Exception/TimeSourceException.php', 'Ramsey\\Uuid\\Exception\\UnableToBuildUuidException' => $vendorDir . '/ramsey/uuid/src/Exception/UnableToBuildUuidException.php', 'Ramsey\\Uuid\\Exception\\UnsupportedOperationException' => $vendorDir . '/ramsey/uuid/src/Exception/UnsupportedOperationException.php', + 'Ramsey\\Uuid\\Exception\\UuidExceptionInterface' => $vendorDir . '/ramsey/uuid/src/Exception/UuidExceptionInterface.php', 'Ramsey\\Uuid\\FeatureSet' => $vendorDir . '/ramsey/uuid/src/FeatureSet.php', 'Ramsey\\Uuid\\Fields\\FieldsInterface' => $vendorDir . '/ramsey/uuid/src/Fields/FieldsInterface.php', 'Ramsey\\Uuid\\Fields\\SerializableFieldsTrait' => $vendorDir . '/ramsey/uuid/src/Fields/SerializableFieldsTrait.php', @@ -2206,6 +2233,7 @@ 'Ramsey\\Uuid\\Generator\\RandomLibAdapter' => $vendorDir . '/ramsey/uuid/src/Generator/RandomLibAdapter.php', 'Ramsey\\Uuid\\Generator\\TimeGeneratorFactory' => $vendorDir . '/ramsey/uuid/src/Generator/TimeGeneratorFactory.php', 'Ramsey\\Uuid\\Generator\\TimeGeneratorInterface' => $vendorDir . '/ramsey/uuid/src/Generator/TimeGeneratorInterface.php', + 'Ramsey\\Uuid\\Generator\\UnixTimeGenerator' => $vendorDir . '/ramsey/uuid/src/Generator/UnixTimeGenerator.php', 'Ramsey\\Uuid\\Guid\\Fields' => $vendorDir . '/ramsey/uuid/src/Guid/Fields.php', 'Ramsey\\Uuid\\Guid\\Guid' => $vendorDir . '/ramsey/uuid/src/Guid/Guid.php', 'Ramsey\\Uuid\\Guid\\GuidBuilder' => $vendorDir . '/ramsey/uuid/src/Guid/GuidBuilder.php', @@ -2230,8 +2258,11 @@ 'Ramsey\\Uuid\\Provider\\Time\\SystemTimeProvider' => $vendorDir . '/ramsey/uuid/src/Provider/Time/SystemTimeProvider.php', 'Ramsey\\Uuid\\Rfc4122\\Fields' => $vendorDir . '/ramsey/uuid/src/Rfc4122/Fields.php', 'Ramsey\\Uuid\\Rfc4122\\FieldsInterface' => $vendorDir . '/ramsey/uuid/src/Rfc4122/FieldsInterface.php', + 'Ramsey\\Uuid\\Rfc4122\\MaxTrait' => $vendorDir . '/ramsey/uuid/src/Rfc4122/MaxTrait.php', + 'Ramsey\\Uuid\\Rfc4122\\MaxUuid' => $vendorDir . '/ramsey/uuid/src/Rfc4122/MaxUuid.php', 'Ramsey\\Uuid\\Rfc4122\\NilTrait' => $vendorDir . '/ramsey/uuid/src/Rfc4122/NilTrait.php', 'Ramsey\\Uuid\\Rfc4122\\NilUuid' => $vendorDir . '/ramsey/uuid/src/Rfc4122/NilUuid.php', + 'Ramsey\\Uuid\\Rfc4122\\TimeTrait' => $vendorDir . '/ramsey/uuid/src/Rfc4122/TimeTrait.php', 'Ramsey\\Uuid\\Rfc4122\\UuidBuilder' => $vendorDir . '/ramsey/uuid/src/Rfc4122/UuidBuilder.php', 'Ramsey\\Uuid\\Rfc4122\\UuidInterface' => $vendorDir . '/ramsey/uuid/src/Rfc4122/UuidInterface.php', 'Ramsey\\Uuid\\Rfc4122\\UuidV1' => $vendorDir . '/ramsey/uuid/src/Rfc4122/UuidV1.php', @@ -2239,6 +2270,9 @@ 'Ramsey\\Uuid\\Rfc4122\\UuidV3' => $vendorDir . '/ramsey/uuid/src/Rfc4122/UuidV3.php', 'Ramsey\\Uuid\\Rfc4122\\UuidV4' => $vendorDir . '/ramsey/uuid/src/Rfc4122/UuidV4.php', 'Ramsey\\Uuid\\Rfc4122\\UuidV5' => $vendorDir . '/ramsey/uuid/src/Rfc4122/UuidV5.php', + 'Ramsey\\Uuid\\Rfc4122\\UuidV6' => $vendorDir . '/ramsey/uuid/src/Rfc4122/UuidV6.php', + 'Ramsey\\Uuid\\Rfc4122\\UuidV7' => $vendorDir . '/ramsey/uuid/src/Rfc4122/UuidV7.php', + 'Ramsey\\Uuid\\Rfc4122\\UuidV8' => $vendorDir . '/ramsey/uuid/src/Rfc4122/UuidV8.php', 'Ramsey\\Uuid\\Rfc4122\\Validator' => $vendorDir . '/ramsey/uuid/src/Rfc4122/Validator.php', 'Ramsey\\Uuid\\Rfc4122\\VariantTrait' => $vendorDir . '/ramsey/uuid/src/Rfc4122/VariantTrait.php', 'Ramsey\\Uuid\\Rfc4122\\VersionTrait' => $vendorDir . '/ramsey/uuid/src/Rfc4122/VersionTrait.php', @@ -2254,6 +2288,7 @@ 'Ramsey\\Uuid\\UuidInterface' => $vendorDir . '/ramsey/uuid/src/UuidInterface.php', 'Ramsey\\Uuid\\Validator\\GenericValidator' => $vendorDir . '/ramsey/uuid/src/Validator/GenericValidator.php', 'Ramsey\\Uuid\\Validator\\ValidatorInterface' => $vendorDir . '/ramsey/uuid/src/Validator/ValidatorInterface.php', + 'ReturnTypeWillChange' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php', 'Sabre\\CalDAV\\Backend\\AbstractBackend' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/AbstractBackend.php', 'Sabre\\CalDAV\\Backend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/BackendInterface.php', 'Sabre\\CalDAV\\Backend\\NotificationSupport' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/NotificationSupport.php', @@ -3354,6 +3389,7 @@ 'Symfony\\Polyfill\\Php73\\Php73' => $vendorDir . '/symfony/polyfill-php73/Php73.php', 'Symfony\\Polyfill\\Php80\\Php80' => $vendorDir . '/symfony/polyfill-php80/Php80.php', 'Symfony\\Polyfill\\Php80\\PhpToken' => $vendorDir . '/symfony/polyfill-php80/PhpToken.php', + 'Symfony\\Polyfill\\Php81\\Php81' => $vendorDir . '/symfony/polyfill-php81/Php81.php', 'System' => $vendorDir . '/pear/pear-core-minimal/src/System.php', 'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php', 'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php', @@ -3440,6 +3476,7 @@ 'Webauthn\\TrustPath\\EmptyTrustPath' => $vendorDir . '/web-auth/webauthn-lib/src/TrustPath/EmptyTrustPath.php', 'Webauthn\\TrustPath\\TrustPath' => $vendorDir . '/web-auth/webauthn-lib/src/TrustPath/TrustPath.php', 'Webauthn\\TrustPath\\TrustPathLoader' => $vendorDir . '/web-auth/webauthn-lib/src/TrustPath/TrustPathLoader.php', + 'Webauthn\\U2FPublicKey' => $vendorDir . '/web-auth/webauthn-lib/src/U2FPublicKey.php', 'Webauthn\\Util\\CoseSignatureFixer' => $vendorDir . '/web-auth/webauthn-lib/src/Util/CoseSignatureFixer.php', 'ZipStreamer\\COMPR' => $vendorDir . '/deepdiver/zipstreamer/src/COMPR.php', 'ZipStreamer\\Count64' => $vendorDir . '/deepdiver/zipstreamer/src/Count64.php', diff --git a/composer/autoload_files.php b/composer/autoload_files.php index b20dade95..d6ba8a522 100644 --- a/composer/autoload_files.php +++ b/composer/autoload_files.php @@ -13,7 +13,6 @@ '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php', 'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php', 'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php', - '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', 'a4ecaeafb8cfb009ad0e052c90355e98' => $vendorDir . '/beberlei/assert/lib/Assert/functions.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php', '2b9d0f43f9552984cfa82fee95491826' => $vendorDir . '/sabre/event/lib/coroutine.php', @@ -21,9 +20,11 @@ 'a1cce3d26cc15c00fcd0b3354bd72c88' => $vendorDir . '/sabre/event/lib/Promise/functions.php', '3569eecfeed3bcf0bad3c998a494ecb8' => $vendorDir . '/sabre/xml/lib/Deserializer/functions.php', '93aa591bc4ca510c520999e34229ee79' => $vendorDir . '/sabre/xml/lib/Serializer/functions.php', + '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', '25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php', 'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php', '8825ede83f2f289127722d4e842cf7e8' => $vendorDir . '/symfony/polyfill-intl-grapheme/bootstrap.php', + '23c18046f52bef3eea034657bafda50f' => $vendorDir . '/symfony/polyfill-php81/bootstrap.php', 'ebdb698ed4152ae445614b69b5e4bb6a' => $vendorDir . '/sabre/http/lib/functions.php', '0d59ee240a4cd96ddbb4ff164fccea4d' => $vendorDir . '/symfony/polyfill-php73/bootstrap.php', 'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php', diff --git a/composer/autoload_psr4.php b/composer/autoload_psr4.php index c5fa437f9..59c548177 100644 --- a/composer/autoload_psr4.php +++ b/composer/autoload_psr4.php @@ -16,6 +16,7 @@ 'ZipStreamer\\' => array($vendorDir . '/deepdiver/zipstreamer/src'), 'Webauthn\\MetadataService\\' => array($vendorDir . '/web-auth/metadata-service/src'), 'Webauthn\\' => array($vendorDir . '/web-auth/webauthn-lib/src'), + 'Symfony\\Polyfill\\Php81\\' => array($vendorDir . '/symfony/polyfill-php81'), 'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'), 'Symfony\\Polyfill\\Php73\\' => array($vendorDir . '/symfony/polyfill-php73'), 'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'), diff --git a/composer/autoload_static.php b/composer/autoload_static.php index 1dc699d53..f583f2768 100644 --- a/composer/autoload_static.php +++ b/composer/autoload_static.php @@ -14,7 +14,6 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', 'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php', 'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php', - '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', 'a4ecaeafb8cfb009ad0e052c90355e98' => __DIR__ . '/..' . '/beberlei/assert/lib/Assert/functions.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php', '2b9d0f43f9552984cfa82fee95491826' => __DIR__ . '/..' . '/sabre/event/lib/coroutine.php', @@ -22,9 +21,11 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'a1cce3d26cc15c00fcd0b3354bd72c88' => __DIR__ . '/..' . '/sabre/event/lib/Promise/functions.php', '3569eecfeed3bcf0bad3c998a494ecb8' => __DIR__ . '/..' . '/sabre/xml/lib/Deserializer/functions.php', '93aa591bc4ca510c520999e34229ee79' => __DIR__ . '/..' . '/sabre/xml/lib/Serializer/functions.php', + '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', '25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php', 'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php', '8825ede83f2f289127722d4e842cf7e8' => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme/bootstrap.php', + '23c18046f52bef3eea034657bafda50f' => __DIR__ . '/..' . '/symfony/polyfill-php81/bootstrap.php', 'ebdb698ed4152ae445614b69b5e4bb6a' => __DIR__ . '/..' . '/sabre/http/lib/functions.php', '0d59ee240a4cd96ddbb4ff164fccea4d' => __DIR__ . '/..' . '/symfony/polyfill-php73/bootstrap.php', 'b6b991a57620e2fb6b2f66f03fe9ddc2' => __DIR__ . '/..' . '/symfony/string/Resources/functions.php', @@ -164,6 +165,7 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 ), 'S' => array ( + 'Symfony\\Polyfill\\Php81\\' => 23, 'Symfony\\Polyfill\\Php80\\' => 23, 'Symfony\\Polyfill\\Php73\\' => 23, 'Symfony\\Polyfill\\Php72\\' => 23, @@ -329,6 +331,10 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 array ( 0 => __DIR__ . '/..' . '/web-auth/webauthn-lib/src', ), + 'Symfony\\Polyfill\\Php81\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-php81', + ), 'Symfony\\Polyfill\\Php80\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-php80', @@ -1620,12 +1626,19 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'CBOR\\ByteStringWithChunkObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/ByteStringWithChunkObject.php', 'CBOR\\CBORObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/CBORObject.php', 'CBOR\\Decoder' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Decoder.php', + 'CBOR\\DecoderInterface' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/DecoderInterface.php', + 'CBOR\\IndefiniteLengthByteStringObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/IndefiniteLengthByteStringObject.php', + 'CBOR\\IndefiniteLengthListObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/IndefiniteLengthListObject.php', + 'CBOR\\IndefiniteLengthMapObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/IndefiniteLengthMapObject.php', + 'CBOR\\IndefiniteLengthTextStringObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/IndefiniteLengthTextStringObject.php', 'CBOR\\InfiniteListObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/InfiniteListObject.php', 'CBOR\\InfiniteMapObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/InfiniteMapObject.php', 'CBOR\\LengthCalculator' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/LengthCalculator.php', 'CBOR\\ListObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/ListObject.php', 'CBOR\\MapItem' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/MapItem.php', 'CBOR\\MapObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/MapObject.php', + 'CBOR\\NegativeIntegerObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/NegativeIntegerObject.php', + 'CBOR\\Normalizable' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Normalizable.php', 'CBOR\\OtherObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/OtherObject.php', 'CBOR\\OtherObject\\BreakObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/OtherObject/BreakObject.php', 'CBOR\\OtherObject\\DoublePrecisionFloatObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/OtherObject/DoublePrecisionFloatObject.php', @@ -1634,6 +1647,7 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'CBOR\\OtherObject\\HalfPrecisionFloatObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/OtherObject/HalfPrecisionFloatObject.php', 'CBOR\\OtherObject\\NullObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/OtherObject/NullObject.php', 'CBOR\\OtherObject\\OtherObjectManager' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/OtherObject/OtherObjectManager.php', + 'CBOR\\OtherObject\\OtherObjectManagerInterface' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/OtherObject/OtherObjectManagerInterface.php', 'CBOR\\OtherObject\\SimpleObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/OtherObject/SimpleObject.php', 'CBOR\\OtherObject\\SinglePrecisionFloatObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/OtherObject/SinglePrecisionFloatObject.php', 'CBOR\\OtherObject\\TrueObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/OtherObject/TrueObject.php', @@ -1641,22 +1655,34 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'CBOR\\SignedIntegerObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/SignedIntegerObject.php', 'CBOR\\Stream' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Stream.php', 'CBOR\\StringStream' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/StringStream.php', + 'CBOR\\Tag' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Tag.php', 'CBOR\\TagObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/TagObject.php', 'CBOR\\Tag\\Base16EncodingTag' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Tag/Base16EncodingTag.php', 'CBOR\\Tag\\Base64EncodingTag' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Tag/Base64EncodingTag.php', + 'CBOR\\Tag\\Base64Tag' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Tag/Base64Tag.php', 'CBOR\\Tag\\Base64UrlEncodingTag' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Tag/Base64UrlEncodingTag.php', + 'CBOR\\Tag\\Base64UrlTag' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Tag/Base64UrlTag.php', 'CBOR\\Tag\\BigFloatTag' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Tag/BigFloatTag.php', + 'CBOR\\Tag\\CBOREncodingTag' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Tag/CBOREncodingTag.php', + 'CBOR\\Tag\\CBORTag' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Tag/CBORTag.php', + 'CBOR\\Tag\\DatetimeTag' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Tag/DatetimeTag.php', 'CBOR\\Tag\\DecimalFractionTag' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Tag/DecimalFractionTag.php', 'CBOR\\Tag\\EpochTag' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Tag/EpochTag.php', 'CBOR\\Tag\\GenericTag' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Tag/GenericTag.php', + 'CBOR\\Tag\\MimeTag' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Tag/MimeTag.php', 'CBOR\\Tag\\NegativeBigIntegerTag' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Tag/NegativeBigIntegerTag.php', 'CBOR\\Tag\\PositiveBigIntegerTag' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Tag/PositiveBigIntegerTag.php', + 'CBOR\\Tag\\TagManager' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Tag/TagManager.php', + 'CBOR\\Tag\\TagManagerInterface' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Tag/TagManagerInterface.php', 'CBOR\\Tag\\TagObjectManager' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Tag/TagObjectManager.php', 'CBOR\\Tag\\TimestampTag' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Tag/TimestampTag.php', + 'CBOR\\Tag\\UnsignedBigIntegerTag' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Tag/UnsignedBigIntegerTag.php', + 'CBOR\\Tag\\UriTag' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Tag/UriTag.php', 'CBOR\\TextStringObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/TextStringObject.php', 'CBOR\\TextStringWithChunkObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/TextStringWithChunkObject.php', 'CBOR\\UnsignedIntegerObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/UnsignedIntegerObject.php', 'CBOR\\Utils' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Utils.php', + 'CURLStringFile' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php', 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 'Console_Getopt' => __DIR__ . '/..' . '/pear/console_getopt/Console/Getopt.php', 'Cose\\Algorithm\\Algorithm' => __DIR__ . '/..' . '/web-auth/cose-lib/src/Algorithm/Algorithm.php', @@ -1689,6 +1715,8 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'Cose\\Algorithm\\Signature\\RSA\\RSA' => __DIR__ . '/..' . '/web-auth/cose-lib/src/Algorithm/Signature/RSA/RSA.php', 'Cose\\Algorithm\\Signature\\Signature' => __DIR__ . '/..' . '/web-auth/cose-lib/src/Algorithm/Signature/Signature.php', 'Cose\\Algorithms' => __DIR__ . '/..' . '/web-auth/cose-lib/src/Algorithms.php', + 'Cose\\BigInteger' => __DIR__ . '/..' . '/web-auth/cose-lib/src/BigInteger.php', + 'Cose\\Hash' => __DIR__ . '/..' . '/web-auth/cose-lib/src/Hash.php', 'Cose\\Key\\Ec2Key' => __DIR__ . '/..' . '/web-auth/cose-lib/src/Key/Ec2Key.php', 'Cose\\Key\\Key' => __DIR__ . '/..' . '/web-auth/cose-lib/src/Key/Key.php', 'Cose\\Key\\OkpKey' => __DIR__ . '/..' . '/web-auth/cose-lib/src/Key/OkpKey.php', @@ -2437,10 +2465,13 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'League\\Uri\\Contracts\\UserInfoInterface' => __DIR__ . '/..' . '/league/uri-interfaces/src/Contracts/UserInfoInterface.php', 'League\\Uri\\Exceptions\\FileinfoSupportMissing' => __DIR__ . '/..' . '/league/uri-interfaces/src/Exceptions/FileinfoSupportMissing.php', 'League\\Uri\\Exceptions\\IdnSupportMissing' => __DIR__ . '/..' . '/league/uri-interfaces/src/Exceptions/IdnSupportMissing.php', + 'League\\Uri\\Exceptions\\IdnaConversionFailed' => __DIR__ . '/..' . '/league/uri-interfaces/src/Exceptions/IdnaConversionFailed.php', 'League\\Uri\\Exceptions\\SyntaxError' => __DIR__ . '/..' . '/league/uri-interfaces/src/Exceptions/SyntaxError.php', 'League\\Uri\\Exceptions\\TemplateCanNotBeExpanded' => __DIR__ . '/..' . '/league/uri/src/Exceptions/TemplateCanNotBeExpanded.php', 'League\\Uri\\Http' => __DIR__ . '/..' . '/league/uri/src/Http.php', 'League\\Uri\\HttpFactory' => __DIR__ . '/..' . '/league/uri/src/HttpFactory.php', + 'League\\Uri\\Idna\\Idna' => __DIR__ . '/..' . '/league/uri-interfaces/src/Idna/Idna.php', + 'League\\Uri\\Idna\\IdnaInfo' => __DIR__ . '/..' . '/league/uri-interfaces/src/Idna/IdnaInfo.php', 'League\\Uri\\Uri' => __DIR__ . '/..' . '/league/uri/src/Uri.php', 'League\\Uri\\UriInfo' => __DIR__ . '/..' . '/league/uri/src/UriInfo.php', 'League\\Uri\\UriResolver' => __DIR__ . '/..' . '/league/uri/src/UriResolver.php', @@ -2829,6 +2860,7 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'Ramsey\\Uuid\\Converter\\Time\\DegradedTimeConverter' => __DIR__ . '/..' . '/ramsey/uuid/src/Converter/Time/DegradedTimeConverter.php', 'Ramsey\\Uuid\\Converter\\Time\\GenericTimeConverter' => __DIR__ . '/..' . '/ramsey/uuid/src/Converter/Time/GenericTimeConverter.php', 'Ramsey\\Uuid\\Converter\\Time\\PhpTimeConverter' => __DIR__ . '/..' . '/ramsey/uuid/src/Converter/Time/PhpTimeConverter.php', + 'Ramsey\\Uuid\\Converter\\Time\\UnixTimeConverter' => __DIR__ . '/..' . '/ramsey/uuid/src/Converter/Time/UnixTimeConverter.php', 'Ramsey\\Uuid\\DegradedUuid' => __DIR__ . '/..' . '/ramsey/uuid/src/DegradedUuid.php', 'Ramsey\\Uuid\\DeprecatedUuidInterface' => __DIR__ . '/..' . '/ramsey/uuid/src/DeprecatedUuidInterface.php', 'Ramsey\\Uuid\\DeprecatedUuidMethodsTrait' => __DIR__ . '/..' . '/ramsey/uuid/src/DeprecatedUuidMethodsTrait.php', @@ -2844,6 +2876,7 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'Ramsey\\Uuid\\Exception\\TimeSourceException' => __DIR__ . '/..' . '/ramsey/uuid/src/Exception/TimeSourceException.php', 'Ramsey\\Uuid\\Exception\\UnableToBuildUuidException' => __DIR__ . '/..' . '/ramsey/uuid/src/Exception/UnableToBuildUuidException.php', 'Ramsey\\Uuid\\Exception\\UnsupportedOperationException' => __DIR__ . '/..' . '/ramsey/uuid/src/Exception/UnsupportedOperationException.php', + 'Ramsey\\Uuid\\Exception\\UuidExceptionInterface' => __DIR__ . '/..' . '/ramsey/uuid/src/Exception/UuidExceptionInterface.php', 'Ramsey\\Uuid\\FeatureSet' => __DIR__ . '/..' . '/ramsey/uuid/src/FeatureSet.php', 'Ramsey\\Uuid\\Fields\\FieldsInterface' => __DIR__ . '/..' . '/ramsey/uuid/src/Fields/FieldsInterface.php', 'Ramsey\\Uuid\\Fields\\SerializableFieldsTrait' => __DIR__ . '/..' . '/ramsey/uuid/src/Fields/SerializableFieldsTrait.php', @@ -2863,6 +2896,7 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'Ramsey\\Uuid\\Generator\\RandomLibAdapter' => __DIR__ . '/..' . '/ramsey/uuid/src/Generator/RandomLibAdapter.php', 'Ramsey\\Uuid\\Generator\\TimeGeneratorFactory' => __DIR__ . '/..' . '/ramsey/uuid/src/Generator/TimeGeneratorFactory.php', 'Ramsey\\Uuid\\Generator\\TimeGeneratorInterface' => __DIR__ . '/..' . '/ramsey/uuid/src/Generator/TimeGeneratorInterface.php', + 'Ramsey\\Uuid\\Generator\\UnixTimeGenerator' => __DIR__ . '/..' . '/ramsey/uuid/src/Generator/UnixTimeGenerator.php', 'Ramsey\\Uuid\\Guid\\Fields' => __DIR__ . '/..' . '/ramsey/uuid/src/Guid/Fields.php', 'Ramsey\\Uuid\\Guid\\Guid' => __DIR__ . '/..' . '/ramsey/uuid/src/Guid/Guid.php', 'Ramsey\\Uuid\\Guid\\GuidBuilder' => __DIR__ . '/..' . '/ramsey/uuid/src/Guid/GuidBuilder.php', @@ -2887,8 +2921,11 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'Ramsey\\Uuid\\Provider\\Time\\SystemTimeProvider' => __DIR__ . '/..' . '/ramsey/uuid/src/Provider/Time/SystemTimeProvider.php', 'Ramsey\\Uuid\\Rfc4122\\Fields' => __DIR__ . '/..' . '/ramsey/uuid/src/Rfc4122/Fields.php', 'Ramsey\\Uuid\\Rfc4122\\FieldsInterface' => __DIR__ . '/..' . '/ramsey/uuid/src/Rfc4122/FieldsInterface.php', + 'Ramsey\\Uuid\\Rfc4122\\MaxTrait' => __DIR__ . '/..' . '/ramsey/uuid/src/Rfc4122/MaxTrait.php', + 'Ramsey\\Uuid\\Rfc4122\\MaxUuid' => __DIR__ . '/..' . '/ramsey/uuid/src/Rfc4122/MaxUuid.php', 'Ramsey\\Uuid\\Rfc4122\\NilTrait' => __DIR__ . '/..' . '/ramsey/uuid/src/Rfc4122/NilTrait.php', 'Ramsey\\Uuid\\Rfc4122\\NilUuid' => __DIR__ . '/..' . '/ramsey/uuid/src/Rfc4122/NilUuid.php', + 'Ramsey\\Uuid\\Rfc4122\\TimeTrait' => __DIR__ . '/..' . '/ramsey/uuid/src/Rfc4122/TimeTrait.php', 'Ramsey\\Uuid\\Rfc4122\\UuidBuilder' => __DIR__ . '/..' . '/ramsey/uuid/src/Rfc4122/UuidBuilder.php', 'Ramsey\\Uuid\\Rfc4122\\UuidInterface' => __DIR__ . '/..' . '/ramsey/uuid/src/Rfc4122/UuidInterface.php', 'Ramsey\\Uuid\\Rfc4122\\UuidV1' => __DIR__ . '/..' . '/ramsey/uuid/src/Rfc4122/UuidV1.php', @@ -2896,6 +2933,9 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'Ramsey\\Uuid\\Rfc4122\\UuidV3' => __DIR__ . '/..' . '/ramsey/uuid/src/Rfc4122/UuidV3.php', 'Ramsey\\Uuid\\Rfc4122\\UuidV4' => __DIR__ . '/..' . '/ramsey/uuid/src/Rfc4122/UuidV4.php', 'Ramsey\\Uuid\\Rfc4122\\UuidV5' => __DIR__ . '/..' . '/ramsey/uuid/src/Rfc4122/UuidV5.php', + 'Ramsey\\Uuid\\Rfc4122\\UuidV6' => __DIR__ . '/..' . '/ramsey/uuid/src/Rfc4122/UuidV6.php', + 'Ramsey\\Uuid\\Rfc4122\\UuidV7' => __DIR__ . '/..' . '/ramsey/uuid/src/Rfc4122/UuidV7.php', + 'Ramsey\\Uuid\\Rfc4122\\UuidV8' => __DIR__ . '/..' . '/ramsey/uuid/src/Rfc4122/UuidV8.php', 'Ramsey\\Uuid\\Rfc4122\\Validator' => __DIR__ . '/..' . '/ramsey/uuid/src/Rfc4122/Validator.php', 'Ramsey\\Uuid\\Rfc4122\\VariantTrait' => __DIR__ . '/..' . '/ramsey/uuid/src/Rfc4122/VariantTrait.php', 'Ramsey\\Uuid\\Rfc4122\\VersionTrait' => __DIR__ . '/..' . '/ramsey/uuid/src/Rfc4122/VersionTrait.php', @@ -2911,6 +2951,7 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'Ramsey\\Uuid\\UuidInterface' => __DIR__ . '/..' . '/ramsey/uuid/src/UuidInterface.php', 'Ramsey\\Uuid\\Validator\\GenericValidator' => __DIR__ . '/..' . '/ramsey/uuid/src/Validator/GenericValidator.php', 'Ramsey\\Uuid\\Validator\\ValidatorInterface' => __DIR__ . '/..' . '/ramsey/uuid/src/Validator/ValidatorInterface.php', + 'ReturnTypeWillChange' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php', 'Sabre\\CalDAV\\Backend\\AbstractBackend' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Backend/AbstractBackend.php', 'Sabre\\CalDAV\\Backend\\BackendInterface' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Backend/BackendInterface.php', 'Sabre\\CalDAV\\Backend\\NotificationSupport' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Backend/NotificationSupport.php', @@ -4011,6 +4052,7 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'Symfony\\Polyfill\\Php73\\Php73' => __DIR__ . '/..' . '/symfony/polyfill-php73/Php73.php', 'Symfony\\Polyfill\\Php80\\Php80' => __DIR__ . '/..' . '/symfony/polyfill-php80/Php80.php', 'Symfony\\Polyfill\\Php80\\PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/PhpToken.php', + 'Symfony\\Polyfill\\Php81\\Php81' => __DIR__ . '/..' . '/symfony/polyfill-php81/Php81.php', 'System' => __DIR__ . '/..' . '/pear/pear-core-minimal/src/System.php', 'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php', 'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php', @@ -4097,6 +4139,7 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'Webauthn\\TrustPath\\EmptyTrustPath' => __DIR__ . '/..' . '/web-auth/webauthn-lib/src/TrustPath/EmptyTrustPath.php', 'Webauthn\\TrustPath\\TrustPath' => __DIR__ . '/..' . '/web-auth/webauthn-lib/src/TrustPath/TrustPath.php', 'Webauthn\\TrustPath\\TrustPathLoader' => __DIR__ . '/..' . '/web-auth/webauthn-lib/src/TrustPath/TrustPathLoader.php', + 'Webauthn\\U2FPublicKey' => __DIR__ . '/..' . '/web-auth/webauthn-lib/src/U2FPublicKey.php', 'Webauthn\\Util\\CoseSignatureFixer' => __DIR__ . '/..' . '/web-auth/webauthn-lib/src/Util/CoseSignatureFixer.php', 'ZipStreamer\\COMPR' => __DIR__ . '/..' . '/deepdiver/zipstreamer/src/COMPR.php', 'ZipStreamer\\Count64' => __DIR__ . '/..' . '/deepdiver/zipstreamer/src/Count64.php', diff --git a/composer/installed.json b/composer/installed.json index d3e8fde4b..900e5879c 100644 --- a/composer/installed.json +++ b/composer/installed.json @@ -181,21 +181,25 @@ "MIT" ], "description": "Convenience wrapper around ini_get()", + "support": { + "issues": "https://github.com/bantuXorg/php-ini-get-wrapper/issues", + "source": "https://github.com/bantuXorg/php-ini-get-wrapper/tree/v1.0.1" + }, "install-path": "../bantu/ini-get-wrapper" }, { "name": "beberlei/assert", - "version": "v3.3.1", - "version_normalized": "3.3.1.0", + "version": "v3.3.2", + "version_normalized": "3.3.2.0", "source": { "type": "git", "url": "https://github.com/beberlei/assert.git", - "reference": "5e721d7e937ca3ba2cdec1e1adf195f9e5188372" + "reference": "cb70015c04be1baee6f5f5c953703347c0ac1655" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/beberlei/assert/zipball/5e721d7e937ca3ba2cdec1e1adf195f9e5188372", - "reference": "5e721d7e937ca3ba2cdec1e1adf195f9e5188372", + "url": "https://api.github.com/repos/beberlei/assert/zipball/cb70015c04be1baee6f5f5c953703347c0ac1655", + "reference": "cb70015c04be1baee6f5f5c953703347c0ac1655", "shasum": "" }, "require": { @@ -214,16 +218,16 @@ "suggest": { "ext-intl": "Needed to allow Assertion::count(), Assertion::isCountable(), Assertion::minCount(), and Assertion::maxCount() to operate on ResourceBundles" }, - "time": "2021-04-18T20:11:03+00:00", + "time": "2021-12-16T21:41:27+00:00", "type": "library", "installation-source": "dist", "autoload": { - "psr-4": { - "Assert\\": "lib/Assert" - }, "files": [ "lib/Assert/functions.php" - ] + ], + "psr-4": { + "Assert\\": "lib/Assert" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -249,23 +253,23 @@ ], "support": { "issues": "https://github.com/beberlei/assert/issues", - "source": "https://github.com/beberlei/assert/tree/v3.3.1" + "source": "https://github.com/beberlei/assert/tree/v3.3.2" }, "install-path": "../beberlei/assert" }, { "name": "brick/math", - "version": "0.9.2", - "version_normalized": "0.9.2.0", + "version": "0.9.3", + "version_normalized": "0.9.3.0", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "dff976c2f3487d42c1db75a3b180e2b9f0e72ce0" + "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/dff976c2f3487d42c1db75a3b180e2b9f0e72ce0", - "reference": "dff976c2f3487d42c1db75a3b180e2b9f0e72ce0", + "url": "https://api.github.com/repos/brick/math/zipball/ca57d18f028f84f777b2168cd1911b0dee2343ae", + "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae", "shasum": "" }, "require": { @@ -275,9 +279,9 @@ "require-dev": { "php-coveralls/php-coveralls": "^2.2", "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0", - "vimeo/psalm": "4.3.2" + "vimeo/psalm": "4.9.2" }, - "time": "2021-01-20T22:51:39+00:00", + "time": "2021-08-15T20:50:18+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -302,9 +306,13 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.9.2" + "source": "https://github.com/brick/math/tree/0.9.3" }, "funding": [ + { + "url": "https://github.com/BenMorel", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/brick/math", "type": "tidelift" @@ -1012,25 +1020,25 @@ }, { "name": "fgrosse/phpasn1", - "version": "v2.3.0", - "version_normalized": "2.3.0.0", + "version": "v2.5.0", + "version_normalized": "2.5.0.0", "source": { "type": "git", "url": "https://github.com/fgrosse/PHPASN1.git", - "reference": "20299033c35f4300eb656e7e8e88cf52d1d6694e" + "reference": "42060ed45344789fb9f21f9f1864fc47b9e3507b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fgrosse/PHPASN1/zipball/20299033c35f4300eb656e7e8e88cf52d1d6694e", - "reference": "20299033c35f4300eb656e7e8e88cf52d1d6694e", + "url": "https://api.github.com/repos/fgrosse/PHPASN1/zipball/42060ed45344789fb9f21f9f1864fc47b9e3507b", + "reference": "42060ed45344789fb9f21f9f1864fc47b9e3507b", "shasum": "" }, "require": { - "php": ">=7.0.0" + "php": "^7.1 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "~6.3", - "satooshi/php-coveralls": "~2.0" + "php-coveralls/php-coveralls": "~2.0", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "suggest": { "ext-bcmath": "BCmath is the fallback extension for big integer calculations", @@ -1038,7 +1046,7 @@ "ext-gmp": "GMP is the preferred extension for big integer calculations", "phpseclib/bcmath_compat": "BCmath polyfill for servers where neither GMP nor BCmath is available" }, - "time": "2021-04-24T19:01:55+00:00", + "time": "2022-12-19T11:08:26+00:00", "type": "library", "extra": { "branch-alias": { @@ -1084,8 +1092,9 @@ ], "support": { "issues": "https://github.com/fgrosse/PHPASN1/issues", - "source": "https://github.com/fgrosse/PHPASN1/tree/v2.3.0" + "source": "https://github.com/fgrosse/PHPASN1/tree/v2.5.0" }, + "abandoned": true, "install-path": "../fgrosse/phpasn1" }, { @@ -1134,6 +1143,7 @@ "issues": "https://github.com/fusonic/linq/issues", "source": "https://github.com/fusonic/linq/tree/master" }, + "abandoned": true, "install-path": "../fusonic/linq" }, { @@ -1788,12 +1798,12 @@ "version_normalized": "5.2.13.0", "source": { "type": "git", - "url": "https://github.com/justinrainbow/json-schema.git", + "url": "https://github.com/jsonrainbow/json-schema.git", "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/fbbe7e5d79f618997bc3332a6f49246036c45793", + "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/fbbe7e5d79f618997bc3332a6f49246036c45793", "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793", "shasum": "" }, @@ -1850,8 +1860,8 @@ "schema" ], "support": { - "issues": "https://github.com/justinrainbow/json-schema/issues", - "source": "https://github.com/justinrainbow/json-schema/tree/v5.2.13" + "issues": "https://github.com/jsonrainbow/json-schema/issues", + "source": "https://github.com/jsonrainbow/json-schema/tree/v5.2.13" }, "install-path": "../justinrainbow/json-schema" }, @@ -1971,34 +1981,37 @@ }, { "name": "league/uri", - "version": "6.4.0", - "version_normalized": "6.4.0.0", + "version": "6.7.2", + "version_normalized": "6.7.2.0", "source": { "type": "git", "url": "https://github.com/thephpleague/uri.git", - "reference": "09da64118eaf4c5d52f9923a1e6a5be1da52fd9a" + "reference": "d3b50812dd51f3fbf176344cc2981db03d10fe06" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri/zipball/09da64118eaf4c5d52f9923a1e6a5be1da52fd9a", - "reference": "09da64118eaf4c5d52f9923a1e6a5be1da52fd9a", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/d3b50812dd51f3fbf176344cc2981db03d10fe06", + "reference": "d3b50812dd51f3fbf176344cc2981db03d10fe06", "shasum": "" }, "require": { "ext-json": "*", - "league/uri-interfaces": "^2.1", - "php": ">=7.2", + "league/uri-interfaces": "^2.3", + "php": "^7.4 || ^8.0", "psr/http-message": "^1.0" }, "conflict": { "league/uri-schemes": "^1.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^2.16", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpstan/phpstan-strict-rules": "^0.12", - "phpunit/phpunit": "^8.0 || ^9.0", + "friendsofphp/php-cs-fixer": "^v3.3.2", + "nyholm/psr7": "^1.5", + "php-http/psr7-integration-tests": "^1.1", + "phpstan/phpstan": "^1.2.0", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0.0", + "phpstan/phpstan-strict-rules": "^1.1.0", + "phpunit/phpunit": "^9.5.10", "psr/http-factory": "^1.0" }, "suggest": { @@ -2007,7 +2020,7 @@ "league/uri-components": "Needed to easily manipulate URI objects", "psr/http-factory": "Needed to use the URI factory" }, - "time": "2020-11-22T14:29:11+00:00", + "time": "2022-09-13T19:50:42+00:00", "type": "library", "extra": { "branch-alias": { @@ -2032,7 +2045,7 @@ } ], "description": "URI manipulation library", - "homepage": "http://uri.thephpleague.com", + "homepage": "https://uri.thephpleague.com", "keywords": [ "data-uri", "file-uri", @@ -2058,7 +2071,7 @@ "docs": "https://uri.thephpleague.com", "forum": "https://thephpleague.slack.com", "issues": "https://github.com/thephpleague/uri/issues", - "source": "https://github.com/thephpleague/uri/tree/6.4.0" + "source": "https://github.com/thephpleague/uri/tree/6.7.2" }, "funding": [ { @@ -2070,30 +2083,35 @@ }, { "name": "league/uri-interfaces", - "version": "2.2.0", - "version_normalized": "2.2.0.0", + "version": "2.3.0", + "version_normalized": "2.3.0.0", "source": { "type": "git", "url": "https://github.com/thephpleague/uri-interfaces.git", - "reference": "667f150e589d65d79c89ffe662e426704f84224f" + "reference": "00e7e2943f76d8cb50c7dfdc2f6dee356e15e383" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/667f150e589d65d79c89ffe662e426704f84224f", - "reference": "667f150e589d65d79c89ffe662e426704f84224f", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/00e7e2943f76d8cb50c7dfdc2f6dee356e15e383", + "reference": "00e7e2943f76d8cb50c7dfdc2f6dee356e15e383", "shasum": "" }, "require": { "ext-json": "*", - "php": "^7.1 || ^8.0" + "php": "^7.2 || ^8.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^2.0", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpstan/phpstan-strict-rules": "^0.12" + "friendsofphp/php-cs-fixer": "^2.19", + "phpstan/phpstan": "^0.12.90", + "phpstan/phpstan-phpunit": "^0.12.19", + "phpstan/phpstan-strict-rules": "^0.12.9", + "phpunit/phpunit": "^8.5.15 || ^9.5" }, - "time": "2020-10-31T13:45:51+00:00", + "suggest": { + "ext-intl": "to use the IDNA feature", + "symfony/intl": "to use the IDNA feature via Symfony Polyfill" + }, + "time": "2021-06-28T04:27:21+00:00", "type": "library", "extra": { "branch-alias": { @@ -2127,7 +2145,7 @@ ], "support": { "issues": "https://github.com/thephpleague/uri-interfaces/issues", - "source": "https://github.com/thephpleague/uri-interfaces/tree/2.2.0" + "source": "https://github.com/thephpleague/uri-interfaces/tree/2.3.0" }, "funding": [ { @@ -2490,6 +2508,10 @@ "log", "normalizer" ], + "support": { + "issues": "https://github.com/nextcloud/lognormalizer/issues", + "source": "https://github.com/nextcloud/lognormalizer/tree/v1.0.0" + }, "install-path": "../nextcloud/lognormalizer" }, { @@ -3442,24 +3464,24 @@ }, { "name": "psr/http-factory", - "version": "1.0.2", - "version_normalized": "1.0.2.0", + "version": "1.1.0", + "version_normalized": "1.1.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/http-factory.git", - "reference": "e616d01114759c4c489f93b099585439f795fe35" + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", - "reference": "e616d01114759c4c489f93b099585439f795fe35", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", "shasum": "" }, "require": { - "php": ">=7.0.0", + "php": ">=7.1", "psr/http-message": "^1.0 || ^2.0" }, - "time": "2023-04-10T20:10:41+00:00", + "time": "2024-04-15T12:06:14+00:00", "type": "library", "extra": { "branch-alias": { @@ -3482,7 +3504,7 @@ "homepage": "https://www.php-fig.org/" } ], - "description": "Common interfaces for PSR-7 HTTP message factories", + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", "keywords": [ "factory", "http", @@ -3494,7 +3516,7 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-factory/tree/1.0.2" + "source": "https://github.com/php-fig/http-factory" }, "install-path": "../psr/http-factory" }, @@ -3746,42 +3768,55 @@ }, { "name": "ramsey/collection", - "version": "1.1.3", - "version_normalized": "1.1.3.0", + "version": "1.3.0", + "version_normalized": "1.3.0.0", "source": { "type": "git", "url": "https://github.com/ramsey/collection.git", - "reference": "28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1" + "reference": "ad7475d1c9e70b190ecffc58f2d989416af339b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/collection/zipball/28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1", - "reference": "28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1", + "url": "https://api.github.com/repos/ramsey/collection/zipball/ad7475d1c9e70b190ecffc58f2d989416af339b4", + "reference": "ad7475d1c9e70b190ecffc58f2d989416af339b4", "shasum": "" }, "require": { - "php": "^7.2 || ^8" + "php": "^7.4 || ^8.0", + "symfony/polyfill-php81": "^1.23" }, "require-dev": { - "captainhook/captainhook": "^5.3", - "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", - "ergebnis/composer-normalize": "^2.6", - "fakerphp/faker": "^1.5", - "hamcrest/hamcrest-php": "^2", - "jangregor/phpstan-prophecy": "^0.8", - "mockery/mockery": "^1.3", - "phpstan/extension-installer": "^1", - "phpstan/phpstan": "^0.12.32", - "phpstan/phpstan-mockery": "^0.12.5", - "phpstan/phpstan-phpunit": "^0.12.11", - "phpunit/phpunit": "^8.5 || ^9", - "psy/psysh": "^0.10.4", - "slevomat/coding-standard": "^6.3", - "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "^4.4" - }, - "time": "2021-01-21T17:40:04+00:00", + "captainhook/plugin-composer": "^5.3", + "ergebnis/composer-normalize": "^2.28.3", + "fakerphp/faker": "^1.21", + "hamcrest/hamcrest-php": "^2.0", + "jangregor/phpstan-prophecy": "^1.0", + "mockery/mockery": "^1.5", + "php-parallel-lint/php-console-highlighter": "^1.0", + "php-parallel-lint/php-parallel-lint": "^1.3", + "phpcsstandards/phpcsutils": "^1.0.0-rc1", + "phpspec/prophecy-phpunit": "^2.0", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.9", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5", + "psalm/plugin-mockery": "^1.1", + "psalm/plugin-phpunit": "^0.18.4", + "ramsey/coding-standard": "^2.0.3", + "ramsey/conventional-commits": "^1.3", + "vimeo/psalm": "^5.4" + }, + "time": "2022-12-27T19:12:24+00:00", "type": "library", + "extra": { + "captainhook": { + "force-install": true + }, + "ramsey/conventional-commits": { + "configFile": "conventional-commits.json" + } + }, "installation-source": "dist", "autoload": { "psr-4": { @@ -3799,7 +3834,7 @@ "homepage": "https://benramsey.com" } ], - "description": "A PHP 7.2+ library for representing and manipulating collections.", + "description": "A PHP library for representing and manipulating collections.", "keywords": [ "array", "collection", @@ -3810,7 +3845,7 @@ ], "support": { "issues": "https://github.com/ramsey/collection/issues", - "source": "https://github.com/ramsey/collection/tree/1.1.3" + "source": "https://github.com/ramsey/collection/tree/1.3.0" }, "funding": [ { @@ -3826,81 +3861,78 @@ }, { "name": "ramsey/uuid", - "version": "4.1.1", - "version_normalized": "4.1.1.0", + "version": "4.7.6", + "version_normalized": "4.7.6.0", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "cd4032040a750077205918c86049aa0f43d22947" + "reference": "91039bc1faa45ba123c4328958e620d382ec7088" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/cd4032040a750077205918c86049aa0f43d22947", - "reference": "cd4032040a750077205918c86049aa0f43d22947", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/91039bc1faa45ba123c4328958e620d382ec7088", + "reference": "91039bc1faa45ba123c4328958e620d382ec7088", "shasum": "" }, "require": { - "brick/math": "^0.8 || ^0.9", + "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12", "ext-json": "*", - "php": "^7.2 || ^8", - "ramsey/collection": "^1.0", - "symfony/polyfill-ctype": "^1.8" + "php": "^8.0", + "ramsey/collection": "^1.2 || ^2.0" }, "replace": { "rhumsaa/uuid": "self.version" }, "require-dev": { - "codeception/aspect-mock": "^3", - "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7.0", + "captainhook/captainhook": "^5.10", + "captainhook/plugin-composer": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "doctrine/annotations": "^1.8", - "goaop/framework": "^2", + "ergebnis/composer-normalize": "^2.15", "mockery/mockery": "^1.3", - "moontoast/math": "^1.1", "paragonie/random-lib": "^2", + "php-mock/php-mock": "^2.2", "php-mock/php-mock-mockery": "^1.3", - "php-mock/php-mock-phpunit": "^2.5", "php-parallel-lint/php-parallel-lint": "^1.1", - "phpbench/phpbench": "^0.17.1", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-mockery": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^8.5", - "psy/psysh": "^0.10.0", - "slevomat/coding-standard": "^6.0", + "phpbench/phpbench": "^1.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^8.5 || ^9", + "ramsey/composer-repl": "^1.4", + "slevomat/coding-standard": "^8.4", "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "3.9.4" + "vimeo/psalm": "^4.9" }, "suggest": { "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", - "ext-ctype": "Enables faster processing of character classification using ctype functions.", "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." }, - "time": "2020-08-18T17:17:46+00:00", + "time": "2024-04-27T21:32:50+00:00", "type": "library", "extra": { - "branch-alias": { - "dev-master": "4.x-dev" + "captainhook": { + "force-install": true } }, "installation-source": "dist", "autoload": { - "psr-4": { - "Ramsey\\Uuid\\": "src/" - }, "files": [ "src/functions.php" - ] + ], + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", - "homepage": "https://github.com/ramsey/uuid", "keywords": [ "guid", "identifier", @@ -3908,13 +3940,16 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "rss": "https://github.com/ramsey/uuid/releases.atom", - "source": "https://github.com/ramsey/uuid" + "source": "https://github.com/ramsey/uuid/tree/4.7.6" }, "funding": [ { "url": "https://github.com/ramsey", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid", + "type": "tidelift" } ], "install-path": "../ramsey/uuid" @@ -4540,35 +4575,44 @@ }, { "name": "spomky-labs/cbor-php", - "version": "v2.0.1", - "version_normalized": "2.0.1.0", + "version": "v2.1.0", + "version_normalized": "2.1.0.0", "source": { "type": "git", "url": "https://github.com/Spomky-Labs/cbor-php.git", - "reference": "9776578000be884cd7864eeb7c37a4ac92d8c995" + "reference": "28e2712cfc0b48fae661a48ffc6896d7abe83684" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Spomky-Labs/cbor-php/zipball/9776578000be884cd7864eeb7c37a4ac92d8c995", - "reference": "9776578000be884cd7864eeb7c37a4ac92d8c995", + "url": "https://api.github.com/repos/Spomky-Labs/cbor-php/zipball/28e2712cfc0b48fae661a48ffc6896d7abe83684", + "reference": "28e2712cfc0b48fae661a48ffc6896d7abe83684", "shasum": "" }, "require": { "brick/math": "^0.8.15|^0.9.0", + "ext-mbstring": "*", "php": ">=7.3" }, "require-dev": { - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-beberlei-assert": "^0.12", - "phpstan/phpstan-deprecation-rules": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpstan/phpstan-strict-rules": "^0.12" + "ekino/phpstan-banned-code": "^1.0", + "ext-json": "*", + "infection/infection": "^0.18|^0.25", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-beberlei-assert": "^1.0", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.12", + "roave/security-advisories": "dev-latest", + "symplify/easy-coding-standard": "^10.0" }, "suggest": { "ext-bcmath": "GMP or BCMath extensions will drastically improve the library performance. BCMath extension needed to handle the Big Float and Decimal Fraction Tags", "ext-gmp": "GMP or BCMath extensions will drastically improve the library performance" }, - "time": "2020-08-31T20:08:03+00:00", + "time": "2021-12-13T12:46:26+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -4598,9 +4642,13 @@ ], "support": { "issues": "https://github.com/Spomky-Labs/cbor-php/issues", - "source": "https://github.com/Spomky-Labs/cbor-php/tree/v2.0.1" + "source": "https://github.com/Spomky-Labs/cbor-php/tree/v2.1.0" }, "funding": [ + { + "url": "https://github.com/Spomky", + "type": "github" + }, { "url": "https://www.patreon.com/FlorentMorselli", "type": "patreon" @@ -4654,6 +4702,10 @@ } ], "description": "Automatic BASH completion for Symfony Console Component based applications.", + "support": { + "issues": "https://github.com/stecman/symfony-console-completion/issues", + "source": "https://github.com/stecman/symfony-console-completion/tree/0.11.0" + }, "install-path": "../stecman/symfony-console-completion" }, { @@ -5392,21 +5444,21 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.28.0", - "version_normalized": "1.28.0.0", + "version": "v1.31.0", + "version_normalized": "1.31.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", - "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-ctype": "*" @@ -5414,12 +5466,9 @@ "suggest": { "ext-ctype": "For best performance" }, - "time": "2023-01-26T09:26:14+00:00", + "time": "2024-09-09T11:45:10+00:00", "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -5457,7 +5506,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" }, "funding": [ { @@ -5985,28 +6034,25 @@ }, { "name": "symfony/polyfill-php80", - "version": "v1.28.0", - "version_normalized": "1.28.0.0", + "version": "v1.31.0", + "version_normalized": "1.31.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", - "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, - "time": "2023-01-26T09:26:14+00:00", + "time": "2024-09-09T11:45:10+00:00", "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -6051,7 +6097,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" }, "funding": [ { @@ -6069,26 +6115,105 @@ ], "install-path": "../symfony/polyfill-php80" }, + { + "name": "symfony/polyfill-php81", + "version": "v1.31.0", + "version_normalized": "1.31.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "time": "2024-09-09T11:45:10+00:00", + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/polyfill-php81" + }, { "name": "symfony/process", - "version": "v5.4.34", - "version_normalized": "5.4.34.0", + "version": "v5.4.44", + "version_normalized": "5.4.44.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "8fa22178dfc368911dbd513b431cd9b06f9afe7a" + "reference": "1b9fa82b5c62cd49da8c9e3952dd8531ada65096" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/8fa22178dfc368911dbd513b431cd9b06f9afe7a", - "reference": "8fa22178dfc368911dbd513b431cd9b06f9afe7a", + "url": "https://api.github.com/repos/symfony/process/zipball/1b9fa82b5c62cd49da8c9e3952dd8531ada65096", + "reference": "1b9fa82b5c62cd49da8c9e3952dd8531ada65096", "shasum": "" }, "require": { "php": ">=7.2.5", "symfony/polyfill-php80": "^1.16" }, - "time": "2023-12-02T08:41:43+00:00", + "time": "2024-09-17T12:46:43+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -6116,7 +6241,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.4.34" + "source": "https://github.com/symfony/process/tree/v5.4.44" }, "funding": [ { @@ -6613,13 +6738,6 @@ }, "installation-source": "dist", "autoload": { - "psr-4": { - "Safe\\": [ - "lib/", - "deprecated/", - "generated/" - ] - }, "files": [ "deprecated/apc.php", "deprecated/libevent.php", @@ -6710,7 +6828,14 @@ "generated/yaz.php", "generated/zip.php", "generated/zlib.php" - ] + ], + "psr-4": { + "Safe\\": [ + "lib/", + "deprecated/", + "generated/" + ] + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -6779,17 +6904,17 @@ }, { "name": "web-auth/cose-lib", - "version": "v3.3.9", - "version_normalized": "3.3.9.0", + "version": "v3.3.12", + "version_normalized": "3.3.12.0", "source": { "type": "git", "url": "https://github.com/web-auth/cose-lib.git", - "reference": "ed172d2dc1a6b87b5c644c07c118cd30c1b3819b" + "reference": "efa6ec2ba4e840bc1316a493973c9916028afeeb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/web-auth/cose-lib/zipball/ed172d2dc1a6b87b5c644c07c118cd30c1b3819b", - "reference": "ed172d2dc1a6b87b5c644c07c118cd30c1b3819b", + "url": "https://api.github.com/repos/web-auth/cose-lib/zipball/efa6ec2ba4e840bc1316a493973c9916028afeeb", + "reference": "efa6ec2ba4e840bc1316a493973c9916028afeeb", "shasum": "" }, "require": { @@ -6800,7 +6925,7 @@ "fgrosse/phpasn1": "^2.1", "php": ">=7.2" }, - "time": "2021-05-02T19:57:09+00:00", + "time": "2021-12-04T12:13:35+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -6829,7 +6954,7 @@ "RFC8152" ], "support": { - "source": "https://github.com/web-auth/cose-lib/tree/v3.3.9" + "source": "https://github.com/web-auth/cose-lib/tree/v3.3.12" }, "funding": [ { @@ -6845,17 +6970,17 @@ }, { "name": "web-auth/metadata-service", - "version": "v3.3.9", - "version_normalized": "3.3.9.0", + "version": "v3.3.12", + "version_normalized": "3.3.12.0", "source": { "type": "git", "url": "https://github.com/web-auth/webauthn-metadata-service.git", - "reference": "8488d3a832a38cc81c670fce05de1e515c6e64b1" + "reference": "ef40d2b7b68c4964247d13fab52e2fa8dbd65246" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/web-auth/webauthn-metadata-service/zipball/8488d3a832a38cc81c670fce05de1e515c6e64b1", - "reference": "8488d3a832a38cc81c670fce05de1e515c6e64b1", + "url": "https://api.github.com/repos/web-auth/webauthn-metadata-service/zipball/ef40d2b7b68c4964247d13fab52e2fa8dbd65246", + "reference": "ef40d2b7b68c4964247d13fab52e2fa8dbd65246", "shasum": "" }, "require": { @@ -6871,7 +6996,7 @@ "web-token/jwt-key-mgmt": "Mandatory for fetching Metadata Statement from distant sources", "web-token/jwt-signature-algorithm-ecdsa": "Mandatory for fetching Metadata Statement from distant sources" }, - "time": "2021-01-09T13:31:01+00:00", + "time": "2021-11-21T11:14:31+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -6901,7 +7026,7 @@ "webauthn" ], "support": { - "source": "https://github.com/web-auth/webauthn-metadata-service/tree/v3.3.9" + "source": "https://github.com/web-auth/webauthn-metadata-service/tree/v3.3.12" }, "funding": [ { @@ -6913,21 +7038,22 @@ "type": "patreon" } ], + "abandoned": "web-auth/webauthn-lib", "install-path": "../web-auth/metadata-service" }, { "name": "web-auth/webauthn-lib", - "version": "v3.3.9", - "version_normalized": "3.3.9.0", + "version": "v3.3.12", + "version_normalized": "3.3.12.0", "source": { "type": "git", "url": "https://github.com/web-auth/webauthn-lib.git", - "reference": "04b98ee3d39cb79dad68a7c15c297c085bf66bfe" + "reference": "5ef9b21c8e9f8a817e524ac93290d08a9f065b33" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/web-auth/webauthn-lib/zipball/04b98ee3d39cb79dad68a7c15c297c085bf66bfe", - "reference": "04b98ee3d39cb79dad68a7c15c297c085bf66bfe", + "url": "https://api.github.com/repos/web-auth/webauthn-lib/zipball/5ef9b21c8e9f8a817e524ac93290d08a9f065b33", + "reference": "5ef9b21c8e9f8a817e524ac93290d08a9f065b33", "shasum": "" }, "require": { @@ -6943,7 +7069,7 @@ "psr/log": "^1.1", "ramsey/uuid": "^3.8|^4.0", "spomky-labs/base64url": "^2.0", - "spomky-labs/cbor-php": "^1.1|^2.0", + "spomky-labs/cbor-php": "^1.0|^2.0", "symfony/process": "^3.0|^4.0|^5.0", "thecodingmachine/safe": "^1.1", "web-auth/cose-lib": "self.version", @@ -6956,7 +7082,7 @@ "web-token/jwt-signature-algorithm-eddsa": "Recommended for the AndroidSafetyNet Attestation Statement support", "web-token/jwt-signature-algorithm-rsa": "Mandatory for the AndroidSafetyNet Attestation Statement support" }, - "time": "2021-04-19T20:22:20+00:00", + "time": "2022-02-18T07:13:44+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -6986,7 +7112,7 @@ "webauthn" ], "support": { - "source": "https://github.com/web-auth/webauthn-lib/tree/v3.3.9" + "source": "https://github.com/web-auth/webauthn-lib/tree/v3.3.12" }, "funding": [ { diff --git a/composer/installed.php b/composer/installed.php index 92d8f4430..b933e0018 100644 --- a/composer/installed.php +++ b/composer/installed.php @@ -3,7 +3,7 @@ 'name' => 'nextcloud/3rdparty', 'pretty_version' => 'dev-stable29', 'version' => 'dev-stable29', - 'reference' => NULL, + 'reference' => null, 'type' => 'library', 'install_path' => __DIR__ . '/../', 'aliases' => array(), @@ -38,18 +38,18 @@ 'dev_requirement' => false, ), 'beberlei/assert' => array( - 'pretty_version' => 'v3.3.1', - 'version' => '3.3.1.0', - 'reference' => '5e721d7e937ca3ba2cdec1e1adf195f9e5188372', + 'pretty_version' => 'v3.3.2', + 'version' => '3.3.2.0', + 'reference' => 'cb70015c04be1baee6f5f5c953703347c0ac1655', 'type' => 'library', 'install_path' => __DIR__ . '/../beberlei/assert', 'aliases' => array(), 'dev_requirement' => false, ), 'brick/math' => array( - 'pretty_version' => '0.9.2', - 'version' => '0.9.2.0', - 'reference' => 'dff976c2f3487d42c1db75a3b180e2b9f0e72ce0', + 'pretty_version' => '0.9.3', + 'version' => '0.9.3.0', + 'reference' => 'ca57d18f028f84f777b2168cd1911b0dee2343ae', 'type' => 'library', 'install_path' => __DIR__ . '/../brick/math', 'aliases' => array(), @@ -137,9 +137,9 @@ 'dev_requirement' => false, ), 'fgrosse/phpasn1' => array( - 'pretty_version' => 'v2.3.0', - 'version' => '2.3.0.0', - 'reference' => '20299033c35f4300eb656e7e8e88cf52d1d6694e', + 'pretty_version' => 'v2.5.0', + 'version' => '2.5.0.0', + 'reference' => '42060ed45344789fb9f21f9f1864fc47b9e3507b', 'type' => 'library', 'install_path' => __DIR__ . '/../fgrosse/phpasn1', 'aliases' => array(), @@ -254,18 +254,18 @@ 'dev_requirement' => false, ), 'league/uri' => array( - 'pretty_version' => '6.4.0', - 'version' => '6.4.0.0', - 'reference' => '09da64118eaf4c5d52f9923a1e6a5be1da52fd9a', + 'pretty_version' => '6.7.2', + 'version' => '6.7.2.0', + 'reference' => 'd3b50812dd51f3fbf176344cc2981db03d10fe06', 'type' => 'library', 'install_path' => __DIR__ . '/../league/uri', 'aliases' => array(), 'dev_requirement' => false, ), 'league/uri-interfaces' => array( - 'pretty_version' => '2.2.0', - 'version' => '2.2.0.0', - 'reference' => '667f150e589d65d79c89ffe662e426704f84224f', + 'pretty_version' => '2.3.0', + 'version' => '2.3.0.0', + 'reference' => '00e7e2943f76d8cb50c7dfdc2f6dee356e15e383', 'type' => 'library', 'install_path' => __DIR__ . '/../league/uri-interfaces', 'aliases' => array(), @@ -319,7 +319,7 @@ 'nextcloud/3rdparty' => array( 'pretty_version' => 'dev-stable29', 'version' => 'dev-stable29', - 'reference' => NULL, + 'reference' => null, 'type' => 'library', 'install_path' => __DIR__ . '/../', 'aliases' => array(), @@ -494,9 +494,9 @@ ), ), 'psr/http-factory' => array( - 'pretty_version' => '1.0.2', - 'version' => '1.0.2.0', - 'reference' => 'e616d01114759c4c489f93b099585439f795fe35', + 'pretty_version' => '1.1.0', + 'version' => '1.1.0.0', + 'reference' => '2b4765fddfe3b508ac62f829e852b1501d3f6e8a', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/http-factory', 'aliases' => array(), @@ -569,18 +569,18 @@ 'dev_requirement' => false, ), 'ramsey/collection' => array( - 'pretty_version' => '1.1.3', - 'version' => '1.1.3.0', - 'reference' => '28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1', + 'pretty_version' => '1.3.0', + 'version' => '1.3.0.0', + 'reference' => 'ad7475d1c9e70b190ecffc58f2d989416af339b4', 'type' => 'library', 'install_path' => __DIR__ . '/../ramsey/collection', 'aliases' => array(), 'dev_requirement' => false, ), 'ramsey/uuid' => array( - 'pretty_version' => '4.1.1', - 'version' => '4.1.1.0', - 'reference' => 'cd4032040a750077205918c86049aa0f43d22947', + 'pretty_version' => '4.7.6', + 'version' => '4.7.6.0', + 'reference' => '91039bc1faa45ba123c4328958e620d382ec7088', 'type' => 'library', 'install_path' => __DIR__ . '/../ramsey/uuid', 'aliases' => array(), @@ -589,7 +589,7 @@ 'rhumsaa/uuid' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => '4.1.1', + 0 => '4.7.6', ), ), 'rsky/pear-core-min' => array( @@ -671,9 +671,9 @@ 'dev_requirement' => false, ), 'spomky-labs/cbor-php' => array( - 'pretty_version' => 'v2.0.1', - 'version' => '2.0.1.0', - 'reference' => '9776578000be884cd7864eeb7c37a4ac92d8c995', + 'pretty_version' => 'v2.1.0', + 'version' => '2.1.0.0', + 'reference' => '28e2712cfc0b48fae661a48ffc6896d7abe83684', 'type' => 'library', 'install_path' => __DIR__ . '/../spomky-labs/cbor-php', 'aliases' => array(), @@ -776,9 +776,9 @@ 'dev_requirement' => false, ), 'symfony/polyfill-ctype' => array( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'reference' => 'ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb', + 'pretty_version' => 'v1.31.0', + 'version' => '1.31.0.0', + 'reference' => 'a3cc8b044a6ea513310cbd48ef7333b384945638', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-ctype', 'aliases' => array(), @@ -839,18 +839,27 @@ 'dev_requirement' => false, ), 'symfony/polyfill-php80' => array( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'reference' => '6caa57379c4aec19c0a12a38b59b26487dcfe4b5', + 'pretty_version' => 'v1.31.0', + 'version' => '1.31.0.0', + 'reference' => '60328e362d4c2c802a54fcbf04f9d3fb892b4cf8', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-php80', 'aliases' => array(), 'dev_requirement' => false, ), + 'symfony/polyfill-php81' => array( + 'pretty_version' => 'v1.31.0', + 'version' => '1.31.0.0', + 'reference' => '4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-php81', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'symfony/process' => array( - 'pretty_version' => 'v5.4.34', - 'version' => '5.4.34.0', - 'reference' => '8fa22178dfc368911dbd513b431cd9b06f9afe7a', + 'pretty_version' => 'v5.4.44', + 'version' => '5.4.44.0', + 'reference' => '1b9fa82b5c62cd49da8c9e3952dd8531ada65096', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/process', 'aliases' => array(), @@ -926,27 +935,27 @@ 'dev_requirement' => false, ), 'web-auth/cose-lib' => array( - 'pretty_version' => 'v3.3.9', - 'version' => '3.3.9.0', - 'reference' => 'ed172d2dc1a6b87b5c644c07c118cd30c1b3819b', + 'pretty_version' => 'v3.3.12', + 'version' => '3.3.12.0', + 'reference' => 'efa6ec2ba4e840bc1316a493973c9916028afeeb', 'type' => 'library', 'install_path' => __DIR__ . '/../web-auth/cose-lib', 'aliases' => array(), 'dev_requirement' => false, ), 'web-auth/metadata-service' => array( - 'pretty_version' => 'v3.3.9', - 'version' => '3.3.9.0', - 'reference' => '8488d3a832a38cc81c670fce05de1e515c6e64b1', + 'pretty_version' => 'v3.3.12', + 'version' => '3.3.12.0', + 'reference' => 'ef40d2b7b68c4964247d13fab52e2fa8dbd65246', 'type' => 'library', 'install_path' => __DIR__ . '/../web-auth/metadata-service', 'aliases' => array(), 'dev_requirement' => false, ), 'web-auth/webauthn-lib' => array( - 'pretty_version' => 'v3.3.9', - 'version' => '3.3.9.0', - 'reference' => '04b98ee3d39cb79dad68a7c15c297c085bf66bfe', + 'pretty_version' => 'v3.3.12', + 'version' => '3.3.12.0', + 'reference' => '5ef9b21c8e9f8a817e524ac93290d08a9f065b33', 'type' => 'library', 'install_path' => __DIR__ . '/../web-auth/webauthn-lib', 'aliases' => array(), diff --git a/fgrosse/phpasn1/lib/ASN1/AbstractTime.php b/fgrosse/phpasn1/lib/ASN1/AbstractTime.php index 9fad50516..8e721ae89 100644 --- a/fgrosse/phpasn1/lib/ASN1/AbstractTime.php +++ b/fgrosse/phpasn1/lib/ASN1/AbstractTime.php @@ -46,7 +46,7 @@ public function getContent() protected function getLastDateTimeErrors() { $messages = ''; - $lastErrors = DateTime::getLastErrors(); + $lastErrors = DateTime::getLastErrors() ?: ['errors' => []]; foreach ($lastErrors['errors'] as $errorMessage) { $messages .= "{$errorMessage}, "; } diff --git a/fgrosse/phpasn1/lib/ASN1/Construct.php b/fgrosse/phpasn1/lib/ASN1/Construct.php index 58f961375..cedf422e5 100644 --- a/fgrosse/phpasn1/lib/ASN1/Construct.php +++ b/fgrosse/phpasn1/lib/ASN1/Construct.php @@ -36,41 +36,49 @@ public function getContent() return $this->children; } + #[\ReturnTypeWillChange] public function rewind() { $this->iteratorPosition = 0; } + #[\ReturnTypeWillChange] public function current() { return $this->children[$this->iteratorPosition]; } + #[\ReturnTypeWillChange] public function key() { return $this->iteratorPosition; } + #[\ReturnTypeWillChange] public function next() { $this->iteratorPosition++; } + #[\ReturnTypeWillChange] public function valid() { return isset($this->children[$this->iteratorPosition]); } + #[\ReturnTypeWillChange] public function offsetExists($offset) { return array_key_exists($offset, $this->children); } + #[\ReturnTypeWillChange] public function offsetGet($offset) { return $this->children[$offset]; } + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { if ($offset === null) { @@ -80,6 +88,7 @@ public function offsetSet($offset, $value) $this->children[$offset] = $value; } + #[\ReturnTypeWillChange] public function offsetUnset($offset) { unset($this->children[$offset]); @@ -154,6 +163,7 @@ public function getFirstChild() * * @return Construct|static */ + #[\ReturnTypeWillChange] public static function fromBinary(&$binaryData, &$offsetIndex = 0) { $parsedObject = new static(); @@ -179,6 +189,7 @@ public static function fromBinary(&$binaryData, &$offsetIndex = 0) return $parsedObject; } + #[\ReturnTypeWillChange] public function count($mode = COUNT_NORMAL) { return count($this->children, $mode); @@ -188,4 +199,4 @@ public function getIterator() { return new ArrayIterator($this->children); } -} +} \ No newline at end of file diff --git a/fgrosse/phpasn1/lib/ASN1/OID.php b/fgrosse/phpasn1/lib/ASN1/OID.php index 7d331b0a7..bfaeae17e 100644 --- a/fgrosse/phpasn1/lib/ASN1/OID.php +++ b/fgrosse/phpasn1/lib/ASN1/OID.php @@ -78,6 +78,830 @@ class OID */ public static function getName($oidString, $loadFromWeb = true) { + $oids = [ + '1.2' => 'ISO Member Body', + '1.3' => 'org', + '1.3.6.1.5.5.8.1.1' => 'hmac-md5', + '1.3.6.1.5.5.8.1.2' => 'hmac-sha1', + '1.3.132' => 'certicom-arc', + '2.23' => 'International Organizations', + '2.23.43' => 'wap', + '2.23.43.1' => 'wap-wsg', + '2.5.1.5' => 'Selected Attribute Types', + '2.5.1.5.55' => 'clearance', + '1.2.840' => 'ISO US Member Body', + '1.2.840.10040' => 'X9.57', + '1.2.840.10040.4' => 'X9.57 CM ?', + '1.2.840.10040.4.1' => 'dsaEncryption', + '1.2.840.10040.4.3' => 'dsaWithSHA1', + '1.2.840.10045' => 'ANSI X9.62', + '1.2.840.10045.1' => 'X9-62_id-fieldType', + '1.2.840.10045.1.1' => 'X9-62_prime-field', + '1.2.840.10045.1.2' => 'X9-62_characteristic-two-field', + '1.2.840.10045.1.2.3' => 'X9-62_id-characteristic-two-basis', + '1.2.840.10045.1.2.3.1' => 'X9-62_onBasis', + '1.2.840.10045.1.2.3.2' => 'X9-62_tpBasis', + '1.2.840.10045.1.2.3.3' => 'X9-62_ppBasis', + '1.2.840.10045.2' => 'X9-62_id-publicKeyType', + '1.2.840.10045.2.1' => 'X9-62_id-ecPublicKey', + '1.2.840.10045.3' => 'X9-62_ellipticCurve', + '1.2.840.10045.3.0' => 'X9-62_c-TwoCurve', + '1.2.840.10045.3.0.1' => 'X9-62_c2pnb163v1', + '1.2.840.10045.3.0.2' => 'X9-62_c2pnb163v2', + '1.2.840.10045.3.0.3' => 'X9-62_c2pnb163v3', + '1.2.840.10045.3.0.4' => 'X9-62_c2pnb176v1', + '1.2.840.10045.3.0.5' => 'X9-62_c2tnb191v1', + '1.2.840.10045.3.0.6' => 'X9-62_c2tnb191v2', + '1.2.840.10045.3.0.7' => 'X9-62_c2tnb191v3', + '1.2.840.10045.3.0.8' => 'X9-62_c2onb191v4', + '1.2.840.10045.3.0.9' => 'X9-62_c2onb191v5', + '1.2.840.10045.3.0.10' => 'X9-62_c2pnb208w1', + '1.2.840.10045.3.0.11' => 'X9-62_c2tnb239v1', + '1.2.840.10045.3.0.12' => 'X9-62_c2tnb239v2', + '1.2.840.10045.3.0.13' => 'X9-62_c2tnb239v3', + '1.2.840.10045.3.0.14' => 'X9-62_c2onb239v4', + '1.2.840.10045.3.0.15' => 'X9-62_c2onb239v5', + '1.2.840.10045.3.0.16' => 'X9-62_c2pnb272w1', + '1.2.840.10045.3.0.17' => 'X9-62_c2pnb304w1', + '1.2.840.10045.3.0.18' => 'X9-62_c2tnb359v1', + '1.2.840.10045.3.0.19' => 'X9-62_c2pnb368w1', + '1.2.840.10045.3.0.20' => 'X9-62_c2tnb431r1', + '1.2.840.10045.3.1' => 'X9-62_primeCurve', + '1.2.840.10045.3.1.1' => 'X9-62_prime192v1', + '1.2.840.10045.3.1.2' => 'X9-62_prime192v2', + '1.2.840.10045.3.1.3' => 'X9-62_prime192v3', + '1.2.840.10045.3.1.4' => 'X9-62_prime239v1', + '1.2.840.10045.3.1.5' => 'X9-62_prime239v2', + '1.2.840.10045.3.1.6' => 'X9-62_prime239v3', + '1.2.840.10045.3.1.7' => 'X9-62_prime256v1', + '1.2.840.10045.4' => 'X9-62_id-ecSigType', + '1.2.840.10045.4.1' => 'ecdsa-with-SHA1', + '1.2.840.10045.4.2' => 'ecdsa-with-Recommended', + '1.2.840.10045.4.3' => 'ecdsa-with-Specified', + '1.2.840.10045.4.3.1' => 'ecdsa-with-SHA224', + '1.2.840.10045.4.3.2' => 'ecdsa-with-SHA256', + '1.2.840.10045.4.3.3' => 'ecdsa-with-SHA384', + '1.2.840.10045.4.3.4' => 'ecdsa-with-SHA512', + '1.3.132.0' => 'secg_ellipticCurve', + '2.23.43.1.4' => 'wap-wsg-idm-ecid', + '2.23.43.1.4.1' => 'wap-wsg-idm-ecid-wtls1', + '2.23.43.1.4.3' => 'wap-wsg-idm-ecid-wtls3', + '2.23.43.1.4.4' => 'wap-wsg-idm-ecid-wtls4', + '2.23.43.1.4.5' => 'wap-wsg-idm-ecid-wtls5', + '2.23.43.1.4.6' => 'wap-wsg-idm-ecid-wtls6', + '2.23.43.1.4.7' => 'wap-wsg-idm-ecid-wtls7', + '2.23.43.1.4.8' => 'wap-wsg-idm-ecid-wtls8', + '2.23.43.1.4.9' => 'wap-wsg-idm-ecid-wtls9', + '2.23.43.1.4.10' => 'wap-wsg-idm-ecid-wtls10', + '2.23.43.1.4.11' => 'wap-wsg-idm-ecid-wtls11', + '2.23.43.1.4.12' => 'wap-wsg-idm-ecid-wtls12', + '1.2.840.113533.7.66.10' => 'cast5-cbc', + '1.2.840.113533.7.66.12' => 'pbeWithMD5AndCast5CBC', + '1.2.840.113533.7.66.13' => 'password based MAC', + '1.2.840.113533.7.66.30' => 'Diffie-Hellman based MAC', + '1.2.840.113549' => 'RSA Data Security, Inc.', + '1.2.840.113549.1' => 'RSA Data Security, Inc. PKCS', + '1.2.840.113549.1.1' => 'pkcs1', + '1.2.840.113549.1.1.1' => 'rsaEncryption', + '1.2.840.113549.1.1.2' => 'md2WithRSAEncryption', + '1.2.840.113549.1.1.3' => 'md4WithRSAEncryption', + '1.2.840.113549.1.1.4' => 'md5WithRSAEncryption', + '1.2.840.113549.1.1.5' => 'sha1WithRSAEncryption', + '1.2.840.113549.1.1.7' => 'rsaesOaep', + '1.2.840.113549.1.1.8' => 'mgf1', + '1.2.840.113549.1.1.9' => 'pSpecified', + '1.2.840.113549.1.1.10' => 'rsassaPss', + '1.2.840.113549.1.1.11' => 'sha256WithRSAEncryption', + '1.2.840.113549.1.1.12' => 'sha384WithRSAEncryption', + '1.2.840.113549.1.1.13' => 'sha512WithRSAEncryption', + '1.2.840.113549.1.1.14' => 'sha224WithRSAEncryption', + '1.2.840.113549.1.3' => 'pkcs3', + '1.2.840.113549.1.3.1' => 'dhKeyAgreement', + '1.2.840.113549.1.5' => 'pkcs5', + '1.2.840.113549.1.5.1' => 'pbeWithMD2AndDES-CBC', + '1.2.840.113549.1.5.3' => 'pbeWithMD5AndDES-CBC', + '1.2.840.113549.1.5.4' => 'pbeWithMD2AndRC2-CBC', + '1.2.840.113549.1.5.6' => 'pbeWithMD5AndRC2-CBC', + '1.2.840.113549.1.5.10' => 'pbeWithSHA1AndDES-CBC', + '1.2.840.113549.1.5.11' => 'pbeWithSHA1AndRC2-CBC', + '1.2.840.113549.1.5.12' => 'PBKDF2', + '1.2.840.113549.1.5.13' => 'PBES2', + '1.2.840.113549.1.5.14' => 'PBMAC1', + '1.2.840.113549.1.7' => 'pkcs7', + '1.2.840.113549.1.7.1' => 'pkcs7-data', + '1.2.840.113549.1.7.2' => 'pkcs7-signedData', + '1.2.840.113549.1.7.3' => 'pkcs7-envelopedData', + '1.2.840.113549.1.7.4' => 'pkcs7-signedAndEnvelopedData', + '1.2.840.113549.1.7.5' => 'pkcs7-digestData', + '1.2.840.113549.1.7.6' => 'pkcs7-encryptedData', + '1.2.840.113549.1.9' => 'pkcs9', + '1.2.840.113549.1.9.1' => 'emailAddress', + '1.2.840.113549.1.9.2' => 'unstructuredName', + '1.2.840.113549.1.9.3' => 'contentType', + '1.2.840.113549.1.9.4' => 'messageDigest', + '1.2.840.113549.1.9.5' => 'signingTime', + '1.2.840.113549.1.9.6' => 'countersignature', + '1.2.840.113549.1.9.7' => 'challengePassword', + '1.2.840.113549.1.9.8' => 'unstructuredAddress', + '1.2.840.113549.1.9.9' => 'extendedCertificateAttributes', + '1.2.840.113549.1.9.14' => 'Extension Request', + '1.2.840.113549.1.9.15' => 'S/MIME Capabilities', + '1.2.840.113549.1.9.16' => 'S/MIME', + '1.2.840.113549.1.9.16.0' => 'id-smime-mod', + '1.2.840.113549.1.9.16.1' => 'id-smime-ct', + '1.2.840.113549.1.9.16.2' => 'id-smime-aa', + '1.2.840.113549.1.9.16.3' => 'id-smime-alg', + '1.2.840.113549.1.9.16.4' => 'id-smime-cd', + '1.2.840.113549.1.9.16.5' => 'id-smime-spq', + '1.2.840.113549.1.9.16.6' => 'id-smime-cti', + '1.2.840.113549.1.9.16.0.1' => 'id-smime-mod-cms', + '1.2.840.113549.1.9.16.0.2' => 'id-smime-mod-ess', + '1.2.840.113549.1.9.16.0.3' => 'id-smime-mod-oid', + '1.2.840.113549.1.9.16.0.4' => 'id-smime-mod-msg-v3', + '1.2.840.113549.1.9.16.0.5' => 'id-smime-mod-ets-eSignature-88', + '1.2.840.113549.1.9.16.0.6' => 'id-smime-mod-ets-eSignature-97', + '1.2.840.113549.1.9.16.0.7' => 'id-smime-mod-ets-eSigPolicy-88', + '1.2.840.113549.1.9.16.0.8' => 'id-smime-mod-ets-eSigPolicy-97', + '1.2.840.113549.1.9.16.1.1' => 'id-smime-ct-receipt', + '1.2.840.113549.1.9.16.1.2' => 'id-smime-ct-authData', + '1.2.840.113549.1.9.16.1.3' => 'id-smime-ct-publishCert', + '1.2.840.113549.1.9.16.1.4' => 'id-smime-ct-TSTInfo', + '1.2.840.113549.1.9.16.1.5' => 'id-smime-ct-TDTInfo', + '1.2.840.113549.1.9.16.1.6' => 'id-smime-ct-contentInfo', + '1.2.840.113549.1.9.16.1.7' => 'id-smime-ct-DVCSRequestData', + '1.2.840.113549.1.9.16.1.8' => 'id-smime-ct-DVCSResponseData', + '1.2.840.113549.1.9.16.1.9' => 'id-smime-ct-compressedData', + '1.2.840.113549.1.9.16.1.27' => 'id-ct-asciiTextWithCRLF', + '1.2.840.113549.1.9.16.2.1' => 'id-smime-aa-receiptRequest', + '1.2.840.113549.1.9.16.2.2' => 'id-smime-aa-securityLabel', + '1.2.840.113549.1.9.16.2.3' => 'id-smime-aa-mlExpandHistory', + '1.2.840.113549.1.9.16.2.4' => 'id-smime-aa-contentHint', + '1.2.840.113549.1.9.16.2.5' => 'id-smime-aa-msgSigDigest', + '1.2.840.113549.1.9.16.2.6' => 'id-smime-aa-encapContentType', + '1.2.840.113549.1.9.16.2.7' => 'id-smime-aa-contentIdentifier', + '1.2.840.113549.1.9.16.2.8' => 'id-smime-aa-macValue', + '1.2.840.113549.1.9.16.2.9' => 'id-smime-aa-equivalentLabels', + '1.2.840.113549.1.9.16.2.10' => 'id-smime-aa-contentReference', + '1.2.840.113549.1.9.16.2.11' => 'id-smime-aa-encrypKeyPref', + '1.2.840.113549.1.9.16.2.12' => 'id-smime-aa-signingCertificate', + '1.2.840.113549.1.9.16.2.13' => 'id-smime-aa-smimeEncryptCerts', + '1.2.840.113549.1.9.16.2.14' => 'id-smime-aa-timeStampToken', + '1.2.840.113549.1.9.16.2.15' => 'id-smime-aa-ets-sigPolicyId', + '1.2.840.113549.1.9.16.2.16' => 'id-smime-aa-ets-commitmentType', + '1.2.840.113549.1.9.16.2.17' => 'id-smime-aa-ets-signerLocation', + '1.2.840.113549.1.9.16.2.18' => 'id-smime-aa-ets-signerAttr', + '1.2.840.113549.1.9.16.2.19' => 'id-smime-aa-ets-otherSigCert', + '1.2.840.113549.1.9.16.2.20' => 'id-smime-aa-ets-contentTimestamp', + '1.2.840.113549.1.9.16.2.21' => 'id-smime-aa-ets-CertificateRefs', + '1.2.840.113549.1.9.16.2.22' => 'id-smime-aa-ets-RevocationRefs', + '1.2.840.113549.1.9.16.2.23' => 'id-smime-aa-ets-certValues', + '1.2.840.113549.1.9.16.2.24' => 'id-smime-aa-ets-revocationValues', + '1.2.840.113549.1.9.16.2.25' => 'id-smime-aa-ets-escTimeStamp', + '1.2.840.113549.1.9.16.2.26' => 'id-smime-aa-ets-certCRLTimestamp', + '1.2.840.113549.1.9.16.2.27' => 'id-smime-aa-ets-archiveTimeStamp', + '1.2.840.113549.1.9.16.2.28' => 'id-smime-aa-signatureType', + '1.2.840.113549.1.9.16.2.29' => 'id-smime-aa-dvcs-dvc', + '1.2.840.113549.1.9.16.3.1' => 'id-smime-alg-ESDHwith3DES', + '1.2.840.113549.1.9.16.3.2' => 'id-smime-alg-ESDHwithRC2', + '1.2.840.113549.1.9.16.3.3' => 'id-smime-alg-3DESwrap', + '1.2.840.113549.1.9.16.3.4' => 'id-smime-alg-RC2wrap', + '1.2.840.113549.1.9.16.3.5' => 'id-smime-alg-ESDH', + '1.2.840.113549.1.9.16.3.6' => 'id-smime-alg-CMS3DESwrap', + '1.2.840.113549.1.9.16.3.7' => 'id-smime-alg-CMSRC2wrap', + '1.2.840.113549.1.9.16.3.9' => 'id-alg-PWRI-KEK', + '1.2.840.113549.1.9.16.4.1' => 'id-smime-cd-ldap', + '1.2.840.113549.1.9.16.5.1' => 'id-smime-spq-ets-sqt-uri', + '1.2.840.113549.1.9.16.5.2' => 'id-smime-spq-ets-sqt-unotice', + '1.2.840.113549.1.9.16.6.1' => 'id-smime-cti-ets-proofOfOrigin', + '1.2.840.113549.1.9.16.6.2' => 'id-smime-cti-ets-proofOfReceipt', + '1.2.840.113549.1.9.16.6.3' => 'id-smime-cti-ets-proofOfDelivery', + '1.2.840.113549.1.9.16.6.4' => 'id-smime-cti-ets-proofOfSender', + '1.2.840.113549.1.9.16.6.5' => 'id-smime-cti-ets-proofOfApproval', + '1.2.840.113549.1.9.16.6.6' => 'id-smime-cti-ets-proofOfCreation', + '1.2.840.113549.1.9.20' => 'friendlyName', + '1.2.840.113549.1.9.21' => 'localKeyID', + '1.3.6.1.4.1.311.17.1' => 'Microsoft CSP Name', + '1.3.6.1.4.1.311.17.2' => 'Microsoft Local Key set', + '1.2.840.113549.1.9.22' => 'certTypes', + '1.2.840.113549.1.9.22.1' => 'x509Certificate', + '1.2.840.113549.1.9.22.2' => 'sdsiCertificate', + + '1.2.840.113549.1.9.23' => 'crlTypes', + '1.2.840.113549.1.9.23.1' => 'x509Crl', + '1.2.840.113549.1.12' => 'pkcs12', + '1.2.840.113549.1.12.1' => 'pkcs12-pbeids', + '1.2.840.113549.1.12.1.1' => 'pbeWithSHA1And128BitRC4', + '1.2.840.113549.1.12.1.2' => 'pbeWithSHA1And40BitRC4', + '1.2.840.113549.1.12.1.3' => 'pbeWithSHA1And3-KeyTripleDES-CBC', + '1.2.840.113549.1.12.1.4' => 'pbeWithSHA1And2-KeyTripleDES-CBC', + '1.2.840.113549.1.12.1.5' => 'pbeWithSHA1And128BitRC2-CBC', + '1.2.840.113549.1.12.1.6' => 'pbeWithSHA1And40BitRC2-CBC', + '1.2.840.113549.1.12.10' => 'pkcs12-Version1', + '1.2.840.113549.1.12.10.1' => 'pkcs12-BagIds', + '1.2.840.113549.1.12.10.1.1' => 'keyBag', + '1.2.840.113549.1.12.10.1.2' => 'pkcs8ShroudedKeyBag', + '1.2.840.113549.1.12.10.1.3' => 'certBag', + '1.2.840.113549.1.12.10.1.4' => 'crlBag', + '1.2.840.113549.1.12.10.1.5' => 'secretBag', + '1.2.840.113549.1.12.10.1.6' => 'safeContentsBag', + '1.2.840.113549.2.2' => 'md2', + '1.2.840.113549.2.4' => 'md4', + '1.2.840.113549.2.5' => 'md5', + '1.2.840.113549.2.6' => 'hmacWithMD5', + '1.2.840.113549.2.7' => 'hmacWithSHA1', + '1.2.840.113549.2.8' => 'hmacWithSHA224', + '1.2.840.113549.2.9' => 'hmacWithSHA256', + '1.2.840.113549.2.10' => 'hmacWithSHA384', + '1.2.840.113549.2.11' => 'hmacWithSHA512', + '1.2.840.113549.3.2' => 'rc2-cbc', + '1.2.840.113549.3.4' => 'rc4', + '1.2.840.113549.3.7' => 'des-ede3-cbc', + '1.2.840.113549.3.8' => 'rc5-cbc', + '1.3.6.1.4.1.311.2.1.14' => 'Microsoft Extension Request', + '1.3.6.1.4.1.311.2.1.21' => 'Microsoft Individual Code Signing', + '1.3.6.1.4.1.311.2.1.22' => 'Microsoft Commercial Code Signing', + '1.3.6.1.4.1.311.10.3.1' => 'Microsoft Trust List Signing', + '1.3.6.1.4.1.311.10.3.3' => 'Microsoft Server Gated Crypto', + '1.3.6.1.4.1.311.10.3.4' => 'Microsoft Encrypted File System', + '1.3.6.1.4.1.311.20.2.2' => 'Microsoft Smartcardlogin', + '1.3.6.1.4.1.311.20.2.3' => 'Microsoft Universal Principal Name', + '1.3.6.1.4.1.188.7.1.1.2' => 'idea-cbc', + '1.3.6.1.4.1.3029.1.2' => 'bf-cbc', + '1.3.6.1.5.5.7' => 'PKIX', + '1.3.6.1.5.5.7.0' => 'id-pkix-mod', + '1.3.6.1.5.5.7.1' => 'id-pe', + '1.3.6.1.5.5.7.2' => 'id-qt', + '1.3.6.1.5.5.7.3' => 'id-kp', + '1.3.6.1.5.5.7.4' => 'id-it', + '1.3.6.1.5.5.7.5' => 'id-pkip', + '1.3.6.1.5.5.7.6' => 'id-alg', + '1.3.6.1.5.5.7.7' => 'id-cmc', + '1.3.6.1.5.5.7.8' => 'id-on', + '1.3.6.1.5.5.7.9' => 'id-pda', + '1.3.6.1.5.5.7.10' => 'id-aca', + '1.3.6.1.5.5.7.11' => 'id-qcs', + '1.3.6.1.5.5.7.12' => 'id-cct', + '1.3.6.1.5.5.7.21' => 'id-ppl', + '1.3.6.1.5.5.7.48' => 'id-ad', + '1.3.6.1.5.5.7.0.1' => 'id-pkix1-explicit-88', + '1.3.6.1.5.5.7.0.2' => 'id-pkix1-implicit-88', + '1.3.6.1.5.5.7.0.3' => 'id-pkix1-explicit-93', + '1.3.6.1.5.5.7.0.4' => 'id-pkix1-implicit-93', + '1.3.6.1.5.5.7.0.5' => 'id-mod-crmf', + '1.3.6.1.5.5.7.0.6' => 'id-mod-cmc', + '1.3.6.1.5.5.7.0.7' => 'id-mod-kea-profile-88', + '1.3.6.1.5.5.7.0.8' => 'id-mod-kea-profile-93', + '1.3.6.1.5.5.7.0.9' => 'id-mod-cmp', + '1.3.6.1.5.5.7.0.10' => 'id-mod-qualified-cert-88', + '1.3.6.1.5.5.7.0.11' => 'id-mod-qualified-cert-93', + '1.3.6.1.5.5.7.0.12' => 'id-mod-attribute-cert', + '1.3.6.1.5.5.7.0.13' => 'id-mod-timestamp-protocol', + '1.3.6.1.5.5.7.0.14' => 'id-mod-ocsp', + '1.3.6.1.5.5.7.0.15' => 'id-mod-dvcs', + '1.3.6.1.5.5.7.0.16' => 'id-mod-cmp2000', + '1.3.6.1.5.5.7.1.1' => 'Authority Information Access', + '1.3.6.1.5.5.7.1.2' => 'Biometric Info', + '1.3.6.1.5.5.7.1.3' => 'qcStatements', + '1.3.6.1.5.5.7.1.4' => 'ac-auditEntity', + '1.3.6.1.5.5.7.1.5' => 'ac-targeting', + '1.3.6.1.5.5.7.1.6' => 'aaControls', + '1.3.6.1.5.5.7.1.7' => 'sbgp-ipAddrBlock', + '1.3.6.1.5.5.7.1.8' => 'sbgp-autonomousSysNum', + '1.3.6.1.5.5.7.1.9' => 'sbgp-routerIdentifier', + '1.3.6.1.5.5.7.1.10' => 'ac-proxying', + '1.3.6.1.5.5.7.1.11' => 'Subject Information Access', + '1.3.6.1.5.5.7.1.14' => 'Proxy Certificate Information', + '1.3.6.1.5.5.7.2.1' => 'Policy Qualifier CPS', + '1.3.6.1.5.5.7.2.2' => 'Policy Qualifier User Notice', + '1.3.6.1.5.5.7.2.3' => 'textNotice', + '1.3.6.1.5.5.7.3.1' => 'TLS Web Server Authentication', + '1.3.6.1.5.5.7.3.2' => 'TLS Web Client Authentication', + '1.3.6.1.5.5.7.3.3' => 'Code Signing', + '1.3.6.1.5.5.7.3.4' => 'E-mail Protection', + '1.3.6.1.5.5.7.3.5' => 'IPSec End System', + '1.3.6.1.5.5.7.3.6' => 'IPSec Tunnel', + '1.3.6.1.5.5.7.3.7' => 'IPSec User', + '1.3.6.1.5.5.7.3.8' => 'Time Stamping', + '1.3.6.1.5.5.7.3.9' => 'OCSP Signing', + '1.3.6.1.5.5.7.3.10' => 'dvcs', + '1.3.6.1.5.5.7.4.1' => 'id-it-caProtEncCert', + '1.3.6.1.5.5.7.4.2' => 'id-it-signKeyPairTypes', + '1.3.6.1.5.5.7.4.3' => 'id-it-encKeyPairTypes', + '1.3.6.1.5.5.7.4.4' => 'id-it-preferredSymmAlg', + '1.3.6.1.5.5.7.4.5' => 'id-it-caKeyUpdateInfo', + '1.3.6.1.5.5.7.4.6' => 'id-it-currentCRL', + '1.3.6.1.5.5.7.4.7' => 'id-it-unsupportedOIDs', + '1.3.6.1.5.5.7.4.8' => 'id-it-subscriptionRequest', + '1.3.6.1.5.5.7.4.9' => 'id-it-subscriptionResponse', + '1.3.6.1.5.5.7.4.10' => 'id-it-keyPairParamReq', + '1.3.6.1.5.5.7.4.11' => 'id-it-keyPairParamRep', + '1.3.6.1.5.5.7.4.12' => 'id-it-revPassphrase', + '1.3.6.1.5.5.7.4.13' => 'id-it-implicitConfirm', + '1.3.6.1.5.5.7.4.14' => 'id-it-confirmWaitTime', + '1.3.6.1.5.5.7.4.15' => 'id-it-origPKIMessage', + '1.3.6.1.5.5.7.4.16' => 'id-it-suppLangTags', + '1.3.6.1.5.5.7.5.1' => 'id-regCtrl', + '1.3.6.1.5.5.7.5.2' => 'id-regInfo', + '1.3.6.1.5.5.7.5.1.1' => 'id-regCtrl-regToken', + '1.3.6.1.5.5.7.5.1.2' => 'id-regCtrl-authenticator', + '1.3.6.1.5.5.7.5.1.3' => 'id-regCtrl-pkiPublicationInfo', + '1.3.6.1.5.5.7.5.1.4' => 'id-regCtrl-pkiArchiveOptions', + '1.3.6.1.5.5.7.5.1.5' => 'id-regCtrl-oldCertID', + '1.3.6.1.5.5.7.5.1.6' => 'id-regCtrl-protocolEncrKey', + '1.3.6.1.5.5.7.5.2.1' => 'id-regInfo-utf8Pairs', + '1.3.6.1.5.5.7.5.2.2' => 'id-regInfo-certReq', + '1.3.6.1.5.5.7.6.1' => 'id-alg-des40', + '1.3.6.1.5.5.7.6.2' => 'id-alg-noSignature', + '1.3.6.1.5.5.7.6.3' => 'id-alg-dh-sig-hmac-sha1', + '1.3.6.1.5.5.7.6.4' => 'id-alg-dh-pop', + '1.3.6.1.5.5.7.7.1' => 'id-cmc-statusInfo', + '1.3.6.1.5.5.7.7.2' => 'id-cmc-identification', + '1.3.6.1.5.5.7.7.3' => 'id-cmc-identityProof', + '1.3.6.1.5.5.7.7.4' => 'id-cmc-dataReturn', + '1.3.6.1.5.5.7.7.5' => 'id-cmc-transactionId', + '1.3.6.1.5.5.7.7.6' => 'id-cmc-senderNonce', + '1.3.6.1.5.5.7.7.7' => 'id-cmc-recipientNonce', + '1.3.6.1.5.5.7.7.8' => 'id-cmc-addExtensions', + '1.3.6.1.5.5.7.7.9' => 'id-cmc-encryptedPOP', + '1.3.6.1.5.5.7.7.10' => 'id-cmc-decryptedPOP', + '1.3.6.1.5.5.7.7.11' => 'id-cmc-lraPOPWitness', + '1.3.6.1.5.5.7.7.15' => 'id-cmc-getCert', + '1.3.6.1.5.5.7.7.16' => 'id-cmc-getCRL', + '1.3.6.1.5.5.7.7.17' => 'id-cmc-revokeRequest', + '1.3.6.1.5.5.7.7.18' => 'id-cmc-regInfo', + '1.3.6.1.5.5.7.7.19' => 'id-cmc-responseInfo', + '1.3.6.1.5.5.7.7.21' => 'id-cmc-queryPending', + '1.3.6.1.5.5.7.7.22' => 'id-cmc-popLinkRandom', + '1.3.6.1.5.5.7.7.23' => 'id-cmc-popLinkWitness', + '1.3.6.1.5.5.7.7.24' => 'id-cmc-confirmCertAcceptance', + '1.3.6.1.5.5.7.8.1' => 'id-on-personalData', + '1.3.6.1.5.5.7.8.3' => 'Permanent Identifier', + '1.3.6.1.5.5.7.9.1' => 'id-pda-dateOfBirth', + '1.3.6.1.5.5.7.9.2' => 'id-pda-placeOfBirth', + '1.3.6.1.5.5.7.9.3' => 'id-pda-gender', + '1.3.6.1.5.5.7.9.4' => 'id-pda-countryOfCitizenship', + '1.3.6.1.5.5.7.9.5' => 'id-pda-countryOfResidence', + '1.3.6.1.5.5.7.10.1' => 'id-aca-authenticationInfo', + '1.3.6.1.5.5.7.10.2' => 'id-aca-accessIdentity', + '1.3.6.1.5.5.7.10.3' => 'id-aca-chargingIdentity', + '1.3.6.1.5.5.7.10.4' => 'id-aca-group', + '1.3.6.1.5.5.7.10.5' => 'id-aca-role', + '1.3.6.1.5.5.7.10.6' => 'id-aca-encAttrs', + '1.3.6.1.5.5.7.11.1' => 'id-qcs-pkixQCSyntax-v1', + '1.3.6.1.5.5.7.12.1' => 'id-cct-crs', + '1.3.6.1.5.5.7.12.2' => 'id-cct-PKIData', + '1.3.6.1.5.5.7.12.3' => 'id-cct-PKIResponse', + '1.3.6.1.5.5.7.21.0' => 'Any language', + '1.3.6.1.5.5.7.21.1' => 'Inherit all', + '1.3.6.1.5.5.7.21.2' => 'Independent', + '1.3.6.1.5.5.7.48.1' => 'OCSP', + '1.3.6.1.5.5.7.48.2' => 'CA Issuers', + '1.3.6.1.5.5.7.48.3' => 'AD Time Stamping', + '1.3.6.1.5.5.7.48.4' => 'ad dvcs', + '1.3.6.1.5.5.7.48.5' => 'CA Repository', + '1.3.6.1.5.5.7.48.1.1' => 'Basic OCSP Response', + '1.3.6.1.5.5.7.48.1.2' => 'OCSP Nonce', + '1.3.6.1.5.5.7.48.1.3' => 'OCSP CRL ID', + '1.3.6.1.5.5.7.48.1.4' => 'Acceptable OCSP Responses', + '1.3.6.1.5.5.7.48.1.5' => 'OCSP No Check', + '1.3.6.1.5.5.7.48.1.6' => 'OCSP Archive Cutoff', + '1.3.6.1.5.5.7.48.1.7' => 'OCSP Service Locator', + '1.3.6.1.5.5.7.48.1.8' => 'Extended OCSP Status', + '1.3.6.1.5.5.7.48.1.9' => 'id-pkix-OCSP_valid', + '1.3.6.1.5.5.7.48.1.10' => 'id-pkix-OCSP_path', + '1.3.6.1.5.5.7.48.1.11' => 'Trust Root', + '1.3.14.3.2' => 'algorithm', + '1.3.14.3.2.3' => 'md5WithRSA', + '1.3.14.3.2.6' => 'des-ecb', + '1.3.14.3.2.7' => 'des-cbc', + '1.3.14.3.2.8' => 'des-ofb', + '1.3.14.3.2.9' => 'des-cfb', + '1.3.14.3.2.11' => 'rsaSignature', + '1.3.14.3.2.12' => 'dsaEncryption-old', + '1.3.14.3.2.13' => 'dsaWithSHA', + '1.3.14.3.2.15' => 'shaWithRSAEncryption', + '1.3.14.3.2.17' => 'des-ede', + '1.3.14.3.2.18' => 'sha', + '1.3.14.3.2.26' => 'sha1', + '1.3.14.3.2.27' => 'dsaWithSHA1-old', + '1.3.14.3.2.29' => 'sha1WithRSA', + '1.3.36.3.2.1' => 'ripemd160', + '1.3.36.3.3.1.2' => 'ripemd160WithRSA', + '1.3.101.1.4.1' => 'Strong Extranet ID', + '2.5' => 'directory services (X.500)', + '2.5.4' => 'X509', + '2.5.4.3' => 'commonName', + '2.5.4.4' => 'surname', + '2.5.4.5' => 'serialNumber', + '2.5.4.6' => 'countryName', + '2.5.4.7' => 'localityName', + '2.5.4.8' => 'stateOrProvinceName', + '2.5.4.9' => 'streetAddress', + '2.5.4.10' => 'organizationName', + '2.5.4.11' => 'organizationalUnitName', + '2.5.4.12' => 'title', + '2.5.4.13' => 'description', + '2.5.4.14' => 'searchGuide', + '2.5.4.15' => 'businessCategory', + '2.5.4.16' => 'postalAddress', + '2.5.4.17' => 'postalCode', + '2.5.4.18' => 'postOfficeBox', + '2.5.4.19' => 'physicalDeliveryOfficeName', + '2.5.4.20' => 'telephoneNumber', + '2.5.4.21' => 'telexNumber', + '2.5.4.22' => 'teletexTerminalIdentifier', + '2.5.4.23' => 'facsimileTelephoneNumber', + '2.5.4.24' => 'x121Address', + '2.5.4.25' => 'internationaliSDNNumber', + '2.5.4.26' => 'registeredAddress', + '2.5.4.27' => 'destinationIndicator', + '2.5.4.28' => 'preferredDeliveryMethod', + '2.5.4.29' => 'presentationAddress', + '2.5.4.30' => 'supportedApplicationContext', + '2.5.4.31' => 'member', + '2.5.4.32' => 'owner', + '2.5.4.33' => 'roleOccupant', + '2.5.4.34' => 'seeAlso', + '2.5.4.35' => 'userPassword', + '2.5.4.36' => 'userCertificate', + '2.5.4.37' => 'cACertificate', + '2.5.4.38' => 'authorityRevocationList', + '2.5.4.39' => 'certificateRevocationList', + '2.5.4.40' => 'crossCertificatePair', + '2.5.4.41' => 'name', + '2.5.4.42' => 'givenName', + '2.5.4.43' => 'initials', + '2.5.4.44' => 'generationQualifier', + '2.5.4.45' => 'x500UniqueIdentifier', + '2.5.4.46' => 'dnQualifier', + '2.5.4.47' => 'enhancedSearchGuide', + '2.5.4.48' => 'protocolInformation', + '2.5.4.49' => 'distinguishedName', + '2.5.4.50' => 'uniqueMember', + '2.5.4.51' => 'houseIdentifier', + '2.5.4.52' => 'supportedAlgorithms', + '2.5.4.53' => 'deltaRevocationList', + '2.5.4.54' => 'dmdName', + '2.5.4.65' => 'pseudonym', + '2.5.4.72' => 'role', + '2.5.8' => 'directory services - algorithms', + '2.5.8.1.1' => 'rsa', + '2.5.8.3.100' => 'mdc2WithRSA', + '2.5.8.3.101' => 'mdc2', + '2.5.29' => 'id-ce', + '2.5.29.9' => 'X509v3 Subject Directory Attributes', + '2.5.29.14' => 'X509v3 Subject Key Identifier', + '2.5.29.15' => 'X509v3 Key Usage', + '2.5.29.16' => 'X509v3 Private Key Usage Period', + '2.5.29.17' => 'X509v3 Subject Alternative Name', + '2.5.29.18' => 'X509v3 Issuer Alternative Name', + '2.5.29.19' => 'X509v3 Basic Constraints', + '2.5.29.20' => 'X509v3 CRL Number', + '2.5.29.21' => 'X509v3 CRL Reason Code', + '2.5.29.24' => 'Invalidity Date', + '2.5.29.27' => 'X509v3 Delta CRL Indicator', + '2.5.29.28' => 'X509v3 Issuing Distribution Point', + '2.5.29.29' => 'X509v3 Certificate Issuer', + '2.5.29.30' => 'X509v3 Name Constraints', + '2.5.29.31' => 'X509v3 CRL Distribution Points', + '2.5.29.32' => 'X509v3 Certificate Policies', + '2.5.29.32.0' => 'X509v3 Any Policy', + '2.5.29.33' => 'X509v3 Policy Mappings', + '2.5.29.35' => 'X509v3 Authority Key Identifier', + '2.5.29.36' => 'X509v3 Policy Constraints', + '2.5.29.37' => 'X509v3 Extended Key Usage', + '2.5.29.46' => 'X509v3 Freshest CRL', + '2.5.29.54' => 'X509v3 Inhibit Any Policy', + '2.5.29.55' => 'X509v3 AC Targeting', + '2.5.29.56' => 'X509v3 No Revocation Available', + '2.5.29.37.0' => 'Any Extended Key Usage', + '2.16.840.1.113730' => 'Netscape Communications Corp.', + '2.16.840.1.113730.1' => 'Netscape Certificate Extension', + '2.16.840.1.113730.2' => 'Netscape Data Type', + '2.16.840.1.113730.1.1' => 'Netscape Cert Type', + '2.16.840.1.113730.1.2' => 'Netscape Base Url', + '2.16.840.1.113730.1.3' => 'Netscape Revocation Url', + '2.16.840.1.113730.1.4' => 'Netscape CA Revocation Url', + '2.16.840.1.113730.1.7' => 'Netscape Renewal Url', + '2.16.840.1.113730.1.8' => 'Netscape CA Policy Url', + '2.16.840.1.113730.1.12' => 'Netscape SSL Server Name', + '2.16.840.1.113730.1.13' => 'Netscape Comment', + '2.16.840.1.113730.2.5' => 'Netscape Certificate Sequence', + '2.16.840.1.113730.4.1' => 'Netscape Server Gated Crypto', + '1.3.6' => 'dod', + '1.3.6.1' => 'iana', + '1.3.6.1.1' => 'Directory', + '1.3.6.1.2' => 'Management', + '1.3.6.1.3' => 'Experimental', + '1.3.6.1.4' => 'Private', + '1.3.6.1.5' => 'Security', + '1.3.6.1.6' => 'SNMPv2', + '1.3.6.1.7' => 'Mail', + '1.3.6.1.4.1' => 'Enterprises', + '1.3.6.1.4.1.1466.344' => 'dcObject', + '1.2.840.113549.1.9.16.3.8' => 'zlib compression', + '2.16.840.1.101.3' => 'csor', + '2.16.840.1.101.3.4' => 'nistAlgorithms', + '2.16.840.1.101.3.4.1' => 'aes', + '2.16.840.1.101.3.4.1.1' => 'aes-128-ecb', + '2.16.840.1.101.3.4.1.2' => 'aes-128-cbc', + '2.16.840.1.101.3.4.1.3' => 'aes-128-ofb', + '2.16.840.1.101.3.4.1.4' => 'aes-128-cfb', + '2.16.840.1.101.3.4.1.5' => 'id-aes128-wrap', + '2.16.840.1.101.3.4.1.6' => 'aes-128-gcm', + '2.16.840.1.101.3.4.1.7' => 'aes-128-ccm', + '2.16.840.1.101.3.4.1.8' => 'id-aes128-wrap-pad', + '2.16.840.1.101.3.4.1.21' => 'aes-192-ecb', + '2.16.840.1.101.3.4.1.22' => 'aes-192-cbc', + '2.16.840.1.101.3.4.1.23' => 'aes-192-ofb', + '2.16.840.1.101.3.4.1.24' => 'aes-192-cfb', + '2.16.840.1.101.3.4.1.25' => 'id-aes192-wrap', + '2.16.840.1.101.3.4.1.26' => 'aes-192-gcm', + '2.16.840.1.101.3.4.1.27' => 'aes-192-ccm', + '2.16.840.1.101.3.4.1.28' => 'id-aes192-wrap-pad', + '2.16.840.1.101.3.4.1.41' => 'aes-256-ecb', + '2.16.840.1.101.3.4.1.42' => 'aes-256-cbc', + '2.16.840.1.101.3.4.1.43' => 'aes-256-ofb', + '2.16.840.1.101.3.4.1.44' => 'aes-256-cfb', + '2.16.840.1.101.3.4.1.45' => 'id-aes256-wrap', + '2.16.840.1.101.3.4.1.46' => 'aes-256-gcm', + '2.16.840.1.101.3.4.1.47' => 'aes-256-ccm', + '2.16.840.1.101.3.4.1.48' => 'id-aes256-wrap-pad', + '2.16.840.1.101.3.4.2' => 'nist_hashalgs', + '2.16.840.1.101.3.4.2.1' => 'sha256', + '2.16.840.1.101.3.4.2.2' => 'sha384', + '2.16.840.1.101.3.4.2.3' => 'sha512', + '2.16.840.1.101.3.4.2.4' => 'sha224', + '2.16.840.1.101.3.4.3' => 'dsa_with_sha2', + '2.16.840.1.101.3.4.3.1' => 'dsa_with_SHA224', + '2.16.840.1.101.3.4.3.2' => 'dsa_with_SHA256', + '2.5.29.23' => 'Hold Instruction Code', + '0.9' => 'data', + '0.9.2342' => 'pss', + '0.9.2342.19200300' => 'ucl', + '0.9.2342.19200300.100' => 'pilot', + '0.9.2342.19200300.100.1' => 'pilotAttributeType', + '0.9.2342.19200300.100.3' => 'pilotAttributeSyntax', + '0.9.2342.19200300.100.4' => 'pilotObjectClass', + '0.9.2342.19200300.100.10' => 'pilotGroups', + '2.23.42' => 'Secure Electronic Transactions', + '2.23.42.0' => 'content types', + '2.23.42.1' => 'message extensions', + '2.23.42.3' => 'set-attr', + '2.23.42.5' => 'set-policy', + '2.23.42.7' => 'certificate extensions', + '2.23.42.8' => 'set-brand', + '2.23.42.0.0' => 'setct-PANData', + '2.23.42.0.1' => 'setct-PANToken', + '2.23.42.0.2' => 'setct-PANOnly', + '2.23.42.0.3' => 'setct-OIData', + '2.23.42.0.4' => 'setct-PI', + '2.23.42.0.5' => 'setct-PIData', + '2.23.42.0.6' => 'setct-PIDataUnsigned', + '2.23.42.0.7' => 'setct-HODInput', + '2.23.42.0.8' => 'setct-AuthResBaggage', + '2.23.42.0.9' => 'setct-AuthRevReqBaggage', + '2.23.42.0.10' => 'setct-AuthRevResBaggage', + '2.23.42.0.11' => 'setct-CapTokenSeq', + '2.23.42.0.12' => 'setct-PInitResData', + '2.23.42.0.13' => 'setct-PI-TBS', + '2.23.42.0.14' => 'setct-PResData', + '2.23.42.0.16' => 'setct-AuthReqTBS', + '2.23.42.0.17' => 'setct-AuthResTBS', + '2.23.42.0.18' => 'setct-AuthResTBSX', + '2.23.42.0.19' => 'setct-AuthTokenTBS', + '2.23.42.0.20' => 'setct-CapTokenData', + '2.23.42.0.21' => 'setct-CapTokenTBS', + '2.23.42.0.22' => 'setct-AcqCardCodeMsg', + '2.23.42.0.23' => 'setct-AuthRevReqTBS', + '2.23.42.0.24' => 'setct-AuthRevResData', + '2.23.42.0.25' => 'setct-AuthRevResTBS', + '2.23.42.0.26' => 'setct-CapReqTBS', + '2.23.42.0.27' => 'setct-CapReqTBSX', + '2.23.42.0.28' => 'setct-CapResData', + '2.23.42.0.29' => 'setct-CapRevReqTBS', + '2.23.42.0.30' => 'setct-CapRevReqTBSX', + '2.23.42.0.31' => 'setct-CapRevResData', + '2.23.42.0.32' => 'setct-CredReqTBS', + '2.23.42.0.33' => 'setct-CredReqTBSX', + '2.23.42.0.34' => 'setct-CredResData', + '2.23.42.0.35' => 'setct-CredRevReqTBS', + '2.23.42.0.36' => 'setct-CredRevReqTBSX', + '2.23.42.0.37' => 'setct-CredRevResData', + '2.23.42.0.38' => 'setct-PCertReqData', + '2.23.42.0.39' => 'setct-PCertResTBS', + '2.23.42.0.40' => 'setct-BatchAdminReqData', + '2.23.42.0.41' => 'setct-BatchAdminResData', + '2.23.42.0.42' => 'setct-CardCInitResTBS', + '2.23.42.0.43' => 'setct-MeAqCInitResTBS', + '2.23.42.0.44' => 'setct-RegFormResTBS', + '2.23.42.0.45' => 'setct-CertReqData', + '2.23.42.0.46' => 'setct-CertReqTBS', + '2.23.42.0.47' => 'setct-CertResData', + '2.23.42.0.48' => 'setct-CertInqReqTBS', + '2.23.42.0.49' => 'setct-ErrorTBS', + '2.23.42.0.50' => 'setct-PIDualSignedTBE', + '2.23.42.0.51' => 'setct-PIUnsignedTBE', + '2.23.42.0.52' => 'setct-AuthReqTBE', + '2.23.42.0.53' => 'setct-AuthResTBE', + '2.23.42.0.54' => 'setct-AuthResTBEX', + '2.23.42.0.55' => 'setct-AuthTokenTBE', + '2.23.42.0.56' => 'setct-CapTokenTBE', + '2.23.42.0.57' => 'setct-CapTokenTBEX', + '2.23.42.0.58' => 'setct-AcqCardCodeMsgTBE', + '2.23.42.0.59' => 'setct-AuthRevReqTBE', + '2.23.42.0.60' => 'setct-AuthRevResTBE', + '2.23.42.0.61' => 'setct-AuthRevResTBEB', + '2.23.42.0.62' => 'setct-CapReqTBE', + '2.23.42.0.63' => 'setct-CapReqTBEX', + '2.23.42.0.64' => 'setct-CapResTBE', + '2.23.42.0.65' => 'setct-CapRevReqTBE', + '2.23.42.0.66' => 'setct-CapRevReqTBEX', + '2.23.42.0.67' => 'setct-CapRevResTBE', + '2.23.42.0.68' => 'setct-CredReqTBE', + '2.23.42.0.69' => 'setct-CredReqTBEX', + '2.23.42.0.70' => 'setct-CredResTBE', + '2.23.42.0.71' => 'setct-CredRevReqTBE', + '2.23.42.0.72' => 'setct-CredRevReqTBEX', + '2.23.42.0.73' => 'setct-CredRevResTBE', + '2.23.42.0.74' => 'setct-BatchAdminReqTBE', + '2.23.42.0.75' => 'setct-BatchAdminResTBE', + '2.23.42.0.76' => 'setct-RegFormReqTBE', + '2.23.42.0.77' => 'setct-CertReqTBE', + '2.23.42.0.78' => 'setct-CertReqTBEX', + '2.23.42.0.79' => 'setct-CertResTBE', + '2.23.42.0.80' => 'setct-CRLNotificationTBS', + '2.23.42.0.81' => 'setct-CRLNotificationResTBS', + '2.23.42.0.82' => 'setct-BCIDistributionTBS', + '2.23.42.1.1' => 'generic cryptogram', + '2.23.42.1.3' => 'merchant initiated auth', + '2.23.42.1.4' => 'setext-pinSecure', + '2.23.42.1.5' => 'setext-pinAny', + '2.23.42.1.7' => 'setext-track2', + '2.23.42.1.8' => 'additional verification', + '2.23.42.5.0' => 'set-policy-root', + '2.23.42.7.0' => 'setCext-hashedRoot', + '2.23.42.7.1' => 'setCext-certType', + '2.23.42.7.2' => 'setCext-merchData', + '2.23.42.7.3' => 'setCext-cCertRequired', + '2.23.42.7.4' => 'setCext-tunneling', + '2.23.42.7.5' => 'setCext-setExt', + '2.23.42.7.6' => 'setCext-setQualf', + '2.23.42.7.7' => 'setCext-PGWYcapabilities', + '2.23.42.7.8' => 'setCext-TokenIdentifier', + '2.23.42.7.9' => 'setCext-Track2Data', + '2.23.42.7.10' => 'setCext-TokenType', + '2.23.42.7.11' => 'setCext-IssuerCapabilities', + '2.23.42.3.0' => 'setAttr-Cert', + '2.23.42.3.1' => 'payment gateway capabilities', + '2.23.42.3.2' => 'setAttr-TokenType', + '2.23.42.3.3' => 'issuer capabilities', + '2.23.42.3.0.0' => 'set-rootKeyThumb', + '2.23.42.3.0.1' => 'set-addPolicy', + '2.23.42.3.2.1' => 'setAttr-Token-EMV', + '2.23.42.3.2.2' => 'setAttr-Token-B0Prime', + '2.23.42.3.3.3' => 'setAttr-IssCap-CVM', + '2.23.42.3.3.4' => 'setAttr-IssCap-T2', + '2.23.42.3.3.5' => 'setAttr-IssCap-Sig', + '2.23.42.3.3.3.1' => 'generate cryptogram', + '2.23.42.3.3.4.1' => 'encrypted track 2', + '2.23.42.3.3.4.2' => 'cleartext track 2', + '2.23.42.3.3.5.1' => 'ICC or token signature', + '2.23.42.3.3.5.2' => 'secure device signature', + '2.23.42.8.1' => 'set-brand-IATA-ATA', + '2.23.42.8.30' => 'set-brand-Diners', + '2.23.42.8.34' => 'set-brand-AmericanExpress', + '2.23.42.8.35' => 'set-brand-JCB', + '2.23.42.8.4' => 'set-brand-Visa', + '2.23.42.8.5' => 'set-brand-MasterCard', + '2.23.42.8.6011' => 'set-brand-Novus', + '1.2.840.113549.3.10' => 'des-cdmf', + '1.2.840.113549.1.1.6' => 'rsaOAEPEncryptionSET', + '1.0.10118.3.0.55' => 'whirlpool', + '1.2.643.2.2' => 'cryptopro', + '1.2.643.2.9' => 'cryptocom', + '1.2.643.2.2.3' => 'GOST R 34.11-94 with GOST R 34.10-2001', + '1.2.643.2.2.4' => 'GOST R 34.11-94 with GOST R 34.10-94', + '1.2.643.2.2.9' => 'GOST R 34.11-94', + '1.2.643.2.2.10' => 'HMAC GOST 34.11-94', + '1.2.643.2.2.19' => 'GOST R 34.10-2001', + '1.2.643.2.2.20' => 'GOST R 34.10-94', + '1.2.643.2.2.21' => 'GOST 28147-89', + '1.2.643.2.2.22' => 'GOST 28147-89 MAC', + '1.2.643.2.2.23' => 'GOST R 34.11-94 PRF', + '1.2.643.2.2.98' => 'GOST R 34.10-2001 DH', + '1.2.643.2.2.99' => 'GOST R 34.10-94 DH', + '1.2.643.2.2.14.1' => 'id-Gost28147-89-CryptoPro-KeyMeshing', + '1.2.643.2.2.14.0' => 'id-Gost28147-89-None-KeyMeshing', + '1.2.643.2.2.30.0' => 'id-GostR3411-94-TestParamSet', + '1.2.643.2.2.30.1' => 'id-GostR3411-94-CryptoProParamSet', + '1.2.643.2.2.31.0' => 'id-Gost28147-89-TestParamSet', + '1.2.643.2.2.31.1' => 'id-Gost28147-89-CryptoPro-A-ParamSet', + '1.2.643.2.2.31.2' => 'id-Gost28147-89-CryptoPro-B-ParamSet', + '1.2.643.2.2.31.3' => 'id-Gost28147-89-CryptoPro-C-ParamSet', + '1.2.643.2.2.31.4' => 'id-Gost28147-89-CryptoPro-D-ParamSet', + '1.2.643.2.2.31.5' => 'id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet', + '1.2.643.2.2.31.6' => 'id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet', + '1.2.643.2.2.31.7' => 'id-Gost28147-89-CryptoPro-RIC-1-ParamSet', + '1.2.643.2.2.32.0' => 'id-GostR3410-94-TestParamSet', + '1.2.643.2.2.32.2' => 'id-GostR3410-94-CryptoPro-A-ParamSet', + '1.2.643.2.2.32.3' => 'id-GostR3410-94-CryptoPro-B-ParamSet', + '1.2.643.2.2.32.4' => 'id-GostR3410-94-CryptoPro-C-ParamSet', + '1.2.643.2.2.32.5' => 'id-GostR3410-94-CryptoPro-D-ParamSet', + '1.2.643.2.2.33.1' => 'id-GostR3410-94-CryptoPro-XchA-ParamSet', + '1.2.643.2.2.33.2' => 'id-GostR3410-94-CryptoPro-XchB-ParamSet', + '1.2.643.2.2.33.3' => 'id-GostR3410-94-CryptoPro-XchC-ParamSet', + '1.2.643.2.2.35.0' => 'id-GostR3410-2001-TestParamSet', + '1.2.643.2.2.35.1' => 'id-GostR3410-2001-CryptoPro-A-ParamSet', + '1.2.643.2.2.35.2' => 'id-GostR3410-2001-CryptoPro-B-ParamSet', + '1.2.643.2.2.35.3' => 'id-GostR3410-2001-CryptoPro-C-ParamSet', + '1.2.643.2.2.36.0' => 'id-GostR3410-2001-CryptoPro-XchA-ParamSet', + '1.2.643.2.2.36.1' => 'id-GostR3410-2001-CryptoPro-XchB-ParamSet', + '1.2.643.2.2.20.1' => 'id-GostR3410-94-a', + '1.2.643.2.2.20.2' => 'id-GostR3410-94-aBis', + '1.2.643.2.2.20.3' => 'id-GostR3410-94-b', + '1.2.643.2.2.20.4' => 'id-GostR3410-94-bBis', + '1.2.643.2.9.1.6.1' => 'GOST 28147-89 Cryptocom ParamSet', + '1.2.643.2.9.1.5.3' => 'GOST 34.10-94 Cryptocom', + '1.2.643.2.9.1.5.4' => 'GOST 34.10-2001 Cryptocom', + '1.2.643.2.9.1.3.3' => 'GOST R 34.11-94 with GOST R 34.10-94 Cryptocom', + '1.2.643.2.9.1.3.4' => 'GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom', + '1.2.643.2.9.1.8.1' => 'GOST R 3410-2001 Parameter Set Cryptocom', + '1.2.392.200011.61.1.1.1.2' => 'camellia-128-cbc', + '1.2.392.200011.61.1.1.1.3' => 'camellia-192-cbc', + '1.2.392.200011.61.1.1.1.4' => 'camellia-256-cbc', + '1.2.392.200011.61.1.1.3.2' => 'id-camellia128-wrap', + '1.2.392.200011.61.1.1.3.3' => 'id-camellia192-wrap', + '1.2.392.200011.61.1.1.3.4' => 'id-camellia256-wrap', + '0.3.4401.5' => 'ntt-ds', + '0.3.4401.5.3.1.9' => 'camellia', + '0.3.4401.5.3.1.9.1' => 'camellia-128-ecb', + '0.3.4401.5.3.1.9.3' => 'camellia-128-ofb', + '0.3.4401.5.3.1.9.4' => 'camellia-128-cfb', + '0.3.4401.5.3.1.9.6' => 'camellia-128-gcm', + '0.3.4401.5.3.1.9.7' => 'camellia-128-ccm', + '0.3.4401.5.3.1.9.9' => 'camellia-128-ctr', + '0.3.4401.5.3.1.9.10' => 'camellia-128-cmac', + '0.3.4401.5.3.1.9.21' => 'camellia-192-ecb', + '0.3.4401.5.3.1.9.23' => 'camellia-192-ofb', + '0.3.4401.5.3.1.9.24' => 'camellia-192-cfb', + '0.3.4401.5.3.1.9.26' => 'camellia-192-gcm', + '0.3.4401.5.3.1.9.27' => 'camellia-192-ccm', + '0.3.4401.5.3.1.9.29' => 'camellia-192-ctr', + '0.3.4401.5.3.1.9.30' => 'camellia-192-cmac', + '0.3.4401.5.3.1.9.41' => 'camellia-256-ecb', + '0.3.4401.5.3.1.9.43' => 'camellia-256-ofb', + '0.3.4401.5.3.1.9.44' => 'camellia-256-cfb', + '0.3.4401.5.3.1.9.46' => 'camellia-256-gcm', + '0.3.4401.5.3.1.9.47' => 'camellia-256-ccm', + '0.3.4401.5.3.1.9.49' => 'camellia-256-ctr', + '0.3.4401.5.3.1.9.50' => 'camellia-256-cmac', + '1.2.410.200004' => 'kisa', + '1.2.410.200004.1.3' => 'seed-ecb', + '1.2.410.200004.1.4' => 'seed-cbc', + '1.2.410.200004.1.5' => 'seed-cfb', + '1.2.410.200004.1.6' => 'seed-ofb', + '1.2.840.10046.2.1' => 'X9.42 DH', + '1.3.36.3.3.2.8.1.1.1' => 'brainpoolP160r1', + '1.3.36.3.3.2.8.1.1.2' => 'brainpoolP160t1', + '1.3.36.3.3.2.8.1.1.3' => 'brainpoolP192r1', + '1.3.36.3.3.2.8.1.1.4' => 'brainpoolP192t1', + '1.3.36.3.3.2.8.1.1.5' => 'brainpoolP224r1', + '1.3.36.3.3.2.8.1.1.6' => 'brainpoolP224t1', + '1.3.36.3.3.2.8.1.1.7' => 'brainpoolP256r1', + '1.3.36.3.3.2.8.1.1.8' => 'brainpoolP256t1', + '1.3.36.3.3.2.8.1.1.9' => 'brainpoolP320r1', + '1.3.36.3.3.2.8.1.1.10' => 'brainpoolP320t1', + '1.3.36.3.3.2.8.1.1.11' => 'brainpoolP384r1', + '1.3.36.3.3.2.8.1.1.12' => 'brainpoolP384t1', + '1.3.36.3.3.2.8.1.1.13' => 'brainpoolP512r1', + '1.3.36.3.3.2.8.1.1.14' => 'brainpoolP512t1', + '1.3.133.16.840.63.0' => 'x9-63-scheme', + '1.3.132.1' => 'secg-scheme', + '1.3.133.16.840.63.0.2' => 'dhSinglePass-stdDH-sha1kdf-scheme', + '1.3.132.1.11.0' => 'dhSinglePass-stdDH-sha224kdf-scheme', + '1.3.132.1.11.1' => 'dhSinglePass-stdDH-sha256kdf-scheme', + '1.3.132.1.11.2' => 'dhSinglePass-stdDH-sha384kdf-scheme', + '1.3.132.1.11.3' => 'dhSinglePass-stdDH-sha512kdf-scheme', + '1.3.133.16.840.63.0.3' => 'dhSinglePass-cofactorDH-sha1kdf-scheme', + '1.3.132.1.14.0' => 'dhSinglePass-cofactorDH-sha224kdf-scheme', + '1.3.132.1.14.1' => 'dhSinglePass-cofactorDH-sha256kdf-scheme', + '1.3.132.1.14.2' => 'dhSinglePass-cofactorDH-sha384kdf-scheme', + '1.3.132.1.14.3' => 'dhSinglePass-cofactorDH-sha512kdf-scheme', + '1.3.6.1.4.1.11129.2.4.2' => 'CT Precertificate SCTs', + '1.3.6.1.4.1.11129.2.4.3' => 'CT Precertificate Poison', + '1.3.6.1.4.1.11129.2.4.4' => 'CT Precertificate Signer', + '1.3.6.1.4.1.11129.2.4.5' => 'CT Certificate SCTs', + '1.3.6.1.4.1.311.60.2.1.1' => 'jurisdictionLocalityName', + '1.3.6.1.4.1.311.60.2.1.2' => 'jurisdictionStateOrProvinceName', + '1.3.6.1.4.1.311.60.2.1.3' => 'jurisdictionCountryName', + '1.3.6.1.4.1.11591.4.11' => 'id-scrypt', + ]; + + if (array_key_exists($oidString, $oids)) { + return $oids[$oidString]; + } + switch ($oidString) { case self::RSA_ENCRYPTION: return 'RSA Encryption'; diff --git a/league/uri-interfaces/src/Exceptions/IdnaConversionFailed.php b/league/uri-interfaces/src/Exceptions/IdnaConversionFailed.php new file mode 100644 index 000000000..80259f3ba --- /dev/null +++ b/league/uri-interfaces/src/Exceptions/IdnaConversionFailed.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Exceptions; + +use League\Uri\Idna\IdnaInfo; + +final class IdnaConversionFailed extends SyntaxError +{ + /** @var IdnaInfo|null */ + private $idnaInfo; + + private function __construct(string $message, IdnaInfo $idnaInfo = null) + { + parent::__construct($message); + $this->idnaInfo = $idnaInfo; + } + + public static function dueToIDNAError(string $domain, IdnaInfo $idnaInfo): self + { + return new self( + 'The host `'.$domain.'` is invalid : '.implode(', ', $idnaInfo->errorList()).' .', + $idnaInfo + ); + } + + public static function dueToInvalidHost(string $domain): self + { + return new self('The host `'.$domain.'` is not a valid IDN host'); + } + + public function idnaInfo(): ?IdnaInfo + { + return $this->idnaInfo; + } +} diff --git a/league/uri-interfaces/src/Idna/Idna.php b/league/uri-interfaces/src/Idna/Idna.php new file mode 100644 index 000000000..593068742 --- /dev/null +++ b/league/uri-interfaces/src/Idna/Idna.php @@ -0,0 +1,212 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Idna; + +use League\Uri\Exceptions\IdnaConversionFailed; +use League\Uri\Exceptions\IdnSupportMissing; +use League\Uri\Exceptions\SyntaxError; +use function defined; +use function function_exists; +use function idn_to_ascii; +use function idn_to_utf8; +use function rawurldecode; +use const INTL_IDNA_VARIANT_UTS46; + +/** + * @see https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/uidna_8h.html + */ +final class Idna +{ + private const REGEXP_IDNA_PATTERN = '/[^\x20-\x7f]/'; + private const MAX_DOMAIN_LENGTH = 253; + private const MAX_LABEL_LENGTH = 63; + + /** + * General registered name regular expression. + * + * @see https://tools.ietf.org/html/rfc3986#section-3.2.2 + * @see https://regex101.com/r/fptU8V/1 + */ + private const REGEXP_REGISTERED_NAME = '/ + (?(DEFINE) + (?[a-z0-9_~\-]) # . is missing as it is used to separate labels + (?[!$&\'()*+,;=]) + (?%[A-F0-9]{2}) + (?(?:(?&unreserved)|(?&sub_delims)|(?&encoded))*) + ) + ^(?:(?®_name)\.)*(?®_name)\.?$ + /ix'; + + /** + * IDNA options. + */ + public const IDNA_DEFAULT = 0; + public const IDNA_ALLOW_UNASSIGNED = 1; + public const IDNA_USE_STD3_RULES = 2; + public const IDNA_CHECK_BIDI = 4; + public const IDNA_CHECK_CONTEXTJ = 8; + public const IDNA_NONTRANSITIONAL_TO_ASCII = 0x10; + public const IDNA_NONTRANSITIONAL_TO_UNICODE = 0x20; + public const IDNA_CHECK_CONTEXTO = 0x40; + + /** + * IDNA errors. + */ + public const ERROR_NONE = 0; + public const ERROR_EMPTY_LABEL = 1; + public const ERROR_LABEL_TOO_LONG = 2; + public const ERROR_DOMAIN_NAME_TOO_LONG = 4; + public const ERROR_LEADING_HYPHEN = 8; + public const ERROR_TRAILING_HYPHEN = 0x10; + public const ERROR_HYPHEN_3_4 = 0x20; + public const ERROR_LEADING_COMBINING_MARK = 0x40; + public const ERROR_DISALLOWED = 0x80; + public const ERROR_PUNYCODE = 0x100; + public const ERROR_LABEL_HAS_DOT = 0x200; + public const ERROR_INVALID_ACE_LABEL = 0x400; + public const ERROR_BIDI = 0x800; + public const ERROR_CONTEXTJ = 0x1000; + public const ERROR_CONTEXTO_PUNCTUATION = 0x2000; + public const ERROR_CONTEXTO_DIGITS = 0x4000; + + /** + * IDNA default options. + */ + public const IDNA2008_ASCII = self::IDNA_NONTRANSITIONAL_TO_ASCII + | self::IDNA_CHECK_BIDI + | self::IDNA_USE_STD3_RULES + | self::IDNA_CHECK_CONTEXTJ; + public const IDNA2008_UNICODE = self::IDNA_NONTRANSITIONAL_TO_UNICODE + | self::IDNA_CHECK_BIDI + | self::IDNA_USE_STD3_RULES + | self::IDNA_CHECK_CONTEXTJ; + + /** + * @codeCoverageIgnore + */ + private static function supportsIdna(): void + { + static $idnSupport; + if (null === $idnSupport) { + $idnSupport = function_exists('\idn_to_ascii') && defined('\INTL_IDNA_VARIANT_UTS46'); + } + + if (!$idnSupport) { + throw new IdnSupportMissing('IDN host can not be processed. Verify that ext/intl is installed for IDN support and that ICU is at least version 4.6.'); + } + } + + /** + * Converts the input to its IDNA ASCII form. + * + * This method returns the string converted to IDN ASCII form + * + * @throws SyntaxError if the string can not be converted to ASCII using IDN UTS46 algorithm + */ + public static function toAscii(string $domain, int $options): IdnaInfo + { + $domain = rawurldecode($domain); + + if (1 === preg_match(self::REGEXP_IDNA_PATTERN, $domain)) { + self::supportsIdna(); + + /* @param-out array{errors: int, isTransitionalDifferent: bool, result: string} $idnaInfo */ + idn_to_ascii($domain, $options, INTL_IDNA_VARIANT_UTS46, $idnaInfo); + if ([] === $idnaInfo) { + return IdnaInfo::fromIntl([ + 'result' => strtolower($domain), + 'isTransitionalDifferent' => false, + 'errors' => self::validateDomainAndLabelLength($domain), + ]); + } + + /* @var array{errors: int, isTransitionalDifferent: bool, result: string} $idnaInfo */ + return IdnaInfo::fromIntl($idnaInfo); + } + + $error = self::ERROR_NONE; + if (1 !== preg_match(self::REGEXP_REGISTERED_NAME, $domain)) { + $error |= self::ERROR_DISALLOWED; + } + + return IdnaInfo::fromIntl([ + 'result' => strtolower($domain), + 'isTransitionalDifferent' => false, + 'errors' => self::validateDomainAndLabelLength($domain) | $error, + ]); + } + + /** + * Converts the input to its IDNA UNICODE form. + * + * This method returns the string converted to IDN UNICODE form + * + * @throws SyntaxError if the string can not be converted to UNICODE using IDN UTS46 algorithm + */ + public static function toUnicode(string $domain, int $options): IdnaInfo + { + $domain = rawurldecode($domain); + + if (false === stripos($domain, 'xn--')) { + return IdnaInfo::fromIntl(['result' => $domain, 'isTransitionalDifferent' => false, 'errors' => self::ERROR_NONE]); + } + + self::supportsIdna(); + + /* @param-out array{errors: int, isTransitionalDifferent: bool, result: string} $idnaInfo */ + idn_to_utf8($domain, $options, INTL_IDNA_VARIANT_UTS46, $idnaInfo); + if ([] === $idnaInfo) { + throw IdnaConversionFailed::dueToInvalidHost($domain); + } + + /* @var array{errors: int, isTransitionalDifferent: bool, result: string} $idnaInfo */ + return IdnaInfo::fromIntl($idnaInfo); + } + + /** + * Adapted from https://github.com/TRowbotham/idna. + * + * @see https://github.com/TRowbotham/idna/blob/master/src/Idna.php#L236 + */ + private static function validateDomainAndLabelLength(string $domain): int + { + $error = self::ERROR_NONE; + $labels = explode('.', $domain); + $maxDomainSize = self::MAX_DOMAIN_LENGTH; + $length = count($labels); + + // If the last label is empty and it is not the first label, then it is the root label. + // Increase the max size by 1, making it 254, to account for the root label's "." + // delimiter. This also means we don't need to check the last label's length for being too + // long. + if ($length > 1 && $labels[$length - 1] === '') { + ++$maxDomainSize; + array_pop($labels); + } + + if (strlen($domain) > $maxDomainSize) { + $error |= self::ERROR_DOMAIN_NAME_TOO_LONG; + } + + foreach ($labels as $label) { + if (strlen($label) > self::MAX_LABEL_LENGTH) { + $error |= self::ERROR_LABEL_TOO_LONG; + + break; + } + } + + return $error; + } +} diff --git a/league/uri-interfaces/src/Idna/IdnaInfo.php b/league/uri-interfaces/src/Idna/IdnaInfo.php new file mode 100644 index 000000000..73610a28d --- /dev/null +++ b/league/uri-interfaces/src/Idna/IdnaInfo.php @@ -0,0 +1,113 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Idna; + +use function array_filter; +use const ARRAY_FILTER_USE_KEY; + +/** + * @see https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/uidna_8h.html + */ +final class IdnaInfo +{ + private const ERRORS = [ + Idna::ERROR_EMPTY_LABEL => 'a non-final domain name label (or the whole domain name) is empty', + Idna::ERROR_LABEL_TOO_LONG => 'a domain name label is longer than 63 bytes', + Idna::ERROR_DOMAIN_NAME_TOO_LONG => 'a domain name is longer than 255 bytes in its storage form', + Idna::ERROR_LEADING_HYPHEN => 'a label starts with a hyphen-minus ("-")', + Idna::ERROR_TRAILING_HYPHEN => 'a label ends with a hyphen-minus ("-")', + Idna::ERROR_HYPHEN_3_4 => 'a label contains hyphen-minus ("-") in the third and fourth positions', + Idna::ERROR_LEADING_COMBINING_MARK => 'a label starts with a combining mark', + Idna::ERROR_DISALLOWED => 'a label or domain name contains disallowed characters', + Idna::ERROR_PUNYCODE => 'a label starts with "xn--" but does not contain valid Punycode', + Idna::ERROR_LABEL_HAS_DOT => 'a label contains a dot=full stop', + Idna::ERROR_INVALID_ACE_LABEL => 'An ACE label does not contain a valid label string', + Idna::ERROR_BIDI => 'a label does not meet the IDNA BiDi requirements (for right-to-left characters)', + Idna::ERROR_CONTEXTJ => 'a label does not meet the IDNA CONTEXTJ requirements', + Idna::ERROR_CONTEXTO_DIGITS => 'a label does not meet the IDNA CONTEXTO requirements for digits', + Idna::ERROR_CONTEXTO_PUNCTUATION => 'a label does not meet the IDNA CONTEXTO requirements for punctuation characters. Some punctuation characters "Would otherwise have been DISALLOWED" but are allowed in certain contexts', + ]; + + /** @var string */ + private $result; + + /** @var bool */ + private $isTransitionalDifferent; + + /** @var int */ + private $errors; + + /** + * @var array + */ + private $errorList; + + private function __construct(string $result, bool $isTransitionalDifferent, int $errors) + { + $this->result = $result; + $this->errors = $errors; + $this->isTransitionalDifferent = $isTransitionalDifferent; + $this->errorList = array_filter( + self::ERRORS, + function (int $error): bool { + return 0 !== ($error & $this->errors); + }, + ARRAY_FILTER_USE_KEY + ); + } + + /** + * @param array{result:string, isTransitionalDifferent:bool, errors:int} $infos + */ + public static function fromIntl(array $infos): self + { + return new self($infos['result'], $infos['isTransitionalDifferent'], $infos['errors']); + } + + /** + * @param array{result:string, isTransitionalDifferent:bool, errors:int} $properties + */ + public static function __set_state(array $properties): self + { + return self::fromIntl($properties); + } + + public function result(): string + { + return $this->result; + } + + public function isTransitionalDifferent(): bool + { + return $this->isTransitionalDifferent; + } + + public function errors(): int + { + return $this->errors; + } + + public function error(int $error): ?string + { + return $this->errorList[$error] ?? null; + } + + /** + * @return array + */ + public function errorList(): array + { + return $this->errorList; + } +} diff --git a/league/uri/src/Exceptions/TemplateCanNotBeExpanded.php b/league/uri/src/Exceptions/TemplateCanNotBeExpanded.php index 5618154c1..7c24b94c5 100644 --- a/league/uri/src/Exceptions/TemplateCanNotBeExpanded.php +++ b/league/uri/src/Exceptions/TemplateCanNotBeExpanded.php @@ -13,9 +13,10 @@ namespace League\Uri\Exceptions; +use InvalidArgumentException; use League\Uri\Contracts\UriException; -class TemplateCanNotBeExpanded extends \InvalidArgumentException implements UriException +class TemplateCanNotBeExpanded extends InvalidArgumentException implements UriException { public static function dueToUnableToProcessValueListWithPrefix(string $variableName): self { diff --git a/league/uri/src/Http.php b/league/uri/src/Http.php index 2bbd8a777..b3b8cea88 100644 --- a/league/uri/src/Http.php +++ b/league/uri/src/Http.php @@ -13,6 +13,7 @@ namespace League\Uri; +use JsonSerializable; use League\Uri\Contracts\UriInterface; use League\Uri\Exceptions\SyntaxError; use Psr\Http\Message\UriInterface as Psr7UriInterface; @@ -21,16 +22,10 @@ use function method_exists; use function sprintf; -final class Http implements Psr7UriInterface, \JsonSerializable +final class Http implements Psr7UriInterface, JsonSerializable { - /** - * @var UriInterface - */ - private $uri; + private UriInterface $uri; - /** - * New instance. - */ private function __construct(UriInterface $uri) { $this->validate($uri); @@ -188,13 +183,14 @@ public function getFragment(): string */ public function withScheme($scheme): self { + /** @var string $scheme */ $scheme = $this->filterInput($scheme); if ('' === $scheme) { $scheme = null; } $uri = $this->uri->withScheme($scheme); - if ($uri->getScheme() === $this->uri->getScheme()) { + if ((string) $uri === (string) $this->uri) { return $this; } @@ -224,13 +220,14 @@ private function filterInput($str) */ public function withUserInfo($user, $password = null): self { + /** @var string $user */ $user = $this->filterInput($user); if ('' === $user) { $user = null; } $uri = $this->uri->withUserInfo($user, $password); - if ($uri->getUserInfo() === $this->uri->getUserInfo()) { + if ((string) $uri === (string) $this->uri) { return $this; } @@ -242,13 +239,14 @@ public function withUserInfo($user, $password = null): self */ public function withHost($host): self { + /** @var string $host */ $host = $this->filterInput($host); if ('' === $host) { $host = null; } $uri = $this->uri->withHost($host); - if ($uri->getHost() === $this->uri->getHost()) { + if ((string) $uri === (string) $this->uri) { return $this; } @@ -261,7 +259,7 @@ public function withHost($host): self public function withPort($port): self { $uri = $this->uri->withPort($port); - if ($uri->getPort() === $this->uri->getPort()) { + if ((string) $uri === (string) $this->uri) { return $this; } @@ -274,7 +272,7 @@ public function withPort($port): self public function withPath($path): self { $uri = $this->uri->withPath($path); - if ($uri->getPath() === $this->uri->getPath()) { + if ((string) $uri === (string) $this->uri) { return $this; } @@ -286,13 +284,14 @@ public function withPath($path): self */ public function withQuery($query): self { + /** @var string $query */ $query = $this->filterInput($query); if ('' === $query) { $query = null; } $uri = $this->uri->withQuery($query); - if ($uri->getQuery() === $this->uri->getQuery()) { + if ((string) $uri === (string) $this->uri) { return $this; } @@ -304,13 +303,14 @@ public function withQuery($query): self */ public function withFragment($fragment): self { + /** @var string $fragment */ $fragment = $this->filterInput($fragment); if ('' === $fragment) { $fragment = null; } $uri = $this->uri->withFragment($fragment); - if ($uri->getFragment() === $this->uri->getFragment()) { + if ((string) $uri === (string) $this->uri) { return $this; } diff --git a/league/uri/src/Uri.php b/league/uri/src/Uri.php index 50e954c36..77cb54bb5 100644 --- a/league/uri/src/Uri.php +++ b/league/uri/src/Uri.php @@ -13,22 +13,23 @@ namespace League\Uri; +use finfo; use League\Uri\Contracts\UriInterface; use League\Uri\Exceptions\FileinfoSupportMissing; +use League\Uri\Exceptions\IdnaConversionFailed; use League\Uri\Exceptions\IdnSupportMissing; use League\Uri\Exceptions\SyntaxError; +use League\Uri\Idna\Idna; use Psr\Http\Message\UriInterface as Psr7UriInterface; +use TypeError; use function array_filter; use function array_map; use function base64_decode; use function base64_encode; use function count; -use function defined; use function explode; use function file_get_contents; use function filter_var; -use function function_exists; -use function idn_to_ascii; use function implode; use function in_array; use function inet_pton; @@ -52,24 +53,6 @@ use const FILTER_NULL_ON_FAILURE; use const FILTER_VALIDATE_BOOLEAN; use const FILTER_VALIDATE_IP; -use const IDNA_CHECK_BIDI; -use const IDNA_CHECK_CONTEXTJ; -use const IDNA_ERROR_BIDI; -use const IDNA_ERROR_CONTEXTJ; -use const IDNA_ERROR_DISALLOWED; -use const IDNA_ERROR_DOMAIN_NAME_TOO_LONG; -use const IDNA_ERROR_EMPTY_LABEL; -use const IDNA_ERROR_HYPHEN_3_4; -use const IDNA_ERROR_INVALID_ACE_LABEL; -use const IDNA_ERROR_LABEL_HAS_DOT; -use const IDNA_ERROR_LABEL_TOO_LONG; -use const IDNA_ERROR_LEADING_COMBINING_MARK; -use const IDNA_ERROR_LEADING_HYPHEN; -use const IDNA_ERROR_PUNYCODE; -use const IDNA_ERROR_TRAILING_HYPHEN; -use const IDNA_NONTRANSITIONAL_TO_ASCII; -use const IDNA_NONTRANSITIONAL_TO_UNICODE; -use const INTL_IDNA_VARIANT_UTS46; final class Uri implements UriInterface { @@ -138,6 +121,11 @@ final class Uri implements UriInterface )+ $/ix'; + /** + * RFC3986 IPvFuture host and port component. + */ + private const REGEXP_HOST_PORT = ',^(?(\[.*]|[^:])*)(:(?[^/?#]*))?$,x'; + /** * Significant 10 bits of IP to detect Zone ID regular expression pattern. */ @@ -171,11 +159,10 @@ final class Uri implements UriInterface */ private const REGEXP_WINDOW_PATH = ',^(?[a-zA-Z][:|\|]),'; - /** * Supported schemes and corresponding default port. * - * @var array + * @var array */ private const SCHEME_DEFAULT_PORT = [ 'data' => null, @@ -191,7 +178,7 @@ final class Uri implements UriInterface /** * URI validation methods per scheme. * - * @var array + * @var array */ private const SCHEME_VALIDATION_METHOD = [ 'data' => 'isUriWithSchemeAndPathOnly', @@ -211,80 +198,16 @@ final class Uri implements UriInterface */ private const ASCII = "\x20\x65\x69\x61\x73\x6E\x74\x72\x6F\x6C\x75\x64\x5D\x5B\x63\x6D\x70\x27\x0A\x67\x7C\x68\x76\x2E\x66\x62\x2C\x3A\x3D\x2D\x71\x31\x30\x43\x32\x2A\x79\x78\x29\x28\x4C\x39\x41\x53\x2F\x50\x22\x45\x6A\x4D\x49\x6B\x33\x3E\x35\x54\x3C\x44\x34\x7D\x42\x7B\x38\x46\x77\x52\x36\x37\x55\x47\x4E\x3B\x4A\x7A\x56\x23\x48\x4F\x57\x5F\x26\x21\x4B\x3F\x58\x51\x25\x59\x5C\x09\x5A\x2B\x7E\x5E\x24\x40\x60\x7F\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"; - /** - * URI scheme component. - * - * @var string|null - */ - private $scheme; - - /** - * URI user info part. - * - * @var string|null - */ - private $user_info; - - /** - * URI host component. - * - * @var string|null - */ - private $host; - - /** - * URI port component. - * - * @var int|null - */ - private $port; - - /** - * URI authority string representation. - * - * @var string|null - */ - private $authority; - - /** - * URI path component. - * - * @var string - */ - private $path = ''; - - /** - * URI query component. - * - * @var string|null - */ - private $query; - - /** - * URI fragment component. - * - * @var string|null - */ - private $fragment; - - /** - * URI string representation. - * - * @var string|null - */ - private $uri; + private ?string $scheme; + private ?string $user_info; + private ?string $host; + private ?int $port; + private ?string $authority; + private string $path = ''; + private ?string $query; + private ?string $fragment; + private ?string $uri; - /** - * Create a new instance. - * - * @param ?string $scheme - * @param ?string $user - * @param ?string $pass - * @param ?string $host - * @param ?int $port - * @param ?string $query - * @param ?string $fragment - */ private function __construct( ?string $scheme, ?string $user, @@ -309,8 +232,7 @@ private function __construct( /** * Format the Scheme and Host component. * - * @param ?string $scheme - * + * @param ?string $scheme * @throws SyntaxError if the scheme is invalid */ private function formatScheme(?string $scheme): ?string @@ -329,7 +251,6 @@ private function formatScheme(?string $scheme): ?string /** * Set the UserInfo component. - * * @param ?string $user * @param ?string $password */ @@ -360,7 +281,6 @@ private static function urlEncodeMatch(array $matches): string /** * Validate and Format the Host component. - * * @param ?string $host */ private function formatHost(?string $host): ?string @@ -386,43 +306,8 @@ private function formatHost(?string $host): ?string */ private function formatRegisteredName(string $host): string { - // @codeCoverageIgnoreStart - // added because it is not possible in travis to disabled the ext/intl extension - // see travis issue https://github.com/travis-ci/travis-ci/issues/4701 - static $idn_support = null; - $idn_support = $idn_support ?? function_exists('idn_to_ascii') && defined('INTL_IDNA_VARIANT_UTS46'); - // @codeCoverageIgnoreEnd - $formatted_host = rawurldecode($host); if (1 === preg_match(self::REGEXP_HOST_REGNAME, $formatted_host)) { - $formatted_host = strtolower($formatted_host); - if (false === strpos($formatted_host, 'xn--')) { - return $formatted_host; - } - - // @codeCoverageIgnoreStart - if (!$idn_support) { - throw new IdnSupportMissing(sprintf('the host `%s` could not be processed for IDN. Verify that ext/intl is installed for IDN support and that ICU is at least version 4.6.', $host)); - } - // @codeCoverageIgnoreEnd - - $unicode = idn_to_utf8( - $host, - IDNA_CHECK_BIDI | IDNA_CHECK_CONTEXTJ | IDNA_NONTRANSITIONAL_TO_UNICODE, - INTL_IDNA_VARIANT_UTS46, - $arr - ); - - if (0 !== $arr['errors']) { - throw new SyntaxError(sprintf('The host `%s` is invalid : %s', $host, $this->getIDNAErrors($arr['errors']))); - } - - // @codeCoverageIgnoreStart - if (false === $unicode) { - throw new IdnSupportMissing(sprintf('The Intl extension is misconfigured for %s, please correct this issue before proceeding.', PHP_OS)); - } - // @codeCoverageIgnoreEnd - return $formatted_host; } @@ -430,70 +315,12 @@ private function formatRegisteredName(string $host): string throw new SyntaxError(sprintf('The host `%s` is invalid : a registered name can not contain URI delimiters or spaces', $host)); } - // @codeCoverageIgnoreStart - if (!$idn_support) { - throw new IdnSupportMissing(sprintf('the host `%s` could not be processed for IDN. Verify that ext/intl is installed for IDN support and that ICU is at least version 4.6.', $host)); + $info = Idna::toAscii($host, Idna::IDNA2008_ASCII); + if (0 !== $info->errors()) { + throw IdnaConversionFailed::dueToIDNAError($host, $info); } - // @codeCoverageIgnoreEnd - $formatted_host = idn_to_ascii( - $formatted_host, - IDNA_CHECK_BIDI | IDNA_CHECK_CONTEXTJ | IDNA_NONTRANSITIONAL_TO_ASCII, - INTL_IDNA_VARIANT_UTS46, - $arr - ); - - if ([] === $arr) { - throw new SyntaxError(sprintf('Host `%s` is invalid', $host)); - } - - if (0 !== $arr['errors']) { - throw new SyntaxError(sprintf('The host `%s` is invalid : %s', $host, $this->getIDNAErrors($arr['errors']))); - } - - // @codeCoverageIgnoreStart - if (false === $formatted_host) { - throw new IdnSupportMissing(sprintf('The Intl extension is misconfigured for %s, please correct this issue before proceeding.', PHP_OS)); - } - // @codeCoverageIgnoreEnd - - return $arr['result']; - } - - /** - * Retrieves and format IDNA conversion error message. - * - * @link http://icu-project.org/apiref/icu4j/com/ibm/icu/text/IDNA.Error.html - */ - private function getIDNAErrors(int $error_byte): string - { - /** - * IDNA errors. - */ - static $idnErrors = [ - IDNA_ERROR_EMPTY_LABEL => 'a non-final domain name label (or the whole domain name) is empty', - IDNA_ERROR_LABEL_TOO_LONG => 'a domain name label is longer than 63 bytes', - IDNA_ERROR_DOMAIN_NAME_TOO_LONG => 'a domain name is longer than 255 bytes in its storage form', - IDNA_ERROR_LEADING_HYPHEN => 'a label starts with a hyphen-minus ("-")', - IDNA_ERROR_TRAILING_HYPHEN => 'a label ends with a hyphen-minus ("-")', - IDNA_ERROR_HYPHEN_3_4 => 'a label contains hyphen-minus ("-") in the third and fourth positions', - IDNA_ERROR_LEADING_COMBINING_MARK => 'a label starts with a combining mark', - IDNA_ERROR_DISALLOWED => 'a label or domain name contains disallowed characters', - IDNA_ERROR_PUNYCODE => 'a label starts with "xn--" but does not contain valid Punycode', - IDNA_ERROR_LABEL_HAS_DOT => 'a label contains a dot=full stop', - IDNA_ERROR_INVALID_ACE_LABEL => 'An ACE label does not contain a valid label string', - IDNA_ERROR_BIDI => 'a label does not meet the IDNA BiDi requirements (for right-to-left characters)', - IDNA_ERROR_CONTEXTJ => 'a label does not meet the IDNA CONTEXTJ requirements', - ]; - - $res = []; - foreach ($idnErrors as $error => $reason) { - if ($error === ($error_byte & $error)) { - $res[] = $reason; - } - } - - return [] === $res ? 'Unknown IDNA conversion error.' : implode(', ', $res).'.'; + return $info->result(); } /** @@ -538,7 +365,7 @@ private function formatIp(string $host): string /** * Format the Port component. * - * @param null|mixed $port + * @param object|null|int|string $port * * @throws SyntaxError */ @@ -549,7 +376,7 @@ private function formatPort($port = null): ?int } if (!is_int($port) && !(is_string($port) && 1 === preg_match('/^\d*$/', $port))) { - throw new SyntaxError(sprintf('The port `%s` is invalid', $port)); + throw new SyntaxError('The port is expected to be an integer or a string representing an integer; '.gettype($port).' given.'); } $port = (int) $port; @@ -653,12 +480,8 @@ public static function createFromString($uri = ''): self } /** - * Create a new instance from a hash of parse_url parts. - * - * Create an new instance from a hash representation of the URI similar - * to PHP parse_url function result - * - * @param array $components + * Create a new instance from a hash representation of the URI similar + * to PHP parse_url function result. */ public static function createFromComponents(array $components = []): self { @@ -690,7 +513,7 @@ public static function createFromComponents(array $components = []): self public static function createFromDataPath(string $path, $context = null): self { static $finfo_support = null; - $finfo_support = $finfo_support ?? class_exists(\finfo::class); + $finfo_support = $finfo_support ?? class_exists(finfo::class); // @codeCoverageIgnoreStart if (!$finfo_support) { @@ -710,7 +533,7 @@ public static function createFromDataPath(string $path, $context = null): self throw new SyntaxError(sprintf('The file `%s` does not exist or is not readable', $path)); } - $mimetype = (string) (new \finfo(FILEINFO_MIME))->file(...$mime_args); + $mimetype = (string) (new finfo(FILEINFO_MIME))->file(...$mime_args); return Uri::createFromComponents([ 'scheme' => 'data', @@ -787,7 +610,7 @@ public static function createFromUri($uri): self } if (!$uri instanceof Psr7UriInterface) { - throw new \TypeError(sprintf('The object must implement the `%s` or the `%s`', Psr7UriInterface::class, UriInterface::class)); + throw new TypeError(sprintf('The object must implement the `%s` or the `%s`', Psr7UriInterface::class, UriInterface::class)); } $scheme = $uri->getScheme(); @@ -894,7 +717,7 @@ private static function fetchUserInfo(array $server): array * * @throws SyntaxError If the host can not be detected * - * @return array{0:?string, 1:?string} + * @return array{0:string|null, 1:int|null} */ private static function fetchHostname(array $server): array { @@ -903,12 +726,14 @@ private static function fetchHostname(array $server): array $server['SERVER_PORT'] = (int) $server['SERVER_PORT']; } - if (isset($server['HTTP_HOST'])) { - preg_match(',^(?(\[.*]|[^:])*)(:(?[^/?#]*))?$,x', $server['HTTP_HOST'], $matches); + if (isset($server['HTTP_HOST']) && 1 === preg_match(self::REGEXP_HOST_PORT, $server['HTTP_HOST'], $matches)) { + if (isset($matches['port'])) { + $matches['port'] = (int) $matches['port']; + } return [ $matches['host'], - isset($matches['port']) ? (int) $matches['port'] : $server['SERVER_PORT'], + $matches['port'] ?? $server['SERVER_PORT'], ]; } @@ -1226,10 +1051,7 @@ private function getUriString( return $scheme.$authority.$path.$query.$fragment; } - /** - * {@inheritDoc} - */ - public function __toString(): string + public function toString(): string { $this->uri = $this->uri ?? $this->getUriString( $this->scheme, @@ -1242,12 +1064,20 @@ public function __toString(): string return $this->uri; } + /** + * {@inheritDoc} + */ + public function __toString(): string + { + return $this->toString(); + } + /** * {@inheritDoc} */ public function jsonSerialize(): string { - return $this->__toString(); + return $this->toString(); } /** @@ -1313,6 +1143,10 @@ public function getPort(): ?int */ public function getPath(): string { + if (0 === strpos($this->path, '//')) { + return '/'.ltrim($this->path, '/'); + } + return $this->path; } @@ -1369,7 +1203,7 @@ private function filterString($str): ?string } if (!is_scalar($str)) { - throw new \TypeError(sprintf('The component must be a string, a scalar or a stringable object %s given.', gettype($str))); + throw new SyntaxError(sprintf('The component must be a string, a scalar or a stringable object; `%s` given.', gettype($str))); } $str = (string) $str; @@ -1445,12 +1279,14 @@ public function withPort($port): UriInterface /** * {@inheritDoc} + * + * @param string|object $path */ public function withPath($path): UriInterface { $path = $this->filterString($path); if (null === $path) { - throw new \TypeError('A path must be a string NULL given.'); + throw new TypeError('A path must be a string NULL given.'); } $path = $this->formatPath($path); diff --git a/league/uri/src/UriInfo.php b/league/uri/src/UriInfo.php index 5dd96e1a7..ec8473c54 100644 --- a/league/uri/src/UriInfo.php +++ b/league/uri/src/UriInfo.php @@ -15,6 +15,7 @@ use League\Uri\Contracts\UriInterface; use Psr\Http\Message\UriInterface as Psr7UriInterface; +use TypeError; use function explode; use function implode; use function preg_replace_callback; @@ -23,9 +24,9 @@ final class UriInfo { - private const REGEXP_ENCODED_CHARS = ',%(2[D|E]|3[0-9]|4[1-9|A-F]|5[0-9|A|F]|6[1-9|A-F]|7[0-9|E]),i'; + private const REGEXP_ENCODED_CHARS = ',%(2[D|E]|3[0-9]|4[1-9|A-F]|5[0-9|AF]|6[1-9|A-F]|7[0-9|E]),i'; - private const WHATWG_SPECIAL_SCHEMES = ['ftp', 'http', 'https', 'ws', 'wss']; + private const WHATWG_SPECIAL_SCHEMES = ['ftp' => 21, 'http' => 80, 'https' => 443, 'ws' => 80, 'wss' => 443]; /** * @codeCoverageIgnore @@ -51,7 +52,7 @@ private static function emptyComponentValue($uri): ?string * * @param mixed $uri the URI to validate * - * @throws \TypeError if the URI object does not implements the supported interfaces. + * @throws TypeError if the URI object does not implements the supported interfaces. * * @return Psr7UriInterface|UriInterface */ @@ -61,7 +62,7 @@ private static function filterUri($uri) return $uri; } - throw new \TypeError(sprintf('The uri must be a valid URI object received `%s`', is_object($uri) ? get_class($uri) : gettype($uri))); + throw new TypeError(sprintf('The uri must be a valid URI object received `%s`', is_object($uri) ? get_class($uri) : gettype($uri))); } /** @@ -87,9 +88,7 @@ private static function normalize($uri) $pairs = null === $query ? [] : explode('&', $query); sort($pairs, SORT_REGULAR); - $replace = static function (array $matches): string { - return rawurldecode($matches[0]); - }; + $replace = static fn (array $matches): string => rawurldecode($matches[0]); $retval = preg_replace_callback(self::REGEXP_ENCODED_CHARS, $replace, [$path, implode('&', $pairs), $fragment]); if (null !== $retval) { @@ -194,12 +193,23 @@ public static function getOrigin($uri): ?string $scheme = $uri->getScheme(); } - if (in_array($scheme, self::WHATWG_SPECIAL_SCHEMES, true)) { - $null = self::emptyComponentValue($uri); - - return (string) $uri->withFragment($null)->withQuery($null)->withPath('')->withUserInfo($null, null); + if (null === $scheme || !array_key_exists($scheme, self::WHATWG_SPECIAL_SCHEMES)) { + return null; } - return null; + $null = self::emptyComponentValue($uri); + + return (string) $uri->withFragment($null)->withQuery($null)->withPath('')->withUserInfo($null); + } + + /** + * @param Psr7UriInterface|UriInterface $uri + * @param Psr7UriInterface|UriInterface $base_uri + */ + public static function isCrossOrigin($uri, $base_uri): bool + { + return null === ($uriString = self::getOrigin(Uri::createFromUri($uri))) + || null === ($baseUriString = self::getOrigin(Uri::createFromUri($base_uri))) + || $uriString !== $baseUriString; } } diff --git a/league/uri/src/UriResolver.php b/league/uri/src/UriResolver.php index 7c34dbef7..1090383c8 100644 --- a/league/uri/src/UriResolver.php +++ b/league/uri/src/UriResolver.php @@ -15,6 +15,7 @@ use League\Uri\Contracts\UriInterface; use Psr\Http\Message\UriInterface as Psr7UriInterface; +use TypeError; use function array_pop; use function array_reduce; use function count; @@ -94,12 +95,12 @@ public static function resolve($uri, $base_uri) * * @param mixed $uri an URI object * - * @throws \TypeError if the URI object does not implements the supported interfaces. + * @throws TypeError if the URI object does not implements the supported interfaces. */ private static function filterUri($uri): void { if (!$uri instanceof UriInterface && !$uri instanceof Psr7UriInterface) { - throw new \TypeError(sprintf('The uri must be a valid URI object received `%s`', gettype($uri))); + throw new TypeError(sprintf('The uri must be a valid URI object received `%s`', gettype($uri))); } } @@ -270,9 +271,9 @@ private static function getComponent(string $method, $uri): ?string /** * Filter the URI object. * - * @param null|mixed $uri + * @param Psr7UriInterface|UriInterface $uri * - * @throws \TypeError if the URI object does not implements the supported interfaces. + * @throws TypeError if the URI object does not implements the supported interfaces. * * @return Psr7UriInterface|UriInterface */ diff --git a/league/uri/src/UriString.php b/league/uri/src/UriString.php index 5ba0bab66..674e1a437 100644 --- a/league/uri/src/UriString.php +++ b/league/uri/src/UriString.php @@ -13,16 +13,15 @@ namespace League\Uri; +use League\Uri\Exceptions\IdnaConversionFailed; use League\Uri\Exceptions\IdnSupportMissing; use League\Uri\Exceptions\SyntaxError; +use League\Uri\Idna\Idna; +use TypeError; use function array_merge; -use function defined; use function explode; use function filter_var; -use function function_exists; use function gettype; -use function idn_to_ascii; -use function implode; use function inet_pton; use function is_object; use function is_scalar; @@ -34,20 +33,6 @@ use function substr; use const FILTER_FLAG_IPV6; use const FILTER_VALIDATE_IP; -use const IDNA_ERROR_BIDI; -use const IDNA_ERROR_CONTEXTJ; -use const IDNA_ERROR_DISALLOWED; -use const IDNA_ERROR_DOMAIN_NAME_TOO_LONG; -use const IDNA_ERROR_EMPTY_LABEL; -use const IDNA_ERROR_HYPHEN_3_4; -use const IDNA_ERROR_INVALID_ACE_LABEL; -use const IDNA_ERROR_LABEL_HAS_DOT; -use const IDNA_ERROR_LABEL_TOO_LONG; -use const IDNA_ERROR_LEADING_COMBINING_MARK; -use const IDNA_ERROR_LEADING_HYPHEN; -use const IDNA_ERROR_PUNYCODE; -use const IDNA_ERROR_TRAILING_HYPHEN; -use const INTL_IDNA_VARIANT_UTS46; /** * A class to parse a URI string according to RFC3986. @@ -164,7 +149,7 @@ final class UriString /** * Generate an URI string representation from its parsed representation - * returned by League\Uri\parse() or PHP's parse_url. + * returned by League\UriString::parse() or PHP's parse_url. * * If you supply your own array, you are responsible for providing * valid components without their URI delimiters. @@ -178,7 +163,7 @@ final class UriString * pass:?string, * host:?string, * port:?int, - * path:string, + * path:?string, * query:?string, * fragment:?string * } $components @@ -281,7 +266,7 @@ public static function parse($uri): array } if (!is_scalar($uri)) { - throw new \TypeError(sprintf('The uri must be a scalar or a stringable object `%s` given', gettype($uri))); + throw new TypeError(sprintf('The uri must be a scalar or a stringable object `%s` given', gettype($uri))); } $uri = (string) $uri; @@ -431,36 +416,8 @@ private static function filterHost(string $host): string */ private static function filterRegisteredName(string $host): string { - // @codeCoverageIgnoreStart - // added because it is not possible in travis to disabled the ext/intl extension - // see travis issue https://github.com/travis-ci/travis-ci/issues/4701 - static $idn_support = null; - $idn_support = $idn_support ?? function_exists('idn_to_ascii') && defined('INTL_IDNA_VARIANT_UTS46'); - // @codeCoverageIgnoreEnd - $formatted_host = rawurldecode($host); if (1 === preg_match(self::REGEXP_REGISTERED_NAME, $formatted_host)) { - if (false === strpos($formatted_host, 'xn--')) { - return $host; - } - - // @codeCoverageIgnoreStart - if (!$idn_support) { - throw new IdnSupportMissing(sprintf('the host `%s` could not be processed for IDN. Verify that ext/intl is installed for IDN support and that ICU is at least version 4.6.', $host)); - } - // @codeCoverageIgnoreEnd - - $unicode = idn_to_utf8($host, 0, INTL_IDNA_VARIANT_UTS46, $arr); - if (0 !== $arr['errors']) { - throw new SyntaxError(sprintf('The host `%s` is invalid : %s', $host, self::getIDNAErrors($arr['errors']))); - } - - // @codeCoverageIgnoreStart - if (false === $unicode) { - throw new IdnSupportMissing(sprintf('The Intl extension is misconfigured for %s, please correct this issue before proceeding.', PHP_OS)); - } - // @codeCoverageIgnoreEnd - return $host; } @@ -469,71 +426,14 @@ private static function filterRegisteredName(string $host): string throw new SyntaxError(sprintf('Host `%s` is invalid : the host is not a valid registered name', $host)); } - // @codeCoverageIgnoreStart - if (!$idn_support) { - throw new IdnSupportMissing(sprintf('the host `%s` could not be processed for IDN. Verify that ext/intl is installed for IDN support and that ICU is at least version 4.6.', $host)); - } - // @codeCoverageIgnoreEnd - - $retval = idn_to_ascii($formatted_host, 0, INTL_IDNA_VARIANT_UTS46, $arr); - - if ([] === $arr) { - throw new SyntaxError(sprintf('Host `%s` is not a valid IDN host', $host)); - } - - if (0 !== $arr['errors']) { - throw new SyntaxError(sprintf('Host `%s` is not a valid IDN host : %s', $host, self::getIDNAErrors($arr['errors']))); - } - - // @codeCoverageIgnoreStart - if (false === $retval) { - throw new IdnSupportMissing(sprintf('The Intl extension is misconfigured for %s, please correct this issue before proceeding.', PHP_OS)); - } - // @codeCoverageIgnoreEnd - - if (false !== strpos($retval, '%')) { - throw new SyntaxError(sprintf('Host `%s` is invalid : the host is not a valid registered name', $host)); + $info = Idna::toAscii($host, Idna::IDNA2008_ASCII); + if (0 !== $info->errors()) { + throw IdnaConversionFailed::dueToIDNAError($host, $info); } return $host; } - /** - * Retrieves and format IDNA conversion error message. - * - * @link http://icu-project.org/apiref/icu4j/com/ibm/icu/text/IDNA.Error.html - */ - private static function getIDNAErrors(int $error_byte): string - { - /** - * IDNA errors. - */ - static $idn_errors = [ - IDNA_ERROR_EMPTY_LABEL => 'a non-final domain name label (or the whole domain name) is empty', - IDNA_ERROR_LABEL_TOO_LONG => 'a domain name label is longer than 63 bytes', - IDNA_ERROR_DOMAIN_NAME_TOO_LONG => 'a domain name is longer than 255 bytes in its storage form', - IDNA_ERROR_LEADING_HYPHEN => 'a label starts with a hyphen-minus ("-")', - IDNA_ERROR_TRAILING_HYPHEN => 'a label ends with a hyphen-minus ("-")', - IDNA_ERROR_HYPHEN_3_4 => 'a label contains hyphen-minus ("-") in the third and fourth positions', - IDNA_ERROR_LEADING_COMBINING_MARK => 'a label starts with a combining mark', - IDNA_ERROR_DISALLOWED => 'a label or domain name contains disallowed characters', - IDNA_ERROR_PUNYCODE => 'a label starts with "xn--" but does not contain valid Punycode', - IDNA_ERROR_LABEL_HAS_DOT => 'a label contains a dot=full stop', - IDNA_ERROR_INVALID_ACE_LABEL => 'An ACE label does not contain a valid label string', - IDNA_ERROR_BIDI => 'a label does not meet the IDNA BiDi requirements (for right-to-left characters)', - IDNA_ERROR_CONTEXTJ => 'a label does not meet the IDNA CONTEXTJ requirements', - ]; - - $res = []; - foreach ($idn_errors as $error => $reason) { - if ($error === ($error_byte & $error)) { - $res[] = $reason; - } - } - - return [] === $res ? 'Unknown IDNA conversion error.' : implode(', ', $res).'.'; - } - /** * Validates a IPv6/IPvfuture host. * diff --git a/league/uri/src/UriTemplate.php b/league/uri/src/UriTemplate.php index 94bbef93e..ba7a5a333 100644 --- a/league/uri/src/UriTemplate.php +++ b/league/uri/src/UriTemplate.php @@ -19,6 +19,7 @@ use League\Uri\Exceptions\TemplateCanNotBeExpanded; use League\Uri\UriTemplate\Template; use League\Uri\UriTemplate\VariableBag; +use TypeError; /** * Defines the URI Template syntax and the process for expanding a URI Template into a URI reference. @@ -33,20 +34,13 @@ */ final class UriTemplate { - /** - * @var Template - */ - private $template; - - /** - * @var VariableBag - */ - private $defaultVariables; + private Template $template; + private VariableBag $defaultVariables; /** * @param object|string $template a string or an object with the __toString method * - * @throws \TypeError if the template is not a string or an object with the __toString method + * @throws TypeError if the template is not a string or an object with the __toString method * @throws SyntaxError if the template syntax is invalid * @throws TemplateCanNotBeExpanded if the template variables are invalid */ @@ -119,10 +113,10 @@ public function getDefaultVariables(): array */ public function withDefaultVariables(array $defaultDefaultVariables): self { - $clone = clone $this; - $clone->defaultVariables = $this->filterVariables($defaultDefaultVariables); - - return $clone; + return new self( + $this->template->toString(), + $this->filterVariables($defaultDefaultVariables)->all() + ); } /** @@ -131,10 +125,10 @@ public function withDefaultVariables(array $defaultDefaultVariables): self */ public function expand(array $variables = []): UriInterface { - $uriString = $this->template->expand( - $this->filterVariables($variables)->replace($this->defaultVariables) + return Uri::createFromString( + $this->template->expand( + $this->filterVariables($variables)->replace($this->defaultVariables) + ) ); - - return Uri::createFromString($uriString); } } diff --git a/league/uri/src/UriTemplate/Expression.php b/league/uri/src/UriTemplate/Expression.php index 7a57b4a21..99ecac98b 100644 --- a/league/uri/src/UriTemplate/Expression.php +++ b/league/uri/src/UriTemplate/Expression.php @@ -64,30 +64,13 @@ final class Expression '&' => ['prefix' => '&', 'joiner' => '&', 'query' => true], ]; - /** - * @var string - */ - private $operator; - - /** - * @var string - */ - private $joiner; - - /** - * @var array - */ - private $varSpecifiers; - - /** - * @var array - */ - private $variableNames; - - /** - * @var string - */ - private $expressionString; + private string $operator; + /** @var array */ + private array $varSpecifiers; + private string $joiner; + /** @var array */ + private array $variableNames; + private string $expressionString; private function __construct(string $operator, VarSpecifier ...$varSpecifiers) { @@ -103,20 +86,18 @@ private function __construct(string $operator, VarSpecifier ...$varSpecifiers) */ private function setVariableNames(): array { - $mapper = static function (VarSpecifier $varSpecifier): string { - return $varSpecifier->name(); - }; - - return array_unique(array_map($mapper, $this->varSpecifiers)); + return array_unique(array_map( + static fn (VarSpecifier $varSpecifier): string => $varSpecifier->name(), + $this->varSpecifiers + )); } private function setExpressionString(): string { - $mapper = static function (VarSpecifier $variable): string { - return $variable->toString(); - }; - - $varSpecifierString = implode(',', array_map($mapper, $this->varSpecifiers)); + $varSpecifierString = implode(',', array_map( + static fn (VarSpecifier $variable): string => $variable->toString(), + $this->varSpecifiers + )); return '{'.$this->operator.$varSpecifierString.'}'; } @@ -146,11 +127,10 @@ public static function createFromString(string $expression): self throw new SyntaxError('The operator used in the expression "'.$expression.'" is reserved.'); } - $mapper = static function (string $varSpec): VarSpecifier { - return VarSpecifier::createFromString($varSpec); - }; - - return new Expression($parts['operator'], ...array_map($mapper, explode(',', $parts['variables']))); + return new Expression($parts['operator'], ...array_map( + static fn (string $varSpec): VarSpecifier => VarSpecifier::createFromString($varSpec), + explode(',', $parts['variables']) + )); } /** @@ -177,11 +157,7 @@ public function expand(VariableBag $variables): string $parts[] = $this->replace($varSpecifier, $variables); } - $nullFilter = static function ($value): bool { - return '' !== $value; - }; - - $expanded = implode($this->joiner, array_filter($parts, $nullFilter)); + $expanded = implode($this->joiner, array_filter($parts, static fn ($value): bool => '' !== $value)); if ('' === $expanded) { return $expanded; } diff --git a/league/uri/src/UriTemplate/Template.php b/league/uri/src/UriTemplate/Template.php index e17b3c940..ecd130fe1 100644 --- a/league/uri/src/UriTemplate/Template.php +++ b/league/uri/src/UriTemplate/Template.php @@ -15,6 +15,7 @@ use League\Uri\Exceptions\SyntaxError; use League\Uri\Exceptions\TemplateCanNotBeExpanded; +use TypeError; use function array_merge; use function array_unique; use function gettype; @@ -34,20 +35,11 @@ final class Template */ private const REGEXP_EXPRESSION_DETECTOR = '/\{[^\}]*\}/x'; - /** - * @var string - */ - private $template; - - /** - * @var array - */ - private $expressions = []; - - /** - * @var array - */ - private $variableNames; + private string $template; + /** @var array */ + private array $expressions = []; + /** @var array */ + private array $variableNames; private function __construct(string $template, Expression ...$expressions) { @@ -71,7 +63,7 @@ public static function __set_state(array $properties): self /** * @param object|string $template a string or an object with the __toString method * - * @throws \TypeError if the template is not a string or an object with the __toString method + * @throws TypeError if the template is not a string or an object with the __toString method * @throws SyntaxError if the template contains invalid expressions * @throws SyntaxError if the template contains invalid variable specification */ @@ -82,7 +74,7 @@ public static function createFromString($template): self } if (!is_string($template)) { - throw new \TypeError(sprintf('The template must be a string or a stringable object %s given.', gettype($template))); + throw new TypeError(sprintf('The template must be a string or a stringable object %s given.', gettype($template))); } /** @var string $remainder */ diff --git a/league/uri/src/UriTemplate/VarSpecifier.php b/league/uri/src/UriTemplate/VarSpecifier.php index e66de0735..ac49efb53 100644 --- a/league/uri/src/UriTemplate/VarSpecifier.php +++ b/league/uri/src/UriTemplate/VarSpecifier.php @@ -28,20 +28,9 @@ final class VarSpecifier (?\:(?\d+)|\*)? $/x'; - /** - * @var string - */ - private $name; - - /** - * @var string - */ - private $modifier; - - /** - * @var int - */ - private $position; + private string $name; + private string $modifier; + private int $position; private function __construct(string $name, string $modifier, int $position) { diff --git a/league/uri/src/UriTemplate/VariableBag.php b/league/uri/src/UriTemplate/VariableBag.php index cd4b09721..cf60de91e 100644 --- a/league/uri/src/UriTemplate/VariableBag.php +++ b/league/uri/src/UriTemplate/VariableBag.php @@ -14,6 +14,7 @@ namespace League\Uri\UriTemplate; use League\Uri\Exceptions\TemplateCanNotBeExpanded; +use TypeError; use function gettype; use function is_array; use function is_bool; @@ -27,10 +28,10 @@ final class VariableBag /** * @var array> */ - private $variables = []; + private array $variables = []; /** - * @param iterable $variables + * @param iterable> $variables */ public function __construct(iterable $variables = []) { @@ -63,7 +64,7 @@ public function fetch(string $name) } /** - * @param string|array $value + * @param string|bool|int|float|array $value */ public function assign(string $name, $value): void { @@ -88,7 +89,7 @@ private function normalizeValue($value, string $name, bool $isNestedListAllowed) } if (!is_array($value)) { - throw new \TypeError(sprintf('The variable '.$name.' must be NULL, a scalar or a stringable object `%s` given', gettype($value))); + throw new TypeError(sprintf('The variable '.$name.' must be NULL, a scalar or a stringable object `%s` given', gettype($value))); } if (!$isNestedListAllowed) { @@ -108,9 +109,6 @@ private function normalizeValue($value, string $name, bool $isNestedListAllowed) */ public function replace(VariableBag $variables): self { - $instance = clone $this; - $instance->variables += $variables->variables; - - return $instance; + return new self($this->variables + $variables->variables); } } diff --git a/psr/http-factory/src/UploadedFileFactoryInterface.php b/psr/http-factory/src/UploadedFileFactoryInterface.php index 7db4e30af..d7adbf0e2 100644 --- a/psr/http-factory/src/UploadedFileFactoryInterface.php +++ b/psr/http-factory/src/UploadedFileFactoryInterface.php @@ -15,10 +15,10 @@ interface UploadedFileFactoryInterface * * @param StreamInterface $stream Underlying stream representing the * uploaded file content. - * @param int $size in bytes + * @param int|null $size in bytes * @param int $error PHP file upload error - * @param string $clientFilename Filename as provided by the client, if any. - * @param string $clientMediaType Media type as provided by the client, if any. + * @param string|null $clientFilename Filename as provided by the client, if any. + * @param string|null $clientMediaType Media type as provided by the client, if any. * * @return UploadedFileInterface * @@ -26,9 +26,9 @@ interface UploadedFileFactoryInterface */ public function createUploadedFile( StreamInterface $stream, - int $size = null, + ?int $size = null, int $error = \UPLOAD_ERR_OK, - string $clientFilename = null, - string $clientMediaType = null + ?string $clientFilename = null, + ?string $clientMediaType = null ): UploadedFileInterface; } diff --git a/ramsey/collection/LICENSE b/ramsey/collection/LICENSE index 0efc999bf..a7fcf1201 100644 --- a/ramsey/collection/LICENSE +++ b/ramsey/collection/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2015-2020 Ben Ramsey +Copyright (c) 2015-2022 Ben Ramsey Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/ramsey/collection/conventional-commits.json b/ramsey/collection/conventional-commits.json new file mode 100644 index 000000000..5fe21d2fa --- /dev/null +++ b/ramsey/collection/conventional-commits.json @@ -0,0 +1,22 @@ +{ + "typeCase": "kebab", + "types": [ + "chore", + "ci", + "docs", + "feat", + "fix", + "refactor", + "security", + "style", + "test" + ], + "scopeCase": "kebab", + "scopeRequired": false, + "scopes": [], + "descriptionCase": null, + "descriptionEndMark": "", + "bodyRequired": false, + "bodyWrapWidth": 72, + "requiredFooters": [] +} diff --git a/ramsey/collection/src/AbstractArray.php b/ramsey/collection/src/AbstractArray.php index 2c6e0dedd..9b39dd0cb 100644 --- a/ramsey/collection/src/AbstractArray.php +++ b/ramsey/collection/src/AbstractArray.php @@ -17,6 +17,7 @@ use ArrayIterator; use Traversable; +use function count; use function serialize; use function unserialize; @@ -25,7 +26,7 @@ * the effort required to implement this interface. * * @template T - * @template-implements ArrayInterface + * @implements ArrayInterface */ abstract class AbstractArray implements ArrayInterface { @@ -34,7 +35,7 @@ abstract class AbstractArray implements ArrayInterface * * @var array */ - protected $data = []; + protected array $data = []; /** * Constructs a new array object. @@ -54,6 +55,8 @@ public function __construct(array $data = []) * Returns an iterator for this array. * * @link http://php.net/manual/en/iteratoraggregate.getiterator.php IteratorAggregate::getIterator() + * + * @return Traversable */ public function getIterator(): Traversable { @@ -82,6 +85,7 @@ public function offsetExists($offset): bool * @return T|null the value stored at the offset, or null if the offset * does not exist. */ + #[\ReturnTypeWillChange] // phpcs:ignore public function offsetGet($offset) { return $this->data[$offset] ?? null; @@ -121,6 +125,8 @@ public function offsetUnset($offset): void /** * Returns a serialized string representation of this array object. * + * @deprecated The Serializable interface will go away in PHP 9. + * * @link http://php.net/manual/en/serializable.serialize.php Serializable::serialize() * * @return string a PHP serialized string. @@ -130,9 +136,24 @@ public function serialize(): string return serialize($this->data); } + /** + * Returns data suitable for PHP serialization. + * + * @link https://www.php.net/manual/en/language.oop5.magic.php#language.oop5.magic.serialize + * @link https://www.php.net/serialize + * + * @return array + */ + public function __serialize(): array + { + return $this->data; + } + /** * Converts a serialized string representation into an instance object. * + * @deprecated The Serializable interface will go away in PHP 9. + * * @link http://php.net/manual/en/serializable.unserialize.php Serializable::unserialize() * * @param string $serialized A PHP serialized string to unserialize. @@ -147,6 +168,16 @@ public function unserialize($serialized): void $this->data = $data; } + /** + * Adds unserialized data to the object. + * + * @param array $data + */ + public function __unserialize(array $data): void + { + $this->data = $data; + } + /** * Returns the number of items in this array. * diff --git a/ramsey/collection/src/AbstractCollection.php b/ramsey/collection/src/AbstractCollection.php index 2facf0e89..38ef7144c 100644 --- a/ramsey/collection/src/AbstractCollection.php +++ b/ramsey/collection/src/AbstractCollection.php @@ -32,7 +32,10 @@ use function current; use function end; use function in_array; +use function is_int; +use function is_object; use function reset; +use function spl_object_id; use function sprintf; use function unserialize; use function usort; @@ -42,8 +45,8 @@ * minimize the effort required to implement this interface * * @template T - * @template-extends AbstractArray - * @template-implements CollectionInterface + * @extends AbstractArray + * @implements CollectionInterface */ abstract class AbstractCollection extends AbstractArray implements CollectionInterface { @@ -77,7 +80,7 @@ public function offsetSet($offset, $value): void if ($this->checkType($this->getType(), $value) === false) { throw new InvalidArgumentException( 'Value must be of type ' . $this->getType() . '; value is ' - . $this->toolValueToString($value) + . $this->toolValueToString($value), ); } @@ -94,7 +97,7 @@ public function offsetSet($offset, $value): void public function remove($element): bool { if (($position = array_search($element, $this->data, true)) !== false) { - unset($this->data[$position]); + unset($this[$position]); return true; } @@ -175,7 +178,7 @@ function ($a, $b) use ($propertyOrMethod, $order): int { $bValue = $this->extractValue($b, $propertyOrMethod); return ($aValue <=> $bValue) * ($order === self::SORT_DESC ? -1 : 1); - } + }, ); return $collection; @@ -238,33 +241,37 @@ public function intersect(CollectionInterface $other): CollectionInterface public function merge(CollectionInterface ...$collections): CollectionInterface { - $temp = [$this->data]; + $mergedCollection = clone $this; foreach ($collections as $index => $collection) { if (!$collection instanceof static) { throw new CollectionMismatchException( - sprintf('Collection with index %d must be of type %s', $index, static::class) + sprintf('Collection with index %d must be of type %s', $index, static::class), ); } // When using generics (Collection.php, Set.php, etc), // we also need to make sure that the internal types match each other - if ($collection->getType() !== $this->getType()) { + if ($this->getUniformType($collection) !== $this->getUniformType($this)) { throw new CollectionMismatchException( - sprintf('Collection items in collection with index %d must be of type %s', $index, $this->getType()) + sprintf( + 'Collection items in collection with index %d must be of type %s', + $index, + $this->getType(), + ), ); } - $temp[] = $collection->toArray(); + foreach ($collection as $key => $value) { + if (is_int($key)) { + $mergedCollection[] = $value; + } else { + $mergedCollection[$key] = $value; + } + } } - /** @var array $merge */ - $merge = array_merge(...$temp); - - $collection = clone $this; - $collection->data = $merge; - - return $collection; + return $mergedCollection; } /** @@ -289,7 +296,7 @@ private function compareCollectionTypes(CollectionInterface $other): void // When using generics (Collection.php, Set.php, etc), // we also need to make sure that the internal types match each other - if ($other->getType() !== $this->getType()) { + if ($this->getUniformType($other) !== $this->getUniformType($this)) { throw new CollectionMismatchException('Collection items must be of type ' . $this->getType()); } } @@ -314,4 +321,21 @@ function ($a, $b): int { return $a === $b ? 0 : ($a < $b ? 1 : -1); }; } + + /** + * @param CollectionInterface $collection + */ + private function getUniformType(CollectionInterface $collection): string + { + switch ($collection->getType()) { + case 'integer': + return 'int'; + case 'boolean': + return 'bool'; + case 'double': + return 'float'; + default: + return $collection->getType(); + } + } } diff --git a/ramsey/collection/src/AbstractSet.php b/ramsey/collection/src/AbstractSet.php index 3bd22965f..1126ccb0a 100644 --- a/ramsey/collection/src/AbstractSet.php +++ b/ramsey/collection/src/AbstractSet.php @@ -20,7 +20,7 @@ * this specific type of collection. * * @template T - * @template-extends AbstractCollection + * @extends AbstractCollection */ abstract class AbstractSet extends AbstractCollection { diff --git a/ramsey/collection/src/ArrayInterface.php b/ramsey/collection/src/ArrayInterface.php index 19fbff336..27af6102b 100644 --- a/ramsey/collection/src/ArrayInterface.php +++ b/ramsey/collection/src/ArrayInterface.php @@ -23,6 +23,8 @@ * `ArrayInterface` provides traversable array functionality to data types. * * @template T + * @extends ArrayAccess + * @extends IteratorAggregate */ interface ArrayInterface extends ArrayAccess, diff --git a/ramsey/collection/src/Collection.php b/ramsey/collection/src/Collection.php index 2f8deddaa..532b971b6 100644 --- a/ramsey/collection/src/Collection.php +++ b/ramsey/collection/src/Collection.php @@ -71,7 +71,7 @@ * ``` * * @template T - * @template-extends AbstractCollection + * @extends AbstractCollection */ class Collection extends AbstractCollection { @@ -80,10 +80,8 @@ class Collection extends AbstractCollection * * A collection's type is immutable once it is set. For this reason, this * property is set private. - * - * @var string */ - private $collectionType; + private string $collectionType; /** * Constructs a collection object of the specified type, optionally with the diff --git a/ramsey/collection/src/CollectionInterface.php b/ramsey/collection/src/CollectionInterface.php index dfef6ca86..9f86a2837 100644 --- a/ramsey/collection/src/CollectionInterface.php +++ b/ramsey/collection/src/CollectionInterface.php @@ -21,7 +21,7 @@ * and others unordered. * * @template T - * @template-extends ArrayInterface + * @extends ArrayInterface */ interface CollectionInterface extends ArrayInterface { @@ -151,6 +151,7 @@ public function filter(callable $callback): self; * * @return CollectionInterface */ + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint public function where(string $propertyOrMethod, $value): self; /** diff --git a/ramsey/collection/src/DoubleEndedQueue.php b/ramsey/collection/src/DoubleEndedQueue.php index 6ebdca5ad..4d1f71ea4 100644 --- a/ramsey/collection/src/DoubleEndedQueue.php +++ b/ramsey/collection/src/DoubleEndedQueue.php @@ -22,17 +22,15 @@ * minimize the effort required to implement this interface. * * @template T - * @template-extends Queue - * @template-implements DoubleEndedQueueInterface + * @extends Queue + * @implements DoubleEndedQueueInterface */ class DoubleEndedQueue extends Queue implements DoubleEndedQueueInterface { /** * Index of the last element in the queue. - * - * @var int */ - private $tail = -1; + private int $tail = -1; /** * @inheritDoc @@ -42,7 +40,7 @@ public function offsetSet($offset, $value): void if ($this->checkType($this->getType(), $value) === false) { throw new InvalidArgumentException( 'Value must be of type ' . $this->getType() . '; value is ' - . $this->toolValueToString($value) + . $this->toolValueToString($value), ); } @@ -52,6 +50,8 @@ public function offsetSet($offset, $value): void } /** + * @throws InvalidArgumentException if $element is of the wrong type + * * @inheritDoc */ public function addFirst($element): bool @@ -59,7 +59,7 @@ public function addFirst($element): bool if ($this->checkType($this->getType(), $element) === false) { throw new InvalidArgumentException( 'Value must be of type ' . $this->getType() . '; value is ' - . $this->toolValueToString($element) + . $this->toolValueToString($element), ); } diff --git a/ramsey/collection/src/DoubleEndedQueueInterface.php b/ramsey/collection/src/DoubleEndedQueueInterface.php index 67aae5e2e..3fa4ecab8 100644 --- a/ramsey/collection/src/DoubleEndedQueueInterface.php +++ b/ramsey/collection/src/DoubleEndedQueueInterface.php @@ -15,6 +15,7 @@ namespace Ramsey\Collection; use Ramsey\Collection\Exception\NoSuchElementException; +use RuntimeException; /** * A linear collection that supports element insertion and removal at both ends. @@ -160,7 +161,7 @@ * empty. * * @template T - * @template-extends QueueInterface + * @extends QueueInterface */ interface DoubleEndedQueueInterface extends QueueInterface { @@ -175,7 +176,7 @@ interface DoubleEndedQueueInterface extends QueueInterface * * @return bool `true` if this queue changed as a result of the call. * - * @throws \RuntimeException if a queue refuses to add a particular element + * @throws RuntimeException if a queue refuses to add a particular element * for any reason other than that it already contains the element. * Implementations should use a more-specific exception that extends * `\RuntimeException`. @@ -196,7 +197,7 @@ public function addFirst($element): bool; * * @return bool `true` if this queue changed as a result of the call. * - * @throws \RuntimeException if a queue refuses to add a particular element + * @throws RuntimeException if a queue refuses to add a particular element * for any reason other than that it already contains the element. * Implementations should use a more-specific exception that extends * `\RuntimeException`. diff --git a/ramsey/collection/src/Exception/CollectionMismatchException.php b/ramsey/collection/src/Exception/CollectionMismatchException.php index d4b335f45..7058bcf6e 100644 --- a/ramsey/collection/src/Exception/CollectionMismatchException.php +++ b/ramsey/collection/src/Exception/CollectionMismatchException.php @@ -14,9 +14,11 @@ namespace Ramsey\Collection\Exception; +use RuntimeException; + /** * Thrown when attempting to operate on collections of differing types. */ -class CollectionMismatchException extends \RuntimeException +class CollectionMismatchException extends RuntimeException { } diff --git a/ramsey/collection/src/Exception/InvalidSortOrderException.php b/ramsey/collection/src/Exception/InvalidSortOrderException.php index 9337ccc66..4491429c7 100644 --- a/ramsey/collection/src/Exception/InvalidSortOrderException.php +++ b/ramsey/collection/src/Exception/InvalidSortOrderException.php @@ -14,9 +14,11 @@ namespace Ramsey\Collection\Exception; +use RuntimeException; + /** * Thrown when attempting to use a sort order that is not recognized. */ -class InvalidSortOrderException extends \RuntimeException +class InvalidSortOrderException extends RuntimeException { } diff --git a/ramsey/collection/src/Exception/NoSuchElementException.php b/ramsey/collection/src/Exception/NoSuchElementException.php index 9debe8f66..cabcb9d88 100644 --- a/ramsey/collection/src/Exception/NoSuchElementException.php +++ b/ramsey/collection/src/Exception/NoSuchElementException.php @@ -14,9 +14,11 @@ namespace Ramsey\Collection\Exception; +use RuntimeException; + /** * Thrown when attempting to access an element that does not exist. */ -class NoSuchElementException extends \RuntimeException +class NoSuchElementException extends RuntimeException { } diff --git a/ramsey/collection/src/Exception/UnsupportedOperationException.php b/ramsey/collection/src/Exception/UnsupportedOperationException.php index 8f45e5836..9b6228971 100644 --- a/ramsey/collection/src/Exception/UnsupportedOperationException.php +++ b/ramsey/collection/src/Exception/UnsupportedOperationException.php @@ -14,9 +14,11 @@ namespace Ramsey\Collection\Exception; +use RuntimeException; + /** * Thrown to indicate that the requested operation is not supported. */ -class UnsupportedOperationException extends \RuntimeException +class UnsupportedOperationException extends RuntimeException { } diff --git a/ramsey/collection/src/Exception/ValueExtractionException.php b/ramsey/collection/src/Exception/ValueExtractionException.php index f6c6cb4ec..32f2a175f 100644 --- a/ramsey/collection/src/Exception/ValueExtractionException.php +++ b/ramsey/collection/src/Exception/ValueExtractionException.php @@ -14,9 +14,11 @@ namespace Ramsey\Collection\Exception; +use RuntimeException; + /** * Thrown when attempting to extract a value for a method or property that does not exist. */ -class ValueExtractionException extends \RuntimeException +class ValueExtractionException extends RuntimeException { } diff --git a/ramsey/collection/src/GenericArray.php b/ramsey/collection/src/GenericArray.php index 9b95df387..2b079aa5e 100644 --- a/ramsey/collection/src/GenericArray.php +++ b/ramsey/collection/src/GenericArray.php @@ -17,7 +17,7 @@ /** * `GenericArray` represents a standard array object. * - * @template-extends AbstractArray + * @extends AbstractArray */ class GenericArray extends AbstractArray { diff --git a/ramsey/collection/src/Map/AbstractMap.php b/ramsey/collection/src/Map/AbstractMap.php index 70f71160c..378807289 100644 --- a/ramsey/collection/src/Map/AbstractMap.php +++ b/ramsey/collection/src/Map/AbstractMap.php @@ -20,14 +20,15 @@ use function array_key_exists; use function array_keys; use function in_array; +use function var_export; /** * This class provides a basic implementation of `MapInterface`, to minimize the * effort required to implement this interface. * * @template T - * @template-extends AbstractArray - * @template-implements MapInterface + * @extends AbstractArray + * @implements MapInterface */ abstract class AbstractMap extends AbstractArray implements MapInterface { @@ -39,7 +40,7 @@ public function offsetSet($offset, $value): void if ($offset === null) { throw new InvalidArgumentException( 'Map elements are key/value pairs; a key must be provided for ' - . 'value ' . var_export($value, true) + . 'value ' . var_export($value, true), ); } diff --git a/ramsey/collection/src/Map/AbstractTypedMap.php b/ramsey/collection/src/Map/AbstractTypedMap.php index ff9f69177..486dc2e29 100644 --- a/ramsey/collection/src/Map/AbstractTypedMap.php +++ b/ramsey/collection/src/Map/AbstractTypedMap.php @@ -18,15 +18,16 @@ use Ramsey\Collection\Tool\TypeTrait; use Ramsey\Collection\Tool\ValueToStringTrait; +use function var_export; + /** * This class provides a basic implementation of `TypedMapInterface`, to * minimize the effort required to implement this interface. * - * @phpstan-ignore-next-line - * @template K as array-key + * @template K of array-key * @template T - * @template-extends AbstractMap - * @template-implements TypedMapInterface + * @extends AbstractMap + * @implements TypedMapInterface */ abstract class AbstractTypedMap extends AbstractMap implements TypedMapInterface { @@ -38,29 +39,27 @@ abstract class AbstractTypedMap extends AbstractMap implements TypedMapInterface * @param T $value * * @inheritDoc - * - * @psalm-suppress MoreSpecificImplementedParamType */ public function offsetSet($offset, $value): void { if ($offset === null) { throw new InvalidArgumentException( 'Map elements are key/value pairs; a key must be provided for ' - . 'value ' . var_export($value, true) + . 'value ' . var_export($value, true), ); } if ($this->checkType($this->getKeyType(), $offset) === false) { throw new InvalidArgumentException( 'Key must be of type ' . $this->getKeyType() . '; key is ' - . $this->toolValueToString($offset) + . $this->toolValueToString($offset), ); } if ($this->checkType($this->getValueType(), $value) === false) { throw new InvalidArgumentException( 'Value must be of type ' . $this->getValueType() . '; value is ' - . $this->toolValueToString($value) + . $this->toolValueToString($value), ); } diff --git a/ramsey/collection/src/Map/AssociativeArrayMap.php b/ramsey/collection/src/Map/AssociativeArrayMap.php index 3274dc9de..79a314d96 100644 --- a/ramsey/collection/src/Map/AssociativeArrayMap.php +++ b/ramsey/collection/src/Map/AssociativeArrayMap.php @@ -18,7 +18,7 @@ * `AssociativeArrayMap` represents a standard associative array object. * * @template T - * @template-extends AbstractMap + * @extends AbstractMap */ class AssociativeArrayMap extends AbstractMap { diff --git a/ramsey/collection/src/Map/MapInterface.php b/ramsey/collection/src/Map/MapInterface.php index 04e52a238..6ed0b2967 100644 --- a/ramsey/collection/src/Map/MapInterface.php +++ b/ramsey/collection/src/Map/MapInterface.php @@ -22,7 +22,7 @@ * A map cannot contain duplicate keys; each key can map to at most one value. * * @template T - * @template-extends ArrayInterface + * @extends ArrayInterface */ interface MapInterface extends ArrayInterface { diff --git a/ramsey/collection/src/Map/NamedParameterMap.php b/ramsey/collection/src/Map/NamedParameterMap.php index ecc52f73a..6e391e970 100644 --- a/ramsey/collection/src/Map/NamedParameterMap.php +++ b/ramsey/collection/src/Map/NamedParameterMap.php @@ -21,12 +21,13 @@ use function array_combine; use function array_key_exists; use function is_int; +use function var_export; /** * `NamedParameterMap` represents a mapping of values to a set of named keys * that may optionally be typed * - * @template-extends AbstractMap + * @extends AbstractMap */ class NamedParameterMap extends AbstractMap { @@ -38,7 +39,7 @@ class NamedParameterMap extends AbstractMap * * @var array */ - protected $namedParameters; + protected array $namedParameters; /** * Constructs a new `NamedParameterMap`. @@ -70,14 +71,14 @@ public function offsetSet($offset, $value): void if ($offset === null) { throw new InvalidArgumentException( 'Map elements are key/value pairs; a key must be provided for ' - . 'value ' . var_export($value, true) + . 'value ' . var_export($value, true), ); } if (!array_key_exists($offset, $this->namedParameters)) { throw new InvalidArgumentException( 'Attempting to set value for unconfigured parameter \'' - . $offset . '\'' + . $offset . '\'', ); } @@ -85,7 +86,7 @@ public function offsetSet($offset, $value): void throw new InvalidArgumentException( 'Value for \'' . $offset . '\' must be of type ' . $this->namedParameters[$offset] . '; value is ' - . $this->toolValueToString($value) + . $this->toolValueToString($value), ); } diff --git a/ramsey/collection/src/Map/TypedMap.php b/ramsey/collection/src/Map/TypedMap.php index 752475fee..77ef8d314 100644 --- a/ramsey/collection/src/Map/TypedMap.php +++ b/ramsey/collection/src/Map/TypedMap.php @@ -20,7 +20,7 @@ * A `TypedMap` represents a map of elements where key and value are typed. * * Each element is identified by a key with defined type and a value of defined - * type. The keys of the map must be unique. The values on the map can be= + * type. The keys of the map must be unique. The values on the map can be * repeated but each with its own different key. * * The most common case is to use a string type key, but it's not limited to @@ -80,10 +80,9 @@ * } * ``` * - * @phpstan-ignore-next-line - * @template K as array-key + * @template K of array-key * @template T - * @template-extends AbstractTypedMap + * @extends AbstractTypedMap */ class TypedMap extends AbstractTypedMap { @@ -94,20 +93,16 @@ class TypedMap extends AbstractTypedMap * * A map key's type is immutable once it is set. For this reason, this * property is set private. - * - * @var string data type of the map key. */ - private $keyType; + private string $keyType; /** * The data type of values stored in this collection. * * A map value's type is immutable once it is set. For this reason, this * property is set private. - * - * @var string data type of the map value. */ - private $valueType; + private string $valueType; /** * Constructs a map object of the specified key and value types, @@ -121,6 +116,7 @@ public function __construct(string $keyType, string $valueType, array $data = [] { $this->keyType = $keyType; $this->valueType = $valueType; + parent::__construct($data); } diff --git a/ramsey/collection/src/Map/TypedMapInterface.php b/ramsey/collection/src/Map/TypedMapInterface.php index 51b6a81a2..0308109cc 100644 --- a/ramsey/collection/src/Map/TypedMapInterface.php +++ b/ramsey/collection/src/Map/TypedMapInterface.php @@ -19,7 +19,7 @@ * typed. * * @template T - * @template-extends MapInterface + * @extends MapInterface */ interface TypedMapInterface extends MapInterface { diff --git a/ramsey/collection/src/Queue.php b/ramsey/collection/src/Queue.php index 4af2fdf76..bc8c24e1c 100644 --- a/ramsey/collection/src/Queue.php +++ b/ramsey/collection/src/Queue.php @@ -24,8 +24,8 @@ * the effort required to implement this interface. * * @template T - * @template-extends AbstractArray - * @template-implements QueueInterface + * @extends AbstractArray + * @implements QueueInterface */ class Queue extends AbstractArray implements QueueInterface { @@ -37,17 +37,13 @@ class Queue extends AbstractArray implements QueueInterface * * A queue's type is immutable once it is set. For this reason, this * property is set private. - * - * @var string */ - private $queueType; + private string $queueType; /** * The index of the head of the queue. - * - * @var int */ - protected $index = 0; + protected int $index = 0; /** * Constructs a queue object of the specified type, optionally with the @@ -68,13 +64,15 @@ public function __construct(string $queueType, array $data = []) * Since arbitrary offsets may not be manipulated in a queue, this method * serves only to fulfill the `ArrayAccess` interface requirements. It is * invoked by other operations when adding values to the queue. + * + * @throws InvalidArgumentException if $value is of the wrong type */ public function offsetSet($offset, $value): void { if ($this->checkType($this->getType(), $value) === false) { throw new InvalidArgumentException( 'Value must be of type ' . $this->getType() . '; value is ' - . $this->toolValueToString($value) + . $this->toolValueToString($value), ); } @@ -82,6 +80,8 @@ public function offsetSet($offset, $value): void } /** + * @throws InvalidArgumentException if $value is of the wrong type + * * @inheritDoc */ public function add($element): bool @@ -100,7 +100,7 @@ public function element() if ($element === null) { throw new NoSuchElementException( - 'Can\'t return element from Queue. Queue is empty.' + 'Can\'t return element from Queue. Queue is empty.', ); } diff --git a/ramsey/collection/src/QueueInterface.php b/ramsey/collection/src/QueueInterface.php index 7ebbb5d06..4f91487fa 100644 --- a/ramsey/collection/src/QueueInterface.php +++ b/ramsey/collection/src/QueueInterface.php @@ -15,6 +15,7 @@ namespace Ramsey\Collection; use Ramsey\Collection\Exception\NoSuchElementException; +use RuntimeException; /** * A queue is a collection in which the entities in the collection are kept in @@ -94,7 +95,7 @@ * `poll()` method to indicate that the queue contains no elements. * * @template T - * @template-extends ArrayInterface + * @extends ArrayInterface */ interface QueueInterface extends ArrayInterface { @@ -123,7 +124,7 @@ interface QueueInterface extends ArrayInterface * * @return bool `true` if this queue changed as a result of the call. * - * @throws \RuntimeException if a queue refuses to add a particular element + * @throws RuntimeException if a queue refuses to add a particular element * for any reason other than that it already contains the element. * Implementations should use a more-specific exception that extends * `\RuntimeException`. diff --git a/ramsey/collection/src/Set.php b/ramsey/collection/src/Set.php index ac1c5cbf0..c1d37ccca 100644 --- a/ramsey/collection/src/Set.php +++ b/ramsey/collection/src/Set.php @@ -36,7 +36,7 @@ * ``` * * @template T - * @template-extends AbstractSet + * @extends AbstractSet */ class Set extends AbstractSet { @@ -44,10 +44,8 @@ class Set extends AbstractSet * The type of elements stored in this set * * A set's type is immutable. For this reason, this property is private. - * - * @var string */ - private $setType; + private string $setType; /** * Constructs a set object of the specified type, optionally with the diff --git a/ramsey/collection/src/Tool/TypeTrait.php b/ramsey/collection/src/Tool/TypeTrait.php index 8214e9654..728d44b65 100644 --- a/ramsey/collection/src/Tool/TypeTrait.php +++ b/ramsey/collection/src/Tool/TypeTrait.php @@ -36,6 +36,7 @@ trait TypeTrait * @param string $type The type to check the value against. * @param mixed $value The value to check. */ + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint protected function checkType(string $type, $value): bool { switch ($type) { diff --git a/ramsey/collection/src/Tool/ValueExtractorTrait.php b/ramsey/collection/src/Tool/ValueExtractorTrait.php index f9be1be28..e10824283 100644 --- a/ramsey/collection/src/Tool/ValueExtractorTrait.php +++ b/ramsey/collection/src/Tool/ValueExtractorTrait.php @@ -17,6 +17,7 @@ use Ramsey\Collection\Exception\ValueExtractionException; use function get_class; +use function is_object; use function method_exists; use function property_exists; use function sprintf; @@ -37,6 +38,7 @@ trait ValueExtractorTrait * * @throws ValueExtractionException if the method or property is not defined. */ + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint protected function extractValue($object, string $propertyOrMethod) { if (!is_object($object)) { @@ -52,7 +54,8 @@ protected function extractValue($object, string $propertyOrMethod) } throw new ValueExtractionException( - sprintf('Method or property "%s" not defined in %s', $propertyOrMethod, get_class($object)) + // phpcs:ignore SlevomatCodingStandard.Classes.ModernClassNameReference.ClassNameReferencedViaFunctionCall + sprintf('Method or property "%s" not defined in %s', $propertyOrMethod, get_class($object)), ); } } diff --git a/ramsey/collection/src/Tool/ValueToStringTrait.php b/ramsey/collection/src/Tool/ValueToStringTrait.php index 721ade002..cacefc8b6 100644 --- a/ramsey/collection/src/Tool/ValueToStringTrait.php +++ b/ramsey/collection/src/Tool/ValueToStringTrait.php @@ -21,8 +21,10 @@ use function is_array; use function is_bool; use function is_callable; +use function is_object; use function is_resource; use function is_scalar; +use function var_export; /** * Provides functionality to express a value as string @@ -44,6 +46,7 @@ trait ValueToStringTrait * * @param mixed $value the value to return as a string. */ + // phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint protected function toolValueToString($value): string { // null @@ -89,6 +92,7 @@ protected function toolValueToString($value): string } // unknown type + // phpcs:ignore SlevomatCodingStandard.Classes.ModernClassNameReference.ClassNameReferencedViaFunctionCall return '(' . get_class($value) . ' Object)'; } } diff --git a/ramsey/uuid/LICENSE b/ramsey/uuid/LICENSE index b2aa4b587..5b2acc5b7 100644 --- a/ramsey/uuid/LICENSE +++ b/ramsey/uuid/LICENSE @@ -1,6 +1,4 @@ -MIT License - -Copyright (c) 2012-2020 Ben Ramsey +Copyright (c) 2012-2023 Ben Ramsey Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/ramsey/uuid/src/Builder/BuilderCollection.php b/ramsey/uuid/src/Builder/BuilderCollection.php index b3e5f1dc9..9df3110fd 100644 --- a/ramsey/uuid/src/Builder/BuilderCollection.php +++ b/ramsey/uuid/src/Builder/BuilderCollection.php @@ -15,7 +15,6 @@ namespace Ramsey\Uuid\Builder; use Ramsey\Collection\AbstractCollection; -use Ramsey\Collection\CollectionInterface; use Ramsey\Uuid\Converter\Number\GenericNumberConverter; use Ramsey\Uuid\Converter\Time\GenericTimeConverter; use Ramsey\Uuid\Converter\Time\PhpTimeConverter; @@ -27,8 +26,15 @@ /** * A collection of UuidBuilderInterface objects + * + * @deprecated this class has been deprecated, and will be removed in 5.0.0. The use-case for this class comes from + * a pre-`phpstan/phpstan` and pre-`vimeo/psalm` ecosystem, in which type safety had to be mostly enforced + * at runtime: that is no longer necessary, now that you can safely verify your code to be correct, and use + * more generic types like `iterable` instead. + * + * @extends AbstractCollection */ -class BuilderCollection extends AbstractCollection implements CollectionInterface +class BuilderCollection extends AbstractCollection { public function getType(): string { @@ -52,10 +58,11 @@ public function getIterator(): Traversable * a UuidInterface instance * * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + * @psalm-suppress RedundantConditionGivenDocblockType */ public function unserialize($serialized): void { - /** @var mixed[] $data */ + /** @var array $data */ $data = unserialize($serialized, [ 'allowed_classes' => [ BrickMathCalculator::class, @@ -68,6 +75,11 @@ public function unserialize($serialized): void ], ]); - $this->data = $data; + $this->data = array_filter( + $data, + function ($unserialized): bool { + return $unserialized instanceof UuidBuilderInterface; + } + ); } } diff --git a/ramsey/uuid/src/Builder/DefaultUuidBuilder.php b/ramsey/uuid/src/Builder/DefaultUuidBuilder.php index 2af4e867d..7c4a6f837 100644 --- a/ramsey/uuid/src/Builder/DefaultUuidBuilder.php +++ b/ramsey/uuid/src/Builder/DefaultUuidBuilder.php @@ -21,6 +21,6 @@ * * @psalm-immutable */ -class DefaultUuidBuilder extends Rfc4122UuidBuilder implements UuidBuilderInterface +class DefaultUuidBuilder extends Rfc4122UuidBuilder { } diff --git a/ramsey/uuid/src/Builder/DegradedUuidBuilder.php b/ramsey/uuid/src/Builder/DegradedUuidBuilder.php index 23931e416..20b384212 100644 --- a/ramsey/uuid/src/Builder/DegradedUuidBuilder.php +++ b/ramsey/uuid/src/Builder/DegradedUuidBuilder.php @@ -30,15 +30,7 @@ */ class DegradedUuidBuilder implements UuidBuilderInterface { - /** - * @var NumberConverterInterface - */ - private $numberConverter; - - /** - * @var TimeConverterInterface - */ - private $timeConverter; + private TimeConverterInterface $timeConverter; /** * @param NumberConverterInterface $numberConverter The number converter to @@ -47,10 +39,9 @@ class DegradedUuidBuilder implements UuidBuilderInterface * for converting timestamps extracted from a UUID to Unix timestamps */ public function __construct( - NumberConverterInterface $numberConverter, + private NumberConverterInterface $numberConverter, ?TimeConverterInterface $timeConverter = null ) { - $this->numberConverter = $numberConverter; $this->timeConverter = $timeConverter ?: new DegradedTimeConverter(); } diff --git a/ramsey/uuid/src/Builder/FallbackBuilder.php b/ramsey/uuid/src/Builder/FallbackBuilder.php index cfd4665ac..ba5f31fbe 100644 --- a/ramsey/uuid/src/Builder/FallbackBuilder.php +++ b/ramsey/uuid/src/Builder/FallbackBuilder.php @@ -28,16 +28,10 @@ class FallbackBuilder implements UuidBuilderInterface { /** - * @var BuilderCollection + * @param iterable $builders An array of UUID builders */ - private $builders; - - /** - * @param BuilderCollection $builders An array of UUID builders - */ - public function __construct(BuilderCollection $builders) + public function __construct(private iterable $builders) { - $this->builders = $builders; } /** @@ -55,7 +49,6 @@ public function build(CodecInterface $codec, string $bytes): UuidInterface { $lastBuilderException = null; - /** @var UuidBuilderInterface $builder */ foreach ($this->builders as $builder) { try { return $builder->build($codec, $bytes); diff --git a/ramsey/uuid/src/Codec/GuidStringCodec.php b/ramsey/uuid/src/Codec/GuidStringCodec.php index f11e9d50a..04872e0bc 100644 --- a/ramsey/uuid/src/Codec/GuidStringCodec.php +++ b/ramsey/uuid/src/Codec/GuidStringCodec.php @@ -18,6 +18,7 @@ use Ramsey\Uuid\UuidInterface; use function bin2hex; +use function sprintf; use function substr; /** @@ -29,6 +30,26 @@ */ class GuidStringCodec extends StringCodec { + public function encode(UuidInterface $uuid): string + { + $hex = bin2hex($uuid->getFields()->getBytes()); + + /** @var non-empty-string */ + return sprintf( + '%02s%02s%02s%02s-%02s%02s-%02s%02s-%04s-%012s', + substr($hex, 6, 2), + substr($hex, 4, 2), + substr($hex, 2, 2), + substr($hex, 0, 2), + substr($hex, 10, 2), + substr($hex, 8, 2), + substr($hex, 14, 2), + substr($hex, 12, 2), + substr($hex, 16, 4), + substr($hex, 20), + ); + } + public function decode(string $encodedUuid): UuidInterface { $bytes = $this->getBytes($encodedUuid); diff --git a/ramsey/uuid/src/Codec/OrderedTimeCodec.php b/ramsey/uuid/src/Codec/OrderedTimeCodec.php index fe9f57c76..0798ebc4d 100644 --- a/ramsey/uuid/src/Codec/OrderedTimeCodec.php +++ b/ramsey/uuid/src/Codec/OrderedTimeCodec.php @@ -67,6 +67,7 @@ public function encodeBinary(UuidInterface $uuid): string $bytes = $uuid->getFields()->getBytes(); + /** @phpstan-ignore-next-line PHPStan complains that this is not a non-empty-string. */ return $bytes[6] . $bytes[7] . $bytes[4] . $bytes[5] . $bytes[0] . $bytes[1] . $bytes[2] . $bytes[3] diff --git a/ramsey/uuid/src/Codec/StringCodec.php b/ramsey/uuid/src/Codec/StringCodec.php index fff13bd81..95f38d2e8 100644 --- a/ramsey/uuid/src/Codec/StringCodec.php +++ b/ramsey/uuid/src/Codec/StringCodec.php @@ -17,12 +17,13 @@ use Ramsey\Uuid\Builder\UuidBuilderInterface; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Exception\InvalidUuidStringException; -use Ramsey\Uuid\Rfc4122\FieldsInterface; use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidInterface; +use function bin2hex; use function hex2bin; use function implode; +use function sprintf; use function str_replace; use function strlen; use function substr; @@ -36,36 +37,28 @@ */ class StringCodec implements CodecInterface { - /** - * @var UuidBuilderInterface - */ - private $builder; - /** * Constructs a StringCodec * * @param UuidBuilderInterface $builder The builder to use when encoding UUIDs */ - public function __construct(UuidBuilderInterface $builder) + public function __construct(private UuidBuilderInterface $builder) { - $this->builder = $builder; } public function encode(UuidInterface $uuid): string { - /** @var FieldsInterface $fields */ - $fields = $uuid->getFields(); - - return $fields->getTimeLow()->toString() - . '-' - . $fields->getTimeMid()->toString() - . '-' - . $fields->getTimeHiAndVersion()->toString() - . '-' - . $fields->getClockSeqHiAndReserved()->toString() - . $fields->getClockSeqLow()->toString() - . '-' - . $fields->getNode()->toString(); + $hex = bin2hex($uuid->getFields()->getBytes()); + + /** @var non-empty-string */ + return sprintf( + '%08s-%04s-%04s-%04s-%012s', + substr($hex, 0, 8), + substr($hex, 8, 4), + substr($hex, 12, 4), + substr($hex, 16, 4), + substr($hex, 20), + ); } /** @@ -75,6 +68,7 @@ public function encode(UuidInterface $uuid): string */ public function encodeBinary(UuidInterface $uuid): string { + /** @phpstan-ignore-next-line PHPStan complains that this is not a non-empty-string. */ return $uuid->getFields()->getBytes(); } diff --git a/ramsey/uuid/src/Codec/TimestampFirstCombCodec.php b/ramsey/uuid/src/Codec/TimestampFirstCombCodec.php index 06ce38fbb..0e0042d0a 100644 --- a/ramsey/uuid/src/Codec/TimestampFirstCombCodec.php +++ b/ramsey/uuid/src/Codec/TimestampFirstCombCodec.php @@ -76,6 +76,7 @@ public function encode(UuidInterface $uuid): string */ public function encodeBinary(UuidInterface $uuid): string { + /** @phpstan-ignore-next-line PHPStan complains that this is not a non-empty-string. */ return $this->swapBytes($uuid->getFields()->getBytes()); } diff --git a/ramsey/uuid/src/Converter/Number/BigNumberConverter.php b/ramsey/uuid/src/Converter/Number/BigNumberConverter.php index fef63fd00..99b88b3bf 100644 --- a/ramsey/uuid/src/Converter/Number/BigNumberConverter.php +++ b/ramsey/uuid/src/Converter/Number/BigNumberConverter.php @@ -27,10 +27,7 @@ */ class BigNumberConverter implements NumberConverterInterface { - /** - * @var NumberConverterInterface - */ - private $converter; + private NumberConverterInterface $converter; public function __construct() { diff --git a/ramsey/uuid/src/Converter/Number/GenericNumberConverter.php b/ramsey/uuid/src/Converter/Number/GenericNumberConverter.php index c85bc3a71..043c3c43d 100644 --- a/ramsey/uuid/src/Converter/Number/GenericNumberConverter.php +++ b/ramsey/uuid/src/Converter/Number/GenericNumberConverter.php @@ -19,21 +19,15 @@ use Ramsey\Uuid\Type\Integer as IntegerObject; /** - * GenericNumberConverter uses the provided calculate to convert decimal + * GenericNumberConverter uses the provided calculator to convert decimal * numbers to and from hexadecimal values * * @psalm-immutable */ class GenericNumberConverter implements NumberConverterInterface { - /** - * @var CalculatorInterface - */ - private $calculator; - - public function __construct(CalculatorInterface $calculator) + public function __construct(private CalculatorInterface $calculator) { - $this->calculator = $calculator; } /** @@ -57,6 +51,7 @@ public function fromHex(string $hex): string */ public function toHex(string $number): string { + /** @phpstan-ignore-next-line PHPStan complains that this is not a non-empty-string. */ return $this->calculator->toBase(new IntegerObject($number), 16); } } diff --git a/ramsey/uuid/src/Converter/Time/BigNumberTimeConverter.php b/ramsey/uuid/src/Converter/Time/BigNumberTimeConverter.php index 7390dad83..b6bca9ee2 100644 --- a/ramsey/uuid/src/Converter/Time/BigNumberTimeConverter.php +++ b/ramsey/uuid/src/Converter/Time/BigNumberTimeConverter.php @@ -29,10 +29,7 @@ */ class BigNumberTimeConverter implements TimeConverterInterface { - /** - * @var TimeConverterInterface - */ - private $converter; + private TimeConverterInterface $converter; public function __construct() { diff --git a/ramsey/uuid/src/Converter/Time/GenericTimeConverter.php b/ramsey/uuid/src/Converter/Time/GenericTimeConverter.php index a8aa64b73..f6b60abbe 100644 --- a/ramsey/uuid/src/Converter/Time/GenericTimeConverter.php +++ b/ramsey/uuid/src/Converter/Time/GenericTimeConverter.php @@ -50,14 +50,8 @@ class GenericTimeConverter implements TimeConverterInterface */ private const MICROSECOND_INTERVALS = '10'; - /** - * @var CalculatorInterface - */ - private $calculator; - - public function __construct(CalculatorInterface $calculator) + public function __construct(private CalculatorInterface $calculator) { - $this->calculator = $calculator; } public function calculateTime(string $seconds, string $microseconds): Hexadecimal diff --git a/ramsey/uuid/src/Converter/Time/PhpTimeConverter.php b/ramsey/uuid/src/Converter/Time/PhpTimeConverter.php index 52963fed6..66009f14d 100644 --- a/ramsey/uuid/src/Converter/Time/PhpTimeConverter.php +++ b/ramsey/uuid/src/Converter/Time/PhpTimeConverter.php @@ -58,20 +58,9 @@ class PhpTimeConverter implements TimeConverterInterface */ private const MICROSECOND_INTERVALS = 10; - /** - * @var CalculatorInterface - */ - private $calculator; - - /** - * @var TimeConverterInterface - */ - private $fallbackConverter; - - /** - * @var int - */ - private $phpPrecision; + private int $phpPrecision; + private CalculatorInterface $calculator; + private TimeConverterInterface $fallbackConverter; public function __construct( ?CalculatorInterface $calculator = null, @@ -111,7 +100,7 @@ public function calculateTime(string $seconds, string $microseconds): Hexadecima ); } - return new Hexadecimal(str_pad(dechex((int) $uuidTime), 16, '0', STR_PAD_LEFT)); + return new Hexadecimal(str_pad(dechex($uuidTime), 16, '0', STR_PAD_LEFT)); } public function convertTime(Hexadecimal $uuidTimestamp): Time @@ -132,11 +121,11 @@ public function convertTime(Hexadecimal $uuidTimestamp): Time } /** - * @param int|float $time The time to split into seconds and microseconds + * @param float|int $time The time to split into seconds and microseconds * * @return string[] */ - private function splitTime($time): array + private function splitTime(float | int $time): array { $split = explode('.', (string) $time, 2); diff --git a/ramsey/uuid/src/Converter/Time/UnixTimeConverter.php b/ramsey/uuid/src/Converter/Time/UnixTimeConverter.php new file mode 100644 index 000000000..4d6d0a8a7 --- /dev/null +++ b/ramsey/uuid/src/Converter/Time/UnixTimeConverter.php @@ -0,0 +1,90 @@ + + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Converter\Time; + +use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Math\CalculatorInterface; +use Ramsey\Uuid\Math\RoundingMode; +use Ramsey\Uuid\Type\Hexadecimal; +use Ramsey\Uuid\Type\Integer as IntegerObject; +use Ramsey\Uuid\Type\Time; + +use function explode; +use function str_pad; + +use const STR_PAD_LEFT; + +/** + * UnixTimeConverter converts Unix Epoch timestamps to/from hexadecimal values + * consisting of milliseconds elapsed since the Unix Epoch + * + * @psalm-immutable + */ +class UnixTimeConverter implements TimeConverterInterface +{ + private const MILLISECONDS = 1000; + + public function __construct(private CalculatorInterface $calculator) + { + } + + public function calculateTime(string $seconds, string $microseconds): Hexadecimal + { + $timestamp = new Time($seconds, $microseconds); + + // Convert the seconds into milliseconds. + $sec = $this->calculator->multiply( + $timestamp->getSeconds(), + new IntegerObject(self::MILLISECONDS), + ); + + // Convert the microseconds into milliseconds; the scale is zero because + // we need to discard the fractional part. + $usec = $this->calculator->divide( + RoundingMode::DOWN, // Always round down to stay in the previous millisecond. + 0, + $timestamp->getMicroseconds(), + new IntegerObject(self::MILLISECONDS), + ); + + /** @var IntegerObject $unixTime */ + $unixTime = $this->calculator->add($sec, $usec); + + $unixTimeHex = str_pad( + $this->calculator->toHexadecimal($unixTime)->toString(), + 12, + '0', + STR_PAD_LEFT + ); + + return new Hexadecimal($unixTimeHex); + } + + public function convertTime(Hexadecimal $uuidTimestamp): Time + { + $milliseconds = $this->calculator->toInteger($uuidTimestamp); + + $unixTimestamp = $this->calculator->divide( + RoundingMode::HALF_UP, + 6, + $milliseconds, + new IntegerObject(self::MILLISECONDS) + ); + + $split = explode('.', (string) $unixTimestamp, 2); + + return new Time($split[0], $split[1] ?? '0'); + } +} diff --git a/ramsey/uuid/src/DeprecatedUuidInterface.php b/ramsey/uuid/src/DeprecatedUuidInterface.php index ed6d9dec8..ac01a79cf 100644 --- a/ramsey/uuid/src/DeprecatedUuidInterface.php +++ b/ramsey/uuid/src/DeprecatedUuidInterface.php @@ -18,8 +18,7 @@ use Ramsey\Uuid\Converter\NumberConverterInterface; /** - * This interface encapsulates deprecated methods for ramsey/uuid; this - * interface and its methods will be removed in ramsey/uuid 5.0.0. + * This interface encapsulates deprecated methods for ramsey/uuid * * @psalm-immutable */ @@ -123,12 +122,6 @@ public function getTimeMidHex(): string; */ public function getTimestampHex(): string; - /** - * @deprecated In ramsey/uuid version 5.0.0, this will be removed from this - * interface. It has moved to {@see \Ramsey\Uuid\Rfc4122\UuidInterface::getUrn()}. - */ - public function getUrn(): string; - /** * @deprecated Use {@see UuidInterface::getFields()} to get a * {@see FieldsInterface} instance. If it is a diff --git a/ramsey/uuid/src/DeprecatedUuidMethodsTrait.php b/ramsey/uuid/src/DeprecatedUuidMethodsTrait.php index 342829523..d3fbb0ccb 100644 --- a/ramsey/uuid/src/DeprecatedUuidMethodsTrait.php +++ b/ramsey/uuid/src/DeprecatedUuidMethodsTrait.php @@ -17,10 +17,8 @@ use DateTimeImmutable; use DateTimeInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; -use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Exception\DateTimeException; use Ramsey\Uuid\Exception\UnsupportedOperationException; -use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; use Throwable; use function str_pad; @@ -32,29 +30,17 @@ * This trait encapsulates deprecated methods for ramsey/uuid; this trait and * its methods will be removed in ramsey/uuid 5.0.0. * + * @deprecated This trait and its methods will be removed in ramsey/uuid 5.0.0. + * * @psalm-immutable */ trait DeprecatedUuidMethodsTrait { - /** - * @var Rfc4122FieldsInterface - */ - protected $fields; - - /** - * @var NumberConverterInterface - */ - protected $numberConverter; - - /** - * @var TimeConverterInterface - */ - protected $timeConverter; - /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getClockSeqHiAndReserved()} + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getClockSeqHiAndReserved()} * and use the arbitrary-precision math library of your choice to * convert it to a string integer. */ @@ -65,8 +51,9 @@ public function getClockSeqHiAndReserved(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getClockSeqHiAndReserved()}. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getClockSeqHiAndReserved()}. */ public function getClockSeqHiAndReservedHex(): string { @@ -75,8 +62,9 @@ public function getClockSeqHiAndReservedHex(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getClockSeqLow()} + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getClockSeqLow()} * and use the arbitrary-precision math library of your choice to * convert it to a string integer. */ @@ -87,8 +75,9 @@ public function getClockSeqLow(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getClockSeqLow()}. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getClockSeqLow()}. */ public function getClockSeqLowHex(): string { @@ -97,8 +86,9 @@ public function getClockSeqLowHex(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getClockSeq()} + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getClockSeq()} * and use the arbitrary-precision math library of your choice to * convert it to a string integer. */ @@ -109,8 +99,9 @@ public function getClockSequence(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getClockSeq()}. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getClockSeq()}. */ public function getClockSequenceHex(): string { @@ -157,7 +148,7 @@ public function getDateTime(): DateTimeInterface /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. * * @return string[] */ @@ -219,10 +210,11 @@ public function getMostSignificantBitsHex(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getNode()} - * and use the arbitrary-precision math library of your choice to - * convert it to a string integer. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getNode()} and use the + * arbitrary-precision math library of your choice to convert it to a + * string integer. */ public function getNode(): string { @@ -231,8 +223,9 @@ public function getNode(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getNode()}. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getNode()}. */ public function getNodeHex(): string { @@ -241,8 +234,9 @@ public function getNodeHex(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getTimeHiAndVersion()} + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimeHiAndVersion()} * and use the arbitrary-precision math library of your choice to * convert it to a string integer. */ @@ -253,8 +247,9 @@ public function getTimeHiAndVersion(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getTimeHiAndVersion()}. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimeHiAndVersion()}. */ public function getTimeHiAndVersionHex(): string { @@ -263,10 +258,11 @@ public function getTimeHiAndVersionHex(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getTimeLow()} - * and use the arbitrary-precision math library of your choice to - * convert it to a string integer. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimeLow()} and use the + * arbitrary-precision math library of your choice to convert it to a + * string integer. */ public function getTimeLow(): string { @@ -275,8 +271,9 @@ public function getTimeLow(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getTimeLow()}. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimeLow()}. */ public function getTimeLowHex(): string { @@ -285,10 +282,11 @@ public function getTimeLowHex(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getTimeMid()} - * and use the arbitrary-precision math library of your choice to - * convert it to a string integer. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimeMid()} and use the + * arbitrary-precision math library of your choice to convert it to a + * string integer. */ public function getTimeMid(): string { @@ -297,8 +295,9 @@ public function getTimeMid(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getTimeMid()}. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimeMid()}. */ public function getTimeMidHex(): string { @@ -307,10 +306,11 @@ public function getTimeMidHex(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getTimestamp()} - * and use the arbitrary-precision math library of your choice to - * convert it to a string integer. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimestamp()} and use + * the arbitrary-precision math library of your choice to convert it to + * a string integer. */ public function getTimestamp(): string { @@ -323,8 +323,9 @@ public function getTimestamp(): string /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} - * instance, you may call {@see Rfc4122FieldsInterface::getTimestamp()}. + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimestamp()}. */ public function getTimestampHex(): string { @@ -335,20 +336,9 @@ public function getTimestampHex(): string return $this->fields->getTimestamp()->toString(); } - /** - * @deprecated This has moved to {@see Rfc4122FieldsInterface::getUrn()} and - * is available on {@see \Ramsey\Uuid\Rfc4122\UuidV1}, - * {@see \Ramsey\Uuid\Rfc4122\UuidV3}, {@see \Ramsey\Uuid\Rfc4122\UuidV4}, - * and {@see \Ramsey\Uuid\Rfc4122\UuidV5}. - */ - public function getUrn(): string - { - return 'urn:uuid:' . $this->toString(); - } - /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getVariant()}. */ @@ -359,7 +349,7 @@ public function getVariant(): ?int /** * @deprecated Use {@see UuidInterface::getFields()} to get a - * {@see FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. If it is a * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getVersion()}. */ diff --git a/ramsey/uuid/src/Exception/BuilderNotFoundException.php b/ramsey/uuid/src/Exception/BuilderNotFoundException.php index c0854d256..220ffedb8 100644 --- a/ramsey/uuid/src/Exception/BuilderNotFoundException.php +++ b/ramsey/uuid/src/Exception/BuilderNotFoundException.php @@ -19,6 +19,6 @@ /** * Thrown to indicate that no suitable builder could be found */ -class BuilderNotFoundException extends PhpRuntimeException +class BuilderNotFoundException extends PhpRuntimeException implements UuidExceptionInterface { } diff --git a/ramsey/uuid/src/Exception/DateTimeException.php b/ramsey/uuid/src/Exception/DateTimeException.php index dbc484045..5f0e658bf 100644 --- a/ramsey/uuid/src/Exception/DateTimeException.php +++ b/ramsey/uuid/src/Exception/DateTimeException.php @@ -19,6 +19,6 @@ /** * Thrown to indicate that the PHP DateTime extension encountered an exception/error */ -class DateTimeException extends PhpRuntimeException +class DateTimeException extends PhpRuntimeException implements UuidExceptionInterface { } diff --git a/ramsey/uuid/src/Exception/DceSecurityException.php b/ramsey/uuid/src/Exception/DceSecurityException.php index a65f80cd4..e6d800136 100644 --- a/ramsey/uuid/src/Exception/DceSecurityException.php +++ b/ramsey/uuid/src/Exception/DceSecurityException.php @@ -20,6 +20,6 @@ * Thrown to indicate an exception occurred while dealing with DCE Security * (version 2) UUIDs */ -class DceSecurityException extends PhpRuntimeException +class DceSecurityException extends PhpRuntimeException implements UuidExceptionInterface { } diff --git a/ramsey/uuid/src/Exception/InvalidArgumentException.php b/ramsey/uuid/src/Exception/InvalidArgumentException.php index 08bbb8029..2a1fa3ac2 100644 --- a/ramsey/uuid/src/Exception/InvalidArgumentException.php +++ b/ramsey/uuid/src/Exception/InvalidArgumentException.php @@ -19,6 +19,6 @@ /** * Thrown to indicate that the argument received is not valid */ -class InvalidArgumentException extends PhpInvalidArgumentException +class InvalidArgumentException extends PhpInvalidArgumentException implements UuidExceptionInterface { } diff --git a/ramsey/uuid/src/Exception/InvalidBytesException.php b/ramsey/uuid/src/Exception/InvalidBytesException.php index b20be3de0..1c94f6596 100644 --- a/ramsey/uuid/src/Exception/InvalidBytesException.php +++ b/ramsey/uuid/src/Exception/InvalidBytesException.php @@ -19,6 +19,6 @@ /** * Thrown to indicate that the bytes being operated on are invalid in some way */ -class InvalidBytesException extends PhpRuntimeException +class InvalidBytesException extends PhpRuntimeException implements UuidExceptionInterface { } diff --git a/ramsey/uuid/src/Exception/InvalidUuidStringException.php b/ramsey/uuid/src/Exception/InvalidUuidStringException.php index 24f42c643..6d9758166 100644 --- a/ramsey/uuid/src/Exception/InvalidUuidStringException.php +++ b/ramsey/uuid/src/Exception/InvalidUuidStringException.php @@ -20,6 +20,6 @@ * The InvalidArgumentException that this extends is the ramsey/uuid version * of this exception. It exists in the same namespace as this class. */ -class InvalidUuidStringException extends InvalidArgumentException +class InvalidUuidStringException extends InvalidArgumentException implements UuidExceptionInterface { } diff --git a/ramsey/uuid/src/Exception/NameException.php b/ramsey/uuid/src/Exception/NameException.php index 54d32ec38..fd96a1faf 100644 --- a/ramsey/uuid/src/Exception/NameException.php +++ b/ramsey/uuid/src/Exception/NameException.php @@ -20,6 +20,6 @@ * Thrown to indicate that an error occurred while attempting to hash a * namespace and name */ -class NameException extends PhpRuntimeException +class NameException extends PhpRuntimeException implements UuidExceptionInterface { } diff --git a/ramsey/uuid/src/Exception/NodeException.php b/ramsey/uuid/src/Exception/NodeException.php index 21b6d1804..0dbdd50b4 100644 --- a/ramsey/uuid/src/Exception/NodeException.php +++ b/ramsey/uuid/src/Exception/NodeException.php @@ -19,6 +19,6 @@ /** * Thrown to indicate that attempting to fetch or create a node ID encountered an error */ -class NodeException extends PhpRuntimeException +class NodeException extends PhpRuntimeException implements UuidExceptionInterface { } diff --git a/ramsey/uuid/src/Exception/RandomSourceException.php b/ramsey/uuid/src/Exception/RandomSourceException.php index 0c3e4f523..a44dd34a2 100644 --- a/ramsey/uuid/src/Exception/RandomSourceException.php +++ b/ramsey/uuid/src/Exception/RandomSourceException.php @@ -22,6 +22,6 @@ * This exception is used mostly to indicate that random_bytes() or random_int() * threw an exception. However, it may be used for other sources of random data. */ -class RandomSourceException extends PhpRuntimeException +class RandomSourceException extends PhpRuntimeException implements UuidExceptionInterface { } diff --git a/ramsey/uuid/src/Exception/TimeSourceException.php b/ramsey/uuid/src/Exception/TimeSourceException.php index accd37f87..fc9cf36b6 100644 --- a/ramsey/uuid/src/Exception/TimeSourceException.php +++ b/ramsey/uuid/src/Exception/TimeSourceException.php @@ -19,6 +19,6 @@ /** * Thrown to indicate that the source of time encountered an error */ -class TimeSourceException extends PhpRuntimeException +class TimeSourceException extends PhpRuntimeException implements UuidExceptionInterface { } diff --git a/ramsey/uuid/src/Exception/UnableToBuildUuidException.php b/ramsey/uuid/src/Exception/UnableToBuildUuidException.php index da9649035..5ba26d8dc 100644 --- a/ramsey/uuid/src/Exception/UnableToBuildUuidException.php +++ b/ramsey/uuid/src/Exception/UnableToBuildUuidException.php @@ -19,6 +19,6 @@ /** * Thrown to indicate a builder is unable to build a UUID */ -class UnableToBuildUuidException extends PhpRuntimeException +class UnableToBuildUuidException extends PhpRuntimeException implements UuidExceptionInterface { } diff --git a/ramsey/uuid/src/Exception/UnsupportedOperationException.php b/ramsey/uuid/src/Exception/UnsupportedOperationException.php index e6391b03d..e1b3eda17 100644 --- a/ramsey/uuid/src/Exception/UnsupportedOperationException.php +++ b/ramsey/uuid/src/Exception/UnsupportedOperationException.php @@ -19,6 +19,6 @@ /** * Thrown to indicate that the requested operation is not supported */ -class UnsupportedOperationException extends PhpLogicException +class UnsupportedOperationException extends PhpLogicException implements UuidExceptionInterface { } diff --git a/ramsey/uuid/src/Exception/UuidExceptionInterface.php b/ramsey/uuid/src/Exception/UuidExceptionInterface.php new file mode 100644 index 000000000..a2f1c103b --- /dev/null +++ b/ramsey/uuid/src/Exception/UuidExceptionInterface.php @@ -0,0 +1,21 @@ + + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Exception; + +use Throwable; + +interface UuidExceptionInterface extends Throwable +{ +} diff --git a/ramsey/uuid/src/FeatureSet.php b/ramsey/uuid/src/FeatureSet.php index 4531a6d7f..b9af869f9 100644 --- a/ramsey/uuid/src/FeatureSet.php +++ b/ramsey/uuid/src/FeatureSet.php @@ -14,7 +14,6 @@ namespace Ramsey\Uuid; -use Ramsey\Uuid\Builder\BuilderCollection; use Ramsey\Uuid\Builder\FallbackBuilder; use Ramsey\Uuid\Builder\UuidBuilderInterface; use Ramsey\Uuid\Codec\CodecInterface; @@ -36,6 +35,7 @@ use Ramsey\Uuid\Generator\RandomGeneratorInterface; use Ramsey\Uuid\Generator\TimeGeneratorFactory; use Ramsey\Uuid\Generator\TimeGeneratorInterface; +use Ramsey\Uuid\Generator\UnixTimeGenerator; use Ramsey\Uuid\Guid\GuidBuilder; use Ramsey\Uuid\Math\BrickMathCalculator; use Ramsey\Uuid\Math\CalculatorInterface; @@ -43,7 +43,6 @@ use Ramsey\Uuid\Provider\Dce\SystemDceSecurityProvider; use Ramsey\Uuid\Provider\DceSecurityProviderInterface; use Ramsey\Uuid\Provider\Node\FallbackNodeProvider; -use Ramsey\Uuid\Provider\Node\NodeProviderCollection; use Ramsey\Uuid\Provider\Node\RandomNodeProvider; use Ramsey\Uuid\Provider\Node\SystemNodeProvider; use Ramsey\Uuid\Provider\NodeProviderInterface; @@ -63,92 +62,25 @@ */ class FeatureSet { - /** - * @var bool - */ - private $disableBigNumber = false; - - /** - * @var bool - */ - private $disable64Bit = false; - - /** - * @var bool - */ - private $ignoreSystemNode = false; - - /** - * @var bool - */ - private $enablePecl = false; - - /** - * @var UuidBuilderInterface - */ - private $builder; - - /** - * @var CodecInterface - */ - private $codec; - - /** - * @var DceSecurityGeneratorInterface - */ - private $dceSecurityGenerator; - - /** - * @var NameGeneratorInterface - */ - private $nameGenerator; - - /** - * @var NodeProviderInterface - */ - private $nodeProvider; - - /** - * @var NumberConverterInterface - */ - private $numberConverter; - - /** - * @var TimeConverterInterface - */ - private $timeConverter; - - /** - * @var RandomGeneratorInterface - */ - private $randomGenerator; - - /** - * @var TimeGeneratorInterface - */ - private $timeGenerator; - - /** - * @var TimeProviderInterface - */ - private $timeProvider; - - /** - * @var ValidatorInterface - */ - private $validator; - - /** - * @var CalculatorInterface - */ - private $calculator; + private ?TimeProviderInterface $timeProvider = null; + private CalculatorInterface $calculator; + private CodecInterface $codec; + private DceSecurityGeneratorInterface $dceSecurityGenerator; + private NameGeneratorInterface $nameGenerator; + private NodeProviderInterface $nodeProvider; + private NumberConverterInterface $numberConverter; + private RandomGeneratorInterface $randomGenerator; + private TimeConverterInterface $timeConverter; + private TimeGeneratorInterface $timeGenerator; + private TimeGeneratorInterface $unixTimeGenerator; + private UuidBuilderInterface $builder; + private ValidatorInterface $validator; /** * @param bool $useGuids True build UUIDs using the GuidStringCodec * @param bool $force32Bit True to force the use of 32-bit functionality * (primarily for testing purposes) - * @param bool $forceNoBigNumber True to disable the use of moontoast/math - * (primarily for testing purposes) + * @param bool $forceNoBigNumber (obsolete) * @param bool $ignoreSystemNode True to disable attempts to check for the * system node ID (primarily for testing purposes) * @param bool $enablePecl True to enable the use of the PeclUuidTimeGenerator @@ -156,25 +88,23 @@ class FeatureSet */ public function __construct( bool $useGuids = false, - bool $force32Bit = false, + private bool $force32Bit = false, bool $forceNoBigNumber = false, - bool $ignoreSystemNode = false, - bool $enablePecl = false + private bool $ignoreSystemNode = false, + private bool $enablePecl = false ) { - $this->disableBigNumber = $forceNoBigNumber; - $this->disable64Bit = $force32Bit; - $this->ignoreSystemNode = $ignoreSystemNode; - $this->enablePecl = $enablePecl; - + $this->randomGenerator = $this->buildRandomGenerator(); $this->setCalculator(new BrickMathCalculator()); $this->builder = $this->buildUuidBuilder($useGuids); $this->codec = $this->buildCodec($useGuids); $this->nodeProvider = $this->buildNodeProvider(); $this->nameGenerator = $this->buildNameGenerator(); - $this->randomGenerator = $this->buildRandomGenerator(); $this->setTimeProvider(new SystemTimeProvider()); $this->setDceSecurityProvider(new SystemDceSecurityProvider()); $this->validator = new GenericValidator(); + + assert($this->timeProvider !== null); + $this->unixTimeGenerator = $this->buildUnixTimeGenerator(); } /** @@ -257,6 +187,14 @@ public function getTimeGenerator(): TimeGeneratorInterface return $this->timeGenerator; } + /** + * Returns the Unix Epoch time generator configured for this environment + */ + public function getUnixTimeGenerator(): TimeGeneratorInterface + { + return $this->unixTimeGenerator; + } + /** * Returns the validator configured for this environment */ @@ -274,6 +212,7 @@ public function setCalculator(CalculatorInterface $calculator): void $this->numberConverter = $this->buildNumberConverter($calculator); $this->timeConverter = $this->buildTimeConverter($calculator); + /** @psalm-suppress RedundantPropertyInitializationCheck */ if (isset($this->timeProvider)) { $this->timeGenerator = $this->buildTimeGenerator($this->timeProvider); } @@ -293,7 +232,10 @@ public function setDceSecurityProvider(DceSecurityProviderInterface $dceSecurity public function setNodeProvider(NodeProviderInterface $nodeProvider): void { $this->nodeProvider = $nodeProvider; - $this->timeGenerator = $this->buildTimeGenerator($this->timeProvider); + + if (isset($this->timeProvider)) { + $this->timeGenerator = $this->buildTimeGenerator($this->timeProvider); + } } /** @@ -349,10 +291,10 @@ private function buildNodeProvider(): NodeProviderInterface return new RandomNodeProvider(); } - return new FallbackNodeProvider(new NodeProviderCollection([ + return new FallbackNodeProvider([ new SystemNodeProvider(), new RandomNodeProvider(), - ])); + ]); } /** @@ -394,6 +336,14 @@ private function buildTimeGenerator(TimeProviderInterface $timeProvider): TimeGe ))->getGenerator(); } + /** + * Returns a Unix Epoch time generator configured for this environment + */ + private function buildUnixTimeGenerator(): TimeGeneratorInterface + { + return new UnixTimeGenerator($this->randomGenerator); + } + /** * Returns a name generator configured for this environment */ @@ -431,11 +381,10 @@ private function buildUuidBuilder(bool $useGuids = false): UuidBuilderInterface return new GuidBuilder($this->numberConverter, $this->timeConverter); } - /** @psalm-suppress ImpureArgument */ - return new FallbackBuilder(new BuilderCollection([ + return new FallbackBuilder([ new Rfc4122UuidBuilder($this->numberConverter, $this->timeConverter), new NonstandardUuidBuilder($this->numberConverter, $this->timeConverter), - ])); + ]); } /** @@ -443,6 +392,6 @@ private function buildUuidBuilder(bool $useGuids = false): UuidBuilderInterface */ private function is64BitSystem(): bool { - return PHP_INT_SIZE === 8 && !$this->disable64Bit; + return PHP_INT_SIZE === 8 && !$this->force32Bit; } } diff --git a/ramsey/uuid/src/Fields/SerializableFieldsTrait.php b/ramsey/uuid/src/Fields/SerializableFieldsTrait.php index 4ae90be2c..3d36b6f12 100644 --- a/ramsey/uuid/src/Fields/SerializableFieldsTrait.php +++ b/ramsey/uuid/src/Fields/SerializableFieldsTrait.php @@ -14,7 +14,10 @@ namespace Ramsey\Uuid\Fields; +use ValueError; + use function base64_decode; +use function sprintf; use function strlen; /** @@ -42,19 +45,43 @@ public function serialize(): string return $this->getBytes(); } + /** + * @return array{bytes: string} + */ + public function __serialize(): array + { + return ['bytes' => $this->getBytes()]; + } + /** * Constructs the object from a serialized string representation * - * @param string $serialized The serialized string representation of the object + * @param string $data The serialized string representation of the object * - * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + * @psalm-suppress UnusedMethodCall */ - public function unserialize($serialized): void + public function unserialize(string $data): void { - if (strlen($serialized) === 16) { - $this->__construct($serialized); + if (strlen($data) === 16) { + $this->__construct($data); } else { - $this->__construct(base64_decode($serialized)); + $this->__construct(base64_decode($data)); + } + } + + /** + * @param array{bytes?: string} $data + * + * @psalm-suppress UnusedMethodCall + */ + public function __unserialize(array $data): void + { + // @codeCoverageIgnoreStart + if (!isset($data['bytes'])) { + throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__)); } + // @codeCoverageIgnoreEnd + + $this->unserialize($data['bytes']); } } diff --git a/ramsey/uuid/src/Generator/CombGenerator.php b/ramsey/uuid/src/Generator/CombGenerator.php index 88ae6ea23..0e8870608 100644 --- a/ramsey/uuid/src/Generator/CombGenerator.php +++ b/ramsey/uuid/src/Generator/CombGenerator.php @@ -61,22 +61,10 @@ class CombGenerator implements RandomGeneratorInterface { public const TIMESTAMP_BYTES = 6; - /** - * @var RandomGeneratorInterface - */ - private $randomGenerator; - - /** - * @var NumberConverterInterface - */ - private $converter; - public function __construct( - RandomGeneratorInterface $generator, - NumberConverterInterface $numberConverter + private RandomGeneratorInterface $generator, + private NumberConverterInterface $numberConverter ) { - $this->converter = $numberConverter; - $this->randomGenerator = $generator; } /** @@ -87,7 +75,7 @@ public function __construct( */ public function generate(int $length): string { - if ($length < self::TIMESTAMP_BYTES || $length < 0) { + if ($length < self::TIMESTAMP_BYTES) { throw new InvalidArgumentException( 'Length must be a positive integer greater than or equal to ' . self::TIMESTAMP_BYTES ); @@ -95,11 +83,11 @@ public function generate(int $length): string $hash = ''; if (self::TIMESTAMP_BYTES > 0 && $length > self::TIMESTAMP_BYTES) { - $hash = $this->randomGenerator->generate($length - self::TIMESTAMP_BYTES); + $hash = $this->generator->generate($length - self::TIMESTAMP_BYTES); } $lsbTime = str_pad( - $this->converter->toHex($this->timestamp()), + $this->numberConverter->toHex($this->timestamp()), self::TIMESTAMP_BYTES * 2, '0', STR_PAD_LEFT @@ -107,7 +95,7 @@ public function generate(int $length): string return (string) hex2bin( str_pad( - bin2hex((string) $hash), + bin2hex($hash), $length - self::TIMESTAMP_BYTES, '0' ) diff --git a/ramsey/uuid/src/Generator/DceSecurityGenerator.php b/ramsey/uuid/src/Generator/DceSecurityGenerator.php index a3f07f2ff..37ba78131 100644 --- a/ramsey/uuid/src/Generator/DceSecurityGenerator.php +++ b/ramsey/uuid/src/Generator/DceSecurityGenerator.php @@ -52,29 +52,11 @@ class DceSecurityGenerator implements DceSecurityGeneratorInterface */ private const CLOCK_SEQ_LOW = 0; - /** - * @var NumberConverterInterface - */ - private $numberConverter; - - /** - * @var TimeGeneratorInterface - */ - private $timeGenerator; - - /** - * @var DceSecurityProviderInterface - */ - private $dceSecurityProvider; - public function __construct( - NumberConverterInterface $numberConverter, - TimeGeneratorInterface $timeGenerator, - DceSecurityProviderInterface $dceSecurityProvider + private NumberConverterInterface $numberConverter, + private TimeGeneratorInterface $timeGenerator, + private DceSecurityProviderInterface $dceSecurityProvider ) { - $this->numberConverter = $numberConverter; - $this->timeGenerator = $timeGenerator; - $this->dceSecurityProvider = $dceSecurityProvider; } public function generate( @@ -138,7 +120,7 @@ public function generate( } $domainByte = pack('n', $localDomain)[1]; - $identifierBytes = hex2bin(str_pad($identifierHex, 8, '0', STR_PAD_LEFT)); + $identifierBytes = (string) hex2bin(str_pad($identifierHex, 8, '0', STR_PAD_LEFT)); if ($node instanceof Hexadecimal) { $node = $node->toString(); @@ -149,13 +131,11 @@ public function generate( $clockSeq = $clockSeq << 8; } - /** @var string $bytes */ $bytes = $this->timeGenerator->generate($node, $clockSeq); // Replace bytes in the time-based UUID with DCE Security values. $bytes = substr_replace($bytes, $identifierBytes, 0, 4); - $bytes = substr_replace($bytes, $domainByte, 9, 1); - return $bytes; + return substr_replace($bytes, $domainByte, 9, 1); } } diff --git a/ramsey/uuid/src/Generator/DefaultNameGenerator.php b/ramsey/uuid/src/Generator/DefaultNameGenerator.php index 270e8fbe1..7303e9fa2 100644 --- a/ramsey/uuid/src/Generator/DefaultNameGenerator.php +++ b/ramsey/uuid/src/Generator/DefaultNameGenerator.php @@ -16,6 +16,7 @@ use Ramsey\Uuid\Exception\NameException; use Ramsey\Uuid\UuidInterface; +use ValueError; use function hash; @@ -28,8 +29,12 @@ class DefaultNameGenerator implements NameGeneratorInterface /** @psalm-pure */ public function generate(UuidInterface $ns, string $name, string $hashAlgorithm): string { - /** @var string|bool $bytes */ - $bytes = @hash($hashAlgorithm, $ns->getBytes() . $name, true); + try { + /** @var string|bool $bytes */ + $bytes = @hash($hashAlgorithm, $ns->getBytes() . $name, true); + } catch (ValueError $e) { + $bytes = false; // keep same behavior than PHP 7 + } if ($bytes === false) { throw new NameException(sprintf( diff --git a/ramsey/uuid/src/Generator/DefaultTimeGenerator.php b/ramsey/uuid/src/Generator/DefaultTimeGenerator.php index d245c7bcc..ea1e2a6ff 100644 --- a/ramsey/uuid/src/Generator/DefaultTimeGenerator.php +++ b/ramsey/uuid/src/Generator/DefaultTimeGenerator.php @@ -23,11 +23,11 @@ use Ramsey\Uuid\Type\Hexadecimal; use Throwable; -use function ctype_xdigit; use function dechex; use function hex2bin; use function is_int; use function pack; +use function preg_match; use function sprintf; use function str_pad; use function strlen; @@ -40,29 +40,11 @@ */ class DefaultTimeGenerator implements TimeGeneratorInterface { - /** - * @var NodeProviderInterface - */ - private $nodeProvider; - - /** - * @var TimeConverterInterface - */ - private $timeConverter; - - /** - * @var TimeProviderInterface - */ - private $timeProvider; - public function __construct( - NodeProviderInterface $nodeProvider, - TimeConverterInterface $timeConverter, - TimeProviderInterface $timeProvider + private NodeProviderInterface $nodeProvider, + private TimeConverterInterface $timeConverter, + private TimeProviderInterface $timeProvider ) { - $this->nodeProvider = $nodeProvider; - $this->timeConverter = $timeConverter; - $this->timeProvider = $timeProvider; } /** @@ -121,13 +103,13 @@ public function generate($node = null, ?int $clockSeq = null): string * Uses the node provider given when constructing this instance to get * the node ID (usually a MAC address) * - * @param string|int|null $node A node value that may be used to override the node provider + * @param int|string|null $node A node value that may be used to override the node provider * * @return string 6-byte binary string representation of the node * * @throws InvalidArgumentException */ - private function getValidNode($node): string + private function getValidNode(int | string | null $node): string { if ($node === null) { $node = $this->nodeProvider->getNode(); @@ -138,7 +120,7 @@ private function getValidNode($node): string $node = dechex($node); } - if (!ctype_xdigit((string) $node) || strlen((string) $node) > 12) { + if (!preg_match('/^[A-Fa-f0-9]+$/', (string) $node) || strlen((string) $node) > 12) { throw new InvalidArgumentException('Invalid node value'); } diff --git a/ramsey/uuid/src/Generator/PeclUuidNameGenerator.php b/ramsey/uuid/src/Generator/PeclUuidNameGenerator.php index 93b786878..6a6d1aec3 100644 --- a/ramsey/uuid/src/Generator/PeclUuidNameGenerator.php +++ b/ramsey/uuid/src/Generator/PeclUuidNameGenerator.php @@ -33,22 +33,17 @@ class PeclUuidNameGenerator implements NameGeneratorInterface /** @psalm-pure */ public function generate(UuidInterface $ns, string $name, string $hashAlgorithm): string { - switch ($hashAlgorithm) { - case 'md5': - $uuid = (string) uuid_generate_md5($ns->toString(), $name); - - break; - case 'sha1': - $uuid = (string) uuid_generate_sha1($ns->toString(), $name); - - break; - default: - throw new NameException(sprintf( + $uuid = match ($hashAlgorithm) { + 'md5' => uuid_generate_md5($ns->toString(), $name), + 'sha1' => uuid_generate_sha1($ns->toString(), $name), + default => throw new NameException( + sprintf( 'Unable to hash namespace and name with algorithm \'%s\'', $hashAlgorithm - )); - } + ) + ), + }; - return (string) uuid_parse($uuid); + return uuid_parse($uuid); } } diff --git a/ramsey/uuid/src/Generator/PeclUuidRandomGenerator.php b/ramsey/uuid/src/Generator/PeclUuidRandomGenerator.php index df750f6a5..07c47d265 100644 --- a/ramsey/uuid/src/Generator/PeclUuidRandomGenerator.php +++ b/ramsey/uuid/src/Generator/PeclUuidRandomGenerator.php @@ -14,6 +14,9 @@ namespace Ramsey\Uuid\Generator; +use function uuid_create; +use function uuid_parse; + use const UUID_TYPE_RANDOM; /** diff --git a/ramsey/uuid/src/Generator/PeclUuidTimeGenerator.php b/ramsey/uuid/src/Generator/PeclUuidTimeGenerator.php index 903798dd3..e01f44e52 100644 --- a/ramsey/uuid/src/Generator/PeclUuidTimeGenerator.php +++ b/ramsey/uuid/src/Generator/PeclUuidTimeGenerator.php @@ -14,6 +14,9 @@ namespace Ramsey\Uuid\Generator; +use function uuid_create; +use function uuid_parse; + use const UUID_TYPE_TIME; /** diff --git a/ramsey/uuid/src/Generator/RandomBytesGenerator.php b/ramsey/uuid/src/Generator/RandomBytesGenerator.php index e6e9a199b..12edb96ae 100644 --- a/ramsey/uuid/src/Generator/RandomBytesGenerator.php +++ b/ramsey/uuid/src/Generator/RandomBytesGenerator.php @@ -15,6 +15,7 @@ namespace Ramsey\Uuid\Generator; use Ramsey\Uuid\Exception\RandomSourceException; +use Throwable; /** * RandomBytesGenerator generates strings of random binary data using the @@ -33,7 +34,7 @@ public function generate(int $length): string { try { return random_bytes($length); - } catch (\Throwable $exception) { + } catch (Throwable $exception) { throw new RandomSourceException( $exception->getMessage(), (int) $exception->getCode(), diff --git a/ramsey/uuid/src/Generator/RandomGeneratorInterface.php b/ramsey/uuid/src/Generator/RandomGeneratorInterface.php index 5c83cb4d8..1180b9764 100644 --- a/ramsey/uuid/src/Generator/RandomGeneratorInterface.php +++ b/ramsey/uuid/src/Generator/RandomGeneratorInterface.php @@ -22,7 +22,7 @@ interface RandomGeneratorInterface /** * Generates a string of randomized binary data * - * @param int $length The number of bytes of random binary data to generate + * @param int<1, max> $length The number of bytes of random binary data to generate * * @return string A binary string */ diff --git a/ramsey/uuid/src/Generator/RandomLibAdapter.php b/ramsey/uuid/src/Generator/RandomLibAdapter.php index 24ed56920..fd0ccc8aa 100644 --- a/ramsey/uuid/src/Generator/RandomLibAdapter.php +++ b/ramsey/uuid/src/Generator/RandomLibAdapter.php @@ -21,14 +21,15 @@ * RandomLibAdapter generates strings of random binary data using the * paragonie/random-lib library * + * @deprecated This class will be removed in 5.0.0. Use the default + * RandomBytesGenerator or implement your own generator that implements + * RandomGeneratorInterface. + * * @link https://packagist.org/packages/paragonie/random-lib paragonie/random-lib */ class RandomLibAdapter implements RandomGeneratorInterface { - /** - * @var Generator - */ - private $generator; + private Generator $generator; /** * Constructs a RandomLibAdapter diff --git a/ramsey/uuid/src/Generator/TimeGeneratorFactory.php b/ramsey/uuid/src/Generator/TimeGeneratorFactory.php index 3d55fc4d6..8d06fc3ae 100644 --- a/ramsey/uuid/src/Generator/TimeGeneratorFactory.php +++ b/ramsey/uuid/src/Generator/TimeGeneratorFactory.php @@ -24,29 +24,11 @@ */ class TimeGeneratorFactory { - /** - * @var NodeProviderInterface - */ - private $nodeProvider; - - /** - * @var TimeConverterInterface - */ - private $timeConverter; - - /** - * @var TimeProviderInterface - */ - private $timeProvider; - public function __construct( - NodeProviderInterface $nodeProvider, - TimeConverterInterface $timeConverter, - TimeProviderInterface $timeProvider + private NodeProviderInterface $nodeProvider, + private TimeConverterInterface $timeConverter, + private TimeProviderInterface $timeProvider ) { - $this->nodeProvider = $nodeProvider; - $this->timeConverter = $timeConverter; - $this->timeProvider = $timeProvider; } /** diff --git a/ramsey/uuid/src/Generator/UnixTimeGenerator.php b/ramsey/uuid/src/Generator/UnixTimeGenerator.php new file mode 100644 index 000000000..d7c8ed4ee --- /dev/null +++ b/ramsey/uuid/src/Generator/UnixTimeGenerator.php @@ -0,0 +1,169 @@ + + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Generator; + +use Brick\Math\BigInteger; +use DateTimeImmutable; +use DateTimeInterface; +use Ramsey\Uuid\Type\Hexadecimal; + +use function hash; +use function pack; +use function str_pad; +use function strlen; +use function substr; +use function substr_replace; +use function unpack; + +use const PHP_INT_SIZE; +use const STR_PAD_LEFT; + +/** + * UnixTimeGenerator generates bytes that combine a 48-bit timestamp in + * milliseconds since the Unix Epoch with 80 random bits + * + * Code and concepts within this class are borrowed from the symfony/uid package + * and are used under the terms of the MIT license distributed with symfony/uid. + * + * symfony/uid is copyright (c) Fabien Potencier. + * + * @link https://symfony.com/components/Uid Symfony Uid component + * @link https://github.com/symfony/uid/blob/4f9f537e57261519808a7ce1d941490736522bbc/UuidV7.php Symfony UuidV7 class + * @link https://github.com/symfony/uid/blob/6.2/LICENSE MIT License + */ +class UnixTimeGenerator implements TimeGeneratorInterface +{ + private static string $time = ''; + private static ?string $seed = null; + private static int $seedIndex = 0; + + /** @var int[] */ + private static array $rand = []; + + /** @var int[] */ + private static array $seedParts; + + public function __construct( + private RandomGeneratorInterface $randomGenerator, + private int $intSize = PHP_INT_SIZE + ) { + } + + /** + * @param Hexadecimal|int|string|null $node Unused in this generator + * @param int|null $clockSeq Unused in this generator + * @param DateTimeInterface $dateTime A date-time instance to use when + * generating bytes + * + * @inheritDoc + */ + public function generate($node = null, ?int $clockSeq = null, ?DateTimeInterface $dateTime = null): string + { + $time = ($dateTime ?? new DateTimeImmutable('now'))->format('Uv'); + + if ($time > self::$time || ($dateTime !== null && $time !== self::$time)) { + $this->randomize($time); + } else { + $time = $this->increment(); + } + + if ($this->intSize >= 8) { + $time = substr(pack('J', (int) $time), -6); + } else { + $time = str_pad(BigInteger::of($time)->toBytes(false), 6, "\x00", STR_PAD_LEFT); + } + + /** @var non-empty-string */ + return $time . pack('n*', self::$rand[1], self::$rand[2], self::$rand[3], self::$rand[4], self::$rand[5]); + } + + private function randomize(string $time): void + { + if (self::$seed === null) { + $seed = $this->randomGenerator->generate(16); + self::$seed = $seed; + } else { + $seed = $this->randomGenerator->generate(10); + } + + /** @var int[] $rand */ + $rand = unpack('n*', $seed); + $rand[1] &= 0x03ff; + + self::$rand = $rand; + self::$time = $time; + } + + /** + * Special thanks to Nicolas Grekas for sharing the following information: + * + * Within the same ms, we increment the rand part by a random 24-bit number. + * + * Instead of getting this number from random_bytes(), which is slow, we get + * it by sha512-hashing self::$seed. This produces 64 bytes of entropy, + * which we need to split in a list of 24-bit numbers. unpack() first splits + * them into 16 x 32-bit numbers; we take the first byte of each of these + * numbers to get 5 extra 24-bit numbers. Then, we consume those numbers + * one-by-one and run this logic every 21 iterations. + * + * self::$rand holds the random part of the UUID, split into 5 x 16-bit + * numbers for x86 portability. We increment this random part by the next + * 24-bit number in the self::$seedParts list and decrement + * self::$seedIndex. + * + * @link https://twitter.com/nicolasgrekas/status/1583356938825261061 Tweet from Nicolas Grekas + */ + private function increment(): string + { + if (self::$seedIndex === 0 && self::$seed !== null) { + self::$seed = hash('sha512', self::$seed, true); + + /** @var int[] $s */ + $s = unpack('l*', self::$seed); + $s[] = ($s[1] >> 8 & 0xff0000) | ($s[2] >> 16 & 0xff00) | ($s[3] >> 24 & 0xff); + $s[] = ($s[4] >> 8 & 0xff0000) | ($s[5] >> 16 & 0xff00) | ($s[6] >> 24 & 0xff); + $s[] = ($s[7] >> 8 & 0xff0000) | ($s[8] >> 16 & 0xff00) | ($s[9] >> 24 & 0xff); + $s[] = ($s[10] >> 8 & 0xff0000) | ($s[11] >> 16 & 0xff00) | ($s[12] >> 24 & 0xff); + $s[] = ($s[13] >> 8 & 0xff0000) | ($s[14] >> 16 & 0xff00) | ($s[15] >> 24 & 0xff); + + self::$seedParts = $s; + self::$seedIndex = 21; + } + + self::$rand[5] = 0xffff & $carry = self::$rand[5] + 1 + (self::$seedParts[self::$seedIndex--] & 0xffffff); + self::$rand[4] = 0xffff & $carry = self::$rand[4] + ($carry >> 16); + self::$rand[3] = 0xffff & $carry = self::$rand[3] + ($carry >> 16); + self::$rand[2] = 0xffff & $carry = self::$rand[2] + ($carry >> 16); + self::$rand[1] += $carry >> 16; + + if (0xfc00 & self::$rand[1]) { + $time = self::$time; + $mtime = (int) substr($time, -9); + + if ($this->intSize >= 8 || strlen($time) < 10) { + $time = (string) ((int) $time + 1); + } elseif ($mtime === 999999999) { + $time = (1 + (int) substr($time, 0, -9)) . '000000000'; + } else { + $mtime++; + $time = substr_replace($time, str_pad((string) $mtime, 9, '0', STR_PAD_LEFT), -9); + } + + $this->randomize($time); + } + + return self::$time; + } +} diff --git a/ramsey/uuid/src/Guid/Fields.php b/ramsey/uuid/src/Guid/Fields.php index 49db4ed2f..0fc5d1c9b 100644 --- a/ramsey/uuid/src/Guid/Fields.php +++ b/ramsey/uuid/src/Guid/Fields.php @@ -17,6 +17,7 @@ use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Fields\SerializableFieldsTrait; use Ramsey\Uuid\Rfc4122\FieldsInterface; +use Ramsey\Uuid\Rfc4122\MaxTrait; use Ramsey\Uuid\Rfc4122\NilTrait; use Ramsey\Uuid\Rfc4122\VariantTrait; use Ramsey\Uuid\Rfc4122\VersionTrait; @@ -44,16 +45,12 @@ */ final class Fields implements FieldsInterface { + use MaxTrait; use NilTrait; use SerializableFieldsTrait; use VariantTrait; use VersionTrait; - /** - * @var string - */ - private $bytes; - /** * @param string $bytes A 16-byte binary string representation of a UUID * @@ -61,17 +58,15 @@ final class Fields implements FieldsInterface * @throws InvalidArgumentException if the byte string does not represent a GUID * @throws InvalidArgumentException if the byte string does not contain a valid version */ - public function __construct(string $bytes) + public function __construct(private string $bytes) { - if (strlen($bytes) !== 16) { + if (strlen($this->bytes) !== 16) { throw new InvalidArgumentException( 'The byte string must be 16 bytes long; ' - . 'received ' . strlen($bytes) . ' bytes' + . 'received ' . strlen($this->bytes) . ' bytes' ); } - $this->bytes = $bytes; - if (!$this->isCorrectVariant()) { throw new InvalidArgumentException( 'The byte string received does not conform to the RFC ' @@ -94,6 +89,7 @@ public function getBytes(): string public function getTimeLow(): Hexadecimal { // Swap the bytes from little endian to network byte order. + /** @var array $hex */ $hex = unpack( 'H*', pack( @@ -109,6 +105,7 @@ public function getTimeLow(): Hexadecimal public function getTimeMid(): Hexadecimal { // Swap the bytes from little endian to network byte order. + /** @var array $hex */ $hex = unpack( 'H*', pack( @@ -123,6 +120,7 @@ public function getTimeMid(): Hexadecimal public function getTimeHiAndVersion(): Hexadecimal { // Swap the bytes from little endian to network byte order. + /** @var array $hex */ $hex = unpack( 'H*', pack( @@ -146,7 +144,13 @@ public function getTimestamp(): Hexadecimal public function getClockSeq(): Hexadecimal { - $clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff; + if ($this->isMax()) { + $clockSeq = 0xffff; + } elseif ($this->isNil()) { + $clockSeq = 0x0000; + } else { + $clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff; + } return new Hexadecimal(str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT)); } @@ -168,10 +172,11 @@ public function getNode(): Hexadecimal public function getVersion(): ?int { - if ($this->isNil()) { + if ($this->isNil() || $this->isMax()) { return null; } + /** @var array $parts */ $parts = unpack('n*', $this->bytes); return ((int) $parts[4] >> 4) & 0x00f; @@ -179,7 +184,7 @@ public function getVersion(): ?int private function isCorrectVariant(): bool { - if ($this->isNil()) { + if ($this->isNil() || $this->isMax()) { return true; } diff --git a/ramsey/uuid/src/Guid/Guid.php b/ramsey/uuid/src/Guid/Guid.php index 08a00695a..b3ed096ab 100644 --- a/ramsey/uuid/src/Guid/Guid.php +++ b/ramsey/uuid/src/Guid/Guid.php @@ -18,7 +18,6 @@ use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Uuid; -use Ramsey\Uuid\UuidInterface; /** * Guid represents a UUID with "native" (little-endian) byte order @@ -49,7 +48,7 @@ * * @psalm-immutable */ -final class Guid extends Uuid implements UuidInterface +final class Guid extends Uuid { public function __construct( Fields $fields, diff --git a/ramsey/uuid/src/Guid/GuidBuilder.php b/ramsey/uuid/src/Guid/GuidBuilder.php index 758dd6b7f..c036bb20b 100644 --- a/ramsey/uuid/src/Guid/GuidBuilder.php +++ b/ramsey/uuid/src/Guid/GuidBuilder.php @@ -31,16 +31,6 @@ */ class GuidBuilder implements UuidBuilderInterface { - /** - * @var NumberConverterInterface - */ - private $numberConverter; - - /** - * @var TimeConverterInterface - */ - private $timeConverter; - /** * @param NumberConverterInterface $numberConverter The number converter to * use when constructing the Guid @@ -48,11 +38,9 @@ class GuidBuilder implements UuidBuilderInterface * for converting timestamps extracted from a UUID to Unix timestamps */ public function __construct( - NumberConverterInterface $numberConverter, - TimeConverterInterface $timeConverter + private NumberConverterInterface $numberConverter, + private TimeConverterInterface $timeConverter ) { - $this->numberConverter = $numberConverter; - $this->timeConverter = $timeConverter; } /** diff --git a/ramsey/uuid/src/Lazy/LazyUuidFromString.php b/ramsey/uuid/src/Lazy/LazyUuidFromString.php index 3d4ddcb21..c0b47bbf2 100644 --- a/ramsey/uuid/src/Lazy/LazyUuidFromString.php +++ b/ramsey/uuid/src/Lazy/LazyUuidFromString.php @@ -7,7 +7,7 @@ * file that was distributed with this source code. * * @copyright Copyright (c) Ben Ramsey - * @license http://opensource.org/licenses/MIT MIT + * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); @@ -18,16 +18,18 @@ use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Exception\UnsupportedOperationException; use Ramsey\Uuid\Fields\FieldsInterface; -use Ramsey\Uuid\Nonstandard\UuidV6; use Ramsey\Uuid\Rfc4122\UuidV1; +use Ramsey\Uuid\Rfc4122\UuidV6; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; use Ramsey\Uuid\UuidFactory; use Ramsey\Uuid\UuidInterface; +use ValueError; use function assert; use function bin2hex; use function hex2bin; +use function sprintf; use function str_replace; use function substr; @@ -53,18 +55,14 @@ final class LazyUuidFromString implements UuidInterface { public const VALID_REGEX = '/\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/ms'; + + private ?UuidInterface $unwrapped = null; + /** - * @var string - * @psalm-var non-empty-string + * @psalm-param non-empty-string $uuid */ - private $uuid; - /** @var UuidInterface|null */ - private $unwrapped; - - /** @psalm-param non-empty-string $uuid */ - public function __construct(string $uuid) + public function __construct(private string $uuid) { - $this->uuid = $uuid; } /** @psalm-pure */ @@ -90,16 +88,43 @@ public function serialize(): string return $this->uuid; } + /** + * @return array{string: string} + * + * @psalm-return array{string: non-empty-string} + */ + public function __serialize(): array + { + return ['string' => $this->uuid]; + } + /** * {@inheritDoc} * - * @param string $serialized + * @param string $data * - * @psalm-param non-empty-string $serialized + * @psalm-param non-empty-string $data */ - public function unserialize($serialized): void + public function unserialize(string $data): void { - $this->uuid = $serialized; + $this->uuid = $data; + } + + /** + * @param array{string?: string} $data + * + * @psalm-param array{string?: non-empty-string} $data + * @psalm-suppress UnusedMethodCall + */ + public function __unserialize(array $data): void + { + // @codeCoverageIgnoreStart + if (!isset($data['string'])) { + throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__)); + } + // @codeCoverageIgnoreEnd + + $this->unserialize($data['string']); } /** @psalm-suppress DeprecatedMethod */ @@ -242,6 +267,7 @@ public function equals(?object $other): bool */ public function getBytes(): string { + /** @phpstan-ignore-next-line PHPStan complains that this is not a non-empty-string. */ return (string) hex2bin(str_replace('-', '', $this->uuid)); } @@ -497,7 +523,7 @@ public function getTimeMid(): string public function getTimestamp(): string { $instance = ($this->unwrapped ?? $this->unwrap()); - $fields = $instance->getFields(); + $fields = $instance->getFields(); if ($fields->getVersion() !== 1) { throw new UnsupportedOperationException('Not a time-based UUID'); diff --git a/ramsey/uuid/src/Math/BrickMathCalculator.php b/ramsey/uuid/src/Math/BrickMathCalculator.php index f2d86788c..f065acd46 100644 --- a/ramsey/uuid/src/Math/BrickMathCalculator.php +++ b/ramsey/uuid/src/Math/BrickMathCalculator.php @@ -136,9 +136,11 @@ public function toInteger(Hexadecimal $value): IntegerObject /** * Maps ramsey/uuid rounding modes to those used by brick/math + * + * @return BrickMathRounding::* */ - private function getBrickRoundingMode(int $roundingMode): int + private function getBrickRoundingMode(int $roundingMode) { - return self::ROUNDING_MODE_MAP[$roundingMode] ?? 0; + return self::ROUNDING_MODE_MAP[$roundingMode] ?? BrickMathRounding::UNNECESSARY; } } diff --git a/ramsey/uuid/src/Nonstandard/Fields.php b/ramsey/uuid/src/Nonstandard/Fields.php index 927bc6a26..5dfe61076 100644 --- a/ramsey/uuid/src/Nonstandard/Fields.php +++ b/ramsey/uuid/src/Nonstandard/Fields.php @@ -47,26 +47,19 @@ final class Fields implements FieldsInterface use SerializableFieldsTrait; use VariantTrait; - /** - * @var string - */ - private $bytes; - /** * @param string $bytes A 16-byte binary string representation of a UUID * * @throws InvalidArgumentException if the byte string is not exactly 16 bytes */ - public function __construct(string $bytes) + public function __construct(private string $bytes) { - if (strlen($bytes) !== 16) { + if (strlen($this->bytes) !== 16) { throw new InvalidArgumentException( 'The byte string must be 16 bytes long; ' - . 'received ' . strlen($bytes) . ' bytes' + . 'received ' . strlen($this->bytes) . ' bytes' ); } - - $this->bytes = $bytes; } public function getBytes(): string @@ -130,4 +123,9 @@ public function isNil(): bool { return false; } + + public function isMax(): bool + { + return false; + } } diff --git a/ramsey/uuid/src/Nonstandard/Uuid.php b/ramsey/uuid/src/Nonstandard/Uuid.php index 5a7a33347..715f82554 100644 --- a/ramsey/uuid/src/Nonstandard/Uuid.php +++ b/ramsey/uuid/src/Nonstandard/Uuid.php @@ -18,14 +18,13 @@ use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Uuid as BaseUuid; -use Ramsey\Uuid\UuidInterface; /** * Nonstandard\Uuid is a UUID that doesn't conform to RFC 4122 * * @psalm-immutable */ -final class Uuid extends BaseUuid implements UuidInterface +final class Uuid extends BaseUuid { public function __construct( Fields $fields, diff --git a/ramsey/uuid/src/Nonstandard/UuidBuilder.php b/ramsey/uuid/src/Nonstandard/UuidBuilder.php index 0c8927738..82efd402f 100644 --- a/ramsey/uuid/src/Nonstandard/UuidBuilder.php +++ b/ramsey/uuid/src/Nonstandard/UuidBuilder.php @@ -29,16 +29,6 @@ */ class UuidBuilder implements UuidBuilderInterface { - /** - * @var NumberConverterInterface - */ - private $numberConverter; - - /** - * @var TimeConverterInterface - */ - private $timeConverter; - /** * @param NumberConverterInterface $numberConverter The number converter to * use when constructing the Nonstandard\Uuid @@ -46,11 +36,9 @@ class UuidBuilder implements UuidBuilderInterface * for converting timestamps extracted from a UUID to Unix timestamps */ public function __construct( - NumberConverterInterface $numberConverter, - TimeConverterInterface $timeConverter + private NumberConverterInterface $numberConverter, + private TimeConverterInterface $timeConverter ) { - $this->numberConverter = $numberConverter; - $this->timeConverter = $timeConverter; } /** diff --git a/ramsey/uuid/src/Nonstandard/UuidV6.php b/ramsey/uuid/src/Nonstandard/UuidV6.php index 05586b3eb..7497dd101 100644 --- a/ramsey/uuid/src/Nonstandard/UuidV6.php +++ b/ramsey/uuid/src/Nonstandard/UuidV6.php @@ -14,39 +14,34 @@ namespace Ramsey\Uuid\Nonstandard; -use DateTimeImmutable; -use DateTimeInterface; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; -use Ramsey\Uuid\Exception\DateTimeException; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Lazy\LazyUuidFromString; use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; +use Ramsey\Uuid\Rfc4122\TimeTrait; use Ramsey\Uuid\Rfc4122\UuidInterface; use Ramsey\Uuid\Rfc4122\UuidV1; -use Ramsey\Uuid\Uuid; -use Throwable; - -use function hex2bin; -use function str_pad; -use function substr; - -use const STR_PAD_LEFT; +use Ramsey\Uuid\Uuid as BaseUuid; /** - * Ordered-time, or version 6, UUIDs include timestamp, clock sequence, and node - * values that are combined into a 128-bit unsigned integer + * Reordered time, or version 6, UUIDs include timestamp, clock sequence, and + * node values that are combined into a 128-bit unsigned integer + * + * @deprecated Use {@see \Ramsey\Uuid\Rfc4122\UuidV6} instead. * * @link https://github.com/uuid6/uuid6-ietf-draft UUID version 6 IETF draft * @link http://gh.peabody.io/uuidv6/ "Version 6" UUIDs * * @psalm-immutable */ -final class UuidV6 extends Uuid implements UuidInterface +class UuidV6 extends BaseUuid implements UuidInterface { + use TimeTrait; + /** - * Creates a version 6 (time-based) UUID + * Creates a version 6 (reordered time) UUID * * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID * @param NumberConverterInterface $numberConverter The number converter to use @@ -62,39 +57,16 @@ public function __construct( CodecInterface $codec, TimeConverterInterface $timeConverter ) { - if ($fields->getVersion() !== Uuid::UUID_TYPE_PEABODY) { + if ($fields->getVersion() !== Uuid::UUID_TYPE_REORDERED_TIME) { throw new InvalidArgumentException( 'Fields used to create a UuidV6 must represent a ' - . 'version 6 (ordered-time) UUID' + . 'version 6 (reordered time) UUID' ); } parent::__construct($fields, $numberConverter, $codec, $timeConverter); } - /** - * Returns a DateTimeInterface object representing the timestamp associated - * with the UUID - * - * @return DateTimeImmutable A PHP DateTimeImmutable instance representing - * the timestamp of a version 6 UUID - */ - public function getDateTime(): DateTimeInterface - { - $time = $this->timeConverter->convertTime($this->fields->getTimestamp()); - - try { - return new DateTimeImmutable( - '@' - . $time->getSeconds()->toString() - . '.' - . str_pad($time->getMicroseconds()->toString(), 6, '0', STR_PAD_LEFT) - ); - } catch (Throwable $e) { - throw new DateTimeException($e->getMessage(), (int) $e->getCode(), $e); - } - } - /** * Converts this UUID into an instance of a version 1 UUID */ @@ -116,7 +88,7 @@ public function toUuidV1(): UuidV1 /** * Converts a version 1 UUID into an instance of a version 6 UUID */ - public static function fromUuidV1(UuidV1 $uuidV1): UuidV6 + public static function fromUuidV1(UuidV1 $uuidV1): \Ramsey\Uuid\Rfc4122\UuidV6 { $hex = $uuidV1->getHex()->toString(); $hex = substr($hex, 13, 3) diff --git a/ramsey/uuid/src/Provider/Dce/SystemDceSecurityProvider.php b/ramsey/uuid/src/Provider/Dce/SystemDceSecurityProvider.php index 1a1f4cf2e..d5b6cf0c0 100644 --- a/ramsey/uuid/src/Provider/Dce/SystemDceSecurityProvider.php +++ b/ramsey/uuid/src/Provider/Dce/SystemDceSecurityProvider.php @@ -21,7 +21,6 @@ use function escapeshellarg; use function preg_split; use function str_getcsv; -use function strpos; use function strrpos; use function strtolower; use function strtoupper; @@ -42,6 +41,7 @@ class SystemDceSecurityProvider implements DceSecurityProviderInterface */ public function getUid(): IntegerObject { + /** @var int|float|string|IntegerObject|null $uid */ static $uid = null; if ($uid instanceof IntegerObject) { @@ -72,6 +72,7 @@ public function getUid(): IntegerObject */ public function getGid(): IntegerObject { + /** @var int|float|string|IntegerObject|null $gid */ static $gid = null; if ($gid instanceof IntegerObject) { @@ -104,15 +105,10 @@ private function getSystemUid(): string return ''; } - switch ($this->getOs()) { - case 'WIN': - return $this->getWindowsUid(); - case 'DAR': - case 'FRE': - case 'LIN': - default: - return trim((string) shell_exec('id -u')); - } + return match ($this->getOs()) { + 'WIN' => $this->getWindowsUid(), + default => trim((string) shell_exec('id -u')), + }; } /** @@ -124,15 +120,10 @@ private function getSystemGid(): string return ''; } - switch ($this->getOs()) { - case 'WIN': - return $this->getWindowsGid(); - case 'DAR': - case 'FRE': - case 'LIN': - default: - return trim((string) shell_exec('id -g')); - } + return match ($this->getOs()) { + 'WIN' => $this->getWindowsGid(), + default => trim((string) shell_exec('id -g')), + }; } /** @@ -142,7 +133,7 @@ private function hasShellExec(): bool { $disabledFunctions = strtolower((string) ini_get('disable_functions')); - return strpos($disabledFunctions, 'shell_exec') === false; + return !str_contains($disabledFunctions, 'shell_exec'); } /** @@ -150,7 +141,13 @@ private function hasShellExec(): bool */ private function getOs(): string { - return strtoupper(substr(constant('PHP_OS'), 0, 3)); + /** + * @psalm-suppress UnnecessaryVarAnnotation + * @var string $phpOs + */ + $phpOs = constant('PHP_OS'); + + return strtoupper(substr($phpOs, 0, 3)); } /** @@ -177,8 +174,7 @@ private function getWindowsUid(): string return ''; } - /** @var string $sid */ - $sid = str_getcsv(trim($response))[1] ?? ''; + $sid = str_getcsv(trim((string) $response))[1] ?? ''; if (($lastHyphen = strrpos($sid, '-')) === false) { return ''; @@ -207,7 +203,7 @@ private function getWindowsGid(): string } /** @var string[] $userGroups */ - $userGroups = preg_split('/\s{2,}/', $response, -1, PREG_SPLIT_NO_EMPTY); + $userGroups = preg_split('/\s{2,}/', (string) $response, -1, PREG_SPLIT_NO_EMPTY); $firstGroup = trim($userGroups[1] ?? '', "* \t\n\r\0\x0B"); @@ -222,7 +218,7 @@ private function getWindowsGid(): string } /** @var string[] $userGroup */ - $userGroup = preg_split('/\s{2,}/', $response, -1, PREG_SPLIT_NO_EMPTY); + $userGroup = preg_split('/\s{2,}/', (string) $response, -1, PREG_SPLIT_NO_EMPTY); $sid = $userGroup[1] ?? ''; @@ -230,6 +226,6 @@ private function getWindowsGid(): string return ''; } - return trim((string) substr($sid, $lastHyphen + 1)); + return trim(substr($sid, $lastHyphen + 1)); } } diff --git a/ramsey/uuid/src/Provider/Node/FallbackNodeProvider.php b/ramsey/uuid/src/Provider/Node/FallbackNodeProvider.php index f6e5e406d..d2eb20b70 100644 --- a/ramsey/uuid/src/Provider/Node/FallbackNodeProvider.php +++ b/ramsey/uuid/src/Provider/Node/FallbackNodeProvider.php @@ -25,24 +25,17 @@ class FallbackNodeProvider implements NodeProviderInterface { /** - * @var NodeProviderCollection + * @param iterable $providers Array of node providers */ - private $nodeProviders; - - /** - * @param NodeProviderCollection $providers Array of node providers - */ - public function __construct(NodeProviderCollection $providers) + public function __construct(private iterable $providers) { - $this->nodeProviders = $providers; } public function getNode(): Hexadecimal { $lastProviderException = null; - /** @var NodeProviderInterface $provider */ - foreach ($this->nodeProviders as $provider) { + foreach ($this->providers as $provider) { try { return $provider->getNode(); } catch (NodeException $exception) { diff --git a/ramsey/uuid/src/Provider/Node/NodeProviderCollection.php b/ramsey/uuid/src/Provider/Node/NodeProviderCollection.php index 89d09178d..1b979faee 100644 --- a/ramsey/uuid/src/Provider/Node/NodeProviderCollection.php +++ b/ramsey/uuid/src/Provider/Node/NodeProviderCollection.php @@ -15,14 +15,20 @@ namespace Ramsey\Uuid\Provider\Node; use Ramsey\Collection\AbstractCollection; -use Ramsey\Collection\CollectionInterface; use Ramsey\Uuid\Provider\NodeProviderInterface; use Ramsey\Uuid\Type\Hexadecimal; /** * A collection of NodeProviderInterface objects + * + * @deprecated this class has been deprecated, and will be removed in 5.0.0. The use-case for this class comes from + * a pre-`phpstan/phpstan` and pre-`vimeo/psalm` ecosystem, in which type safety had to be mostly enforced + * at runtime: that is no longer necessary, now that you can safely verify your code to be correct, and use + * more generic types like `iterable` instead. + * + * @extends AbstractCollection */ -class NodeProviderCollection extends AbstractCollection implements CollectionInterface +class NodeProviderCollection extends AbstractCollection { public function getType(): string { @@ -36,10 +42,11 @@ public function getType(): string * a UuidInterface instance * * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + * @psalm-suppress RedundantConditionGivenDocblockType */ public function unserialize($serialized): void { - /** @var mixed[] $data */ + /** @var array $data */ $data = unserialize($serialized, [ 'allowed_classes' => [ Hexadecimal::class, @@ -49,6 +56,11 @@ public function unserialize($serialized): void ], ]); - $this->data = $data; + $this->data = array_filter( + $data, + function ($unserialized): bool { + return $unserialized instanceof NodeProviderInterface; + } + ); } } diff --git a/ramsey/uuid/src/Provider/Node/RandomNodeProvider.php b/ramsey/uuid/src/Provider/Node/RandomNodeProvider.php index 266c0b738..76141361b 100644 --- a/ramsey/uuid/src/Provider/Node/RandomNodeProvider.php +++ b/ramsey/uuid/src/Provider/Node/RandomNodeProvider.php @@ -17,6 +17,7 @@ use Ramsey\Uuid\Exception\RandomSourceException; use Ramsey\Uuid\Provider\NodeProviderInterface; use Ramsey\Uuid\Type\Hexadecimal; +use Throwable; use function bin2hex; use function dechex; @@ -38,7 +39,7 @@ public function getNode(): Hexadecimal { try { $nodeBytes = random_bytes(6); - } catch (\Throwable $exception) { + } catch (Throwable $exception) { throw new RandomSourceException( $exception->getMessage(), (int) $exception->getCode(), diff --git a/ramsey/uuid/src/Provider/Node/StaticNodeProvider.php b/ramsey/uuid/src/Provider/Node/StaticNodeProvider.php index 51f1b02ea..0f7536a82 100644 --- a/ramsey/uuid/src/Provider/Node/StaticNodeProvider.php +++ b/ramsey/uuid/src/Provider/Node/StaticNodeProvider.php @@ -32,10 +32,7 @@ */ class StaticNodeProvider implements NodeProviderInterface { - /** - * @var Hexadecimal - */ - private $node; + private Hexadecimal $node; /** * @param Hexadecimal $node The static node value to use diff --git a/ramsey/uuid/src/Provider/Node/SystemNodeProvider.php b/ramsey/uuid/src/Provider/Node/SystemNodeProvider.php index 8234abaee..a03c93b4d 100644 --- a/ramsey/uuid/src/Provider/Node/SystemNodeProvider.php +++ b/ramsey/uuid/src/Provider/Node/SystemNodeProvider.php @@ -27,8 +27,8 @@ use function preg_match; use function preg_match_all; use function reset; +use function str_contains; use function str_replace; -use function strpos; use function strtolower; use function strtoupper; use function substr; @@ -100,12 +100,18 @@ protected function getIfconfig(): string { $disabledFunctions = strtolower((string) ini_get('disable_functions')); - if (strpos($disabledFunctions, 'passthru') !== false) { + if (str_contains($disabledFunctions, 'passthru')) { return ''; } + /** + * @psalm-suppress UnnecessaryVarAnnotation + * @var string $phpOs + */ + $phpOs = constant('PHP_OS'); + ob_start(); - switch (strtoupper(substr(constant('PHP_OS'), 0, 3))) { + switch (strtoupper(substr($phpOs, 0, 3))) { case 'WIN': passthru('ipconfig /all 2>&1'); @@ -127,12 +133,15 @@ protected function getIfconfig(): string $ifconfig = (string) ob_get_clean(); - $node = ''; if (preg_match_all(self::IFCONFIG_PATTERN, $ifconfig, $matches, PREG_PATTERN_ORDER)) { - $node = $matches[1][0] ?? ''; + foreach ($matches[1] as $iface) { + if ($iface !== '00:00:00:00:00:00' && $iface !== '00-00-00-00-00-00') { + return $iface; + } + } } - return (string) $node; + return ''; } /** @@ -142,13 +151,20 @@ protected function getSysfs(): string { $mac = ''; - if (strtoupper(constant('PHP_OS')) === 'LINUX') { + /** + * @psalm-suppress UnnecessaryVarAnnotation + * @var string $phpOs + */ + $phpOs = constant('PHP_OS'); + + if (strtoupper($phpOs) === 'LINUX') { $addressPaths = glob('/sys/class/net/*/address', GLOB_NOSORT); if ($addressPaths === false || count($addressPaths) === 0) { return ''; } + /** @var array $macs */ $macs = []; array_walk($addressPaths, function (string $addressPath) use (&$macs): void { @@ -157,7 +173,10 @@ protected function getSysfs(): string } }); - $macs = array_map('trim', $macs); + /** @var callable $trim */ + $trim = 'trim'; + + $macs = array_map($trim, $macs); // Remove invalid entries. $macs = array_filter($macs, function (string $address) { @@ -165,6 +184,7 @@ protected function getSysfs(): string && preg_match(self::SYSFS_PATTERN, $address); }); + /** @var string|bool $mac */ $mac = reset($macs); } diff --git a/ramsey/uuid/src/Provider/Time/FixedTimeProvider.php b/ramsey/uuid/src/Provider/Time/FixedTimeProvider.php index b8bfd7215..526c8ff46 100644 --- a/ramsey/uuid/src/Provider/Time/FixedTimeProvider.php +++ b/ramsey/uuid/src/Provider/Time/FixedTimeProvider.php @@ -19,21 +19,15 @@ use Ramsey\Uuid\Type\Time; /** - * FixedTimeProvider uses an known time to provide the time + * FixedTimeProvider uses a known time to provide the time * * This provider allows the use of a previously-generated, or known, time * when generating time-based UUIDs. */ class FixedTimeProvider implements TimeProviderInterface { - /** - * @var Time - */ - private $fixedTime; - - public function __construct(Time $time) + public function __construct(private Time $time) { - $this->fixedTime = $time; } /** @@ -43,7 +37,7 @@ public function __construct(Time $time) */ public function setUsec($value): void { - $this->fixedTime = new Time($this->fixedTime->getSeconds(), $value); + $this->time = new Time($this->time->getSeconds(), $value); } /** @@ -53,11 +47,11 @@ public function setUsec($value): void */ public function setSec($value): void { - $this->fixedTime = new Time($value, $this->fixedTime->getMicroseconds()); + $this->time = new Time($value, $this->time->getMicroseconds()); } public function getTime(): Time { - return $this->fixedTime; + return $this->time; } } diff --git a/ramsey/uuid/src/Rfc4122/Fields.php b/ramsey/uuid/src/Rfc4122/Fields.php index 0989d842a..9acf810c2 100644 --- a/ramsey/uuid/src/Rfc4122/Fields.php +++ b/ramsey/uuid/src/Rfc4122/Fields.php @@ -40,16 +40,12 @@ */ final class Fields implements FieldsInterface { + use MaxTrait; use NilTrait; use SerializableFieldsTrait; use VariantTrait; use VersionTrait; - /** - * @var string - */ - private $bytes; - /** * @param string $bytes A 16-byte binary string representation of a UUID * @@ -57,17 +53,15 @@ final class Fields implements FieldsInterface * @throws InvalidArgumentException if the byte string does not represent an RFC 4122 UUID * @throws InvalidArgumentException if the byte string does not contain a valid version */ - public function __construct(string $bytes) + public function __construct(private string $bytes) { - if (strlen($bytes) !== 16) { + if (strlen($this->bytes) !== 16) { throw new InvalidArgumentException( 'The byte string must be 16 bytes long; ' - . 'received ' . strlen($bytes) . ' bytes' + . 'received ' . strlen($this->bytes) . ' bytes' ); } - $this->bytes = $bytes; - if (!$this->isCorrectVariant()) { throw new InvalidArgumentException( 'The byte string received does not conform to the RFC 4122 variant' @@ -88,7 +82,13 @@ public function getBytes(): string public function getClockSeq(): Hexadecimal { - $clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff; + if ($this->isMax()) { + $clockSeq = 0xffff; + } elseif ($this->isNil()) { + $clockSeq = 0x0000; + } else { + $clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff; + } return new Hexadecimal(str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT)); } @@ -140,51 +140,53 @@ public function getTimeMid(): Hexadecimal */ public function getTimestamp(): Hexadecimal { - switch ($this->getVersion()) { - case Uuid::UUID_TYPE_DCE_SECURITY: - $timestamp = sprintf( - '%03x%04s%08s', - hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff, - $this->getTimeMid()->toString(), - '' - ); - - break; - case Uuid::UUID_TYPE_PEABODY: - $timestamp = sprintf( - '%08s%04s%03x', - $this->getTimeLow()->toString(), - $this->getTimeMid()->toString(), - hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff - ); - - break; - default: - $timestamp = sprintf( - '%03x%04s%08s', - hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff, - $this->getTimeMid()->toString(), - $this->getTimeLow()->toString() - ); - } + $timestamp = match ($this->getVersion()) { + Uuid::UUID_TYPE_DCE_SECURITY => sprintf( + '%03x%04s%08s', + hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff, + $this->getTimeMid()->toString(), + '' + ), + Uuid::UUID_TYPE_REORDERED_TIME => sprintf( + '%08s%04s%03x', + $this->getTimeLow()->toString(), + $this->getTimeMid()->toString(), + hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff + ), + // The Unix timestamp in version 7 UUIDs is a 48-bit number, + // but for consistency, we will return a 60-bit number, padded + // to the left with zeros. + Uuid::UUID_TYPE_UNIX_TIME => sprintf( + '%011s%04s', + $this->getTimeLow()->toString(), + $this->getTimeMid()->toString(), + ), + default => sprintf( + '%03x%04s%08s', + hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff, + $this->getTimeMid()->toString(), + $this->getTimeLow()->toString() + ), + }; return new Hexadecimal($timestamp); } public function getVersion(): ?int { - if ($this->isNil()) { + if ($this->isNil() || $this->isMax()) { return null; } + /** @var int[] $parts */ $parts = unpack('n*', $this->bytes); - return (int) $parts[4] >> 12; + return $parts[4] >> 12; } private function isCorrectVariant(): bool { - if ($this->isNil()) { + if ($this->isNil() || $this->isMax()) { return true; } diff --git a/ramsey/uuid/src/Rfc4122/FieldsInterface.php b/ramsey/uuid/src/Rfc4122/FieldsInterface.php index a303525d6..2241cf574 100644 --- a/ramsey/uuid/src/Rfc4122/FieldsInterface.php +++ b/ramsey/uuid/src/Rfc4122/FieldsInterface.php @@ -103,11 +103,13 @@ public function getVariant(): int; * The version number describes how the UUID was generated and has the * following meaning: * - * 1. Time-based UUID + * 1. Gregorian time UUID * 2. DCE security UUID * 3. Name-based UUID hashed with MD5 * 4. Randomly generated UUID * 5. Name-based UUID hashed with SHA-1 + * 6. Reordered time UUID + * 7. Unix Epoch time UUID * * This returns `null` if the UUID is not an RFC 4122 variant, since version * is only meaningful for this variant. diff --git a/ramsey/uuid/src/Rfc4122/MaxTrait.php b/ramsey/uuid/src/Rfc4122/MaxTrait.php new file mode 100644 index 000000000..dedb72798 --- /dev/null +++ b/ramsey/uuid/src/Rfc4122/MaxTrait.php @@ -0,0 +1,41 @@ + + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +/** + * Provides common functionality for max UUIDs + * + * The max UUID is special form of UUID that is specified to have all 128 bits + * set to one. It is the inverse of the nil UUID. + * + * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.10 Max UUID + * + * @psalm-immutable + */ +trait MaxTrait +{ + /** + * Returns the bytes that comprise the fields + */ + abstract public function getBytes(): string; + + /** + * Returns true if the byte string represents a max UUID + */ + public function isMax(): bool + { + return $this->getBytes() === "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"; + } +} diff --git a/ramsey/uuid/src/Rfc4122/MaxUuid.php b/ramsey/uuid/src/Rfc4122/MaxUuid.php new file mode 100644 index 000000000..e5ffa72c6 --- /dev/null +++ b/ramsey/uuid/src/Rfc4122/MaxUuid.php @@ -0,0 +1,27 @@ + + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +use Ramsey\Uuid\Uuid; + +/** + * The max UUID is special form of UUID that is specified to have all 128 bits + * set to one + * + * @psalm-immutable + */ +final class MaxUuid extends Uuid implements UuidInterface +{ +} diff --git a/ramsey/uuid/src/Rfc4122/TimeTrait.php b/ramsey/uuid/src/Rfc4122/TimeTrait.php new file mode 100644 index 000000000..5d939fac6 --- /dev/null +++ b/ramsey/uuid/src/Rfc4122/TimeTrait.php @@ -0,0 +1,55 @@ + + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +use DateTimeImmutable; +use DateTimeInterface; +use Ramsey\Uuid\Exception\DateTimeException; +use Throwable; + +use function str_pad; + +use const STR_PAD_LEFT; + +/** + * Provides common functionality for getting the time from a time-based UUID + * + * @psalm-immutable + */ +trait TimeTrait +{ + /** + * Returns a DateTimeInterface object representing the timestamp associated + * with the UUID + * + * @return DateTimeImmutable A PHP DateTimeImmutable instance representing + * the timestamp of a time-based UUID + */ + public function getDateTime(): DateTimeInterface + { + $time = $this->timeConverter->convertTime($this->fields->getTimestamp()); + + try { + return new DateTimeImmutable( + '@' + . $time->getSeconds()->toString() + . '.' + . str_pad($time->getMicroseconds()->toString(), 6, '0', STR_PAD_LEFT) + ); + } catch (Throwable $e) { + throw new DateTimeException($e->getMessage(), (int) $e->getCode(), $e); + } + } +} diff --git a/ramsey/uuid/src/Rfc4122/UuidBuilder.php b/ramsey/uuid/src/Rfc4122/UuidBuilder.php index 736931af2..2c2677db7 100644 --- a/ramsey/uuid/src/Rfc4122/UuidBuilder.php +++ b/ramsey/uuid/src/Rfc4122/UuidBuilder.php @@ -17,11 +17,13 @@ use Ramsey\Uuid\Builder\UuidBuilderInterface; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Converter\Time\UnixTimeConverter; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Exception\UnableToBuildUuidException; use Ramsey\Uuid\Exception\UnsupportedOperationException; -use Ramsey\Uuid\Nonstandard\UuidV6; +use Ramsey\Uuid\Math\BrickMathCalculator; use Ramsey\Uuid\Rfc4122\UuidInterface as Rfc4122UuidInterface; +use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidInterface; use Throwable; @@ -32,15 +34,7 @@ */ class UuidBuilder implements UuidBuilderInterface { - /** - * @var NumberConverterInterface - */ - private $numberConverter; - - /** - * @var TimeConverterInterface - */ - private $timeConverter; + private TimeConverterInterface $unixTimeConverter; /** * Constructs the DefaultUuidBuilder @@ -48,14 +42,18 @@ class UuidBuilder implements UuidBuilderInterface * @param NumberConverterInterface $numberConverter The number converter to * use when constructing the Uuid * @param TimeConverterInterface $timeConverter The time converter to use - * for converting timestamps extracted from a UUID to Unix timestamps + * for converting Gregorian time extracted from version 1, 2, and 6 + * UUIDs to Unix timestamps + * @param TimeConverterInterface|null $unixTimeConverter The time converter + * to use for converter Unix Epoch time extracted from version 7 UUIDs + * to Unix timestamps */ public function __construct( - NumberConverterInterface $numberConverter, - TimeConverterInterface $timeConverter + private NumberConverterInterface $numberConverter, + private TimeConverterInterface $timeConverter, + ?TimeConverterInterface $unixTimeConverter = null ) { - $this->numberConverter = $numberConverter; - $this->timeConverter = $timeConverter; + $this->unixTimeConverter = $unixTimeConverter ?? new UnixTimeConverter(new BrickMathCalculator()); } /** @@ -71,25 +69,34 @@ public function __construct( public function build(CodecInterface $codec, string $bytes): UuidInterface { try { + /** @var Fields $fields */ $fields = $this->buildFields($bytes); if ($fields->isNil()) { return new NilUuid($fields, $this->numberConverter, $codec, $this->timeConverter); } + if ($fields->isMax()) { + return new MaxUuid($fields, $this->numberConverter, $codec, $this->timeConverter); + } + switch ($fields->getVersion()) { - case 1: + case Uuid::UUID_TYPE_TIME: return new UuidV1($fields, $this->numberConverter, $codec, $this->timeConverter); - case 2: + case Uuid::UUID_TYPE_DCE_SECURITY: return new UuidV2($fields, $this->numberConverter, $codec, $this->timeConverter); - case 3: + case Uuid::UUID_TYPE_HASH_MD5: return new UuidV3($fields, $this->numberConverter, $codec, $this->timeConverter); - case 4: + case Uuid::UUID_TYPE_RANDOM: return new UuidV4($fields, $this->numberConverter, $codec, $this->timeConverter); - case 5: + case Uuid::UUID_TYPE_HASH_SHA1: return new UuidV5($fields, $this->numberConverter, $codec, $this->timeConverter); - case 6: + case Uuid::UUID_TYPE_REORDERED_TIME: return new UuidV6($fields, $this->numberConverter, $codec, $this->timeConverter); + case Uuid::UUID_TYPE_UNIX_TIME: + return new UuidV7($fields, $this->numberConverter, $codec, $this->unixTimeConverter); + case Uuid::UUID_TYPE_CUSTOM: + return new UuidV8($fields, $this->numberConverter, $codec, $this->timeConverter); } throw new UnsupportedOperationException( diff --git a/ramsey/uuid/src/Rfc4122/UuidInterface.php b/ramsey/uuid/src/Rfc4122/UuidInterface.php index 3e4d9faee..e80f33bef 100644 --- a/ramsey/uuid/src/Rfc4122/UuidInterface.php +++ b/ramsey/uuid/src/Rfc4122/UuidInterface.php @@ -26,11 +26,4 @@ */ interface UuidInterface extends BaseUuidInterface { - /** - * Returns the string standard representation of the UUID as a URN - * - * @link http://en.wikipedia.org/wiki/Uniform_Resource_Name Uniform Resource Name - * @link https://tools.ietf.org/html/rfc4122#section-3 RFC 4122, § 3: Namespace Registration Template - */ - public function getUrn(): string; } diff --git a/ramsey/uuid/src/Rfc4122/UuidV1.php b/ramsey/uuid/src/Rfc4122/UuidV1.php index 764e42f84..515c038d9 100644 --- a/ramsey/uuid/src/Rfc4122/UuidV1.php +++ b/ramsey/uuid/src/Rfc4122/UuidV1.php @@ -14,31 +14,25 @@ namespace Ramsey\Uuid\Rfc4122; -use DateTimeImmutable; -use DateTimeInterface; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; -use Ramsey\Uuid\Exception\DateTimeException; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; use Ramsey\Uuid\Uuid; -use Throwable; - -use function str_pad; - -use const STR_PAD_LEFT; /** - * Time-based, or version 1, UUIDs include timestamp, clock sequence, and node + * Gregorian time, or version 1, UUIDs include timestamp, clock sequence, and node * values that are combined into a 128-bit unsigned integer * * @psalm-immutable */ final class UuidV1 extends Uuid implements UuidInterface { + use TimeTrait; + /** - * Creates a version 1 (time-based) UUID + * Creates a version 1 (Gregorian time) UUID * * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID * @param NumberConverterInterface $numberConverter The number converter to use @@ -63,30 +57,4 @@ public function __construct( parent::__construct($fields, $numberConverter, $codec, $timeConverter); } - - /** - * Returns a DateTimeInterface object representing the timestamp associated - * with the UUID - * - * The timestamp value is only meaningful in a time-based UUID, which - * has version type 1. - * - * @return DateTimeImmutable A PHP DateTimeImmutable instance representing - * the timestamp of a version 1 UUID - */ - public function getDateTime(): DateTimeInterface - { - $time = $this->timeConverter->convertTime($this->fields->getTimestamp()); - - try { - return new DateTimeImmutable( - '@' - . $time->getSeconds()->toString() - . '.' - . str_pad($time->getMicroseconds()->toString(), 6, '0', STR_PAD_LEFT) - ); - } catch (Throwable $e) { - throw new DateTimeException($e->getMessage(), (int) $e->getCode(), $e); - } - } } diff --git a/ramsey/uuid/src/Rfc4122/UuidV2.php b/ramsey/uuid/src/Rfc4122/UuidV2.php index 74906f050..c8ccbe422 100644 --- a/ramsey/uuid/src/Rfc4122/UuidV2.php +++ b/ramsey/uuid/src/Rfc4122/UuidV2.php @@ -14,28 +14,33 @@ namespace Ramsey\Uuid\Rfc4122; -use DateTimeImmutable; -use DateTimeInterface; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; -use Ramsey\Uuid\Exception\DateTimeException; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; use Ramsey\Uuid\Type\Integer as IntegerObject; use Ramsey\Uuid\Uuid; -use Throwable; use function hexdec; -use function str_pad; - -use const STR_PAD_LEFT; /** * DCE Security version, or version 2, UUIDs include local domain identifier, * local ID for the specified domain, and node values that are combined into a * 128-bit unsigned integer * + * It is important to note that a version 2 UUID suffers from some loss of + * fidelity of the timestamp, due to replacing the time_low field with the + * local identifier. When constructing the timestamp value for date + * purposes, we replace the local identifier bits with zeros. As a result, + * the timestamp can be off by a range of 0 to 429.4967295 seconds (or 7 + * minutes, 9 seconds, and 496730 microseconds). + * + * Astute observers might note this value directly corresponds to 2^32 - 1, + * or 0xffffffff. The local identifier is 32-bits, and we have set each of + * these bits to 0, so the maximum range of timestamp drift is 0x00000000 + * to 0xffffffff (counted in 100-nanosecond intervals). + * * @link https://publications.opengroup.org/c311 DCE 1.1: Authentication and Security Services * @link https://publications.opengroup.org/c706 DCE 1.1: Remote Procedure Call * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01 DCE 1.1: Auth & Sec, §5.2.1.1 @@ -47,6 +52,8 @@ */ final class UuidV2 extends Uuid implements UuidInterface { + use TimeTrait; + /** * Creates a version 2 (DCE Security) UUID * @@ -74,41 +81,6 @@ public function __construct( parent::__construct($fields, $numberConverter, $codec, $timeConverter); } - /** - * Returns a DateTimeInterface object representing the timestamp associated - * with the UUID - * - * It is important to note that a version 2 UUID suffers from some loss of - * fidelity of the timestamp, due to replacing the time_low field with the - * local identifier. When constructing the timestamp value for date - * purposes, we replace the local identifier bits with zeros. As a result, - * the timestamp can be off by a range of 0 to 429.4967295 seconds (or 7 - * minutes, 9 seconds, and 496730 microseconds). - * - * Astute observers might note this value directly corresponds to 2^32 - 1, - * or 0xffffffff. The local identifier is 32-bits, and we have set each of - * these bits to 0, so the maximum range of timestamp drift is 0x00000000 - * to 0xffffffff (counted in 100-nanosecond intervals). - * - * @return DateTimeImmutable A PHP DateTimeImmutable instance representing - * the timestamp of a version 2 UUID - */ - public function getDateTime(): DateTimeInterface - { - $time = $this->timeConverter->convertTime($this->fields->getTimestamp()); - - try { - return new DateTimeImmutable( - '@' - . $time->getSeconds()->toString() - . '.' - . str_pad($time->getMicroseconds()->toString(), 6, '0', STR_PAD_LEFT) - ); - } catch (Throwable $e) { - throw new DateTimeException($e->getMessage(), (int) $e->getCode(), $e); - } - } - /** * Returns the local domain used to create this version 2 UUID */ diff --git a/ramsey/uuid/src/Rfc4122/UuidV6.php b/ramsey/uuid/src/Rfc4122/UuidV6.php new file mode 100644 index 000000000..7e3743391 --- /dev/null +++ b/ramsey/uuid/src/Rfc4122/UuidV6.php @@ -0,0 +1,29 @@ + + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +use Ramsey\Uuid\Nonstandard\UuidV6 as NonstandardUuidV6; + +/** + * Reordered time, or version 6, UUIDs include timestamp, clock sequence, and + * node values that are combined into a 128-bit unsigned integer + * + * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.6 UUID Version 6 + * + * @psalm-immutable + */ +final class UuidV6 extends NonstandardUuidV6 implements UuidInterface +{ +} diff --git a/ramsey/uuid/src/Rfc4122/UuidV7.php b/ramsey/uuid/src/Rfc4122/UuidV7.php new file mode 100644 index 000000000..5b524c486 --- /dev/null +++ b/ramsey/uuid/src/Rfc4122/UuidV7.php @@ -0,0 +1,62 @@ + + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +use Ramsey\Uuid\Codec\CodecInterface; +use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Exception\InvalidArgumentException; +use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; +use Ramsey\Uuid\Uuid; + +/** + * Unix Epoch time, or version 7, UUIDs include a timestamp in milliseconds + * since the Unix Epoch, along with random bytes + * + * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.7 UUID Version 7 + * + * @psalm-immutable + */ +final class UuidV7 extends Uuid implements UuidInterface +{ + use TimeTrait; + + /** + * Creates a version 7 (Unix Epoch time) UUID + * + * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID + * @param NumberConverterInterface $numberConverter The number converter to use + * for converting hex values to/from integers + * @param CodecInterface $codec The codec to use when encoding or decoding + * UUID strings + * @param TimeConverterInterface $timeConverter The time converter to use + * for converting timestamps extracted from a UUID to unix timestamps + */ + public function __construct( + Rfc4122FieldsInterface $fields, + NumberConverterInterface $numberConverter, + CodecInterface $codec, + TimeConverterInterface $timeConverter + ) { + if ($fields->getVersion() !== Uuid::UUID_TYPE_UNIX_TIME) { + throw new InvalidArgumentException( + 'Fields used to create a UuidV7 must represent a ' + . 'version 7 (Unix Epoch time) UUID' + ); + } + + parent::__construct($fields, $numberConverter, $codec, $timeConverter); + } +} diff --git a/ramsey/uuid/src/Rfc4122/UuidV8.php b/ramsey/uuid/src/Rfc4122/UuidV8.php new file mode 100644 index 000000000..78b0290c7 --- /dev/null +++ b/ramsey/uuid/src/Rfc4122/UuidV8.php @@ -0,0 +1,65 @@ + + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +use Ramsey\Uuid\Codec\CodecInterface; +use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Exception\InvalidArgumentException; +use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; +use Ramsey\Uuid\Uuid; + +/** + * Version 8, Custom UUIDs provide an RFC 4122 compatible format for + * experimental or vendor-specific uses + * + * The only requirement for version 8 UUIDs is that the version and variant bits + * must be set. Otherwise, implementations are free to set the other bits + * according to their needs. As a result, the uniqueness of version 8 UUIDs is + * implementation-specific and should not be assumed. + * + * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.8 UUID Version 8 + * + * @psalm-immutable + */ +final class UuidV8 extends Uuid implements UuidInterface +{ + /** + * Creates a version 8 (custom) UUID + * + * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID + * @param NumberConverterInterface $numberConverter The number converter to use + * for converting hex values to/from integers + * @param CodecInterface $codec The codec to use when encoding or decoding + * UUID strings + * @param TimeConverterInterface $timeConverter The time converter to use + * for converting timestamps extracted from a UUID to unix timestamps + */ + public function __construct( + Rfc4122FieldsInterface $fields, + NumberConverterInterface $numberConverter, + CodecInterface $codec, + TimeConverterInterface $timeConverter + ) { + if ($fields->getVersion() !== Uuid::UUID_TYPE_CUSTOM) { + throw new InvalidArgumentException( + 'Fields used to create a UuidV8 must represent a ' + . 'version 8 (custom) UUID' + ); + } + + parent::__construct($fields, $numberConverter, $codec, $timeConverter); + } +} diff --git a/ramsey/uuid/src/Rfc4122/Validator.php b/ramsey/uuid/src/Rfc4122/Validator.php index ed43c982f..e82a11e6e 100644 --- a/ramsey/uuid/src/Rfc4122/Validator.php +++ b/ramsey/uuid/src/Rfc4122/Validator.php @@ -28,7 +28,7 @@ final class Validator implements ValidatorInterface { private const VALID_PATTERN = '\A[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-' - . '[1-5]{1}[0-9A-Fa-f]{3}-[ABab89]{1}[0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}\z'; + . '[1-8][0-9A-Fa-f]{3}-[ABab89][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}\z'; /** * @psalm-return non-empty-string @@ -43,7 +43,8 @@ public function getPattern(): string public function validate(string $uuid): bool { $uuid = str_replace(['urn:', 'uuid:', 'URN:', 'UUID:', '{', '}'], '', $uuid); + $uuid = strtolower($uuid); - return $uuid === Uuid::NIL || preg_match('/' . self::VALID_PATTERN . '/Dms', $uuid); + return $uuid === Uuid::NIL || $uuid === Uuid::MAX || preg_match('/' . self::VALID_PATTERN . '/Dms', $uuid); } } diff --git a/ramsey/uuid/src/Rfc4122/VariantTrait.php b/ramsey/uuid/src/Rfc4122/VariantTrait.php index c32a8ce80..1041de51e 100644 --- a/ramsey/uuid/src/Rfc4122/VariantTrait.php +++ b/ramsey/uuid/src/Rfc4122/VariantTrait.php @@ -19,8 +19,8 @@ use function decbin; use function str_pad; +use function str_starts_with; use function strlen; -use function strpos; use function substr; use function unpack; @@ -58,6 +58,13 @@ public function getVariant(): int throw new InvalidBytesException('Invalid number of bytes'); } + if ($this->isMax() || $this->isNil()) { + // RFC 4122 defines these special types of UUID, so we will consider + // them as belonging to the RFC 4122 variant. + return Uuid::RFC_4122; + } + + /** @var int[] $parts */ $parts = unpack('n*', $this->getBytes()); // $parts[5] is a 16-bit, unsigned integer containing the variant bits @@ -66,7 +73,7 @@ public function getVariant(): int // three characters (three most-significant bits) to determine the // variant. $binary = str_pad( - decbin((int) $parts[5]), + decbin($parts[5]), 16, '0', STR_PAD_LEFT @@ -75,15 +82,13 @@ public function getVariant(): int $msb = substr($binary, 0, 3); if ($msb === '111') { - $variant = Uuid::RESERVED_FUTURE; + return Uuid::RESERVED_FUTURE; } elseif ($msb === '110') { - $variant = Uuid::RESERVED_MICROSOFT; - } elseif (strpos($msb, '10') === 0) { - $variant = Uuid::RFC_4122; - } else { - $variant = Uuid::RESERVED_NCS; + return Uuid::RESERVED_MICROSOFT; + } elseif (str_starts_with($msb, '10')) { + return Uuid::RFC_4122; } - return $variant; + return Uuid::RESERVED_NCS; } } diff --git a/ramsey/uuid/src/Rfc4122/VersionTrait.php b/ramsey/uuid/src/Rfc4122/VersionTrait.php index cee55fbef..0195e46c7 100644 --- a/ramsey/uuid/src/Rfc4122/VersionTrait.php +++ b/ramsey/uuid/src/Rfc4122/VersionTrait.php @@ -14,6 +14,8 @@ namespace Ramsey\Uuid\Rfc4122; +use Ramsey\Uuid\Uuid; + /** * Provides common functionality for handling the version, as defined by RFC 4122 * @@ -26,6 +28,11 @@ trait VersionTrait */ abstract public function getVersion(): ?int; + /** + * Returns true if these fields represent a max UUID + */ + abstract public function isMax(): bool; + /** * Returns true if these fields represent a nil UUID */ @@ -38,20 +45,16 @@ abstract public function isNil(): bool; */ private function isCorrectVersion(): bool { - if ($this->isNil()) { + if ($this->isNil() || $this->isMax()) { return true; } - switch ($this->getVersion()) { - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - return true; - } - - return false; + return match ($this->getVersion()) { + Uuid::UUID_TYPE_TIME, Uuid::UUID_TYPE_DCE_SECURITY, + Uuid::UUID_TYPE_HASH_MD5, Uuid::UUID_TYPE_RANDOM, + Uuid::UUID_TYPE_HASH_SHA1, Uuid::UUID_TYPE_REORDERED_TIME, + Uuid::UUID_TYPE_UNIX_TIME, Uuid::UUID_TYPE_CUSTOM => true, + default => false, + }; } } diff --git a/ramsey/uuid/src/Type/Decimal.php b/ramsey/uuid/src/Type/Decimal.php index 5ba886535..acc5e754b 100644 --- a/ramsey/uuid/src/Type/Decimal.php +++ b/ramsey/uuid/src/Type/Decimal.php @@ -15,8 +15,11 @@ namespace Ramsey\Uuid\Type; use Ramsey\Uuid\Exception\InvalidArgumentException; +use ValueError; use function is_numeric; +use function sprintf; +use function str_starts_with; /** * A value object representing a decimal @@ -32,20 +35,10 @@ */ final class Decimal implements NumberInterface { - /** - * @var string - */ - private $value; - - /** - * @var bool - */ - private $isNegative = false; + private string $value; + private bool $isNegative = false; - /** - * @param mixed $value The decimal value to store - */ - public function __construct($value) + public function __construct(float | int | string | self $value) { $value = (string) $value; @@ -57,7 +50,7 @@ public function __construct($value) } // Remove the leading +-symbol. - if (strpos($value, '+') === 0) { + if (str_starts_with($value, '+')) { $value = substr($value, 1); } @@ -66,7 +59,7 @@ public function __construct($value) $value = '0'; } - if (strpos($value, '-') === 0) { + if (str_starts_with($value, '-')) { $this->isNegative = true; } @@ -98,15 +91,39 @@ public function serialize(): string return $this->toString(); } + /** + * @return array{string: string} + */ + public function __serialize(): array + { + return ['string' => $this->toString()]; + } + /** * Constructs the object from a serialized string representation * - * @param string $serialized The serialized string representation of the object + * @param string $data The serialized string representation of the object + * + * @psalm-suppress UnusedMethodCall + */ + public function unserialize(string $data): void + { + $this->__construct($data); + } + + /** + * @param array{string?: string} $data * - * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + * @psalm-suppress UnusedMethodCall */ - public function unserialize($serialized): void + public function __unserialize(array $data): void { - $this->__construct($serialized); + // @codeCoverageIgnoreStart + if (!isset($data['string'])) { + throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__)); + } + // @codeCoverageIgnoreEnd + + $this->unserialize($data['string']); } } diff --git a/ramsey/uuid/src/Type/Hexadecimal.php b/ramsey/uuid/src/Type/Hexadecimal.php index 11450186e..bf71ec4b1 100644 --- a/ramsey/uuid/src/Type/Hexadecimal.php +++ b/ramsey/uuid/src/Type/Hexadecimal.php @@ -15,10 +15,10 @@ namespace Ramsey\Uuid\Type; use Ramsey\Uuid\Exception\InvalidArgumentException; +use ValueError; -use function ctype_xdigit; -use function strpos; -use function strtolower; +use function preg_match; +use function sprintf; use function substr; /** @@ -32,29 +32,14 @@ */ final class Hexadecimal implements TypeInterface { - /** - * @var string - */ - private $value; + private string $value; /** - * @param string $value The hexadecimal value to store + * @param self|string $value The hexadecimal value to store */ - public function __construct(string $value) + public function __construct(self | string $value) { - $value = strtolower($value); - - if (strpos($value, '0x') === 0) { - $value = substr($value, 2); - } - - if (!ctype_xdigit($value)) { - throw new InvalidArgumentException( - 'Value must be a hexadecimal number' - ); - } - - $this->value = $value; + $this->value = $value instanceof self ? (string) $value : $this->prepareValue($value); } public function toString(): string @@ -77,15 +62,54 @@ public function serialize(): string return $this->toString(); } + /** + * @return array{string: string} + */ + public function __serialize(): array + { + return ['string' => $this->toString()]; + } + /** * Constructs the object from a serialized string representation * - * @param string $serialized The serialized string representation of the object + * @param string $data The serialized string representation of the object * - * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + * @psalm-suppress UnusedMethodCall */ - public function unserialize($serialized): void + public function unserialize(string $data): void { - $this->__construct($serialized); + $this->__construct($data); + } + + /** + * @param array{string?: string} $data + */ + public function __unserialize(array $data): void + { + // @codeCoverageIgnoreStart + if (!isset($data['string'])) { + throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__)); + } + // @codeCoverageIgnoreEnd + + $this->unserialize($data['string']); + } + + private function prepareValue(string $value): string + { + $value = strtolower($value); + + if (str_starts_with($value, '0x')) { + $value = substr($value, 2); + } + + if (!preg_match('/^[A-Fa-f0-9]+$/', $value)) { + throw new InvalidArgumentException( + 'Value must be a hexadecimal number' + ); + } + + return $value; } } diff --git a/ramsey/uuid/src/Type/Integer.php b/ramsey/uuid/src/Type/Integer.php index 05d420a85..50dac9934 100644 --- a/ramsey/uuid/src/Type/Integer.php +++ b/ramsey/uuid/src/Type/Integer.php @@ -15,10 +15,12 @@ namespace Ramsey\Uuid\Type; use Ramsey\Uuid\Exception\InvalidArgumentException; +use ValueError; -use function ctype_digit; -use function ltrim; -use function strpos; +use function assert; +use function is_numeric; +use function preg_match; +use function sprintf; use function substr; /** @@ -36,51 +38,15 @@ final class Integer implements NumberInterface { /** - * @var string + * @psalm-var numeric-string */ - private $value; + private string $value; - /** - * @var bool - */ - private $isNegative = false; + private bool $isNegative = false; - /** - * @param mixed $value The integer value to store - */ - public function __construct($value) + public function __construct(float | int | string | self $value) { - $value = (string) $value; - $sign = '+'; - - // If the value contains a sign, remove it for ctype_digit() check. - if (strpos($value, '-') === 0 || strpos($value, '+') === 0) { - $sign = substr($value, 0, 1); - $value = substr($value, 1); - } - - if (!ctype_digit($value)) { - throw new InvalidArgumentException( - 'Value must be a signed integer or a string containing only ' - . 'digits 0-9 and, optionally, a sign (+ or -)' - ); - } - - // Trim any leading zeros. - $value = ltrim($value, '0'); - - // Set to zero if the string is empty after trimming zeros. - if ($value === '') { - $value = '0'; - } - - // Add the negative sign back to the value. - if ($sign === '-' && $value !== '0') { - $value = $sign . $value; - $this->isNegative = true; - } - - $this->value = $value; + $this->value = $value instanceof self ? (string) $value : $this->prepareValue($value); } public function isNegative(): bool @@ -88,11 +54,17 @@ public function isNegative(): bool return $this->isNegative; } + /** + * @psalm-return numeric-string + */ public function toString(): string { return $this->value; } + /** + * @psalm-return numeric-string + */ public function __toString(): string { return $this->toString(); @@ -108,15 +80,79 @@ public function serialize(): string return $this->toString(); } + /** + * @return array{string: string} + */ + public function __serialize(): array + { + return ['string' => $this->toString()]; + } + /** * Constructs the object from a serialized string representation * - * @param string $serialized The serialized string representation of the object + * @param string $data The serialized string representation of the object * - * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + * @psalm-suppress UnusedMethodCall */ - public function unserialize($serialized): void + public function unserialize(string $data): void { - $this->__construct($serialized); + $this->__construct($data); + } + + /** + * @param array{string?: string} $data + */ + public function __unserialize(array $data): void + { + // @codeCoverageIgnoreStart + if (!isset($data['string'])) { + throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__)); + } + // @codeCoverageIgnoreEnd + + $this->unserialize($data['string']); + } + + /** + * @return numeric-string + */ + private function prepareValue(float | int | string $value): string + { + $value = (string) $value; + $sign = '+'; + + // If the value contains a sign, remove it for digit pattern check. + if (str_starts_with($value, '-') || str_starts_with($value, '+')) { + $sign = substr($value, 0, 1); + $value = substr($value, 1); + } + + if (!preg_match('/^\d+$/', $value)) { + throw new InvalidArgumentException( + 'Value must be a signed integer or a string containing only ' + . 'digits 0-9 and, optionally, a sign (+ or -)' + ); + } + + // Trim any leading zeros. + $value = ltrim($value, '0'); + + // Set to zero if the string is empty after trimming zeros. + if ($value === '') { + $value = '0'; + } + + // Add the negative sign back to the value. + if ($sign === '-' && $value !== '0') { + $value = $sign . $value; + + /** @psalm-suppress InaccessibleProperty */ + $this->isNegative = true; + } + + assert(is_numeric($value)); + + return $value; } } diff --git a/ramsey/uuid/src/Type/Time.php b/ramsey/uuid/src/Type/Time.php index f6a140f05..0cedb4476 100644 --- a/ramsey/uuid/src/Type/Time.php +++ b/ramsey/uuid/src/Type/Time.php @@ -16,10 +16,11 @@ use Ramsey\Uuid\Exception\UnsupportedOperationException; use Ramsey\Uuid\Type\Integer as IntegerObject; -use stdClass; +use ValueError; use function json_decode; use function json_encode; +use function sprintf; /** * A value object representing a timestamp @@ -32,22 +33,13 @@ */ final class Time implements TypeInterface { - /** - * @var IntegerObject - */ - private $seconds; - - /** - * @var IntegerObject - */ - private $microseconds; + private IntegerObject $seconds; + private IntegerObject $microseconds; - /** - * @param mixed $seconds - * @param mixed $microseconds - */ - public function __construct($seconds, $microseconds = 0) - { + public function __construct( + float | int | string | IntegerObject $seconds, + float | int | string | IntegerObject $microseconds = 0, + ) { $this->seconds = new IntegerObject($seconds); $this->microseconds = new IntegerObject($microseconds); } @@ -64,7 +56,7 @@ public function getMicroseconds(): IntegerObject public function toString(): string { - return $this->seconds->toString() . '.' . $this->microseconds->toString(); + return $this->seconds->toString() . '.' . sprintf('%06s', $this->microseconds->toString()); } public function __toString(): string @@ -88,24 +80,49 @@ public function serialize(): string return (string) json_encode($this); } + /** + * @return array{seconds: string, microseconds: string} + */ + public function __serialize(): array + { + return [ + 'seconds' => $this->getSeconds()->toString(), + 'microseconds' => $this->getMicroseconds()->toString(), + ]; + } + /** * Constructs the object from a serialized string representation * - * @param string $serialized The serialized string representation of the object + * @param string $data The serialized string representation of the object * - * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + * @psalm-suppress UnusedMethodCall */ - public function unserialize($serialized): void + public function unserialize(string $data): void { - /** @var stdClass $time */ - $time = json_decode($serialized); + /** @var array{seconds?: int|float|string, microseconds?: int|float|string} $time */ + $time = json_decode($data, true); - if (!isset($time->seconds) || !isset($time->microseconds)) { + if (!isset($time['seconds']) || !isset($time['microseconds'])) { throw new UnsupportedOperationException( 'Attempted to unserialize an invalid value' ); } - $this->__construct($time->seconds, $time->microseconds); + $this->__construct($time['seconds'], $time['microseconds']); + } + + /** + * @param array{seconds?: string, microseconds?: string} $data + */ + public function __unserialize(array $data): void + { + // @codeCoverageIgnoreStart + if (!isset($data['seconds']) || !isset($data['microseconds'])) { + throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__)); + } + // @codeCoverageIgnoreEnd + + $this->__construct($data['seconds'], $data['microseconds']); } } diff --git a/ramsey/uuid/src/Uuid.php b/ramsey/uuid/src/Uuid.php index 762dfdbae..e0384a50c 100644 --- a/ramsey/uuid/src/Uuid.php +++ b/ramsey/uuid/src/Uuid.php @@ -14,18 +14,24 @@ namespace Ramsey\Uuid; +use BadMethodCallException; use DateTimeInterface; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Exception\UnsupportedOperationException; use Ramsey\Uuid\Fields\FieldsInterface; use Ramsey\Uuid\Lazy\LazyUuidFromString; use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; +use ValueError; +use function assert; use function bin2hex; +use function method_exists; use function preg_match; +use function sprintf; use function str_replace; use function strcmp; use function strlen; @@ -79,6 +85,14 @@ class Uuid implements UuidInterface */ public const NIL = '00000000-0000-0000-0000-000000000000'; + /** + * The max UUID is a special form of UUID that is specified to have all 128 + * bits set to one + * + * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.10 Max UUID + */ + public const MAX = 'ffffffff-ffff-ffff-ffff-ffffffffffff'; + /** * Variant: reserved, NCS backward compatibility * @@ -113,7 +127,7 @@ class Uuid implements UuidInterface public const VALID_PATTERN = '^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$'; /** - * Version 1 (time-based) UUID + * Version 1 (Gregorian time) UUID * * @link https://tools.ietf.org/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3: Version */ @@ -153,15 +167,28 @@ class Uuid implements UuidInterface public const UUID_TYPE_HASH_SHA1 = 5; /** - * Version 6 (ordered-time) UUID + * @deprecated Use {@see Uuid::UUID_TYPE_REORDERED_TIME} instead. + */ + public const UUID_TYPE_PEABODY = 6; + + /** + * Version 6 (reordered time) UUID * - * This is named `UUID_TYPE_PEABODY`, since the specification is still in - * draft form, and the primary author/editor's name is Brad Peabody. + * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.6 UUID Version 6 + */ + public const UUID_TYPE_REORDERED_TIME = 6; + + /** + * Version 7 (Unix Epoch time) UUID * - * @link https://github.com/uuid6/uuid6-ietf-draft UUID version 6 IETF draft - * @link http://gh.peabody.io/uuidv6/ "Version 6" UUIDs + * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.7 UUID Version 7 */ - public const UUID_TYPE_PEABODY = 6; + public const UUID_TYPE_UNIX_TIME = 7; + + /** + * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.8 UUID Version 8 + */ + public const UUID_TYPE_CUSTOM = 8; /** * DCE Security principal domain @@ -195,38 +222,19 @@ class Uuid implements UuidInterface self::DCE_DOMAIN_ORG => 'org', ]; - /** - * @var UuidFactoryInterface|null - */ - private static $factory = null; - - /** - * @var bool flag to detect if the UUID factory was replaced internally, which disables all optimizations - * for the default/happy path internal scenarios - */ - private static $factoryReplaced = false; - - /** - * @var CodecInterface - */ - protected $codec; + private static ?UuidFactoryInterface $factory = null; /** - * The fields that make up this UUID - * - * @var Rfc4122FieldsInterface + * @var bool flag to detect if the UUID factory was replaced internally, + * which disables all optimizations for the default/happy path internal + * scenarios */ - protected $fields; + private static bool $factoryReplaced = false; - /** - * @var NumberConverterInterface - */ - protected $numberConverter; - - /** - * @var TimeConverterInterface - */ - protected $timeConverter; + protected CodecInterface $codec; + protected NumberConverterInterface $numberConverter; + protected Rfc4122FieldsInterface $fields; + protected TimeConverterInterface $timeConverter; /** * Creates a universally unique identifier (UUID) from an array of fields @@ -238,9 +246,9 @@ class Uuid implements UuidInterface * ``` * use Ramsey\Uuid\Uuid; * - * $timeBasedUuid = Uuid::uuid1(); - * $namespaceMd5Uuid = Uuid::uuid3(Uuid::NAMESPACE_URL, 'http://php.net/'); - * $randomUuid = Uuid::uuid4(); + * $timeBasedUuid = Uuid::uuid1(); + * $namespaceMd5Uuid = Uuid::uuid3(Uuid::NAMESPACE_URL, 'http://php.net/'); + * $randomUuid = Uuid::uuid4(); * $namespaceSha1Uuid = Uuid::uuid5(Uuid::NAMESPACE_URL, 'http://php.net/'); * ``` * @@ -285,25 +293,31 @@ public function jsonSerialize(): string */ public function serialize(): string { - return $this->getBytes(); + return $this->codec->encode($this); + } + + /** + * @return array{bytes: string} + */ + public function __serialize(): array + { + return ['bytes' => $this->serialize()]; } /** * Re-constructs the object from its serialized form * - * @param string $serialized The serialized PHP string to unserialize into + * @param string $data The serialized PHP string to unserialize into * a UuidInterface instance - * - * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint */ - public function unserialize($serialized): void + public function unserialize(string $data): void { - if (strlen($serialized) === 16) { + if (strlen($data) === 16) { /** @var Uuid $uuid */ - $uuid = self::getFactory()->fromBytes($serialized); + $uuid = self::getFactory()->fromBytes($data); } else { /** @var Uuid $uuid */ - $uuid = self::getFactory()->fromString($serialized); + $uuid = self::getFactory()->fromString($data); } $this->codec = $uuid->codec; @@ -312,6 +326,20 @@ public function unserialize($serialized): void $this->timeConverter = $uuid->timeConverter; } + /** + * @param array{bytes?: string} $data + */ + public function __unserialize(array $data): void + { + // @codeCoverageIgnoreStart + if (!isset($data['bytes'])) { + throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__)); + } + // @codeCoverageIgnoreEnd + + $this->unserialize($data['bytes']); + } + public function compareTo(UuidInterface $other): int { $compare = strcmp($this->toString(), $other->toString()); @@ -359,6 +387,11 @@ public function getInteger(): IntegerObject return new IntegerObject($this->numberConverter->fromHex($this->getHex()->toString())); } + public function getUrn(): string + { + return 'urn:uuid:' . $this->toString(); + } + /** * @psalm-return non-empty-string */ @@ -413,20 +446,20 @@ public static function setFactory(UuidFactoryInterface $factory): void */ public static function fromBytes(string $bytes): UuidInterface { - if (! self::$factoryReplaced && strlen($bytes) === 16) { + if (!self::$factoryReplaced && strlen($bytes) === 16) { $base16Uuid = bin2hex($bytes); // Note: we are calling `fromString` internally because we don't know if the given `$bytes` is a valid UUID return self::fromString( substr($base16Uuid, 0, 8) - . '-' - . substr($base16Uuid, 8, 4) - . '-' - . substr($base16Uuid, 12, 4) - . '-' - . substr($base16Uuid, 16, 4) - . '-' - . substr($base16Uuid, 20, 12) + . '-' + . substr($base16Uuid, 8, 4) + . '-' + . substr($base16Uuid, 12, 4) + . '-' + . substr($base16Uuid, 16, 4) + . '-' + . substr($base16Uuid, 20, 12) ); } @@ -451,8 +484,11 @@ public static function fromBytes(string $bytes): UuidInterface */ public static function fromString(string $uuid): UuidInterface { - if (! self::$factoryReplaced && preg_match(LazyUuidFromString::VALID_REGEX, $uuid) === 1) { - return new LazyUuidFromString(strtolower($uuid)); + $uuid = strtolower($uuid); + if (!self::$factoryReplaced && preg_match(LazyUuidFromString::VALID_REGEX, $uuid) === 1) { + assert($uuid !== ''); + + return new LazyUuidFromString($uuid); } return self::getFactory()->fromString($uuid); @@ -479,6 +515,33 @@ public static function fromDateTime( return self::getFactory()->fromDateTime($dateTime, $node, $clockSeq); } + /** + * Creates a UUID from the Hexadecimal object + * + * @param Hexadecimal $hex Hexadecimal object representing a hexadecimal number + * + * @return UuidInterface A UuidInterface instance created from the Hexadecimal + * object representing a hexadecimal number + * + * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants, + * but under constant factory setups, this method operates in functionally pure manners + * @psalm-suppress MixedInferredReturnType,MixedReturnStatement + */ + public static function fromHexadecimal(Hexadecimal $hex): UuidInterface + { + $factory = self::getFactory(); + + if (method_exists($factory, 'fromHexadecimal')) { + /** + * @phpstan-ignore-next-line + * @psalm-suppress UndefinedInterfaceMethod + */ + return self::getFactory()->fromHexadecimal($hex); + } + + throw new BadMethodCallException('The method fromHexadecimal() does not exist on the provided factory'); + } + /** * Creates a UUID from a 128-bit integer string * @@ -492,6 +555,7 @@ public static function fromDateTime( */ public static function fromInteger(string $integer): UuidInterface { + /** @psalm-suppress ImpureMethodCall */ return self::getFactory()->fromInteger($integer); } @@ -504,20 +568,23 @@ public static function fromInteger(string $integer): UuidInterface * * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants, * but under constant factory setups, this method operates in functionally pure manners + * + * @psalm-assert-if-true =non-empty-string $uuid */ public static function isValid(string $uuid): bool { + /** @psalm-suppress ImpureMethodCall */ return self::getFactory()->getValidator()->validate($uuid); } /** - * Returns a version 1 (time-based) UUID from a host ID, sequence number, + * Returns a version 1 (Gregorian time) UUID from a host ID, sequence number, * and the current time * * @param Hexadecimal|int|string|null $node A 48-bit number representing the * hardware address; this number may be represented as an integer or a * hexadecimal string - * @param int $clockSeq A 14-bit number used to help avoid duplicates that + * @param int|null $clockSeq A 14-bit number used to help avoid duplicates that * could arise when the clock is set backwards in time or if the node ID * changes * @@ -616,12 +683,12 @@ public static function uuid5($ns, string $name): UuidInterface } /** - * Returns a version 6 (ordered-time) UUID from a host ID, sequence number, + * Returns a version 6 (reordered time) UUID from a host ID, sequence number, * and the current time * * @param Hexadecimal|null $node A 48-bit number representing the hardware * address - * @param int $clockSeq A 14-bit number used to help avoid duplicates that + * @param int|null $clockSeq A 14-bit number used to help avoid duplicates that * could arise when the clock is set backwards in time or if the node ID * changes * @@ -634,4 +701,58 @@ public static function uuid6( ): UuidInterface { return self::getFactory()->uuid6($node, $clockSeq); } + + /** + * Returns a version 7 (Unix Epoch time) UUID + * + * @param DateTimeInterface|null $dateTime An optional date/time from which + * to create the version 7 UUID. If not provided, the UUID is generated + * using the current date/time. + * + * @return UuidInterface A UuidInterface instance that represents a + * version 7 UUID + */ + public static function uuid7(?DateTimeInterface $dateTime = null): UuidInterface + { + $factory = self::getFactory(); + + if (method_exists($factory, 'uuid7')) { + /** @var UuidInterface */ + return $factory->uuid7($dateTime); + } + + throw new UnsupportedOperationException( + 'The provided factory does not support the uuid7() method', + ); + } + + /** + * Returns a version 8 (custom) UUID + * + * The bytes provided may contain any value according to your application's + * needs. Be aware, however, that other applications may not understand the + * semantics of the value. + * + * @param string $bytes A 16-byte octet string. This is an open blob + * of data that you may fill with 128 bits of information. Be aware, + * however, bits 48 through 51 will be replaced with the UUID version + * field, and bits 64 and 65 will be replaced with the UUID variant. You + * MUST NOT rely on these bits for your application needs. + * + * @return UuidInterface A UuidInterface instance that represents a + * version 8 UUID + */ + public static function uuid8(string $bytes): UuidInterface + { + $factory = self::getFactory(); + + if (method_exists($factory, 'uuid8')) { + /** @var UuidInterface */ + return $factory->uuid8($bytes); + } + + throw new UnsupportedOperationException( + 'The provided factory does not support the uuid8() method', + ); + } } diff --git a/ramsey/uuid/src/UuidFactory.php b/ramsey/uuid/src/UuidFactory.php index feddef88d..1b06ea6ed 100644 --- a/ramsey/uuid/src/UuidFactory.php +++ b/ramsey/uuid/src/UuidFactory.php @@ -24,6 +24,7 @@ use Ramsey\Uuid\Generator\NameGeneratorInterface; use Ramsey\Uuid\Generator\RandomGeneratorInterface; use Ramsey\Uuid\Generator\TimeGeneratorInterface; +use Ramsey\Uuid\Generator\UnixTimeGenerator; use Ramsey\Uuid\Lazy\LazyUuidFromString; use Ramsey\Uuid\Provider\NodeProviderInterface; use Ramsey\Uuid\Provider\Time\FixedTimeProvider; @@ -45,61 +46,26 @@ class UuidFactory implements UuidFactoryInterface { - /** - * @var CodecInterface - */ - private $codec; - - /** - * @var DceSecurityGeneratorInterface - */ - private $dceSecurityGenerator; - - /** - * @var NameGeneratorInterface - */ - private $nameGenerator; - - /** - * @var NodeProviderInterface - */ - private $nodeProvider; - - /** - * @var NumberConverterInterface - */ - private $numberConverter; - - /** - * @var RandomGeneratorInterface - */ - private $randomGenerator; - - /** - * @var TimeConverterInterface - */ - private $timeConverter; + private CodecInterface $codec; + private DceSecurityGeneratorInterface $dceSecurityGenerator; + private NameGeneratorInterface $nameGenerator; + private NodeProviderInterface $nodeProvider; + private NumberConverterInterface $numberConverter; + private RandomGeneratorInterface $randomGenerator; + private TimeConverterInterface $timeConverter; + private TimeGeneratorInterface $timeGenerator; + private TimeGeneratorInterface $unixTimeGenerator; + private UuidBuilderInterface $uuidBuilder; + private ValidatorInterface $validator; /** - * @var TimeGeneratorInterface + * @var bool whether the feature set was provided from outside, or we can + * operate under "default" assumptions */ - private $timeGenerator; + private bool $isDefaultFeatureSet; /** - * @var UuidBuilderInterface - */ - private $uuidBuilder; - - /** - * @var ValidatorInterface - */ - private $validator; - - /** @var bool whether the feature set was provided from outside, or we can operate under "default" assumptions */ - private $isDefaultFeatureSet; - - /** - * @param FeatureSet $features A set of available features in the current environment + * @param FeatureSet|null $features A set of available features in the current environment */ public function __construct(?FeatureSet $features = null) { @@ -117,6 +83,7 @@ public function __construct(?FeatureSet $features = null) $this->timeGenerator = $features->getTimeGenerator(); $this->uuidBuilder = $features->getBuilder(); $this->validator = $features->getValidator(); + $this->unixTimeGenerator = $features->getUnixTimeGenerator(); } /** @@ -342,7 +309,15 @@ public function fromDateTime( $bytes = $timeGenerator->generate($nodeHex, $clockSeq); - return $this->uuidFromBytesAndVersion($bytes, 1); + return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_TIME); + } + + /** + * @psalm-pure + */ + public function fromHexadecimal(Hexadecimal $hex): UuidInterface + { + return $this->codec->decode($hex->__toString()); } /** @@ -352,7 +327,7 @@ public function uuid1($node = null, ?int $clockSeq = null): UuidInterface { $bytes = $this->timeGenerator->generate($node, $clockSeq); - return $this->uuidFromBytesAndVersion($bytes, 1); + return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_TIME); } public function uuid2( @@ -368,7 +343,7 @@ public function uuid2( $clockSeq ); - return $this->uuidFromBytesAndVersion($bytes, 2); + return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_DCE_SECURITY); } /** @@ -377,14 +352,14 @@ public function uuid2( */ public function uuid3($ns, string $name): UuidInterface { - return $this->uuidFromNsAndName($ns, $name, 3, 'md5'); + return $this->uuidFromNsAndName($ns, $name, Uuid::UUID_TYPE_HASH_MD5, 'md5'); } public function uuid4(): UuidInterface { $bytes = $this->randomGenerator->generate(16); - return $this->uuidFromBytesAndVersion($bytes, 4); + return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_RANDOM); } /** @@ -393,7 +368,7 @@ public function uuid4(): UuidInterface */ public function uuid5($ns, string $name): UuidInterface { - return $this->uuidFromNsAndName($ns, $name, 5, 'sha1'); + return $this->uuidFromNsAndName($ns, $name, Uuid::UUID_TYPE_HASH_SHA1, 'sha1'); } public function uuid6(?Hexadecimal $node = null, ?int $clockSeq = null): UuidInterface @@ -412,7 +387,46 @@ public function uuid6(?Hexadecimal $node = null, ?int $clockSeq = null): UuidInt $v6Bytes = hex2bin(substr($v6, 1, 12) . '0' . substr($v6, -3)); $v6Bytes .= substr($bytes, 8); - return $this->uuidFromBytesAndVersion($v6Bytes, 6); + return $this->uuidFromBytesAndVersion($v6Bytes, Uuid::UUID_TYPE_REORDERED_TIME); + } + + /** + * Returns a version 7 (Unix Epoch time) UUID + * + * @param DateTimeInterface|null $dateTime An optional date/time from which + * to create the version 7 UUID. If not provided, the UUID is generated + * using the current date/time. + * + * @return UuidInterface A UuidInterface instance that represents a + * version 7 UUID + */ + public function uuid7(?DateTimeInterface $dateTime = null): UuidInterface + { + assert($this->unixTimeGenerator instanceof UnixTimeGenerator); + $bytes = $this->unixTimeGenerator->generate(null, null, $dateTime); + + return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_UNIX_TIME); + } + + /** + * Returns a version 8 (Custom) UUID + * + * The bytes provided may contain any value according to your application's + * needs. Be aware, however, that other applications may not understand the + * semantics of the value. + * + * @param string $bytes A 16-byte octet string. This is an open blob + * of data that you may fill with 128 bits of information. Be aware, + * however, bits 48 through 51 will be replaced with the UUID version + * field, and bits 64 and 65 will be replaced with the UUID variant. You + * MUST NOT rely on these bits for your application needs. + * + * @return UuidInterface A UuidInterface instance that represents a + * version 8 UUID + */ + public function uuid8(string $bytes): UuidInterface + { + return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_CUSTOM); } /** @@ -430,6 +444,7 @@ public function uuid6(?Hexadecimal $node = null, ?int $clockSeq = null): UuidInt */ public function uuid(string $bytes): UuidInterface { + /** @psalm-suppress ImpurePropertyFetch */ return $this->uuidBuilder->build($this->codec, $bytes); } @@ -447,8 +462,12 @@ public function uuid(string $bytes): UuidInterface * * @psalm-pure */ - private function uuidFromNsAndName($ns, string $name, int $version, string $hashAlgorithm): UuidInterface - { + private function uuidFromNsAndName( + UuidInterface | string $ns, + string $name, + int $version, + string $hashAlgorithm + ): UuidInterface { if (!($ns instanceof UuidInterface)) { $ns = $this->fromString($ns); } @@ -471,10 +490,14 @@ private function uuidFromNsAndName($ns, string $name, int $version, string $hash */ private function uuidFromBytesAndVersion(string $bytes, int $version): UuidInterface { - $timeHi = (int) unpack('n*', substr($bytes, 6, 2))[1]; + /** @var array $unpackedTime */ + $unpackedTime = unpack('n*', substr($bytes, 6, 2)); + $timeHi = (int) $unpackedTime[1]; $timeHiAndVersion = pack('n*', BinaryUtils::applyVersion($timeHi, $version)); - $clockSeqHi = (int) unpack('n*', substr($bytes, 8, 2))[1]; + /** @var array $unpackedClockSeq */ + $unpackedClockSeq = unpack('n*', substr($bytes, 8, 2)); + $clockSeqHi = (int) $unpackedClockSeq[1]; $clockSeqHiAndReserved = pack('n*', BinaryUtils::applyVariant($clockSeqHi)); $bytes = substr_replace($bytes, $timeHiAndVersion, 6, 2); @@ -484,6 +507,7 @@ private function uuidFromBytesAndVersion(string $bytes, int $version): UuidInter return LazyUuidFromString::fromBytes($bytes); } + /** @psalm-suppress ImpureVariable */ return $this->uuid($bytes); } } diff --git a/ramsey/uuid/src/UuidFactoryInterface.php b/ramsey/uuid/src/UuidFactoryInterface.php index 468cc6377..d99fc9d58 100644 --- a/ramsey/uuid/src/UuidFactoryInterface.php +++ b/ramsey/uuid/src/UuidFactoryInterface.php @@ -25,6 +25,61 @@ */ interface UuidFactoryInterface { + /** + * Creates a UUID from a byte string + * + * @param string $bytes A binary string + * + * @return UuidInterface A UuidInterface instance created from a binary + * string representation + * + * @psalm-pure + */ + public function fromBytes(string $bytes): UuidInterface; + + /** + * Creates a UUID from a DateTimeInterface instance + * + * @param DateTimeInterface $dateTime The date and time + * @param Hexadecimal|null $node A 48-bit number representing the hardware + * address + * @param int|null $clockSeq A 14-bit number used to help avoid duplicates + * that could arise when the clock is set backwards in time or if the + * node ID changes + * + * @return UuidInterface A UuidInterface instance that represents a + * version 1 UUID created from a DateTimeInterface instance + */ + public function fromDateTime( + DateTimeInterface $dateTime, + ?Hexadecimal $node = null, + ?int $clockSeq = null + ): UuidInterface; + + /** + * Creates a UUID from a 128-bit integer string + * + * @param string $integer String representation of 128-bit integer + * + * @return UuidInterface A UuidInterface instance created from the string + * representation of a 128-bit integer + * + * @psalm-pure + */ + public function fromInteger(string $integer): UuidInterface; + + /** + * Creates a UUID from the string standard representation + * + * @param string $uuid A hexadecimal string + * + * @return UuidInterface A UuidInterface instance created from a hexadecimal + * string representation + * + * @psalm-pure + */ + public function fromString(string $uuid): UuidInterface; + /** * Returns the validator to use for the factory * @@ -33,7 +88,7 @@ interface UuidFactoryInterface public function getValidator(): ValidatorInterface; /** - * Returns a version 1 (time-based) UUID from a host ID, sequence number, + * Returns a version 1 (Gregorian time) UUID from a host ID, sequence number, * and the current time * * @param Hexadecimal|int|string|null $node A 48-bit number representing the @@ -111,7 +166,7 @@ public function uuid4(): UuidInterface; public function uuid5($ns, string $name): UuidInterface; /** - * Returns a version 6 (ordered-time) UUID from a host ID, sequence number, + * Returns a version 6 (reordered time) UUID from a host ID, sequence number, * and the current time * * @param Hexadecimal|null $node A 48-bit number representing the hardware @@ -124,59 +179,4 @@ public function uuid5($ns, string $name): UuidInterface; * version 6 UUID */ public function uuid6(?Hexadecimal $node = null, ?int $clockSeq = null): UuidInterface; - - /** - * Creates a UUID from a byte string - * - * @param string $bytes A binary string - * - * @return UuidInterface A UuidInterface instance created from a binary - * string representation - * - * @psalm-pure - */ - public function fromBytes(string $bytes): UuidInterface; - - /** - * Creates a UUID from the string standard representation - * - * @param string $uuid A hexadecimal string - * - * @return UuidInterface A UuidInterface instance created from a hexadecimal - * string representation - * - * @psalm-pure - */ - public function fromString(string $uuid): UuidInterface; - - /** - * Creates a UUID from a 128-bit integer string - * - * @param string $integer String representation of 128-bit integer - * - * @return UuidInterface A UuidInterface instance created from the string - * representation of a 128-bit integer - * - * @psalm-pure - */ - public function fromInteger(string $integer): UuidInterface; - - /** - * Creates a UUID from a DateTimeInterface instance - * - * @param DateTimeInterface $dateTime The date and time - * @param Hexadecimal|null $node A 48-bit number representing the hardware - * address - * @param int|null $clockSeq A 14-bit number used to help avoid duplicates - * that could arise when the clock is set backwards in time or if the - * node ID changes - * - * @return UuidInterface A UuidInterface instance that represents a - * version 1 UUID created from a DateTimeInterface instance - */ - public function fromDateTime( - DateTimeInterface $dateTime, - ?Hexadecimal $node = null, - ?int $clockSeq = null - ): UuidInterface; } diff --git a/ramsey/uuid/src/UuidInterface.php b/ramsey/uuid/src/UuidInterface.php index f22eb0f99..cac9457de 100644 --- a/ramsey/uuid/src/UuidInterface.php +++ b/ramsey/uuid/src/UuidInterface.php @@ -19,6 +19,7 @@ use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; use Serializable; +use Stringable; /** * A UUID is a universally unique identifier adhering to an agreed-upon @@ -29,7 +30,8 @@ interface UuidInterface extends DeprecatedUuidInterface, JsonSerializable, - Serializable + Serializable, + Stringable { /** * Returns -1, 0, or 1 if the UUID is less than, equal to, or greater than @@ -44,7 +46,7 @@ interface UuidInterface extends * * @param UuidInterface $other The UUID to compare * - * @return int -1, 0, or 1 if the UUID is less than, equal to, or greater than $other + * @return int<-1,1> -1, 0, or 1 if the UUID is less than, equal to, or greater than $other */ public function compareTo(UuidInterface $other): int; @@ -83,6 +85,14 @@ public function getHex(): Hexadecimal; */ public function getInteger(): IntegerObject; + /** + * Returns the string standard representation of the UUID as a URN + * + * @link http://en.wikipedia.org/wiki/Uniform_Resource_Name Uniform Resource Name + * @link https://tools.ietf.org/html/rfc4122#section-3 RFC 4122, § 3: Namespace Registration Template + */ + public function getUrn(): string; + /** * Returns the string standard representation of the UUID * diff --git a/ramsey/uuid/src/functions.php b/ramsey/uuid/src/functions.php index 7b29ec4b1..1b3ce00f7 100644 --- a/ramsey/uuid/src/functions.php +++ b/ramsey/uuid/src/functions.php @@ -15,21 +15,22 @@ namespace Ramsey\Uuid; +use DateTimeInterface; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; /** - * Returns a version 1 (time-based) UUID from a host ID, sequence number, + * Returns a version 1 (Gregorian time) UUID from a host ID, sequence number, * and the current time * * @param Hexadecimal|int|string|null $node A 48-bit number representing the * hardware address; this number may be represented as an integer or a * hexadecimal string - * @param int $clockSeq A 14-bit number used to help avoid duplicates that + * @param int|null $clockSeq A 14-bit number used to help avoid duplicates that * could arise when the clock is set backwards in time or if the node ID * changes * - * @return string Version 1 UUID as a string + * @return non-empty-string Version 1 UUID as a string */ function v1($node = null, ?int $clockSeq = null): string { @@ -52,7 +53,7 @@ function v1($node = null, ?int $clockSeq = null): string * that could arise when the clock is set backwards in time or if the * node ID changes * - * @return string Version 2 UUID as a string + * @return non-empty-string Version 2 UUID as a string */ function v2( int $localDomain, @@ -69,7 +70,10 @@ function v2( * * @param string|UuidInterface $ns The namespace (must be a valid UUID) * - * @return string Version 3 UUID as a string + * @return non-empty-string Version 3 UUID as a string + * + * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants, + * but under constant factory setups, this method operates in functionally pure manners */ function v3($ns, string $name): string { @@ -79,7 +83,7 @@ function v3($ns, string $name): string /** * Returns a version 4 (random) UUID * - * @return string Version 4 UUID as a string + * @return non-empty-string Version 4 UUID as a string */ function v4(): string { @@ -92,7 +96,10 @@ function v4(): string * * @param string|UuidInterface $ns The namespace (must be a valid UUID) * - * @return string Version 5 UUID as a string + * @return non-empty-string Version 5 UUID as a string + * + * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants, + * but under constant factory setups, this method operates in functionally pure manners */ function v5($ns, string $name): string { @@ -100,18 +107,52 @@ function v5($ns, string $name): string } /** - * Returns a version 6 (ordered-time) UUID from a host ID, sequence number, + * Returns a version 6 (reordered time) UUID from a host ID, sequence number, * and the current time * * @param Hexadecimal|null $node A 48-bit number representing the hardware * address - * @param int $clockSeq A 14-bit number used to help avoid duplicates that + * @param int|null $clockSeq A 14-bit number used to help avoid duplicates that * could arise when the clock is set backwards in time or if the node ID * changes * - * @return string Version 6 UUID as a string + * @return non-empty-string Version 6 UUID as a string */ function v6(?Hexadecimal $node = null, ?int $clockSeq = null): string { return Uuid::uuid6($node, $clockSeq)->toString(); } + +/** + * Returns a version 7 (Unix Epoch time) UUID + * + * @param DateTimeInterface|null $dateTime An optional date/time from which + * to create the version 7 UUID. If not provided, the UUID is generated + * using the current date/time. + * + * @return non-empty-string Version 7 UUID as a string + */ +function v7(?DateTimeInterface $dateTime = null): string +{ + return Uuid::uuid7($dateTime)->toString(); +} + +/** + * Returns a version 8 (custom) UUID + * + * The bytes provided may contain any value according to your application's + * needs. Be aware, however, that other applications may not understand the + * semantics of the value. + * + * @param string $bytes A 16-byte octet string. This is an open blob + * of data that you may fill with 128 bits of information. Be aware, + * however, bits 48 through 51 will be replaced with the UUID version + * field, and bits 64 and 65 will be replaced with the UUID variant. You + * MUST NOT rely on these bits for your application needs. + * + * @return non-empty-string Version 8 UUID as a string + */ +function v8(string $bytes): string +{ + return Uuid::uuid8($bytes)->toString(); +} diff --git a/spomky-labs/cbor-php/infection.json.dist b/spomky-labs/cbor-php/infection.json.dist deleted file mode 100644 index 7084dd289..000000000 --- a/spomky-labs/cbor-php/infection.json.dist +++ /dev/null @@ -1,11 +0,0 @@ -{ - "timeout":20, - "source": { - "directories": [ - "src" - ] - }, - "logs": { - "text": "infection-log.txt" - } -} diff --git a/spomky-labs/cbor-php/src/AbstractCBORObject.php b/spomky-labs/cbor-php/src/AbstractCBORObject.php index 764d7e6be..a14d2626f 100644 --- a/spomky-labs/cbor-php/src/AbstractCBORObject.php +++ b/spomky-labs/cbor-php/src/AbstractCBORObject.php @@ -21,6 +21,7 @@ abstract class AbstractCBORObject implements CBORObject * @var int */ protected $additionalInformation; + /** * @var int */ diff --git a/spomky-labs/cbor-php/src/ByteStringObject.php b/spomky-labs/cbor-php/src/ByteStringObject.php index 11092d465..450f7ee27 100644 --- a/spomky-labs/cbor-php/src/ByteStringObject.php +++ b/spomky-labs/cbor-php/src/ByteStringObject.php @@ -13,9 +13,9 @@ namespace CBOR; -final class ByteStringObject extends AbstractCBORObject +final class ByteStringObject extends AbstractCBORObject implements Normalizable { - private const MAJOR_TYPE = 0b010; + private const MAJOR_TYPE = self::MAJOR_TYPE_BYTE_STRING; /** * @var string @@ -23,13 +23,13 @@ final class ByteStringObject extends AbstractCBORObject private $value; /** - * @var int|null + * @var string|null */ private $length; public function __construct(string $data) { - list($additionalInformation, $length) = LengthCalculator::getLengthOfString($data); + [$additionalInformation, $length] = LengthCalculator::getLengthOfString($data); parent::__construct(self::MAJOR_TYPE, $additionalInformation); $this->length = $length; @@ -39,12 +39,16 @@ public function __construct(string $data) public function __toString(): string { $result = parent::__toString(); - if (null !== $this->length) { + if ($this->length !== null) { $result .= $this->length; } - $result .= $this->value; - return $result; + return $result . $this->value; + } + + public static function create(string $data): self + { + return new self($data); } public function getValue(): string @@ -57,6 +61,14 @@ public function getLength(): int return mb_strlen($this->value, '8bit'); } + public function normalize(): string + { + return $this->value; + } + + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ public function getNormalizedData(bool $ignoreTags = false): string { return $this->value; diff --git a/spomky-labs/cbor-php/src/ByteStringWithChunkObject.php b/spomky-labs/cbor-php/src/ByteStringWithChunkObject.php index d2f47638e..d173e2f7a 100644 --- a/spomky-labs/cbor-php/src/ByteStringWithChunkObject.php +++ b/spomky-labs/cbor-php/src/ByteStringWithChunkObject.php @@ -13,75 +13,9 @@ namespace CBOR; -use InvalidArgumentException; - -final class ByteStringWithChunkObject extends AbstractCBORObject +/** + * @deprecated Will be removed in v3.0. Please use IndefiniteLengthByteStringObject instead + */ +final class ByteStringWithChunkObject extends IndefiniteLengthByteStringObject { - private const MAJOR_TYPE = 0b010; - private const ADDITIONAL_INFORMATION = 0b00011111; - - /** - * @var ByteStringObject[] - */ - private $chunks = []; - - public function __construct() - { - parent::__construct(self::MAJOR_TYPE, self::ADDITIONAL_INFORMATION); - } - - public function __toString(): string - { - $result = parent::__toString(); - foreach ($this->chunks as $chunk) { - $result .= (string) $chunk; - } - $bin = hex2bin('FF'); - if (false === $bin) { - throw new InvalidArgumentException('Unable to convert the data'); - } - $result .= $bin; - - return $result; - } - - public function add(ByteStringObject $chunk): void - { - $this->chunks[] = $chunk; - } - - public function append(string $chunk): void - { - $this->add(new ByteStringObject($chunk)); - } - - public function getValue(): string - { - $result = ''; - foreach ($this->chunks as $chunk) { - $result .= $chunk->getValue(); - } - - return $result; - } - - public function getLength(): int - { - $length = 0; - foreach ($this->chunks as $chunk) { - $length += $chunk->getLength(); - } - - return $length; - } - - public function getNormalizedData(bool $ignoreTags = false): string - { - $result = ''; - foreach ($this->chunks as $chunk) { - $result .= $chunk->getNormalizedData($ignoreTags); - } - - return $result; - } } diff --git a/spomky-labs/cbor-php/src/CBORObject.php b/spomky-labs/cbor-php/src/CBORObject.php index 08fd7dec1..ab9d2287c 100644 --- a/spomky-labs/cbor-php/src/CBORObject.php +++ b/spomky-labs/cbor-php/src/CBORObject.php @@ -15,6 +15,86 @@ interface CBORObject { + public const MAJOR_TYPE_UNSIGNED_INTEGER = 0b000; + + public const MAJOR_TYPE_NEGATIVE_INTEGER = 0b001; + + public const MAJOR_TYPE_BYTE_STRING = 0b010; + + public const MAJOR_TYPE_TEXT_STRING = 0b011; + + public const MAJOR_TYPE_LIST = 0b100; + + public const MAJOR_TYPE_MAP = 0b101; + + public const MAJOR_TYPE_TAG = 0b110; + + public const MAJOR_TYPE_OTHER_TYPE = 0b111; + + public const LENGTH_1_BYTE = 0b00011000; + + public const LENGTH_2_BYTES = 0b00011001; + + public const LENGTH_4_BYTES = 0b00011010; + + public const LENGTH_8_BYTES = 0b00011011; + + public const LENGTH_INDEFINITE = 0b00011111; + + public const FUTURE_USE_1 = 0b00011100; + + public const FUTURE_USE_2 = 0b00011101; + + public const FUTURE_USE_3 = 0b00011110; + + public const OBJECT_FALSE = 20; + + public const OBJECT_TRUE = 21; + + public const OBJECT_NULL = 22; + + public const OBJECT_UNDEFINED = 23; + + public const OBJECT_SIMPLE_VALUE = 24; + + public const OBJECT_HALF_PRECISION_FLOAT = 25; + + public const OBJECT_SINGLE_PRECISION_FLOAT = 26; + + public const OBJECT_DOUBLE_PRECISION_FLOAT = 27; + + public const OBJECT_BREAK = 0b00011111; + + public const TAG_STANDARD_DATETIME = 0; + + public const TAG_EPOCH_DATETIME = 1; + + public const TAG_UNSIGNED_BIG_NUM = 2; + + public const TAG_NEGATIVE_BIG_NUM = 3; + + public const TAG_DECIMAL_FRACTION = 4; + + public const TAG_BIG_FLOAT = 5; + + public const TAG_ENCODED_BASE64_URL = 21; + + public const TAG_ENCODED_BASE64 = 22; + + public const TAG_ENCODED_BASE16 = 23; + + public const TAG_ENCODED_CBOR = 24; + + public const TAG_URI = 32; + + public const TAG_BASE64_URL = 33; + + public const TAG_BASE64 = 34; + + public const TAG_MIME = 36; + + public const TAG_CBOR = 55799; + public function __toString(): string; public function getMajorType(): int; @@ -22,6 +102,8 @@ public function getMajorType(): int; public function getAdditionalInformation(): int; /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + * * @return mixed|null */ public function getNormalizedData(bool $ignoreTags = false); diff --git a/spomky-labs/cbor-php/src/Decoder.php b/spomky-labs/cbor-php/src/Decoder.php index 8fba1c94e..3c7377d29 100644 --- a/spomky-labs/cbor-php/src/Decoder.php +++ b/spomky-labs/cbor-php/src/Decoder.php @@ -14,53 +14,106 @@ namespace CBOR; use CBOR\OtherObject\BreakObject; +use CBOR\OtherObject\DoublePrecisionFloatObject; +use CBOR\OtherObject\FalseObject; +use CBOR\OtherObject\HalfPrecisionFloatObject; +use CBOR\OtherObject\NullObject; use CBOR\OtherObject\OtherObjectManager; -use CBOR\Tag\TagObjectManager; +use CBOR\OtherObject\OtherObjectManagerInterface; +use CBOR\OtherObject\SimpleObject; +use CBOR\OtherObject\SinglePrecisionFloatObject; +use CBOR\OtherObject\TrueObject; +use CBOR\OtherObject\UndefinedObject; +use CBOR\Tag\Base16EncodingTag; +use CBOR\Tag\Base64EncodingTag; +use CBOR\Tag\Base64Tag; +use CBOR\Tag\Base64UrlEncodingTag; +use CBOR\Tag\Base64UrlTag; +use CBOR\Tag\BigFloatTag; +use CBOR\Tag\CBOREncodingTag; +use CBOR\Tag\CBORTag; +use CBOR\Tag\DatetimeTag; +use CBOR\Tag\DecimalFractionTag; +use CBOR\Tag\MimeTag; +use CBOR\Tag\NegativeBigIntegerTag; +use CBOR\Tag\TagManager; +use CBOR\Tag\TagManagerInterface; +use CBOR\Tag\TimestampTag; +use CBOR\Tag\UnsignedBigIntegerTag; +use CBOR\Tag\UriTag; use InvalidArgumentException; use function ord; use RuntimeException; +use const STR_PAD_LEFT; -final class Decoder +final class Decoder implements DecoderInterface { /** - * @var TagObjectManager + * @var Tag\TagManagerInterface */ - private $tagObjectManager; + private $tagManager; /** - * @var OtherObjectManager + * @var OtherObject\OtherObjectManagerInterface */ - private $otherTypeManager; + private $otherObjectManager; - public function __construct(TagObjectManager $tagObjectManager, OtherObjectManager $otherTypeManager) + public function __construct( + ?TagManagerInterface $tagManager = null, + ?OtherObjectManagerInterface $otherTypeManager = null + ) { + $this->tagManager = $tagManager ?? $this->generateTagManager(); + $this->otherObjectManager = $otherTypeManager ?? $this->generateOtherObjectManager(); + } + + public static function create( + ?TagManagerInterface $tagManager = null, + ?OtherObjectManagerInterface $otherObjectManager = null + ): self { + return new self($tagManager, $otherObjectManager); + } + + public function withTagManager(TagManagerInterface $tagManager): self { - $this->tagObjectManager = $tagObjectManager; - $this->otherTypeManager = $otherTypeManager; + $this->tagManager = $tagManager; + + return $this; + } + + public function withOtherObjectManager(OtherObjectManagerInterface $otherObjectManager): self + { + $this->otherObjectManager = $otherObjectManager; + + return $this; } public function decode(Stream $stream): CBORObject { - return $this->process($stream); + return $this->process($stream, false); } - private function process(Stream $stream, bool $breakable = false): CBORObject + private function process(Stream $stream, bool $breakable): CBORObject { $ib = ord($stream->read(1)); $mt = $ib >> 5; $ai = $ib & 0b00011111; $val = null; switch ($ai) { - case 0b00011000: //24 - case 0b00011001: //25 - case 0b00011010: //26 - case 0b00011011: //27 + case CBORObject::LENGTH_1_BYTE: //24 + case CBORObject::LENGTH_2_BYTES: //25 + case CBORObject::LENGTH_4_BYTES: //26 + case CBORObject::LENGTH_8_BYTES: //27 $val = $stream->read(2 ** ($ai & 0b00000111)); break; - case 0b00011100: //28 - case 0b00011101: //29 - case 0b00011110: //30 - throw new InvalidArgumentException(sprintf('Cannot parse the data. Found invalid Additional Information "%s" (%d).', str_pad(decbin($ai), 5, '0', STR_PAD_LEFT), $ai)); - case 0b00011111: //31 + case CBORObject::FUTURE_USE_1: //28 + case CBORObject::FUTURE_USE_2: //29 + case CBORObject::FUTURE_USE_3: //30 + throw new InvalidArgumentException(sprintf( + 'Cannot parse the data. Found invalid Additional Information "%s" (%d).', + str_pad(decbin($ai), 8, '0', STR_PAD_LEFT), + $ai + )); + case CBORObject::LENGTH_INDEFINITE: //31 return $this->processInfinite($stream, $mt, $breakable); } @@ -70,91 +123,146 @@ private function process(Stream $stream, bool $breakable = false): CBORObject private function processFinite(Stream $stream, int $mt, int $ai, ?string $val): CBORObject { switch ($mt) { - case 0b000: //0 + case CBORObject::MAJOR_TYPE_UNSIGNED_INTEGER: //0 return UnsignedIntegerObject::createObjectForValue($ai, $val); - case 0b001: //1 - return SignedIntegerObject::createObjectForValue($ai, $val); - case 0b010: //2 - $length = null === $val ? $ai : Utils::binToInt($val); - - return new ByteStringObject($stream->read($length)); - case 0b011: //3 - $length = null === $val ? $ai : Utils::binToInt($val); - - return new TextStringObject($stream->read($length)); - case 0b100: //4 - $object = new ListObject(); - $nbItems = null === $val ? $ai : Utils::binToInt($val); + case CBORObject::MAJOR_TYPE_NEGATIVE_INTEGER: //1 + return NegativeIntegerObject::createObjectForValue($ai, $val); + case CBORObject::MAJOR_TYPE_BYTE_STRING: //2 + $length = $val === null ? $ai : Utils::binToInt($val); + + return ByteStringObject::create($stream->read($length)); + case CBORObject::MAJOR_TYPE_TEXT_STRING: //3 + $length = $val === null ? $ai : Utils::binToInt($val); + + return TextStringObject::create($stream->read($length)); + case CBORObject::MAJOR_TYPE_LIST: //4 + $object = ListObject::create(); + $nbItems = $val === null ? $ai : Utils::binToInt($val); for ($i = 0; $i < $nbItems; ++$i) { - $object->add($this->process($stream)); + $object->add($this->process($stream, false)); } return $object; - case 0b101: //5 - $object = new MapObject(); - $nbItems = null === $val ? $ai : Utils::binToInt($val); + case CBORObject::MAJOR_TYPE_MAP: //5 + $object = MapObject::create(); + $nbItems = $val === null ? $ai : Utils::binToInt($val); for ($i = 0; $i < $nbItems; ++$i) { - $object->add($this->process($stream), $this->process($stream)); + $object->add($this->process($stream, false), $this->process($stream, false)); } return $object; - case 0b110: //6 - return $this->tagObjectManager->createObjectForValue($ai, $val, $this->process($stream)); - case 0b111: //7 - return $this->otherTypeManager->createObjectForValue($ai, $val); + case CBORObject::MAJOR_TYPE_TAG: //6 + return $this->tagManager->createObjectForValue($ai, $val, $this->process($stream, false)); + case CBORObject::MAJOR_TYPE_OTHER_TYPE: //7 + return $this->otherObjectManager->createObjectForValue($ai, $val); default: - throw new RuntimeException(sprintf('Unsupported major type "%s" (%d).', str_pad(decbin($mt), 5, '0', STR_PAD_LEFT), $mt)); // Should never append + throw new RuntimeException(sprintf( + 'Unsupported major type "%s" (%d).', + str_pad(decbin($mt), 5, '0', STR_PAD_LEFT), + $mt + )); // Should never append } } private function processInfinite(Stream $stream, int $mt, bool $breakable): CBORObject { switch ($mt) { - case 0b010: //2 - $object = new ByteStringWithChunkObject(); - while (!($it = $this->process($stream, true)) instanceof BreakObject) { - if (!$it instanceof ByteStringObject) { - throw new RuntimeException('Unable to parse the data. Infinite Byte String object can only get Byte String objects.'); + case CBORObject::MAJOR_TYPE_BYTE_STRING: //2 + $object = IndefiniteLengthByteStringObject::create(); + while (! ($it = $this->process($stream, true)) instanceof BreakObject) { + if (! $it instanceof ByteStringObject) { + throw new RuntimeException( + 'Unable to parse the data. Infinite Byte String object can only get Byte String objects.' + ); } $object->add($it); } return $object; - case 0b011: //3 - $object = new TextStringWithChunkObject(); - while (!($it = $this->process($stream, true)) instanceof BreakObject) { - if (!$it instanceof TextStringObject) { - throw new RuntimeException('Unable to parse the data. Infinite Text String object can only get Text String objects.'); + case CBORObject::MAJOR_TYPE_TEXT_STRING: //3 + $object = IndefiniteLengthTextStringObject::create(); + while (! ($it = $this->process($stream, true)) instanceof BreakObject) { + if (! $it instanceof TextStringObject) { + throw new RuntimeException( + 'Unable to parse the data. Infinite Text String object can only get Text String objects.' + ); } $object->add($it); } return $object; - case 0b100: //4 - $object = new InfiniteListObject(); - while (!($it = $this->process($stream, true)) instanceof BreakObject) { + case CBORObject::MAJOR_TYPE_LIST: //4 + $object = IndefiniteLengthListObject::create(); + $it = $this->process($stream, true); + while (! $it instanceof BreakObject) { $object->add($it); + $it = $this->process($stream, true); } return $object; - case 0b101: //5 - $object = new InfiniteMapObject(); - while (!($it = $this->process($stream, true)) instanceof BreakObject) { - $object->append($it, $this->process($stream)); + case CBORObject::MAJOR_TYPE_MAP: //5 + $object = IndefiniteLengthMapObject::create(); + while (! ($it = $this->process($stream, true)) instanceof BreakObject) { + $object->add($it, $this->process($stream, false)); } return $object; - case 0b111: //7 - if (!$breakable) { + case CBORObject::MAJOR_TYPE_OTHER_TYPE: //7 + if (! $breakable) { throw new InvalidArgumentException('Cannot parse the data. No enclosing indefinite.'); } - return new BreakObject(); - case 0b000: //0 - case 0b001: //1 - case 0b110: //6 + return BreakObject::create(); + case CBORObject::MAJOR_TYPE_UNSIGNED_INTEGER: //0 + case CBORObject::MAJOR_TYPE_NEGATIVE_INTEGER: //1 + case CBORObject::MAJOR_TYPE_TAG: //6 default: - throw new InvalidArgumentException(sprintf('Cannot parse the data. Found infinite length for Major Type "%s" (%d).', str_pad(decbin($mt), 5, '0', STR_PAD_LEFT), $mt)); + throw new InvalidArgumentException(sprintf( + 'Cannot parse the data. Found infinite length for Major Type "%s" (%d).', + str_pad(decbin($mt), 5, '0', STR_PAD_LEFT), + $mt + )); } } + + private function generateTagManager(): TagManagerInterface + { + return TagManager::create() + ->add(DatetimeTag::class) + ->add(TimestampTag::class) + + ->add(UnsignedBigIntegerTag::class) + ->add(NegativeBigIntegerTag::class) + + ->add(DecimalFractionTag::class) + ->add(BigFloatTag::class) + + ->add(Base64UrlEncodingTag::class) + ->add(Base64EncodingTag::class) + ->add(Base16EncodingTag::class) + ->add(CBOREncodingTag::class) + + ->add(UriTag::class) + ->add(Base64UrlTag::class) + ->add(Base64Tag::class) + ->add(MimeTag::class) + + ->add(CBORTag::class) + ; + } + + private function generateOtherObjectManager(): OtherObjectManagerInterface + { + return OtherObjectManager::create() + ->add(BreakObject::class) + ->add(SimpleObject::class) + ->add(FalseObject::class) + ->add(TrueObject::class) + ->add(NullObject::class) + ->add(UndefinedObject::class) + ->add(HalfPrecisionFloatObject::class) + ->add(SinglePrecisionFloatObject::class) + ->add(DoublePrecisionFloatObject::class) + ; + } } diff --git a/spomky-labs/cbor-php/src/DecoderInterface.php b/spomky-labs/cbor-php/src/DecoderInterface.php new file mode 100644 index 000000000..3d7b19249 --- /dev/null +++ b/spomky-labs/cbor-php/src/DecoderInterface.php @@ -0,0 +1,19 @@ +chunks as $chunk) { + $result .= $chunk->__toString(); + } + + return $result . "\xFF"; + } + + public static function create(): self + { + return new self(); + } + + public function add(ByteStringObject $chunk): self + { + $this->chunks[] = $chunk; + + return $this; + } + + public function append(string $chunk): self + { + $this->add(ByteStringObject::create($chunk)); + + return $this; + } + + public function getValue(): string + { + $result = ''; + foreach ($this->chunks as $chunk) { + $result .= $chunk->getValue(); + } + + return $result; + } + + public function getLength(): int + { + $length = 0; + foreach ($this->chunks as $chunk) { + $length += $chunk->getLength(); + } + + return $length; + } + + public function normalize(): string + { + $result = ''; + foreach ($this->chunks as $chunk) { + $result .= $chunk->normalize(); + } + + return $result; + } + + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ + public function getNormalizedData(bool $ignoreTags = false): string + { + $result = ''; + foreach ($this->chunks as $chunk) { + $result .= $chunk->getNormalizedData($ignoreTags); + } + + return $result; + } +} diff --git a/spomky-labs/cbor-php/src/IndefiniteLengthListObject.php b/spomky-labs/cbor-php/src/IndefiniteLengthListObject.php new file mode 100644 index 000000000..2bf44fb49 --- /dev/null +++ b/spomky-labs/cbor-php/src/IndefiniteLengthListObject.php @@ -0,0 +1,167 @@ + + * @phpstan-implements IteratorAggregate + * @final + */ +class IndefiniteLengthListObject extends AbstractCBORObject implements Countable, IteratorAggregate, Normalizable, ArrayAccess +{ + private const MAJOR_TYPE = self::MAJOR_TYPE_LIST; + + private const ADDITIONAL_INFORMATION = self::LENGTH_INDEFINITE; + + /** + * @var CBORObject[] + */ + private $data = []; + + public function __construct() + { + parent::__construct(self::MAJOR_TYPE, self::ADDITIONAL_INFORMATION); + } + + public function __toString(): string + { + $result = parent::__toString(); + foreach ($this->data as $object) { + $result .= (string) $object; + } + + return $result . "\xFF"; + } + + public static function create(): self + { + return new self(); + } + + /** + * @return mixed[] + */ + public function normalize(): array + { + return array_map(static function (CBORObject $object) { + return $object instanceof Normalizable ? $object->normalize() : $object; + }, $this->data); + } + + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + * + * @return mixed[] + */ + public function getNormalizedData(bool $ignoreTags = false): array + { + return array_map(static function (CBORObject $object) use ($ignoreTags) { + return $object->getNormalizedData($ignoreTags); + }, $this->data); + } + + public function add(CBORObject $item): self + { + $this->data[] = $item; + + return $this; + } + + public function has(int $index): bool + { + return array_key_exists($index, $this->data); + } + + public function remove(int $index): self + { + if (! $this->has($index)) { + return $this; + } + unset($this->data[$index]); + $this->data = array_values($this->data); + + return $this; + } + + public function get(int $index): CBORObject + { + if (! $this->has($index)) { + throw new InvalidArgumentException('Index not found.'); + } + + return $this->data[$index]; + } + + public function set(int $index, CBORObject $object): self + { + if (! $this->has($index)) { + throw new InvalidArgumentException('Index not found.'); + } + + $this->data[$index] = $object; + + return $this; + } + + /** + * @deprecated The method will be removed on v3.0. No replacement + */ + public function count(): int + { + return count($this->data); + } + + /** + * @return Iterator + */ + public function getIterator(): Iterator + { + return new ArrayIterator($this->data); + } + + public function offsetExists($offset): bool + { + return $this->has($offset); + } + + public function offsetGet($offset): CBORObject + { + return $this->get($offset); + } + + public function offsetSet($offset, $value): void + { + if ($offset === null) { + $this->add($value); + + return; + } + + $this->set($offset, $value); + } + + public function offsetUnset($offset): void + { + $this->remove($offset); + } +} diff --git a/spomky-labs/cbor-php/src/IndefiniteLengthMapObject.php b/spomky-labs/cbor-php/src/IndefiniteLengthMapObject.php new file mode 100644 index 000000000..7bc7a1c12 --- /dev/null +++ b/spomky-labs/cbor-php/src/IndefiniteLengthMapObject.php @@ -0,0 +1,201 @@ + + * @phpstan-implements IteratorAggregate + * @final + */ +class IndefiniteLengthMapObject extends AbstractCBORObject implements Countable, IteratorAggregate, Normalizable, ArrayAccess +{ + private const MAJOR_TYPE = self::MAJOR_TYPE_MAP; + + private const ADDITIONAL_INFORMATION = self::LENGTH_INDEFINITE; + + /** + * @var MapItem[] + */ + private $data = []; + + public function __construct() + { + parent::__construct(self::MAJOR_TYPE, self::ADDITIONAL_INFORMATION); + } + + public function __toString(): string + { + $result = parent::__toString(); + foreach ($this->data as $object) { + $result .= (string) $object->getKey(); + $result .= (string) $object->getValue(); + } + + return $result . "\xFF"; + } + + public static function create(): self + { + return new self(); + } + + /** + * @deprecated The method will be removed on v3.0. Please use "add" instead + */ + public function append(CBORObject $key, CBORObject $value): self + { + return $this->add($key, $value); + } + + public function add(CBORObject $key, CBORObject $value): self + { + if (! $key instanceof Normalizable) { + throw new InvalidArgumentException('Invalid key. Shall be normalizable'); + } + $this->data[$key->normalize()] = MapItem::create($key, $value); + + return $this; + } + + /** + * @param int|string $key + */ + public function has($key): bool + { + return array_key_exists($key, $this->data); + } + + /** + * @param int|string $index + */ + public function remove($index): self + { + if (! $this->has($index)) { + return $this; + } + unset($this->data[$index]); + $this->data = array_values($this->data); + + return $this; + } + + /** + * @param int|string $index + */ + public function get($index): CBORObject + { + if (! $this->has($index)) { + throw new InvalidArgumentException('Index not found.'); + } + + return $this->data[$index]->getValue(); + } + + public function set(MapItem $object): self + { + $key = $object->getKey(); + if (! $key instanceof Normalizable) { + throw new InvalidArgumentException('Invalid key. Shall be normalizable'); + } + + $this->data[$key->normalize()] = $object; + + return $this; + } + + /** + * @deprecated The method will be removed on v3.0. No replacement + */ + public function count(): int + { + return count($this->data); + } + + /** + * @return Iterator + */ + public function getIterator(): Iterator + { + return new ArrayIterator($this->data); + } + + /** + * @return mixed[] + */ + public function normalize(): array + { + return array_reduce($this->data, static function (array $carry, MapItem $item): array { + $key = $item->getKey(); + if (! $key instanceof Normalizable) { + throw new InvalidArgumentException('Invalid key. Shall be normalizable'); + } + $valueObject = $item->getValue(); + $carry[$key->normalize()] = $valueObject instanceof Normalizable ? $valueObject->normalize() : $valueObject; + + return $carry; + }, []); + } + + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + * + * @return mixed[] + */ + public function getNormalizedData(bool $ignoreTags = false): array + { + return array_reduce($this->data, static function (array $carry, MapItem $item) use ($ignoreTags): array { + $key = $item->getKey(); + $valueObject = $item->getValue(); + $carry[$key->getNormalizedData($ignoreTags)] = $valueObject->getNormalizedData($ignoreTags); + + return $carry; + }, []); + } + + public function offsetExists($offset): bool + { + return $this->has($offset); + } + + public function offsetGet($offset): CBORObject + { + return $this->get($offset); + } + + public function offsetSet($offset, $value): void + { + if (! $offset instanceof CBORObject) { + throw new InvalidArgumentException('Invalid key'); + } + if (! $value instanceof CBORObject) { + throw new InvalidArgumentException('Invalid value'); + } + + $this->set(MapItem::create($offset, $value)); + } + + public function offsetUnset($offset): void + { + $this->remove($offset); + } +} diff --git a/spomky-labs/cbor-php/src/IndefiniteLengthTextStringObject.php b/spomky-labs/cbor-php/src/IndefiniteLengthTextStringObject.php new file mode 100644 index 000000000..108528e24 --- /dev/null +++ b/spomky-labs/cbor-php/src/IndefiniteLengthTextStringObject.php @@ -0,0 +1,106 @@ +data as $object) { + $result .= (string) $object; + } + + return $result . "\xFF"; + } + + public static function create(): self + { + return new self(); + } + + public function add(TextStringObject $chunk): self + { + $this->data[] = $chunk; + + return $this; + } + + public function append(string $chunk): self + { + $this->add(TextStringObject::create($chunk)); + + return $this; + } + + public function getValue(): string + { + $result = ''; + foreach ($this->data as $object) { + $result .= $object->getValue(); + } + + return $result; + } + + public function getLength(): int + { + $length = 0; + foreach ($this->data as $object) { + $length += $object->getLength(); + } + + return $length; + } + + public function normalize(): string + { + $result = ''; + foreach ($this->data as $object) { + $result .= $object->normalize(); + } + + return $result; + } + + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ + public function getNormalizedData(bool $ignoreTags = false): string + { + $result = ''; + foreach ($this->data as $object) { + $result .= $object->getNormalizedData($ignoreTags); + } + + return $result; + } +} diff --git a/spomky-labs/cbor-php/src/InfiniteListObject.php b/spomky-labs/cbor-php/src/InfiniteListObject.php index 76e13f012..526d74cc3 100644 --- a/spomky-labs/cbor-php/src/InfiniteListObject.php +++ b/spomky-labs/cbor-php/src/InfiniteListObject.php @@ -13,62 +13,9 @@ namespace CBOR; -use ArrayIterator; -use function count; -use Countable; -use InvalidArgumentException; -use Iterator; -use IteratorAggregate; - -final class InfiniteListObject extends AbstractCBORObject implements Countable, IteratorAggregate +/** + * @deprecated Will be removed in v3.0. Please use IndefiniteLengthListObject instead + */ +final class InfiniteListObject extends IndefiniteLengthListObject { - private const MAJOR_TYPE = 0b100; - private const ADDITIONAL_INFORMATION = 0b00011111; - - /** - * @var CBORObject[] - */ - private $data = []; - - public function __construct() - { - parent::__construct(self::MAJOR_TYPE, self::ADDITIONAL_INFORMATION); - } - - public function __toString(): string - { - $result = parent::__toString(); - foreach ($this->data as $object) { - $result .= (string) $object; - } - $bin = hex2bin('FF'); - if (false === $bin) { - throw new InvalidArgumentException('Unable to convert the data'); - } - $result .= $bin; - - return $result; - } - - public function getNormalizedData(bool $ignoreTags = false): array - { - return array_map(function (CBORObject $item) use ($ignoreTags) { - return $item->getNormalizedData($ignoreTags); - }, $this->data); - } - - public function add(CBORObject $item): void - { - $this->data[] = $item; - } - - public function count(): int - { - return count($this->data); - } - - public function getIterator(): Iterator - { - return new ArrayIterator($this->data); - } } diff --git a/spomky-labs/cbor-php/src/InfiniteMapObject.php b/spomky-labs/cbor-php/src/InfiniteMapObject.php index 05d3cc32a..efcf781d3 100644 --- a/spomky-labs/cbor-php/src/InfiniteMapObject.php +++ b/spomky-labs/cbor-php/src/InfiniteMapObject.php @@ -13,66 +13,9 @@ namespace CBOR; -use ArrayIterator; -use function count; -use Countable; -use InvalidArgumentException; -use Iterator; -use IteratorAggregate; - -final class InfiniteMapObject extends AbstractCBORObject implements Countable, IteratorAggregate +/** + * @deprecated Will be removed in v3.0. Please use IndefiniteLengthMapObject instead + */ +final class InfiniteMapObject extends IndefiniteLengthMapObject { - private const MAJOR_TYPE = 0b101; - private const ADDITIONAL_INFORMATION = 0b00011111; - - /** - * @var MapItem[] - */ - private $data = []; - - public function __construct() - { - parent::__construct(self::MAJOR_TYPE, self::ADDITIONAL_INFORMATION); - } - - public function __toString(): string - { - $result = parent::__toString(); - foreach ($this->data as $object) { - $result .= (string) $object->getKey(); - $result .= (string) $object->getValue(); - } - $bin = hex2bin('FF'); - if (false === $bin) { - throw new InvalidArgumentException('Unable to convert the data'); - } - $result .= $bin; - - return $result; - } - - public function append(CBORObject $key, CBORObject $value): void - { - $this->data[] = new MapItem($key, $value); - } - - public function count(): int - { - return count($this->data); - } - - public function getIterator(): Iterator - { - return new ArrayIterator($this->data); - } - - public function getNormalizedData(bool $ignoreTags = false): array - { - $result = []; - foreach ($this->data as $object) { - $result[$object->getKey()->getNormalizedData($ignoreTags)] = $object->getValue()->getNormalizedData($ignoreTags); - } - - return $result; - } } diff --git a/spomky-labs/cbor-php/src/LengthCalculator.php b/spomky-labs/cbor-php/src/LengthCalculator.php index d03571598..e6276dd0b 100644 --- a/spomky-labs/cbor-php/src/LengthCalculator.php +++ b/spomky-labs/cbor-php/src/LengthCalculator.php @@ -17,9 +17,13 @@ use function chr; use function count; use InvalidArgumentException; +use const STR_PAD_LEFT; final class LengthCalculator { + /** + * @return array{int, null|string} + */ public static function getLengthOfString(string $data): array { $length = mb_strlen($data, '8bit'); @@ -27,6 +31,11 @@ public static function getLengthOfString(string $data): array return self::computeLength($length); } + /** + * @param array $data + * + * @return array{int, null|string} + */ public static function getLengthOfArray(array $data): array { $length = count($data); @@ -34,36 +43,35 @@ public static function getLengthOfArray(array $data): array return self::computeLength($length); } + /** + * @return array{int, null|string} + */ private static function computeLength(int $length): array { switch (true) { - case $length < 24: + case $length <= 23: return [$length, null]; - case $length < 0xFF: - return [24, chr($length)]; - case $length < 0xFFFF: - return [25, self::hex2bin(static::fixHexLength(Utils::intToHex($length)))]; - case $length < 0xFFFFFFFF: - return [26, self::hex2bin(static::fixHexLength(Utils::intToHex($length)))]; - case BigInteger::of($length)->isLessThan(BigInteger::fromBase('FFFFFFFFFFFFFFFF', 16)): - return [27, self::hex2bin(static::fixHexLength(Utils::intToHex($length)))]; + case $length <= 0xFF: + return [CBORObject::LENGTH_1_BYTE, chr($length)]; + case $length <= 0xFFFF: + return [CBORObject::LENGTH_2_BYTES, self::hex2bin(dechex($length))]; + case $length <= 0xFFFFFFFF: + return [CBORObject::LENGTH_4_BYTES, self::hex2bin(dechex($length))]; + case BigInteger::of($length)->isLessThanOrEqualTo(BigInteger::fromBase('FFFFFFFFFFFFFFFF', 16)): + return [CBORObject::LENGTH_8_BYTES, self::hex2bin(dechex($length))]; default: - return [31, null]; + return [CBORObject::LENGTH_INDEFINITE, null]; } } private static function hex2bin(string $data): string { + $data = str_pad($data, (int) (2 ** ceil(log(mb_strlen($data, '8bit'), 2))), '0', STR_PAD_LEFT); $result = hex2bin($data); - if (false === $result) { + if ($result === false) { throw new InvalidArgumentException('Unable to convert the data'); } return $result; } - - private static function fixHexLength(string $data): string - { - return str_pad($data, (int) (2 ** ceil(log(mb_strlen($data, '8bit'), 2))), '0', STR_PAD_LEFT); - } } diff --git a/spomky-labs/cbor-php/src/ListObject.php b/spomky-labs/cbor-php/src/ListObject.php index 2139095ed..f3a32133f 100644 --- a/spomky-labs/cbor-php/src/ListObject.php +++ b/spomky-labs/cbor-php/src/ListObject.php @@ -14,6 +14,7 @@ namespace CBOR; use function array_key_exists; +use ArrayAccess; use ArrayIterator; use function count; use Countable; @@ -21,17 +22,21 @@ use Iterator; use IteratorAggregate; -class ListObject extends AbstractCBORObject implements Countable, IteratorAggregate +/** + * @phpstan-implements ArrayAccess + * @phpstan-implements IteratorAggregate + */ +class ListObject extends AbstractCBORObject implements Countable, IteratorAggregate, Normalizable, ArrayAccess { - private const MAJOR_TYPE = 0b100; + private const MAJOR_TYPE = self::MAJOR_TYPE_LIST; /** * @var CBORObject[] */ - private $data = []; + private $data; /** - * @var int|null + * @var string|null */ private $length; @@ -40,22 +45,22 @@ class ListObject extends AbstractCBORObject implements Countable, IteratorAggreg */ public function __construct(array $data = []) { - list($additionalInformation, $length) = LengthCalculator::getLengthOfArray($data); + [$additionalInformation, $length] = LengthCalculator::getLengthOfArray($data); array_map(static function ($item): void { - if (!$item instanceof CBORObject) { + if (! $item instanceof CBORObject) { throw new InvalidArgumentException('The list must contain only CBORObject objects.'); } }, $data); parent::__construct(self::MAJOR_TYPE, $additionalInformation); - $this->data = $data; + $this->data = array_values($data); $this->length = $length; } public function __toString(): string { $result = parent::__toString(); - if (null !== $this->length) { + if ($this->length !== null) { $result .= $this->length; } foreach ($this->data as $object) { @@ -65,25 +70,79 @@ public function __toString(): string return $result; } - public function add(CBORObject $object): void + /** + * @param CBORObject[] $data + */ + public static function create(array $data = []): self + { + return new self($data); + } + + public function add(CBORObject $object): self { $this->data[] = $object; - list($this->additionalInformation, $this->length) = LengthCalculator::getLengthOfArray($this->data); + [$this->additionalInformation, $this->length] = LengthCalculator::getLengthOfArray($this->data); + + return $this; + } + + public function has(int $index): bool + { + return array_key_exists($index, $this->data); + } + + public function remove(int $index): self + { + if (! $this->has($index)) { + return $this; + } + unset($this->data[$index]); + $this->data = array_values($this->data); + [$this->additionalInformation, $this->length] = LengthCalculator::getLengthOfArray($this->data); + + return $this; } public function get(int $index): CBORObject { - if (!array_key_exists($index, $this->data)) { + if (! $this->has($index)) { throw new InvalidArgumentException('Index not found.'); } return $this->data[$index]; } + public function set(int $index, CBORObject $object): self + { + if (! $this->has($index)) { + throw new InvalidArgumentException('Index not found.'); + } + + $this->data[$index] = $object; + [$this->additionalInformation, $this->length] = LengthCalculator::getLengthOfArray($this->data); + + return $this; + } + + /** + * @return array + */ + public function normalize(): array + { + return array_map(static function (CBORObject $object) { + return $object instanceof Normalizable ? $object->normalize() : $object; + }, $this->data); + } + + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + * + * @return array + */ public function getNormalizedData(bool $ignoreTags = false): array { - return array_map(function (CBORObject $item) use ($ignoreTags) { - return $item->getNormalizedData($ignoreTags); + return array_map(static function (CBORObject $object) use ($ignoreTags) { + return $object->getNormalizedData($ignoreTags); }, $this->data); } @@ -92,8 +151,37 @@ public function count(): int return count($this->data); } + /** + * @return Iterator + */ public function getIterator(): Iterator { return new ArrayIterator($this->data); } + + public function offsetExists($offset): bool + { + return $this->has($offset); + } + + public function offsetGet($offset): CBORObject + { + return $this->get($offset); + } + + public function offsetSet($offset, $value): void + { + if ($offset === null) { + $this->add($value); + + return; + } + + $this->set($offset, $value); + } + + public function offsetUnset($offset): void + { + $this->remove($offset); + } } diff --git a/spomky-labs/cbor-php/src/MapItem.php b/spomky-labs/cbor-php/src/MapItem.php index de70895ba..39578a6e9 100644 --- a/spomky-labs/cbor-php/src/MapItem.php +++ b/spomky-labs/cbor-php/src/MapItem.php @@ -31,6 +31,11 @@ public function __construct(CBORObject $key, CBORObject $value) $this->value = $value; } + public static function create(CBORObject $key, CBORObject $value): self + { + return new self($key, $value); + } + public function getKey(): CBORObject { return $this->key; diff --git a/spomky-labs/cbor-php/src/MapObject.php b/spomky-labs/cbor-php/src/MapObject.php index 0afd4d193..9c71332e0 100644 --- a/spomky-labs/cbor-php/src/MapObject.php +++ b/spomky-labs/cbor-php/src/MapObject.php @@ -13,6 +13,8 @@ namespace CBOR; +use function array_key_exists; +use ArrayAccess; use ArrayIterator; use function count; use Countable; @@ -20,17 +22,21 @@ use Iterator; use IteratorAggregate; -final class MapObject extends AbstractCBORObject implements Countable, IteratorAggregate +/** + * @phpstan-implements ArrayAccess + * @phpstan-implements IteratorAggregate + */ +final class MapObject extends AbstractCBORObject implements Countable, IteratorAggregate, Normalizable, ArrayAccess { - private const MAJOR_TYPE = 0b101; + private const MAJOR_TYPE = self::MAJOR_TYPE_MAP; /** * @var MapItem[] */ - private $data = []; + private $data; /** - * @var int|null + * @var string|null */ private $length; @@ -39,9 +45,9 @@ final class MapObject extends AbstractCBORObject implements Countable, IteratorA */ public function __construct(array $data = []) { - list($additionalInformation, $length) = LengthCalculator::getLengthOfArray($data); + [$additionalInformation, $length] = LengthCalculator::getLengthOfArray($data); array_map(static function ($item): void { - if (!$item instanceof MapItem) { + if (! $item instanceof MapItem) { throw new InvalidArgumentException('The list must contain only MapItem objects.'); } }, $data); @@ -54,21 +60,86 @@ public function __construct(array $data = []) public function __toString(): string { $result = parent::__toString(); - if (null !== $this->length) { + if ($this->length !== null) { $result .= $this->length; } foreach ($this->data as $object) { - $result .= (string) $object->getKey(); - $result .= (string) $object->getValue(); + $result .= $object->getKey() + ->__toString() + ; + $result .= $object->getValue() + ->__toString() + ; } return $result; } - public function add(CBORObject $key, CBORObject $value): void + /** + * @param MapItem[] $data + */ + public static function create(array $data = []): self + { + return new self($data); + } + + public function add(CBORObject $key, CBORObject $value): self + { + if (! $key instanceof Normalizable) { + throw new InvalidArgumentException('Invalid key. Shall be normalizable'); + } + $this->data[$key->normalize()] = MapItem::create($key, $value); + [$this->additionalInformation, $this->length] = LengthCalculator::getLengthOfArray($this->data); + + return $this; + } + + /** + * @param int|string $key + */ + public function has($key): bool { - $this->data[] = new MapItem($key, $value); - list($this->additionalInformation, $this->length) = LengthCalculator::getLengthOfArray($this->data); + return array_key_exists($key, $this->data); + } + + /** + * @param int|string $index + */ + public function remove($index): self + { + if (! $this->has($index)) { + return $this; + } + unset($this->data[$index]); + $this->data = array_values($this->data); + [$this->additionalInformation, $this->length] = LengthCalculator::getLengthOfArray($this->data); + + return $this; + } + + /** + * @param int|string $index + */ + public function get($index): CBORObject + { + if (! $this->has($index)) { + throw new InvalidArgumentException('Index not found.'); + } + + return $this->data[$index]->getValue(); + } + + public function set(MapItem $object): self + { + $key = $object->getKey(); + if (! $key instanceof Normalizable) { + throw new InvalidArgumentException('Invalid key. Shall be normalizable'); + } + + $this->data[$key->normalize()] = $object; + [$this->additionalInformation, $this->length] = LengthCalculator::getLengthOfArray($this->data); + + return $this; } public function count(): int @@ -76,18 +147,71 @@ public function count(): int return count($this->data); } + /** + * @return Iterator + */ public function getIterator(): Iterator { return new ArrayIterator($this->data); } + /** + * @return array + */ + public function normalize(): array + { + return array_reduce($this->data, static function (array $carry, MapItem $item): array { + $key = $item->getKey(); + if (! $key instanceof Normalizable) { + throw new InvalidArgumentException('Invalid key. Shall be normalizable'); + } + $valueObject = $item->getValue(); + $carry[$key->normalize()] = $valueObject instanceof Normalizable ? $valueObject->normalize() : $valueObject; + + return $carry; + }, []); + } + + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + * + * @return array + */ public function getNormalizedData(bool $ignoreTags = false): array { - $result = []; - foreach ($this->data as $object) { - $result[$object->getKey()->getNormalizedData($ignoreTags)] = $object->getValue()->getNormalizedData($ignoreTags); + return array_reduce($this->data, static function (array $carry, MapItem $item) use ($ignoreTags): array { + $key = $item->getKey(); + $valueObject = $item->getValue(); + $carry[$key->getNormalizedData($ignoreTags)] = $valueObject->getNormalizedData($ignoreTags); + + return $carry; + }, []); + } + + public function offsetExists($offset): bool + { + return $this->has($offset); + } + + public function offsetGet($offset): CBORObject + { + return $this->get($offset); + } + + public function offsetSet($offset, $value): void + { + if (! $offset instanceof CBORObject) { + throw new InvalidArgumentException('Invalid key'); + } + if (! $value instanceof CBORObject) { + throw new InvalidArgumentException('Invalid value'); } - return $result; + $this->set(MapItem::create($offset, $value)); + } + + public function offsetUnset($offset): void + { + $this->remove($offset); } } diff --git a/spomky-labs/cbor-php/src/NegativeIntegerObject.php b/spomky-labs/cbor-php/src/NegativeIntegerObject.php new file mode 100644 index 000000000..ad1bbe1ef --- /dev/null +++ b/spomky-labs/cbor-php/src/NegativeIntegerObject.php @@ -0,0 +1,136 @@ +data = $data; + } + + public function __toString(): string + { + $result = parent::__toString(); + if ($this->data !== null) { + $result .= $this->data; + } + + return $result; + } + + public static function createObjectForValue(int $additionalInformation, ?string $data): self + { + return new self($additionalInformation, $data); + } + + public static function create(int $value): self + { + return self::createFromString((string) $value); + } + + public static function createFromString(string $value): self + { + $integer = BigInteger::of($value); + + return self::createBigInteger($integer); + } + + public function getValue(): string + { + if ($this->data === null) { + return (string) (-1 - $this->additionalInformation); + } + + $result = Utils::binToBigInteger($this->data); + $minusOne = BigInteger::of(-1); + + return $minusOne->minus($result) + ->toBase(10) + ; + } + + public function normalize(): string + { + return $this->getValue(); + } + + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ + public function getNormalizedData(bool $ignoreTags = false): string + { + return $this->getValue(); + } + + private static function createBigInteger(BigInteger $integer): self + { + if ($integer->isGreaterThanOrEqualTo(BigInteger::zero())) { + throw new InvalidArgumentException('The value must be a negative integer.'); + } + + $minusOne = BigInteger::of(-1); + $computed_value = $minusOne->minus($integer); + + switch (true) { + case $computed_value->isLessThan(BigInteger::of(24)): + $ai = $computed_value->toInt(); + $data = null; + break; + case $computed_value->isLessThan(BigInteger::fromBase('FF', 16)): + $ai = 24; + $data = self::hex2bin(str_pad($computed_value->toBase(16), 2, '0', STR_PAD_LEFT)); + break; + case $computed_value->isLessThan(BigInteger::fromBase('FFFF', 16)): + $ai = 25; + $data = self::hex2bin(str_pad($computed_value->toBase(16), 4, '0', STR_PAD_LEFT)); + break; + case $computed_value->isLessThan(BigInteger::fromBase('FFFFFFFF', 16)): + $ai = 26; + $data = self::hex2bin(str_pad($computed_value->toBase(16), 8, '0', STR_PAD_LEFT)); + break; + default: + throw new InvalidArgumentException( + 'Out of range. Please use NegativeBigIntegerTag tag with ByteStringObject object instead.' + ); + } + + return new self($ai, $data); + } + + private static function hex2bin(string $data): string + { + $result = hex2bin($data); + if ($result === false) { + throw new InvalidArgumentException('Unable to convert the data'); + } + + return $result; + } +} diff --git a/spomky-labs/cbor-php/src/Normalizable.php b/spomky-labs/cbor-php/src/Normalizable.php new file mode 100644 index 000000000..3b776621a --- /dev/null +++ b/spomky-labs/cbor-php/src/Normalizable.php @@ -0,0 +1,22 @@ +data) { + if ($this->data !== null) { $result .= $this->data; } return $result; } + public function getContent(): ?string + { + return $this->data; + } + /** * @return int[] */ diff --git a/spomky-labs/cbor-php/src/OtherObject/BreakObject.php b/spomky-labs/cbor-php/src/OtherObject/BreakObject.php index 6a99028d5..339f11b38 100644 --- a/spomky-labs/cbor-php/src/OtherObject/BreakObject.php +++ b/spomky-labs/cbor-php/src/OtherObject/BreakObject.php @@ -19,12 +19,17 @@ final class BreakObject extends Base { public function __construct() { - parent::__construct(0b00011111, null); + parent::__construct(self::OBJECT_BREAK, null); + } + + public static function create(): self + { + return new self(); } public static function supportedAdditionalInformation(): array { - return [0b00011111]; + return [self::OBJECT_BREAK]; } public static function createFromLoadedData(int $additionalInformation, ?string $data): Base @@ -32,6 +37,9 @@ public static function createFromLoadedData(int $additionalInformation, ?string return new self(); } + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ public function getNormalizedData(bool $ignoreTags = false): bool { return false; diff --git a/spomky-labs/cbor-php/src/OtherObject/DoublePrecisionFloatObject.php b/spomky-labs/cbor-php/src/OtherObject/DoublePrecisionFloatObject.php index 1f382debc..abd448859 100644 --- a/spomky-labs/cbor-php/src/OtherObject/DoublePrecisionFloatObject.php +++ b/spomky-labs/cbor-php/src/OtherObject/DoublePrecisionFloatObject.php @@ -14,15 +14,18 @@ namespace CBOR\OtherObject; use Brick\Math\BigInteger; +use CBOR\Normalizable; use CBOR\OtherObject as Base; use CBOR\Utils; +use const INF; use InvalidArgumentException; +use const NAN; -final class DoublePrecisionFloatObject extends Base +final class DoublePrecisionFloatObject extends Base implements Normalizable { public static function supportedAdditionalInformation(): array { - return [27]; + return [self::OBJECT_DOUBLE_PRECISION_FLOAT]; } public static function createFromLoadedData(int $additionalInformation, ?string $data): Base @@ -30,30 +33,38 @@ public static function createFromLoadedData(int $additionalInformation, ?string return new self($additionalInformation, $data); } - /** - * @return DoublePrecisionFloatObject - */ public static function create(string $value): self { - if (8 !== mb_strlen($value, '8bit')) { + if (mb_strlen($value, '8bit') !== 8) { throw new InvalidArgumentException('The value is not a valid double precision floating point'); } - return new self(27, $value); + return new self(self::OBJECT_DOUBLE_PRECISION_FLOAT, $value); } + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ public function getNormalizedData(bool $ignoreTags = false) { - $exp = $this->getExponent(); - $mant = $this->getMantissa(); + return $this->normalize(); + } + + /** + * @return float|int + */ + public function normalize() + { + $exponent = $this->getExponent(); + $mantissa = $this->getMantissa(); $sign = $this->getSign(); - if (0 === $exp) { - $val = $mant * 2 ** (-(1022 + 52)); - } elseif (0b11111111111 !== $exp) { - $val = ($mant + (1 << 52)) * 2 ** ($exp - (1023 + 52)); + if ($exponent === 0) { + $val = $mantissa * 2 ** (-(1022 + 52)); + } elseif ($exponent !== 0b11111111111) { + $val = ($mantissa + (1 << 52)) * 2 ** ($exponent - (1023 + 52)); } else { - $val = 0 === $mant ? INF : NAN; + $val = $mantissa === 0 ? INF : NAN; } return $sign * $val; diff --git a/spomky-labs/cbor-php/src/OtherObject/FalseObject.php b/spomky-labs/cbor-php/src/OtherObject/FalseObject.php index dfc15d326..c3ce42ab1 100644 --- a/spomky-labs/cbor-php/src/OtherObject/FalseObject.php +++ b/spomky-labs/cbor-php/src/OtherObject/FalseObject.php @@ -13,18 +13,24 @@ namespace CBOR\OtherObject; +use CBOR\Normalizable; use CBOR\OtherObject as Base; -final class FalseObject extends Base +final class FalseObject extends Base implements Normalizable { public function __construct() { - parent::__construct(20, null); + parent::__construct(self::OBJECT_FALSE, null); + } + + public static function create(): self + { + return new self(); } public static function supportedAdditionalInformation(): array { - return [20]; + return [self::OBJECT_FALSE]; } public static function createFromLoadedData(int $additionalInformation, ?string $data): Base @@ -32,8 +38,16 @@ public static function createFromLoadedData(int $additionalInformation, ?string return new self(); } - public function getNormalizedData(bool $ignoreTags = false): bool + public function normalize(): bool { return false; } + + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ + public function getNormalizedData(bool $ignoreTags = false): bool + { + return $this->normalize(); + } } diff --git a/spomky-labs/cbor-php/src/OtherObject/GenericObject.php b/spomky-labs/cbor-php/src/OtherObject/GenericObject.php index 36a873bab..fb9fccc4a 100644 --- a/spomky-labs/cbor-php/src/OtherObject/GenericObject.php +++ b/spomky-labs/cbor-php/src/OtherObject/GenericObject.php @@ -14,6 +14,8 @@ namespace CBOR\OtherObject; use CBOR\OtherObject as Base; +use InvalidArgumentException; +use function ord; final class GenericObject extends Base { @@ -24,9 +26,16 @@ public static function supportedAdditionalInformation(): array public static function createFromLoadedData(int $additionalInformation, ?string $data): Base { + if ($data !== null && ord($data) < 32) { + throw new InvalidArgumentException('Invalid simple value. Content data should not be present.'); + } + return new self($additionalInformation, $data); } + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ public function getNormalizedData(bool $ignoreTags = false) { return $this->data; diff --git a/spomky-labs/cbor-php/src/OtherObject/HalfPrecisionFloatObject.php b/spomky-labs/cbor-php/src/OtherObject/HalfPrecisionFloatObject.php index bfd19abfd..1f05c5bbc 100644 --- a/spomky-labs/cbor-php/src/OtherObject/HalfPrecisionFloatObject.php +++ b/spomky-labs/cbor-php/src/OtherObject/HalfPrecisionFloatObject.php @@ -14,15 +14,18 @@ namespace CBOR\OtherObject; use Brick\Math\BigInteger; +use CBOR\Normalizable; use CBOR\OtherObject as Base; use CBOR\Utils; +use const INF; use InvalidArgumentException; +use const NAN; -final class HalfPrecisionFloatObject extends Base +final class HalfPrecisionFloatObject extends Base implements Normalizable { public static function supportedAdditionalInformation(): array { - return [25]; + return [self::OBJECT_HALF_PRECISION_FLOAT]; } public static function createFromLoadedData(int $additionalInformation, ?string $data): Base @@ -30,30 +33,38 @@ public static function createFromLoadedData(int $additionalInformation, ?string return new self($additionalInformation, $data); } - /** - * @return HalfPrecisionFloatObject - */ public static function create(string $value): self { - if (4 !== mb_strlen($value, '8bit')) { + if (mb_strlen($value, '8bit') !== 2) { throw new InvalidArgumentException('The value is not a valid half precision floating point'); } - return new self(25, $value); + return new self(self::OBJECT_HALF_PRECISION_FLOAT, $value); } + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ public function getNormalizedData(bool $ignoreTags = false) { - $exp = $this->getExponent(); - $mant = $this->getMantissa(); + return $this->normalize(); + } + + /** + * @return float|int + */ + public function normalize() + { + $exponent = $this->getExponent(); + $mantissa = $this->getMantissa(); $sign = $this->getSign(); - if (0 === $exp) { - $val = $mant * 2 ** (-24); - } elseif (0b11111 !== $exp) { - $val = ($mant + (1 << 10)) * 2 ** ($exp - 25); + if ($exponent === 0) { + $val = $mantissa * 2 ** (-24); + } elseif ($exponent !== 0b11111) { + $val = ($mantissa + (1 << 10)) * 2 ** ($exponent - 25); } else { - $val = 0 === $mant ? INF : NAN; + $val = $mantissa === 0 ? INF : NAN; } return $sign * $val; diff --git a/spomky-labs/cbor-php/src/OtherObject/NullObject.php b/spomky-labs/cbor-php/src/OtherObject/NullObject.php index 424896058..a960acf4f 100644 --- a/spomky-labs/cbor-php/src/OtherObject/NullObject.php +++ b/spomky-labs/cbor-php/src/OtherObject/NullObject.php @@ -13,18 +13,24 @@ namespace CBOR\OtherObject; +use CBOR\Normalizable; use CBOR\OtherObject as Base; -final class NullObject extends Base +final class NullObject extends Base implements Normalizable { public function __construct() { - parent::__construct(22, null); + parent::__construct(self::OBJECT_NULL, null); + } + + public static function create(): self + { + return new self(); } public static function supportedAdditionalInformation(): array { - return [22]; + return [self::OBJECT_NULL]; } public static function createFromLoadedData(int $additionalInformation, ?string $data): Base @@ -32,7 +38,16 @@ public static function createFromLoadedData(int $additionalInformation, ?string return new self(); } + public function normalize(): ?string + { + return null; + } + + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ public function getNormalizedData(bool $ignoreTags = false) { + return $this->normalize(); } } diff --git a/spomky-labs/cbor-php/src/OtherObject/OtherObjectManager.php b/spomky-labs/cbor-php/src/OtherObject/OtherObjectManager.php index 43607fcf4..88edcd192 100644 --- a/spomky-labs/cbor-php/src/OtherObject/OtherObjectManager.php +++ b/spomky-labs/cbor-php/src/OtherObject/OtherObjectManager.php @@ -17,14 +17,22 @@ use CBOR\OtherObject; use InvalidArgumentException; -class OtherObjectManager +/** + * @final + */ +class OtherObjectManager implements OtherObjectManagerInterface { /** * @var string[] */ private $classes = []; - public function add(string $class): void + public static function create(): self + { + return new self(); + } + + public function add(string $class): self { foreach ($class::supportedAdditionalInformation() as $ai) { if ($ai < 0) { @@ -32,6 +40,8 @@ public function add(string $class): void } $this->classes[$ai] = $class; } + + return $this; } public function getClassForValue(int $value): string diff --git a/spomky-labs/cbor-php/src/OtherObject/OtherObjectManagerInterface.php b/spomky-labs/cbor-php/src/OtherObject/OtherObjectManagerInterface.php new file mode 100644 index 000000000..6c0336de4 --- /dev/null +++ b/spomky-labs/cbor-php/src/OtherObject/OtherObjectManagerInterface.php @@ -0,0 +1,21 @@ +data) { + if ($this->data === null) { return $this->getAdditionalInformation(); } @@ -40,17 +58,22 @@ public function getNormalizedData(bool $ignoreTags = false) } /** - * @return SimpleObject + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface */ + public function getNormalizedData(bool $ignoreTags = false): int + { + return $this->normalize(); + } + public static function create(int $value): self { switch (true) { - case $value < 24: + case $value < 32: return new self($value, null); case $value < 256: return new self(24, chr($value)); default: - throw new InvalidArgumentException('The value is not a valid simple value'); + throw new InvalidArgumentException('The value is not a valid simple value.'); } } } diff --git a/spomky-labs/cbor-php/src/OtherObject/SinglePrecisionFloatObject.php b/spomky-labs/cbor-php/src/OtherObject/SinglePrecisionFloatObject.php index 87c529ffd..3c3af6136 100644 --- a/spomky-labs/cbor-php/src/OtherObject/SinglePrecisionFloatObject.php +++ b/spomky-labs/cbor-php/src/OtherObject/SinglePrecisionFloatObject.php @@ -16,13 +16,15 @@ use Brick\Math\BigInteger; use CBOR\OtherObject as Base; use CBOR\Utils; +use const INF; use InvalidArgumentException; +use const NAN; final class SinglePrecisionFloatObject extends Base { public static function supportedAdditionalInformation(): array { - return [26]; + return [self::OBJECT_SINGLE_PRECISION_FLOAT]; } public static function createFromLoadedData(int $additionalInformation, ?string $data): Base @@ -30,30 +32,38 @@ public static function createFromLoadedData(int $additionalInformation, ?string return new self($additionalInformation, $data); } - /** - * @return SinglePrecisionFloatObject - */ public static function create(string $value): self { - if (4 !== mb_strlen($value, '8bit')) { + if (mb_strlen($value, '8bit') !== 4) { throw new InvalidArgumentException('The value is not a valid single precision floating point'); } - return new self(26, $value); + return new self(self::OBJECT_SINGLE_PRECISION_FLOAT, $value); } + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ public function getNormalizedData(bool $ignoreTags = false) { - $exp = $this->getExponent(); - $mant = $this->getMantissa(); + return $this->normalize(); + } + + /** + * @return float|int + */ + public function normalize() + { + $exponent = $this->getExponent(); + $mantissa = $this->getMantissa(); $sign = $this->getSign(); - if (0 === $exp) { - $val = $mant * 2 ** (-(126 + 23)); - } elseif (0b11111111 !== $exp) { - $val = ($mant + (1 << 23)) * 2 ** ($exp - (127 + 23)); + if ($exponent === 0) { + $val = $mantissa * 2 ** (-(126 + 23)); + } elseif ($exponent !== 0b11111111) { + $val = ($mantissa + (1 << 23)) * 2 ** ($exponent - (127 + 23)); } else { - $val = 0 === $mant ? INF : NAN; + $val = $mantissa === 0 ? INF : NAN; } return $sign * $val; @@ -79,7 +89,7 @@ public function getSign(): int { $data = $this->data; Utils::assertString($data, 'Invalid data'); - $sign = Utils::binToBigInteger($data)->shiftedRight(32); + $sign = Utils::binToBigInteger($data)->shiftedRight(31); return $sign->isEqualTo(BigInteger::one()) ? -1 : 1; } diff --git a/spomky-labs/cbor-php/src/OtherObject/TrueObject.php b/spomky-labs/cbor-php/src/OtherObject/TrueObject.php index 944d9d223..d348a1ba6 100644 --- a/spomky-labs/cbor-php/src/OtherObject/TrueObject.php +++ b/spomky-labs/cbor-php/src/OtherObject/TrueObject.php @@ -13,18 +13,24 @@ namespace CBOR\OtherObject; +use CBOR\Normalizable; use CBOR\OtherObject as Base; -final class TrueObject extends Base +final class TrueObject extends Base implements Normalizable { public function __construct() { - parent::__construct(21, null); + parent::__construct(self::OBJECT_TRUE, null); + } + + public static function create(): self + { + return new self(); } public static function supportedAdditionalInformation(): array { - return [21]; + return [self::OBJECT_TRUE]; } public static function createFromLoadedData(int $additionalInformation, ?string $data): Base @@ -32,8 +38,16 @@ public static function createFromLoadedData(int $additionalInformation, ?string return new self(); } - public function getNormalizedData(bool $ignoreTags = false): bool + public function normalize(): bool { return true; } + + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ + public function getNormalizedData(bool $ignoreTags = false): bool + { + return $this->normalize(); + } } diff --git a/spomky-labs/cbor-php/src/OtherObject/UndefinedObject.php b/spomky-labs/cbor-php/src/OtherObject/UndefinedObject.php index 4fc83271d..0b4bf8991 100644 --- a/spomky-labs/cbor-php/src/OtherObject/UndefinedObject.php +++ b/spomky-labs/cbor-php/src/OtherObject/UndefinedObject.php @@ -19,12 +19,17 @@ final class UndefinedObject extends Base { public function __construct() { - parent::__construct(23, null); + parent::__construct(self::OBJECT_UNDEFINED, null); + } + + public static function create(): self + { + return new self(); } public static function supportedAdditionalInformation(): array { - return [23]; + return [self::OBJECT_UNDEFINED]; } public static function createFromLoadedData(int $additionalInformation, ?string $data): Base @@ -32,6 +37,11 @@ public static function createFromLoadedData(int $additionalInformation, ?string return new self(); } + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + * + * @return string + */ public function getNormalizedData(bool $ignoreTags = false) { return 'undefined'; diff --git a/spomky-labs/cbor-php/src/SignedIntegerObject.php b/spomky-labs/cbor-php/src/SignedIntegerObject.php index 3c9b860dc..4526f99bd 100644 --- a/spomky-labs/cbor-php/src/SignedIntegerObject.php +++ b/spomky-labs/cbor-php/src/SignedIntegerObject.php @@ -13,108 +13,9 @@ namespace CBOR; -use Brick\Math\BigInteger; -use InvalidArgumentException; - -final class SignedIntegerObject extends AbstractCBORObject +/** + * @deprecated Will be removed in v3.0. Please use NegativeIntegerObject instead + */ +final class SignedIntegerObject extends NegativeIntegerObject { - private const MAJOR_TYPE = 0b001; - - /** - * @var string|null - */ - private $data; - - public function __construct(int $additionalInformation, ?string $data) - { - parent::__construct(self::MAJOR_TYPE, $additionalInformation); - $this->data = $data; - } - - public function __toString(): string - { - $result = parent::__toString(); - if (null !== $this->data) { - $result .= $this->data; - } - - return $result; - } - - public static function createObjectForValue(int $additionalInformation, ?string $data): self - { - return new self($additionalInformation, $data); - } - - public static function create(int $value): self - { - return self::createFromString((string) $value); - } - - public static function createFromString(string $value): self - { - $integer = BigInteger::of($value); - - return self::createBigInteger($integer); - } - - public function getValue(): string - { - return $this->getNormalizedData(); - } - - public function getNormalizedData(bool $ignoreTags = false): string - { - if (null === $this->data) { - return (string) (-1 - $this->additionalInformation); - } - - $result = Utils::binToBigInteger($this->data); - $minusOne = BigInteger::of(-1); - - return $minusOne->minus($result)->toBase(10); - } - - private static function createBigInteger(BigInteger $integer): self - { - if ($integer->isGreaterThanOrEqualTo(BigInteger::zero())) { - throw new InvalidArgumentException('The value must be a negative integer.'); - } - - $minusOne = BigInteger::of(-1); - $computed_value = $minusOne->minus($integer); - - switch (true) { - case $computed_value->isLessThan(BigInteger::of(24)): - $ai = $computed_value->toInt(); - $data = null; - break; - case $computed_value->isLessThan(BigInteger::fromBase('FF', 16)): - $ai = 24; - $data = self::hex2bin(str_pad($computed_value->toBase(16), 2, '0', STR_PAD_LEFT)); - break; - case $computed_value->isLessThan(BigInteger::fromBase('FFFF', 16)): - $ai = 25; - $data = self::hex2bin(str_pad($computed_value->toBase(16), 4, '0', STR_PAD_LEFT)); - break; - case $computed_value->isLessThan(BigInteger::fromBase('FFFFFFFF', 16)): - $ai = 26; - $data = self::hex2bin(str_pad($computed_value->toBase(16), 8, '0', STR_PAD_LEFT)); - break; - default: - throw new InvalidArgumentException('Out of range. Please use NegativeBigIntegerTag tag with ByteStringObject object instead.'); - } - - return new self($ai, $data); - } - - private static function hex2bin(string $data): string - { - $result = hex2bin($data); - if (false === $result) { - throw new InvalidArgumentException('Unable to convert the data'); - } - - return $result; - } } diff --git a/spomky-labs/cbor-php/src/StringStream.php b/spomky-labs/cbor-php/src/StringStream.php index e43908435..3676c7d65 100644 --- a/spomky-labs/cbor-php/src/StringStream.php +++ b/spomky-labs/cbor-php/src/StringStream.php @@ -26,31 +26,58 @@ final class StringStream implements Stream public function __construct(string $data) { $resource = fopen('php://memory', 'rb+'); - if (false === $resource) { + if ($resource === false) { throw new RuntimeException('Unable to open the memory'); } $result = fwrite($resource, $data); - if (false === $result) { + if ($result === false) { throw new RuntimeException('Unable to write the memory'); } $result = rewind($resource); - if (false === $result) { + if ($result === false) { throw new RuntimeException('Unable to rewind the memory'); } $this->resource = $resource; } + public static function create(string $data): self + { + return new self($data); + } + public function read(int $length): string { - if (0 === $length) { + if ($length === 0) { return ''; } - $data = fread($this->resource, $length); - if (false === $data) { - throw new RuntimeException('Unable to read the memory'); + + $alreadyRead = 0; + $data = ''; + while ($alreadyRead < $length) { + $left = $length - $alreadyRead; + $sizeToRead = $left < 1024 && $left > 0 ? $left : 1024; + $newData = fread($this->resource, $sizeToRead); + $alreadyRead += $sizeToRead; + + if ($newData === false) { + throw new RuntimeException('Unable to read the memory'); + } + if (mb_strlen($newData, '8bit') < $sizeToRead) { + throw new InvalidArgumentException(sprintf( + 'Out of range. Expected: %d, read: %d.', + $length, + mb_strlen($data, '8bit') + )); + } + $data .= $newData; } + if (mb_strlen($data, '8bit') !== $length) { - throw new InvalidArgumentException(sprintf('Out of range. Expected: %d, read: %d.', $length, mb_strlen($data, '8bit'))); + throw new InvalidArgumentException(sprintf( + 'Out of range. Expected: %d, read: %d.', + $length, + mb_strlen($data, '8bit') + )); } return $data; diff --git a/spomky-labs/cbor-php/src/Tag.php b/spomky-labs/cbor-php/src/Tag.php new file mode 100644 index 000000000..9d7171a91 --- /dev/null +++ b/spomky-labs/cbor-php/src/Tag.php @@ -0,0 +1,99 @@ +data = $data; + $this->object = $object; + } + + public function __toString(): string + { + $result = parent::__toString(); + if ($this->data !== null) { + $result .= $this->data; + } + + return $result . $this->object; + } + + public function getData(): ?string + { + return $this->data; + } + + abstract public static function getTagId(): int; + + abstract public static function createFromLoadedData( + int $additionalInformation, + ?string $data, + CBORObject $object + ): self; + + public function getValue(): CBORObject + { + return $this->object; + } + + /** + * @return array{int, null|string} + */ + protected static function determineComponents(int $tag): array + { + switch (true) { + case $tag < 0: + throw new InvalidArgumentException('The value must be a positive integer.'); + case $tag < 24: + return [$tag, null]; + case $tag < 0xFF: + return [24, self::hex2bin(dechex($tag))]; + case $tag < 0xFFFF: + return [25, self::hex2bin(dechex($tag))]; + case $tag < 0xFFFFFFFF: + return [26, self::hex2bin(dechex($tag))]; + default: + throw new InvalidArgumentException( + 'Out of range. Please use PositiveBigIntegerTag tag with ByteStringObject object instead.' + ); + } + } + + private static function hex2bin(string $data): string + { + $result = hex2bin($data); + if ($result === false) { + throw new InvalidArgumentException('Unable to convert the data'); + } + + return $result; + } +} diff --git a/spomky-labs/cbor-php/src/Tag/Base16EncodingTag.php b/spomky-labs/cbor-php/src/Tag/Base16EncodingTag.php index 55d356446..1130358d5 100644 --- a/spomky-labs/cbor-php/src/Tag/Base16EncodingTag.php +++ b/spomky-labs/cbor-php/src/Tag/Base16EncodingTag.php @@ -14,41 +14,41 @@ namespace CBOR\Tag; use CBOR\ByteStringObject; -use CBOR\ByteStringWithChunkObject; use CBOR\CBORObject; -use CBOR\TagObject as Base; +use CBOR\IndefiniteLengthByteStringObject; +use CBOR\IndefiniteLengthTextStringObject; +use CBOR\Tag; use CBOR\TextStringObject; -use CBOR\TextStringWithChunkObject; -use InvalidArgumentException; -final class Base16EncodingTag extends Base +final class Base16EncodingTag extends Tag { public static function getTagId(): int { - return 23; + return self::TAG_ENCODED_BASE16; } - public static function createFromLoadedData(int $additionalInformation, ?string $data, CBORObject $object): Base + public static function createFromLoadedData(int $additionalInformation, ?string $data, CBORObject $object): Tag { return new self($additionalInformation, $data, $object); } - public static function create(CBORObject $object): Base + public static function create(CBORObject $object): Tag { - if (!$object instanceof ByteStringObject && !$object instanceof ByteStringWithChunkObject && !$object instanceof TextStringObject && !$object instanceof TextStringWithChunkObject) { - throw new InvalidArgumentException('This tag only accepts Byte String, Infinite Byte String, Text String or Infinite Text String objects.'); - } + [$ai, $data] = self::determineComponents(self::TAG_ENCODED_BASE16); - return new self(23, null, $object); + return new self($ai, $data, $object); } + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ public function getNormalizedData(bool $ignoreTags = false) { if ($ignoreTags) { return $this->object->getNormalizedData($ignoreTags); } - if (!$this->object instanceof ByteStringObject && !$this->object instanceof ByteStringWithChunkObject && !$this->object instanceof TextStringObject && !$this->object instanceof TextStringWithChunkObject) { + if (! $this->object instanceof ByteStringObject && ! $this->object instanceof IndefiniteLengthByteStringObject && ! $this->object instanceof TextStringObject && ! $this->object instanceof IndefiniteLengthTextStringObject) { return $this->object->getNormalizedData($ignoreTags); } diff --git a/spomky-labs/cbor-php/src/Tag/Base64EncodingTag.php b/spomky-labs/cbor-php/src/Tag/Base64EncodingTag.php index f7a1d9890..6f8bb60eb 100644 --- a/spomky-labs/cbor-php/src/Tag/Base64EncodingTag.php +++ b/spomky-labs/cbor-php/src/Tag/Base64EncodingTag.php @@ -14,46 +14,47 @@ namespace CBOR\Tag; use CBOR\ByteStringObject; -use CBOR\ByteStringWithChunkObject; use CBOR\CBORObject; -use CBOR\TagObject as Base; +use CBOR\IndefiniteLengthByteStringObject; +use CBOR\IndefiniteLengthTextStringObject; +use CBOR\Tag; use CBOR\TextStringObject; -use CBOR\TextStringWithChunkObject; use InvalidArgumentException; -final class Base64EncodingTag extends Base +final class Base64EncodingTag extends Tag { public static function getTagId(): int { - return 22; + return self::TAG_ENCODED_BASE64; } - public static function createFromLoadedData(int $additionalInformation, ?string $data, CBORObject $object): Base + public static function createFromLoadedData(int $additionalInformation, ?string $data, CBORObject $object): Tag { return new self($additionalInformation, $data, $object); } - public static function create(CBORObject $object): Base + public static function create(CBORObject $object): Tag { - if (!$object instanceof ByteStringObject && !$object instanceof ByteStringWithChunkObject && !$object instanceof TextStringObject && !$object instanceof TextStringWithChunkObject) { - throw new InvalidArgumentException('This tag only accepts Byte String, Infinite Byte String, Text String or Infinite Text String objects.'); - } + [$ai, $data] = self::determineComponents(self::TAG_ENCODED_BASE64); - return new self(22, null, $object); + return new self($ai, $data, $object); } + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ public function getNormalizedData(bool $ignoreTags = false) { if ($ignoreTags) { return $this->object->getNormalizedData($ignoreTags); } - if (!$this->object instanceof ByteStringObject && !$this->object instanceof ByteStringWithChunkObject && !$this->object instanceof TextStringObject && !$this->object instanceof TextStringWithChunkObject) { + if (! $this->object instanceof ByteStringObject && ! $this->object instanceof IndefiniteLengthByteStringObject && ! $this->object instanceof TextStringObject && ! $this->object instanceof IndefiniteLengthTextStringObject) { return $this->object->getNormalizedData($ignoreTags); } $result = base64_decode($this->object->getNormalizedData($ignoreTags), true); - if (false === $result) { + if ($result === false) { throw new InvalidArgumentException('Unable to decode the data'); } diff --git a/spomky-labs/cbor-php/src/Tag/Base64Tag.php b/spomky-labs/cbor-php/src/Tag/Base64Tag.php new file mode 100644 index 000000000..b66932703 --- /dev/null +++ b/spomky-labs/cbor-php/src/Tag/Base64Tag.php @@ -0,0 +1,57 @@ +object->getNormalizedData($ignoreTags); + } +} diff --git a/spomky-labs/cbor-php/src/Tag/Base64UrlEncodingTag.php b/spomky-labs/cbor-php/src/Tag/Base64UrlEncodingTag.php index ac8b880b8..4dbaaf825 100644 --- a/spomky-labs/cbor-php/src/Tag/Base64UrlEncodingTag.php +++ b/spomky-labs/cbor-php/src/Tag/Base64UrlEncodingTag.php @@ -14,42 +14,42 @@ namespace CBOR\Tag; use CBOR\ByteStringObject; -use CBOR\ByteStringWithChunkObject; use CBOR\CBORObject; -use CBOR\TagObject as Base; +use CBOR\IndefiniteLengthByteStringObject; +use CBOR\IndefiniteLengthTextStringObject; +use CBOR\Tag; use CBOR\TextStringObject; -use CBOR\TextStringWithChunkObject; use CBOR\Utils; -use InvalidArgumentException; -final class Base64UrlEncodingTag extends Base +final class Base64UrlEncodingTag extends Tag { public static function getTagId(): int { - return 21; + return self::TAG_ENCODED_BASE64_URL; } - public static function createFromLoadedData(int $additionalInformation, ?string $data, CBORObject $object): Base + public static function createFromLoadedData(int $additionalInformation, ?string $data, CBORObject $object): Tag { return new self($additionalInformation, $data, $object); } - public static function create(CBORObject $object): Base + public static function create(CBORObject $object): Tag { - if (!$object instanceof ByteStringObject && !$object instanceof ByteStringWithChunkObject && !$object instanceof TextStringObject && !$object instanceof TextStringWithChunkObject) { - throw new InvalidArgumentException('This tag only accepts Byte String, Infinite Byte String, Text String or Infinite Text String objects.'); - } + [$ai, $data] = self::determineComponents(self::TAG_ENCODED_BASE64_URL); - return new self(21, null, $object); + return new self($ai, $data, $object); } + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ public function getNormalizedData(bool $ignoreTags = false) { if ($ignoreTags) { return $this->object->getNormalizedData($ignoreTags); } - if (!$this->object instanceof ByteStringObject && !$this->object instanceof ByteStringWithChunkObject && !$this->object instanceof TextStringObject && !$this->object instanceof TextStringWithChunkObject) { + if (! $this->object instanceof ByteStringObject && ! $this->object instanceof IndefiniteLengthByteStringObject && ! $this->object instanceof TextStringObject && ! $this->object instanceof IndefiniteLengthTextStringObject) { return $this->object->getNormalizedData($ignoreTags); } diff --git a/spomky-labs/cbor-php/src/Tag/Base64UrlTag.php b/spomky-labs/cbor-php/src/Tag/Base64UrlTag.php new file mode 100644 index 000000000..1d7d27f6f --- /dev/null +++ b/spomky-labs/cbor-php/src/Tag/Base64UrlTag.php @@ -0,0 +1,57 @@ +object->getNormalizedData($ignoreTags); + } +} diff --git a/spomky-labs/cbor-php/src/Tag/BigFloatTag.php b/spomky-labs/cbor-php/src/Tag/BigFloatTag.php index 2233f7830..c6a33b24c 100644 --- a/spomky-labs/cbor-php/src/Tag/BigFloatTag.php +++ b/spomky-labs/cbor-php/src/Tag/BigFloatTag.php @@ -15,88 +15,94 @@ use CBOR\CBORObject; use CBOR\ListObject; -use CBOR\SignedIntegerObject; -use CBOR\TagObject as Base; +use CBOR\NegativeIntegerObject; +use CBOR\Normalizable; +use CBOR\Tag; use CBOR\UnsignedIntegerObject; use function count; use function extension_loaded; use InvalidArgumentException; use RuntimeException; -final class BigFloatTag extends Base +final class BigFloatTag extends Tag implements Normalizable { public function __construct(int $additionalInformation, ?string $data, CBORObject $object) { - if (!extension_loaded('bcmath')) { + if (! extension_loaded('bcmath')) { throw new RuntimeException('The extension "bcmath" is required to use this tag'); } + + if (! $object instanceof ListObject || count($object) !== 2) { + throw new InvalidArgumentException( + 'This tag only accepts a ListObject object that contains an exponent and a mantissa.' + ); + } + $e = $object->get(0); + if (! $e instanceof UnsignedIntegerObject && ! $e instanceof NegativeIntegerObject) { + throw new InvalidArgumentException('The exponent must be a Signed Integer or an Unsigned Integer object.'); + } + $m = $object->get(1); + if (! $m instanceof UnsignedIntegerObject && ! $m instanceof NegativeIntegerObject && ! $m instanceof NegativeBigIntegerTag && ! $m instanceof UnsignedBigIntegerTag) { + throw new InvalidArgumentException( + 'The mantissa must be a Positive or Negative Signed Integer or an Unsigned Integer object.' + ); + } + parent::__construct($additionalInformation, $data, $object); } public static function getTagId(): int { - return 5; + return self::TAG_BIG_FLOAT; } - public static function createFromLoadedData(int $additionalInformation, ?string $data, CBORObject $object): Base + public static function createFromLoadedData(int $additionalInformation, ?string $data, CBORObject $object): Tag { return new self($additionalInformation, $data, $object); } - public static function create(CBORObject $object): Base + public static function create(CBORObject $object): Tag { - if (!$object instanceof ListObject || 2 !== count($object)) { - throw new InvalidArgumentException('This tag only accepts a ListObject object that contains an exponent and a mantissa.'); - } - $e = $object->get(0); - if (!$e instanceof UnsignedIntegerObject && !$e instanceof SignedIntegerObject) { - throw new InvalidArgumentException('The exponent must be a Signed Integer or an Unsigned Integer object.'); - } - $m = $object->get(1); - if (!$m instanceof UnsignedIntegerObject && !$m instanceof SignedIntegerObject && !$m instanceof NegativeBigIntegerTag && !$m instanceof PositiveBigIntegerTag) { - throw new InvalidArgumentException('The mantissa must be a Positive or Negative Signed Integer or an Unsigned Integer object.'); - } + [$ai, $data] = self::determineComponents(self::TAG_BIG_FLOAT); - return new self(5, null, $object); + return new self($ai, $data, $object); } - public static function createFromExponentAndMantissa(CBORObject $e, CBORObject $m): Base + public static function createFromExponentAndMantissa(CBORObject $e, CBORObject $m): Tag { - $object = new ListObject(); - $object->add($e); - $object->add($m); + $object = ListObject::create() + ->add($e) + ->add($m) + ; return self::create($object); } + public function normalize() + { + /** @var ListObject $object */ + $object = $this->object; + /** @var UnsignedIntegerObject|NegativeIntegerObject $e */ + $e = $object->get(0); + /** @var UnsignedIntegerObject|NegativeIntegerObject|NegativeBigIntegerTag|UnsignedBigIntegerTag $m */ + $m = $object->get(1); + + return rtrim(bcmul($m->normalize(), bcpow('2', $e->normalize(), 100), 100), '0'); + } + + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ public function getNormalizedData(bool $ignoreTags = false) { if ($ignoreTags) { return $this->object->getNormalizedData($ignoreTags); } - if (!$this->object instanceof ListObject || 2 !== count($this->object)) { - return $this->object->getNormalizedData($ignoreTags); - } - $e = $this->object->get(0); - $m = $this->object->get(1); - - if (!$e instanceof UnsignedIntegerObject && !$e instanceof SignedIntegerObject) { - return $this->object->getNormalizedData($ignoreTags); - } - if (!$m instanceof UnsignedIntegerObject && !$m instanceof SignedIntegerObject && !$m instanceof NegativeBigIntegerTag && !$m instanceof PositiveBigIntegerTag) { + if (! $this->object instanceof ListObject || count($this->object) !== 2) { return $this->object->getNormalizedData($ignoreTags); } - return rtrim( - bcmul( - $m->getNormalizedData($ignoreTags), - bcpow( - '2', - $e->getNormalizedData($ignoreTags), - 100), - 100), - '0' - ); + return $this->normalize(); } } diff --git a/spomky-labs/cbor-php/src/Tag/CBOREncodingTag.php b/spomky-labs/cbor-php/src/Tag/CBOREncodingTag.php new file mode 100644 index 000000000..612a6d319 --- /dev/null +++ b/spomky-labs/cbor-php/src/Tag/CBOREncodingTag.php @@ -0,0 +1,57 @@ +object->getNormalizedData($ignoreTags); + } +} diff --git a/spomky-labs/cbor-php/src/Tag/CBORTag.php b/spomky-labs/cbor-php/src/Tag/CBORTag.php new file mode 100644 index 000000000..fbb8581f5 --- /dev/null +++ b/spomky-labs/cbor-php/src/Tag/CBORTag.php @@ -0,0 +1,54 @@ +object instanceof Normalizable ? $this->object->normalize() : $this->object; + } + + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ + public function getNormalizedData(bool $ignoreTags = false) + { + return $this->object->getNormalizedData($ignoreTags); + } +} diff --git a/spomky-labs/cbor-php/src/Tag/DatetimeTag.php b/spomky-labs/cbor-php/src/Tag/DatetimeTag.php new file mode 100644 index 000000000..ac0783748 --- /dev/null +++ b/spomky-labs/cbor-php/src/Tag/DatetimeTag.php @@ -0,0 +1,84 @@ +object; + $result = DateTimeImmutable::createFromFormat(DATE_RFC3339, $object->normalize()); + if ($result !== false) { + return $result; + } + + $formatted = DateTimeImmutable::createFromFormat('Y-m-d\TH:i:s.uP', $object->normalize()); + if ($formatted === false) { + throw new InvalidArgumentException('Invalid data. Cannot be converted into a datetime object'); + } + + return $formatted; + } + + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ + public function getNormalizedData(bool $ignoreTags = false) + { + if ($ignoreTags) { + return $this->object->getNormalizedData($ignoreTags); + } + + return $this->normalize(); + } +} diff --git a/spomky-labs/cbor-php/src/Tag/DecimalFractionTag.php b/spomky-labs/cbor-php/src/Tag/DecimalFractionTag.php index 2f1bbe44f..76b5c6a7a 100644 --- a/spomky-labs/cbor-php/src/Tag/DecimalFractionTag.php +++ b/spomky-labs/cbor-php/src/Tag/DecimalFractionTag.php @@ -15,83 +15,100 @@ use CBOR\CBORObject; use CBOR\ListObject; -use CBOR\SignedIntegerObject; -use CBOR\TagObject as Base; +use CBOR\NegativeIntegerObject; +use CBOR\Normalizable; +use CBOR\Tag; use CBOR\UnsignedIntegerObject; use function count; use function extension_loaded; use InvalidArgumentException; use RuntimeException; -final class DecimalFractionTag extends Base +final class DecimalFractionTag extends Tag implements Normalizable { public function __construct(CBORObject $object) { - if (!extension_loaded('bcmath')) { + if (! extension_loaded('bcmath')) { throw new RuntimeException('The extension "bcmath" is required to use this tag'); } - if (!$object instanceof ListObject || 2 !== count($object)) { - throw new InvalidArgumentException('This tag only accepts a ListObject object that contains an exponent and a mantissa.'); + if (! $object instanceof ListObject || count($object) !== 2) { + throw new InvalidArgumentException( + 'This tag only accepts a ListObject object that contains an exponent and a mantissa.' + ); } $e = $object->get(0); - if (!$e instanceof UnsignedIntegerObject && !$e instanceof SignedIntegerObject) { + if (! $e instanceof UnsignedIntegerObject && ! $e instanceof NegativeIntegerObject) { throw new InvalidArgumentException('The exponent must be a Signed Integer or an Unsigned Integer object.'); } $m = $object->get(1); - if (!$m instanceof UnsignedIntegerObject && !$m instanceof SignedIntegerObject && !$m instanceof NegativeBigIntegerTag && !$m instanceof PositiveBigIntegerTag) { - throw new InvalidArgumentException('The mantissa must be a Positive or Negative Signed Integer or an Unsigned Integer object.'); + if (! $m instanceof UnsignedIntegerObject && ! $m instanceof NegativeIntegerObject && ! $m instanceof NegativeBigIntegerTag && ! $m instanceof UnsignedBigIntegerTag) { + throw new InvalidArgumentException( + 'The mantissa must be a Positive or Negative Signed Integer or an Unsigned Integer object.' + ); } - parent::__construct(4, null, $object); + parent::__construct(self::TAG_DECIMAL_FRACTION, null, $object); + } + + public static function create(CBORObject $object): self + { + return new self($object); } public static function getTagId(): int { - return 4; + return self::TAG_DECIMAL_FRACTION; } - public static function createFromLoadedData(int $additionalInformation, ?string $data, CBORObject $object): Base + public static function createFromLoadedData(int $additionalInformation, ?string $data, CBORObject $object): Tag { return new self($object); } - public static function createFromExponentAndMantissa(CBORObject $e, CBORObject $m): Base + public static function createFromExponentAndMantissa(CBORObject $e, CBORObject $m): Tag { - $object = new ListObject(); - $object->add($e); - $object->add($m); + $object = ListObject::create() + ->add($e) + ->add($m) + ; - return new self($object); + return self::create($object); + } + + public function normalize() + { + /** @var ListObject $object */ + $object = $this->object; + /** @var UnsignedIntegerObject|NegativeIntegerObject $e */ + $e = $object->get(0); + /** @var UnsignedIntegerObject|NegativeIntegerObject|NegativeBigIntegerTag|UnsignedBigIntegerTag $m */ + $m = $object->get(1); + + return rtrim(bcmul($m->normalize(), bcpow('10', $e->normalize(), 100), 100), '0'); } + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ public function getNormalizedData(bool $ignoreTags = false) { if ($ignoreTags) { return $this->object->getNormalizedData($ignoreTags); } - if (!$this->object instanceof ListObject || 2 !== count($this->object)) { + if (! $this->object instanceof ListObject || count($this->object) !== 2) { return $this->object->getNormalizedData($ignoreTags); } $e = $this->object->get(0); $m = $this->object->get(1); - if (!$e instanceof UnsignedIntegerObject && !$e instanceof SignedIntegerObject) { + if (! $e instanceof UnsignedIntegerObject && ! $e instanceof NegativeIntegerObject) { return $this->object->getNormalizedData($ignoreTags); } - if (!$m instanceof UnsignedIntegerObject && !$m instanceof SignedIntegerObject && !$m instanceof NegativeBigIntegerTag && !$m instanceof PositiveBigIntegerTag) { + if (! $m instanceof UnsignedIntegerObject && ! $m instanceof NegativeIntegerObject && ! $m instanceof NegativeBigIntegerTag && ! $m instanceof UnsignedBigIntegerTag) { return $this->object->getNormalizedData($ignoreTags); } - return rtrim( - bcmul( - $m->getNormalizedData($ignoreTags), - bcpow( - '10', - $e->getNormalizedData($ignoreTags), - 100), - 100), - '0' - ); + return $this->normalize(); } } diff --git a/spomky-labs/cbor-php/src/Tag/EpochTag.php b/spomky-labs/cbor-php/src/Tag/EpochTag.php index ae96e6efe..aa00c73ff 100644 --- a/spomky-labs/cbor-php/src/Tag/EpochTag.php +++ b/spomky-labs/cbor-php/src/Tag/EpochTag.php @@ -13,33 +13,9 @@ namespace CBOR\Tag; -use CBOR\CBORObject; -use CBOR\TagObject as Base; -use DateTimeImmutable; - -final class EpochTag extends Base +/** + * @deprecated The class EpochTag is deprecated and will be removed in v3.0. Please use DatetimeTag instead + */ +final class EpochTag extends DatetimeTag { - public static function getTagId(): int - { - return 0; - } - - public static function createFromLoadedData(int $additionalInformation, ?string $data, CBORObject $object): Base - { - return new self($additionalInformation, $data, $object); - } - - public static function create(CBORObject $object): Base - { - return new self(0, null, $object); - } - - public function getNormalizedData(bool $ignoreTags = false) - { - if ($ignoreTags) { - return $this->object->getNormalizedData($ignoreTags); - } - - return DateTimeImmutable::createFromFormat(DATE_RFC3339, $this->object->getNormalizedData($ignoreTags)); - } } diff --git a/spomky-labs/cbor-php/src/Tag/GenericTag.php b/spomky-labs/cbor-php/src/Tag/GenericTag.php index 2e2df6387..73e6ff7d8 100644 --- a/spomky-labs/cbor-php/src/Tag/GenericTag.php +++ b/spomky-labs/cbor-php/src/Tag/GenericTag.php @@ -14,20 +14,23 @@ namespace CBOR\Tag; use CBOR\CBORObject; -use CBOR\TagObject as Base; +use CBOR\Tag; -final class GenericTag extends Base +final class GenericTag extends Tag { public static function getTagId(): int { return -1; } - public static function createFromLoadedData(int $additionalInformation, ?string $data, CBORObject $object): Base + public static function createFromLoadedData(int $additionalInformation, ?string $data, CBORObject $object): Tag { return new self($additionalInformation, $data, $object); } + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ public function getNormalizedData(bool $ignoreTags = false) { return $this->object; diff --git a/spomky-labs/cbor-php/src/Tag/MimeTag.php b/spomky-labs/cbor-php/src/Tag/MimeTag.php new file mode 100644 index 000000000..bf5d2bb1a --- /dev/null +++ b/spomky-labs/cbor-php/src/Tag/MimeTag.php @@ -0,0 +1,66 @@ +object; + + return $object->normalize(); + } + + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ + public function getNormalizedData(bool $ignoreTags = false) + { + return $this->object->getNormalizedData($ignoreTags); + } +} diff --git a/spomky-labs/cbor-php/src/Tag/NegativeBigIntegerTag.php b/spomky-labs/cbor-php/src/Tag/NegativeBigIntegerTag.php index ace8a9cab..15726366d 100644 --- a/spomky-labs/cbor-php/src/Tag/NegativeBigIntegerTag.php +++ b/spomky-labs/cbor-php/src/Tag/NegativeBigIntegerTag.php @@ -16,42 +16,68 @@ use Brick\Math\BigInteger; use CBOR\ByteStringObject; use CBOR\CBORObject; -use CBOR\TagObject as Base; +use CBOR\IndefiniteLengthByteStringObject; +use CBOR\Normalizable; +use CBOR\Tag; use InvalidArgumentException; -final class NegativeBigIntegerTag extends Base +final class NegativeBigIntegerTag extends Tag implements Normalizable { + public function __construct(int $additionalInformation, ?string $data, CBORObject $object) + { + if (! $object instanceof ByteStringObject && ! $object instanceof IndefiniteLengthByteStringObject) { + throw new InvalidArgumentException('This tag only accepts a Byte String object.'); + } + + parent::__construct($additionalInformation, $data, $object); + } + public static function getTagId(): int { - return 3; + return self::TAG_NEGATIVE_BIG_NUM; } - public static function createFromLoadedData(int $additionalInformation, ?string $data, CBORObject $object): Base + public static function createFromLoadedData(int $additionalInformation, ?string $data, CBORObject $object): Tag { return new self($additionalInformation, $data, $object); } - public static function create(CBORObject $object): Base + public static function create(CBORObject $object): Tag { - if (!$object instanceof ByteStringObject) { - throw new InvalidArgumentException('This tag only accepts a Byte String object.'); - } + [$ai, $data] = self::determineComponents(self::TAG_NEGATIVE_BIG_NUM); + + return new self($ai, $data, $object); + } + + public function normalize(): string + { + /** @var ByteStringObject|IndefiniteLengthByteStringObject $object */ + $object = $this->object; + $integer = BigInteger::fromBase(bin2hex($object->getValue()), 16); + $minusOne = BigInteger::of(-1); - return new self(3, null, $object); + return $minusOne->minus($integer) + ->toBase(10) + ; } + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ public function getNormalizedData(bool $ignoreTags = false) { if ($ignoreTags) { return $this->object->getNormalizedData($ignoreTags); } - if (!$this->object instanceof ByteStringObject) { + if (! $this->object instanceof ByteStringObject) { return $this->object->getNormalizedData($ignoreTags); } $integer = BigInteger::fromBase(bin2hex($this->object->getValue()), 16); $minusOne = BigInteger::of(-1); - return $minusOne->minus($integer)->toBase(10); + return $minusOne->minus($integer) + ->toBase(10) + ; } } diff --git a/spomky-labs/cbor-php/src/Tag/PositiveBigIntegerTag.php b/spomky-labs/cbor-php/src/Tag/PositiveBigIntegerTag.php index ddb85c9f9..0a35896cf 100644 --- a/spomky-labs/cbor-php/src/Tag/PositiveBigIntegerTag.php +++ b/spomky-labs/cbor-php/src/Tag/PositiveBigIntegerTag.php @@ -13,43 +13,9 @@ namespace CBOR\Tag; -use CBOR\ByteStringObject; -use CBOR\CBORObject; -use CBOR\TagObject as Base; -use CBOR\Utils; -use InvalidArgumentException; - -final class PositiveBigIntegerTag extends Base +/** + * @deprecated Will be removed in v3.0. Please use UnsignedBigIntegerTag instead + */ +final class PositiveBigIntegerTag extends UnsignedBigIntegerTag { - public static function getTagId(): int - { - return 2; - } - - public static function createFromLoadedData(int $additionalInformation, ?string $data, CBORObject $object): Base - { - return new self($additionalInformation, $data, $object); - } - - public static function create(CBORObject $object): Base - { - if (!$object instanceof ByteStringObject) { - throw new InvalidArgumentException('This tag only accepts a Byte String object.'); - } - - return new self(2, null, $object); - } - - public function getNormalizedData(bool $ignoreTags = false) - { - if ($ignoreTags) { - return $this->object->getNormalizedData($ignoreTags); - } - - if (!$this->object instanceof ByteStringObject) { - return $this->object->getNormalizedData($ignoreTags); - } - - return Utils::hexToString($this->object->getValue()); - } } diff --git a/spomky-labs/cbor-php/src/Tag/TagManager.php b/spomky-labs/cbor-php/src/Tag/TagManager.php new file mode 100644 index 000000000..9dcbad9d0 --- /dev/null +++ b/spomky-labs/cbor-php/src/Tag/TagManager.php @@ -0,0 +1,64 @@ +classes[$class::getTagId()] = $class; + + return $this; + } + + public function getClassForValue(int $value): string + { + return array_key_exists($value, $this->classes) ? $this->classes[$value] : GenericTag::class; + } + + public function createObjectForValue(int $additionalInformation, ?string $data, CBORObject $object): Tag + { + $value = $additionalInformation; + if ($additionalInformation >= 24) { + Utils::assertString($data, 'Invalid data'); + $value = Utils::binToInt($data); + } + /** @var Tag $class */ + $class = $this->getClassForValue($value); + + return $class::createFromLoadedData($additionalInformation, $data, $object); + } +} diff --git a/spomky-labs/cbor-php/src/Tag/TagManagerInterface.php b/spomky-labs/cbor-php/src/Tag/TagManagerInterface.php new file mode 100644 index 000000000..37e386200 --- /dev/null +++ b/spomky-labs/cbor-php/src/Tag/TagManagerInterface.php @@ -0,0 +1,22 @@ +classes[$class::getTagId()] = $class; - } - - public function getClassForValue(int $value): string - { - return array_key_exists($value, $this->classes) ? $this->classes[$value] : GenericTag::class; - } - - public function createObjectForValue(int $additionalInformation, ?string $data, CBORObject $object): TagObject - { - $value = $additionalInformation; - if ($additionalInformation >= 24) { - Utils::assertString($data, 'Invalid data'); - $value = Utils::binToInt($data); - } - /** @var TagObject $class */ - $class = $this->getClassForValue($value); - - return $class::createFromLoadedData($additionalInformation, $data, $object); - } } diff --git a/spomky-labs/cbor-php/src/Tag/TimestampTag.php b/spomky-labs/cbor-php/src/Tag/TimestampTag.php index a56465ddd..332ae6900 100644 --- a/spomky-labs/cbor-php/src/Tag/TimestampTag.php +++ b/spomky-labs/cbor-php/src/Tag/TimestampTag.php @@ -14,36 +14,84 @@ namespace CBOR\Tag; use CBOR\CBORObject; +use CBOR\NegativeIntegerObject; +use CBOR\Normalizable; use CBOR\OtherObject\DoublePrecisionFloatObject; use CBOR\OtherObject\HalfPrecisionFloatObject; use CBOR\OtherObject\SinglePrecisionFloatObject; -use CBOR\TagObject as Base; +use CBOR\Tag; use CBOR\UnsignedIntegerObject; use DateTimeImmutable; +use DateTimeInterface; use InvalidArgumentException; -use function strval; +use const STR_PAD_RIGHT; -final class TimestampTag extends Base +final class TimestampTag extends Tag implements Normalizable { + public function __construct(int $additionalInformation, ?string $data, CBORObject $object) + { + if (! $object instanceof UnsignedIntegerObject && ! $object instanceof NegativeIntegerObject && ! $object instanceof HalfPrecisionFloatObject && ! $object instanceof SinglePrecisionFloatObject && ! $object instanceof DoublePrecisionFloatObject) { + throw new InvalidArgumentException('This tag only accepts integer-based or float-based objects.'); + } + parent::__construct($additionalInformation, $data, $object); + } + public static function getTagId(): int { - return 1; + return self::TAG_EPOCH_DATETIME; } - public static function createFromLoadedData(int $additionalInformation, ?string $data, CBORObject $object): Base + public static function createFromLoadedData(int $additionalInformation, ?string $data, CBORObject $object): Tag { return new self($additionalInformation, $data, $object); } - public static function create(CBORObject $object): Base + public static function create(CBORObject $object): Tag + { + [$ai, $data] = self::determineComponents(self::TAG_EPOCH_DATETIME); + + return new self($ai, $data, $object); + } + + public function normalize(): DateTimeInterface { - if (!$object instanceof UnsignedIntegerObject && !$object instanceof HalfPrecisionFloatObject && !$object instanceof SinglePrecisionFloatObject && !$object instanceof DoublePrecisionFloatObject) { - throw new InvalidArgumentException('This tag only accepts a Byte String object.'); + $object = $this->object; + + switch (true) { + case $object instanceof UnsignedIntegerObject: + case $object instanceof NegativeIntegerObject: + $formatted = DateTimeImmutable::createFromFormat('U', $object->normalize()); + + break; + case $object instanceof HalfPrecisionFloatObject: + case $object instanceof SinglePrecisionFloatObject: + case $object instanceof DoublePrecisionFloatObject: + $value = (string) $object->normalize(); + $parts = explode('.', $value); + if (isset($parts[1])) { + if (mb_strlen($parts[1], '8bit') > 6) { + $parts[1] = mb_substr($parts[1], 0, 6, '8bit'); + } else { + $parts[1] = str_pad($parts[1], 6, '0', STR_PAD_RIGHT); + } + } + $formatted = DateTimeImmutable::createFromFormat('U.u', implode('.', $parts)); + + break; + default: + throw new InvalidArgumentException('Unable to normalize the object'); + } + + if ($formatted === false) { + throw new InvalidArgumentException('Invalid data. Cannot be converted into a datetime object'); } - return new self(1, null, $object); + return $formatted; } + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ public function getNormalizedData(bool $ignoreTags = false) { if ($ignoreTags) { @@ -51,11 +99,11 @@ public function getNormalizedData(bool $ignoreTags = false) } switch (true) { case $this->object instanceof UnsignedIntegerObject: - return DateTimeImmutable::createFromFormat('U', strval($this->object->getNormalizedData($ignoreTags))); + case $this->object instanceof NegativeIntegerObject: case $this->object instanceof HalfPrecisionFloatObject: case $this->object instanceof SinglePrecisionFloatObject: case $this->object instanceof DoublePrecisionFloatObject: - return DateTimeImmutable::createFromFormat('U.u', strval($this->object->getNormalizedData($ignoreTags))); + return $this->normalize(); default: return $this->object->getNormalizedData($ignoreTags); } diff --git a/spomky-labs/cbor-php/src/Tag/UnsignedBigIntegerTag.php b/spomky-labs/cbor-php/src/Tag/UnsignedBigIntegerTag.php new file mode 100644 index 000000000..37e5bd7b3 --- /dev/null +++ b/spomky-labs/cbor-php/src/Tag/UnsignedBigIntegerTag.php @@ -0,0 +1,78 @@ +object; + + return Utils::hexToString($object->normalize()); + } + + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ + public function getNormalizedData(bool $ignoreTags = false) + { + if ($ignoreTags) { + return $this->object->getNormalizedData($ignoreTags); + } + + if (! $this->object instanceof ByteStringObject) { + return $this->object->getNormalizedData($ignoreTags); + } + + return Utils::hexToString($this->object->getValue()); + } +} diff --git a/spomky-labs/cbor-php/src/Tag/UriTag.php b/spomky-labs/cbor-php/src/Tag/UriTag.php new file mode 100644 index 000000000..c14f17325 --- /dev/null +++ b/spomky-labs/cbor-php/src/Tag/UriTag.php @@ -0,0 +1,66 @@ +object; + + return $object->normalize(); + } + + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ + public function getNormalizedData(bool $ignoreTags = false) + { + return $this->object->getNormalizedData($ignoreTags); + } +} diff --git a/spomky-labs/cbor-php/src/TagObject.php b/spomky-labs/cbor-php/src/TagObject.php index 3f100f9f1..0ccb5c803 100644 --- a/spomky-labs/cbor-php/src/TagObject.php +++ b/spomky-labs/cbor-php/src/TagObject.php @@ -13,44 +13,9 @@ namespace CBOR; -abstract class TagObject extends AbstractCBORObject +/** + * @deprecated Will be removed in v3.0. Please use Tag instead + */ +abstract class TagObject extends Tag { - private const MAJOR_TYPE = 0b110; - - /** - * @var string|null - */ - protected $data; - - /** - * @var CBORObject - */ - protected $object; - - public function __construct(int $additionalInformation, ?string $data, CBORObject $object) - { - parent::__construct(self::MAJOR_TYPE, $additionalInformation); - $this->data = $data; - $this->object = $object; - } - - public function __toString(): string - { - $result = parent::__toString(); - if (null !== $this->data) { - $result .= $this->data; - } - $result .= (string) $this->object; - - return $result; - } - - abstract public static function getTagId(): int; - - abstract public static function createFromLoadedData(int $additionalInformation, ?string $data, CBORObject $object): self; - - public function getValue(): CBORObject - { - return $this->object; - } } diff --git a/spomky-labs/cbor-php/src/TextStringObject.php b/spomky-labs/cbor-php/src/TextStringObject.php index 2ac9b1fea..1481a0723 100644 --- a/spomky-labs/cbor-php/src/TextStringObject.php +++ b/spomky-labs/cbor-php/src/TextStringObject.php @@ -13,12 +13,12 @@ namespace CBOR; -final class TextStringObject extends AbstractCBORObject +final class TextStringObject extends AbstractCBORObject implements Normalizable { - private const MAJOR_TYPE = 0b011; + private const MAJOR_TYPE = self::MAJOR_TYPE_TEXT_STRING; /** - * @var int|null + * @var string|null */ private $length; @@ -29,7 +29,7 @@ final class TextStringObject extends AbstractCBORObject public function __construct(string $data) { - list($additionalInformation, $length) = LengthCalculator::getLengthOfString($data); + [$additionalInformation, $length] = LengthCalculator::getLengthOfString($data); parent::__construct(self::MAJOR_TYPE, $additionalInformation); $this->data = $data; @@ -39,12 +39,16 @@ public function __construct(string $data) public function __toString(): string { $result = parent::__toString(); - if (null !== $this->length) { + if ($this->length !== null) { $result .= $this->length; } - $result .= $this->data; - return $result; + return $result . $this->data; + } + + public static function create(string $data): self + { + return new self($data); } public function getValue(): string @@ -57,8 +61,16 @@ public function getLength(): int return mb_strlen($this->data, 'utf8'); } + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ public function getNormalizedData(bool $ignoreTags = false): string { return $this->data; } + + public function normalize() + { + return $this->data; + } } diff --git a/spomky-labs/cbor-php/src/TextStringWithChunkObject.php b/spomky-labs/cbor-php/src/TextStringWithChunkObject.php index 76b4ad2d9..0cb6b9607 100644 --- a/spomky-labs/cbor-php/src/TextStringWithChunkObject.php +++ b/spomky-labs/cbor-php/src/TextStringWithChunkObject.php @@ -13,75 +13,9 @@ namespace CBOR; -use InvalidArgumentException; - -final class TextStringWithChunkObject extends AbstractCBORObject +/** + * @deprecated Will be removed in v3.0. Please use IndefiniteLengthTextStringObject instead + */ +final class TextStringWithChunkObject extends IndefiniteLengthTextStringObject { - private const MAJOR_TYPE = 0b011; - private const ADDITIONAL_INFORMATION = 0b00011111; - - /** - * @var TextStringObject[] - */ - private $data = []; - - public function __construct() - { - parent::__construct(self::MAJOR_TYPE, self::ADDITIONAL_INFORMATION); - } - - public function __toString(): string - { - $result = parent::__toString(); - foreach ($this->data as $object) { - $result .= (string) $object; - } - $bin = hex2bin('FF'); - if (false === $bin) { - throw new InvalidArgumentException('Unable to convert the data'); - } - $result .= $bin; - - return $result; - } - - public function add(TextStringObject $chunk): void - { - $this->data[] = $chunk; - } - - public function append(string $chunk): void - { - $this->add(new TextStringObject($chunk)); - } - - public function getValue(): string - { - $result = ''; - foreach ($this->data as $object) { - $result .= $object->getValue(); - } - - return $result; - } - - public function getLength(): int - { - $length = 0; - foreach ($this->data as $object) { - $length += $object->getLength(); - } - - return $length; - } - - public function getNormalizedData(bool $ignoreTags = false): string - { - $result = ''; - foreach ($this->data as $object) { - $result .= $object->getNormalizedData($ignoreTags); - } - - return $result; - } } diff --git a/spomky-labs/cbor-php/src/UnsignedIntegerObject.php b/spomky-labs/cbor-php/src/UnsignedIntegerObject.php index d9ff80f98..867dfa79f 100644 --- a/spomky-labs/cbor-php/src/UnsignedIntegerObject.php +++ b/spomky-labs/cbor-php/src/UnsignedIntegerObject.php @@ -15,10 +15,11 @@ use Brick\Math\BigInteger; use InvalidArgumentException; +use const STR_PAD_LEFT; -final class UnsignedIntegerObject extends AbstractCBORObject +final class UnsignedIntegerObject extends AbstractCBORObject implements Normalizable { - private const MAJOR_TYPE = 0b000; + private const MAJOR_TYPE = self::MAJOR_TYPE_UNSIGNED_INTEGER; /** * @var string|null @@ -34,7 +35,7 @@ public function __construct(int $additionalInformation, ?string $data) public function __toString(): string { $result = parent::__toString(); - if (null !== $this->data) { + if ($this->data !== null) { $result .= $this->data; } @@ -70,19 +71,9 @@ public function getMajorType(): int return self::MAJOR_TYPE; } - public function getAdditionalInformation(): int - { - return $this->additionalInformation; - } - public function getValue(): string { - return $this->getNormalizedData(); - } - - public function getNormalizedData(bool $ignoreTags = false): string - { - if (null === $this->data) { + if ($this->data === null) { return (string) $this->additionalInformation; } @@ -91,6 +82,19 @@ public function getNormalizedData(bool $ignoreTags = false): string return $integer->toBase(10); } + public function normalize(): string + { + return $this->getValue(); + } + + /** + * @deprecated The method will be removed on v3.0. Please rely on the CBOR\Normalizable interface + */ + public function getNormalizedData(bool $ignoreTags = false): string + { + return $this->getValue(); + } + private static function createBigInteger(BigInteger $integer): self { if ($integer->isLessThan(BigInteger::zero())) { @@ -115,7 +119,9 @@ private static function createBigInteger(BigInteger $integer): self $data = self::hex2bin(str_pad($integer->toBase(16), 8, '0', STR_PAD_LEFT)); break; default: - throw new InvalidArgumentException('Out of range. Please use PositiveBigIntegerTag tag with ByteStringObject object instead.'); + throw new InvalidArgumentException( + 'Out of range. Please use PositiveBigIntegerTag tag with ByteStringObject object instead.' + ); } return new self($ai, $data); @@ -124,7 +130,7 @@ private static function createBigInteger(BigInteger $integer): self private static function hex2bin(string $data): string { $result = hex2bin($data); - if (false === $result) { + if ($result === false) { throw new InvalidArgumentException('Unable to convert the data'); } diff --git a/spomky-labs/cbor-php/src/Utils.php b/spomky-labs/cbor-php/src/Utils.php index 69b9bcf55..b671ed6e2 100644 --- a/spomky-labs/cbor-php/src/Utils.php +++ b/spomky-labs/cbor-php/src/Utils.php @@ -47,25 +47,23 @@ public static function hexToString(string $value): string return BigInteger::fromBase(bin2hex($value), 16)->toBase(10); } - public static function intToHex(int $value): string - { - return BigInteger::of($value)->toBase(16); - } - public static function decode(string $data): string { $decoded = base64_decode(strtr($data, '-_', '+/'), true); - if (false === $decoded) { + if ($decoded === false) { throw new InvalidArgumentException('Invalid data provided'); } return $decoded; } + /** + * @param mixed|null $data + */ public static function assertString($data, ?string $message = null): void { - if (!is_string($data)) { - throw new InvalidArgumentException($message); + if (! is_string($data)) { + throw new InvalidArgumentException($message ?? ''); } } } diff --git a/symfony/polyfill-php81/LICENSE b/symfony/polyfill-php81/LICENSE new file mode 100644 index 000000000..99c6bdf35 --- /dev/null +++ b/symfony/polyfill-php81/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2021-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/symfony/polyfill-php81/Php81.php b/symfony/polyfill-php81/Php81.php new file mode 100644 index 000000000..f0507b765 --- /dev/null +++ b/symfony/polyfill-php81/Php81.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Php81; + +/** + * @author Nicolas Grekas + * + * @internal + */ +final class Php81 +{ + public static function array_is_list(array $array): bool + { + if ([] === $array || $array === array_values($array)) { + return true; + } + + $nextKey = -1; + + foreach ($array as $k => $v) { + if ($k !== ++$nextKey) { + return false; + } + } + + return true; + } +} diff --git a/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php b/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php new file mode 100644 index 000000000..5ff93fcaf --- /dev/null +++ b/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (\PHP_VERSION_ID >= 70400 && extension_loaded('curl')) { + /** + * @property string $data + */ + class CURLStringFile extends CURLFile + { + private $data; + + public function __construct(string $data, string $postname, string $mime = 'application/octet-stream') + { + $this->data = $data; + parent::__construct('data://application/octet-stream;base64,'.base64_encode($data), $mime, $postname); + } + + public function __set(string $name, $value): void + { + if ('data' !== $name) { + $this->$name = $value; + + return; + } + + if (is_object($value) ? !method_exists($value, '__toString') : !is_scalar($value)) { + throw new TypeError('Cannot assign '.gettype($value).' to property CURLStringFile::$data of type string'); + } + + $this->name = 'data://application/octet-stream;base64,'.base64_encode($value); + } + + public function __isset(string $name): bool + { + return isset($this->$name); + } + + public function &__get(string $name) + { + return $this->$name; + } + } +} diff --git a/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php b/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php new file mode 100644 index 000000000..cb7720a8d --- /dev/null +++ b/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (\PHP_VERSION_ID < 80100) { + #[Attribute(Attribute::TARGET_METHOD)] + final class ReturnTypeWillChange + { + public function __construct() + { + } + } +} diff --git a/symfony/polyfill-php81/bootstrap.php b/symfony/polyfill-php81/bootstrap.php new file mode 100644 index 000000000..9f872e02f --- /dev/null +++ b/symfony/polyfill-php81/bootstrap.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Php81 as p; + +if (\PHP_VERSION_ID >= 80100) { + return; +} + +if (defined('MYSQLI_REFRESH_SLAVE') && !defined('MYSQLI_REFRESH_REPLICA')) { + define('MYSQLI_REFRESH_REPLICA', 64); +} + +if (!function_exists('array_is_list')) { + function array_is_list(array $array): bool { return p\Php81::array_is_list($array); } +} + +if (!function_exists('enum_exists')) { + function enum_exists(string $enum, bool $autoload = true): bool { return $autoload && class_exists($enum) && false; } +} diff --git a/symfony/process/ExecutableFinder.php b/symfony/process/ExecutableFinder.php index eb8f06292..6dc00b7c2 100644 --- a/symfony/process/ExecutableFinder.php +++ b/symfony/process/ExecutableFinder.php @@ -46,27 +46,12 @@ public function addSuffix(string $suffix) * * @return string|null */ - public function find(string $name, string $default = null, array $extraDirs = []) + public function find(string $name, ?string $default = null, array $extraDirs = []) { - if (\ini_get('open_basedir')) { - $searchPath = array_merge(explode(\PATH_SEPARATOR, \ini_get('open_basedir')), $extraDirs); - $dirs = []; - foreach ($searchPath as $path) { - // Silencing against https://bugs.php.net/69240 - if (@is_dir($path)) { - $dirs[] = $path; - } else { - if (basename($path) == $name && @is_executable($path)) { - return $path; - } - } - } - } else { - $dirs = array_merge( - explode(\PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')), - $extraDirs - ); - } + $dirs = array_merge( + explode(\PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')), + $extraDirs + ); $suffixes = ['']; if ('\\' === \DIRECTORY_SEPARATOR) { @@ -78,9 +63,18 @@ public function find(string $name, string $default = null, array $extraDirs = [] if (@is_file($file = $dir.\DIRECTORY_SEPARATOR.$name.$suffix) && ('\\' === \DIRECTORY_SEPARATOR || @is_executable($file))) { return $file; } + + if (!@is_dir($dir) && basename($dir) === $name.$suffix && @is_executable($dir)) { + return $dir; + } } } + $command = '\\' === \DIRECTORY_SEPARATOR ? 'where' : 'command -v --'; + if (\function_exists('exec') && ($executablePath = strtok(@exec($command.' '.escapeshellarg($name)), \PHP_EOL)) && @is_executable($executablePath)) { + return $executablePath; + } + return $default; } } diff --git a/symfony/process/InputStream.php b/symfony/process/InputStream.php index 240665f32..0c45b5245 100644 --- a/symfony/process/InputStream.php +++ b/symfony/process/InputStream.php @@ -30,7 +30,7 @@ class InputStream implements \IteratorAggregate /** * Sets a callback that is called when the write buffer becomes empty. */ - public function onEmpty(callable $onEmpty = null) + public function onEmpty(?callable $onEmpty = null) { $this->onEmpty = $onEmpty; } diff --git a/symfony/process/PhpExecutableFinder.php b/symfony/process/PhpExecutableFinder.php index bed6c3dc8..54fe74434 100644 --- a/symfony/process/PhpExecutableFinder.php +++ b/symfony/process/PhpExecutableFinder.php @@ -35,8 +35,8 @@ public function find(bool $includeArgs = true) { if ($php = getenv('PHP_BINARY')) { if (!is_executable($php)) { - $command = '\\' === \DIRECTORY_SEPARATOR ? 'where' : 'command -v'; - if ($php = strtok(exec($command.' '.escapeshellarg($php)), \PHP_EOL)) { + $command = '\\' === \DIRECTORY_SEPARATOR ? 'where' : 'command -v --'; + if (\function_exists('exec') && $php = strtok(exec($command.' '.escapeshellarg($php)), \PHP_EOL)) { if (!is_executable($php)) { return false; } diff --git a/symfony/process/PhpProcess.php b/symfony/process/PhpProcess.php index 2bc338e5e..3a1d147c8 100644 --- a/symfony/process/PhpProcess.php +++ b/symfony/process/PhpProcess.php @@ -32,7 +32,7 @@ class PhpProcess extends Process * @param int $timeout The timeout in seconds * @param array|null $php Path to the PHP binary to use with any additional arguments */ - public function __construct(string $script, string $cwd = null, array $env = null, int $timeout = 60, array $php = null) + public function __construct(string $script, ?string $cwd = null, ?array $env = null, int $timeout = 60, ?array $php = null) { if (null === $php) { $executableFinder = new PhpExecutableFinder(); @@ -53,7 +53,7 @@ public function __construct(string $script, string $cwd = null, array $env = nul /** * {@inheritdoc} */ - public static function fromShellCommandline(string $command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60) + public static function fromShellCommandline(string $command, ?string $cwd = null, ?array $env = null, $input = null, ?float $timeout = 60) { throw new LogicException(sprintf('The "%s()" method cannot be called when using "%s".', __METHOD__, self::class)); } @@ -61,7 +61,7 @@ public static function fromShellCommandline(string $command, string $cwd = null, /** * {@inheritdoc} */ - public function start(callable $callback = null, array $env = []) + public function start(?callable $callback = null, array $env = []) { if (null === $this->getCommandLine()) { throw new RuntimeException('Unable to find the PHP executable.'); diff --git a/symfony/process/Process.php b/symfony/process/Process.php index 30ebeb6b5..62addf1e7 100644 --- a/symfony/process/Process.php +++ b/symfony/process/Process.php @@ -80,6 +80,7 @@ class Process implements \IteratorAggregate private $processPipes; private $latestSignal; + private $cachedExitCode; private static $sigchild; @@ -140,7 +141,7 @@ class Process implements \IteratorAggregate * * @throws LogicException When proc_open is not installed */ - public function __construct(array $command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60) + public function __construct(array $command, ?string $cwd = null, ?array $env = null, $input = null, ?float $timeout = 60) { if (!\function_exists('proc_open')) { throw new LogicException('The Process class relies on proc_open, which is not available on your PHP installation.'); @@ -189,7 +190,7 @@ public function __construct(array $command, string $cwd = null, array $env = nul * * @throws LogicException When proc_open is not installed */ - public static function fromShellCommandline(string $command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60) + public static function fromShellCommandline(string $command, ?string $cwd = null, ?array $env = null, $input = null, ?float $timeout = 60) { $process = new static([], $cwd, $env, $input, $timeout); $process->commandline = $command; @@ -247,7 +248,7 @@ public function __clone() * * @final */ - public function run(callable $callback = null, array $env = []): int + public function run(?callable $callback = null, array $env = []): int { $this->start($callback, $env); @@ -266,7 +267,7 @@ public function run(callable $callback = null, array $env = []): int * * @final */ - public function mustRun(callable $callback = null, array $env = []): self + public function mustRun(?callable $callback = null, array $env = []): self { if (0 !== $this->run($callback, $env)) { throw new ProcessFailedException($this); @@ -294,7 +295,7 @@ public function mustRun(callable $callback = null, array $env = []): self * @throws RuntimeException When process is already running * @throws LogicException In case a callback is provided and output has been disabled */ - public function start(callable $callback = null, array $env = []) + public function start(?callable $callback = null, array $env = []) { if ($this->isRunning()) { throw new RuntimeException('Process is already running.'); @@ -351,7 +352,7 @@ public function start(callable $callback = null, array $env = []) $this->process = @proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $envPairs, $this->options); - if (!\is_resource($this->process)) { + if (!$this->process) { throw new RuntimeException('Unable to launch a new process.'); } $this->status = self::STATUS_STARTED; @@ -385,7 +386,7 @@ public function start(callable $callback = null, array $env = []) * * @final */ - public function restart(callable $callback = null, array $env = []): self + public function restart(?callable $callback = null, array $env = []): self { if ($this->isRunning()) { throw new RuntimeException('Process is already running.'); @@ -412,7 +413,7 @@ public function restart(callable $callback = null, array $env = []): self * @throws ProcessSignaledException When process stopped after receiving signal * @throws LogicException When process is not yet started */ - public function wait(callable $callback = null) + public function wait(?callable $callback = null) { $this->requireProcessIsStarted(__FUNCTION__); @@ -914,7 +915,7 @@ public function getStatus() * * @return int|null The exit-code of the process or null if it's not running */ - public function stop(float $timeout = 10, int $signal = null) + public function stop(float $timeout = 10, ?int $signal = null) { $timeoutMicro = microtime(true) + $timeout; if ($this->isRunning()) { @@ -1310,7 +1311,7 @@ private function getDescriptors(): array * * @return \Closure */ - protected function buildCallback(callable $callback = null) + protected function buildCallback(?callable $callback = null) { if ($this->outputDisabled) { return function ($type, $data) use ($callback): bool { @@ -1345,6 +1346,19 @@ protected function updateStatus(bool $blocking) $this->processInformation = proc_get_status($this->process); $running = $this->processInformation['running']; + // In PHP < 8.3, "proc_get_status" only returns the correct exit status on the first call. + // Subsequent calls return -1 as the process is discarded. This workaround caches the first + // retrieved exit status for consistent results in later calls, mimicking PHP 8.3 behavior. + if (\PHP_VERSION_ID < 80300) { + if (!isset($this->cachedExitCode) && !$running && -1 !== $this->processInformation['exitcode']) { + $this->cachedExitCode = $this->processInformation['exitcode']; + } + + if (isset($this->cachedExitCode) && !$running && -1 === $this->processInformation['exitcode']) { + $this->processInformation['exitcode'] = $this->cachedExitCode; + } + } + $this->readPipes($running && $blocking, '\\' !== \DIRECTORY_SEPARATOR || !$running); if ($this->fallbackStatus && $this->isSigchildEnabled()) { @@ -1442,8 +1456,9 @@ private function readPipes(bool $blocking, bool $close) private function close(): int { $this->processPipes->close(); - if (\is_resource($this->process)) { + if ($this->process) { proc_close($this->process); + $this->process = null; } $this->exitcode = $this->processInformation['exitcode']; $this->status = self::STATUS_TERMINATED; diff --git a/web-auth/cose-lib/src/Algorithm/Algorithm.php b/web-auth/cose-lib/src/Algorithm/Algorithm.php index 60b717b99..c79e40576 100644 --- a/web-auth/cose-lib/src/Algorithm/Algorithm.php +++ b/web-auth/cose-lib/src/Algorithm/Algorithm.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Algorithm/Mac/HS256.php b/web-auth/cose-lib/src/Algorithm/Mac/HS256.php index 54c7cdb70..199ef4a45 100644 --- a/web-auth/cose-lib/src/Algorithm/Mac/HS256.php +++ b/web-auth/cose-lib/src/Algorithm/Mac/HS256.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Algorithm/Mac/HS256Truncated64.php b/web-auth/cose-lib/src/Algorithm/Mac/HS256Truncated64.php index cc2c5654f..216989cef 100644 --- a/web-auth/cose-lib/src/Algorithm/Mac/HS256Truncated64.php +++ b/web-auth/cose-lib/src/Algorithm/Mac/HS256Truncated64.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Algorithm/Mac/HS384.php b/web-auth/cose-lib/src/Algorithm/Mac/HS384.php index 6d135fa03..e0d9b2308 100644 --- a/web-auth/cose-lib/src/Algorithm/Mac/HS384.php +++ b/web-auth/cose-lib/src/Algorithm/Mac/HS384.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Algorithm/Mac/HS512.php b/web-auth/cose-lib/src/Algorithm/Mac/HS512.php index c65ad4a57..6a2e2057c 100644 --- a/web-auth/cose-lib/src/Algorithm/Mac/HS512.php +++ b/web-auth/cose-lib/src/Algorithm/Mac/HS512.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Algorithm/Mac/Hmac.php b/web-auth/cose-lib/src/Algorithm/Mac/Hmac.php index ba077b6bb..3eb935110 100644 --- a/web-auth/cose-lib/src/Algorithm/Mac/Hmac.php +++ b/web-auth/cose-lib/src/Algorithm/Mac/Hmac.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -23,7 +23,7 @@ public function hash(string $data, Key $key): string $this->checKey($key); $signature = hash_hmac($this->getHashAlgorithm(), $data, $key->get(-1), true); - return mb_substr($signature, 0, $this->getSignatureLength() / 8, '8bit'); + return mb_substr($signature, 0, intdiv($this->getSignatureLength(), 8), '8bit'); } public function verify(string $data, Key $key, string $signature): bool diff --git a/web-auth/cose-lib/src/Algorithm/Mac/Mac.php b/web-auth/cose-lib/src/Algorithm/Mac/Mac.php index 23f11c7e3..c4051cb09 100644 --- a/web-auth/cose-lib/src/Algorithm/Mac/Mac.php +++ b/web-auth/cose-lib/src/Algorithm/Mac/Mac.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Algorithm/Manager.php b/web-auth/cose-lib/src/Algorithm/Manager.php index 9e80d024d..cc4dc83fa 100644 --- a/web-auth/cose-lib/src/Algorithm/Manager.php +++ b/web-auth/cose-lib/src/Algorithm/Manager.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Algorithm/ManagerFactory.php b/web-auth/cose-lib/src/Algorithm/ManagerFactory.php index 050377e32..c3fb032a4 100644 --- a/web-auth/cose-lib/src/Algorithm/ManagerFactory.php +++ b/web-auth/cose-lib/src/Algorithm/ManagerFactory.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Algorithm/Signature/ECDSA/ECDSA.php b/web-auth/cose-lib/src/Algorithm/Signature/ECDSA/ECDSA.php index 6aa39e2ba..6bac0061c 100644 --- a/web-auth/cose-lib/src/Algorithm/Signature/ECDSA/ECDSA.php +++ b/web-auth/cose-lib/src/Algorithm/Signature/ECDSA/ECDSA.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Algorithm/Signature/ECDSA/ECSignature.php b/web-auth/cose-lib/src/Algorithm/Signature/ECDSA/ECSignature.php index 1a0dc90b5..c4690e918 100644 --- a/web-auth/cose-lib/src/Algorithm/Signature/ECDSA/ECSignature.php +++ b/web-auth/cose-lib/src/Algorithm/Signature/ECDSA/ECSignature.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -92,7 +92,7 @@ public static function fromAsn1(string $signature, int $length): string private static function octetLength(string $data): int { - return (int) (mb_strlen($data, '8bit') / self::BYTE_SIZE); + return intdiv(mb_strlen($data, '8bit'), self::BYTE_SIZE); } private static function preparePositiveInteger(string $data): string diff --git a/web-auth/cose-lib/src/Algorithm/Signature/ECDSA/ES256.php b/web-auth/cose-lib/src/Algorithm/Signature/ECDSA/ES256.php index 1c302baa2..5726ee4d1 100644 --- a/web-auth/cose-lib/src/Algorithm/Signature/ECDSA/ES256.php +++ b/web-auth/cose-lib/src/Algorithm/Signature/ECDSA/ES256.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Algorithm/Signature/ECDSA/ES256K.php b/web-auth/cose-lib/src/Algorithm/Signature/ECDSA/ES256K.php index 0db37ce3e..a1685c893 100644 --- a/web-auth/cose-lib/src/Algorithm/Signature/ECDSA/ES256K.php +++ b/web-auth/cose-lib/src/Algorithm/Signature/ECDSA/ES256K.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Algorithm/Signature/ECDSA/ES384.php b/web-auth/cose-lib/src/Algorithm/Signature/ECDSA/ES384.php index 88365cf19..a6f2cf517 100644 --- a/web-auth/cose-lib/src/Algorithm/Signature/ECDSA/ES384.php +++ b/web-auth/cose-lib/src/Algorithm/Signature/ECDSA/ES384.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Algorithm/Signature/ECDSA/ES512.php b/web-auth/cose-lib/src/Algorithm/Signature/ECDSA/ES512.php index abfd1fe7d..90d6ab068 100644 --- a/web-auth/cose-lib/src/Algorithm/Signature/ECDSA/ES512.php +++ b/web-auth/cose-lib/src/Algorithm/Signature/ECDSA/ES512.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Algorithm/Signature/EdDSA/ED256.php b/web-auth/cose-lib/src/Algorithm/Signature/EdDSA/ED256.php index 3bb71482a..00cae54da 100644 --- a/web-auth/cose-lib/src/Algorithm/Signature/EdDSA/ED256.php +++ b/web-auth/cose-lib/src/Algorithm/Signature/EdDSA/ED256.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Algorithm/Signature/EdDSA/ED512.php b/web-auth/cose-lib/src/Algorithm/Signature/EdDSA/ED512.php index 54272d507..1c3d1bdb2 100644 --- a/web-auth/cose-lib/src/Algorithm/Signature/EdDSA/ED512.php +++ b/web-auth/cose-lib/src/Algorithm/Signature/EdDSA/ED512.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Algorithm/Signature/EdDSA/Ed25519.php b/web-auth/cose-lib/src/Algorithm/Signature/EdDSA/Ed25519.php index 1964a23ee..cd425c5ae 100644 --- a/web-auth/cose-lib/src/Algorithm/Signature/EdDSA/Ed25519.php +++ b/web-auth/cose-lib/src/Algorithm/Signature/EdDSA/Ed25519.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Algorithm/Signature/EdDSA/EdDSA.php b/web-auth/cose-lib/src/Algorithm/Signature/EdDSA/EdDSA.php index bdc42d744..d778f374b 100644 --- a/web-auth/cose-lib/src/Algorithm/Signature/EdDSA/EdDSA.php +++ b/web-auth/cose-lib/src/Algorithm/Signature/EdDSA/EdDSA.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Algorithm/Signature/RSA/PS256.php b/web-auth/cose-lib/src/Algorithm/Signature/RSA/PS256.php index e3d89b0ad..40bbeb0e3 100644 --- a/web-auth/cose-lib/src/Algorithm/Signature/RSA/PS256.php +++ b/web-auth/cose-lib/src/Algorithm/Signature/RSA/PS256.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -13,7 +13,7 @@ namespace Cose\Algorithm\Signature\RSA; -use Jose\Component\Core\Util\Hash; +use Cose\Hash; final class PS256 extends PSSRSA { diff --git a/web-auth/cose-lib/src/Algorithm/Signature/RSA/PS384.php b/web-auth/cose-lib/src/Algorithm/Signature/RSA/PS384.php index 5ab32b1bb..f64fb3705 100644 --- a/web-auth/cose-lib/src/Algorithm/Signature/RSA/PS384.php +++ b/web-auth/cose-lib/src/Algorithm/Signature/RSA/PS384.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -13,7 +13,7 @@ namespace Cose\Algorithm\Signature\RSA; -use Jose\Component\Core\Util\Hash; +use Cose\Hash; final class PS384 extends PSSRSA { diff --git a/web-auth/cose-lib/src/Algorithm/Signature/RSA/PS512.php b/web-auth/cose-lib/src/Algorithm/Signature/RSA/PS512.php index 6fdeecb50..d1268b624 100644 --- a/web-auth/cose-lib/src/Algorithm/Signature/RSA/PS512.php +++ b/web-auth/cose-lib/src/Algorithm/Signature/RSA/PS512.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -13,7 +13,7 @@ namespace Cose\Algorithm\Signature\RSA; -use Jose\Component\Core\Util\Hash; +use Cose\Hash; final class PS512 extends PSSRSA { diff --git a/web-auth/cose-lib/src/Algorithm/Signature/RSA/PSSRSA.php b/web-auth/cose-lib/src/Algorithm/Signature/RSA/PSSRSA.php index 8f87dd7c6..c8befdc34 100644 --- a/web-auth/cose-lib/src/Algorithm/Signature/RSA/PSSRSA.php +++ b/web-auth/cose-lib/src/Algorithm/Signature/RSA/PSSRSA.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -16,12 +16,12 @@ use function ceil; use function chr; use Cose\Algorithm\Signature\Signature; +use Cose\BigInteger; +use Cose\Hash; use Cose\Key\Key; use Cose\Key\RsaKey; use function hash_equals; use InvalidArgumentException; -use Jose\Component\Core\Util\BigInteger; -use Jose\Component\Core\Util\Hash; use function mb_strlen; use function mb_substr; use function ord; @@ -76,10 +76,8 @@ public function exponentiate(RsaKey $key, BigInteger $c): BigInteger return $c->modPow(BigInteger::createFromBinaryString($key->e()), BigInteger::createFromBinaryString($key->n())); } - $p = $key->primes()[0]; - $q = $key->primes()[1]; - $dP = $key->exponents()[0]; - $dQ = $key->exponents()[1]; + [$p, $q] = $key->primes(); + [$dP, $dQ] = $key->exponents(); $qInv = BigInteger::createFromBinaryString($key->QInv()); $m1 = $c->modPow($dP, $p); diff --git a/web-auth/cose-lib/src/Algorithm/Signature/RSA/RS1.php b/web-auth/cose-lib/src/Algorithm/Signature/RSA/RS1.php index c9e796fcc..61b0400e7 100644 --- a/web-auth/cose-lib/src/Algorithm/Signature/RSA/RS1.php +++ b/web-auth/cose-lib/src/Algorithm/Signature/RSA/RS1.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Algorithm/Signature/RSA/RS256.php b/web-auth/cose-lib/src/Algorithm/Signature/RSA/RS256.php index 40d6fc585..370ee11c5 100644 --- a/web-auth/cose-lib/src/Algorithm/Signature/RSA/RS256.php +++ b/web-auth/cose-lib/src/Algorithm/Signature/RSA/RS256.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Algorithm/Signature/RSA/RS384.php b/web-auth/cose-lib/src/Algorithm/Signature/RSA/RS384.php index d073d34e6..b524c42cb 100644 --- a/web-auth/cose-lib/src/Algorithm/Signature/RSA/RS384.php +++ b/web-auth/cose-lib/src/Algorithm/Signature/RSA/RS384.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Algorithm/Signature/RSA/RS512.php b/web-auth/cose-lib/src/Algorithm/Signature/RSA/RS512.php index d88216129..7266f8bb2 100644 --- a/web-auth/cose-lib/src/Algorithm/Signature/RSA/RS512.php +++ b/web-auth/cose-lib/src/Algorithm/Signature/RSA/RS512.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Algorithm/Signature/RSA/RSA.php b/web-auth/cose-lib/src/Algorithm/Signature/RSA/RSA.php index 79fdb665e..08abebe77 100644 --- a/web-auth/cose-lib/src/Algorithm/Signature/RSA/RSA.php +++ b/web-auth/cose-lib/src/Algorithm/Signature/RSA/RSA.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Algorithm/Signature/Signature.php b/web-auth/cose-lib/src/Algorithm/Signature/Signature.php index 164a2dc6d..9bf9c64f9 100644 --- a/web-auth/cose-lib/src/Algorithm/Signature/Signature.php +++ b/web-auth/cose-lib/src/Algorithm/Signature/Signature.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Algorithms.php b/web-auth/cose-lib/src/Algorithms.php index a4d07d0e2..8d52619e9 100644 --- a/web-auth/cose-lib/src/Algorithms.php +++ b/web-auth/cose-lib/src/Algorithms.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/BigInteger.php b/web-auth/cose-lib/src/BigInteger.php new file mode 100644 index 000000000..a7c59eb56 --- /dev/null +++ b/web-auth/cose-lib/src/BigInteger.php @@ -0,0 +1,154 @@ +value = $value; + } + + public static function createFromBinaryString(string $value): self + { + $res = unpack('H*', $value); + if (false === $res) { + throw new InvalidArgumentException('Unable to convert the data from binary'); + } + $data = current($res); + + return new self(BrickBigInteger::fromBase($data, 16)); + } + + public static function createFromDecimal(int $value): self + { + return new self(BrickBigInteger::of($value)); + } + + /** + * Converts a BigInteger to a binary string. + */ + public function toBytes(): string + { + if ($this->value->isEqualTo(BrickBigInteger::zero())) { + return ''; + } + + $temp = $this->value->toBase(16); + $temp = 0 !== (mb_strlen($temp, '8bit') & 1) ? '0'.$temp : $temp; + $temp = hex2bin($temp); + if (false === $temp) { + throw new InvalidArgumentException('Unable to convert the data into binary'); + } + + return ltrim($temp, chr(0)); + } + + /** + * Adds two BigIntegers. + * + * @param BigInteger $y + * + * @return BigInteger + */ + public function add(self $y): self + { + $value = $this->value->plus($y->value); + + return new self($value); + } + + /** + * Subtracts two BigIntegers. + * + * @param BigInteger $y + * + * @return BigInteger + */ + public function subtract(self $y): self + { + $value = $this->value->minus($y->value); + + return new self($value); + } + + /** + * Multiplies two BigIntegers. + * + * @param BigInteger $x + * + * @return BigInteger + */ + public function multiply(self $x): self + { + $value = $this->value->multipliedBy($x->value); + + return new self($value); + } + + /** + * Performs modular exponentiation. + * + * @param BigInteger $e + * @param BigInteger $n + * + * @return BigInteger + */ + public function modPow(self $e, self $n): self + { + $value = $this->value->modPow($e->value, $n->value); + + return new self($value); + } + + /** + * Performs modular exponentiation. + * + * @param BigInteger $d + * + * @return BigInteger + */ + public function mod(self $d): self + { + $value = $this->value->mod($d->value); + + return new self($value); + } + + /** + * Compares two numbers. + * + * @param BigInteger $y + */ + public function compare(self $y): int + { + return $this->value->compareTo($y->value); + } +} diff --git a/web-auth/cose-lib/src/Hash.php b/web-auth/cose-lib/src/Hash.php new file mode 100644 index 000000000..2f3722ccd --- /dev/null +++ b/web-auth/cose-lib/src/Hash.php @@ -0,0 +1,103 @@ +hash = $hash; + $this->length = $length; + $this->t = $t; + } + + /** + * @return Hash + */ + public static function sha1(): self + { + return new self('sha1', 20, "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14"); + } + + /** + * @return Hash + */ + public static function sha256(): self + { + return new self('sha256', 32, "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20"); + } + + /** + * @return Hash + */ + public static function sha384(): self + { + return new self('sha384', 48, "\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30"); + } + + /** + * @return Hash + */ + public static function sha512(): self + { + return new self('sha512', 64, "\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40"); + } + + public function getLength(): int + { + return $this->length; + } + + /** + * Compute the HMAC. + */ + public function hash(string $text): string + { + return hash($this->hash, $text, true); + } + + public function name(): string + { + return $this->hash; + } + + public function t(): string + { + return $this->t; + } +} diff --git a/web-auth/cose-lib/src/Key/Ec2Key.php b/web-auth/cose-lib/src/Key/Ec2Key.php index 064b705ee..b4a48ecaa 100644 --- a/web-auth/cose-lib/src/Key/Ec2Key.php +++ b/web-auth/cose-lib/src/Key/Ec2Key.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Key/Key.php b/web-auth/cose-lib/src/Key/Key.php index 423371a73..afb9c52c1 100644 --- a/web-auth/cose-lib/src/Key/Key.php +++ b/web-auth/cose-lib/src/Key/Key.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Key/OkpKey.php b/web-auth/cose-lib/src/Key/OkpKey.php index 3be3d767c..2baabd4fa 100644 --- a/web-auth/cose-lib/src/Key/OkpKey.php +++ b/web-auth/cose-lib/src/Key/OkpKey.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Key/RsaKey.php b/web-auth/cose-lib/src/Key/RsaKey.php index 151ac06a7..96371f7f5 100644 --- a/web-auth/cose-lib/src/Key/RsaKey.php +++ b/web-auth/cose-lib/src/Key/RsaKey.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Key/SymmetricKey.php b/web-auth/cose-lib/src/Key/SymmetricKey.php index 681adf3a4..1e63562de 100644 --- a/web-auth/cose-lib/src/Key/SymmetricKey.php +++ b/web-auth/cose-lib/src/Key/SymmetricKey.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/cose-lib/src/Verifier.php b/web-auth/cose-lib/src/Verifier.php index f56ececfd..d300be8e1 100644 --- a/web-auth/cose-lib/src/Verifier.php +++ b/web-auth/cose-lib/src/Verifier.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/metadata-service/src/AbstractDescriptor.php b/web-auth/metadata-service/src/AbstractDescriptor.php index 779723939..06dba720a 100644 --- a/web-auth/metadata-service/src/AbstractDescriptor.php +++ b/web-auth/metadata-service/src/AbstractDescriptor.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/metadata-service/src/AuthenticatorStatus.php b/web-auth/metadata-service/src/AuthenticatorStatus.php index d4e884536..a6873c8bd 100644 --- a/web-auth/metadata-service/src/AuthenticatorStatus.php +++ b/web-auth/metadata-service/src/AuthenticatorStatus.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/metadata-service/src/BiometricAccuracyDescriptor.php b/web-auth/metadata-service/src/BiometricAccuracyDescriptor.php index 74743c628..f2bc84f97 100644 --- a/web-auth/metadata-service/src/BiometricAccuracyDescriptor.php +++ b/web-auth/metadata-service/src/BiometricAccuracyDescriptor.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/metadata-service/src/BiometricStatusReport.php b/web-auth/metadata-service/src/BiometricStatusReport.php index 9169e1f29..dae9c9740 100644 --- a/web-auth/metadata-service/src/BiometricStatusReport.php +++ b/web-auth/metadata-service/src/BiometricStatusReport.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/metadata-service/src/CodeAccuracyDescriptor.php b/web-auth/metadata-service/src/CodeAccuracyDescriptor.php index 19496df60..1ef25fa74 100644 --- a/web-auth/metadata-service/src/CodeAccuracyDescriptor.php +++ b/web-auth/metadata-service/src/CodeAccuracyDescriptor.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/metadata-service/src/DisplayPNGCharacteristicsDescriptor.php b/web-auth/metadata-service/src/DisplayPNGCharacteristicsDescriptor.php index b64eecf42..deb9e6b23 100644 --- a/web-auth/metadata-service/src/DisplayPNGCharacteristicsDescriptor.php +++ b/web-auth/metadata-service/src/DisplayPNGCharacteristicsDescriptor.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/metadata-service/src/DistantSingleMetadata.php b/web-auth/metadata-service/src/DistantSingleMetadata.php index a8aee7400..b7c2991ef 100644 --- a/web-auth/metadata-service/src/DistantSingleMetadata.php +++ b/web-auth/metadata-service/src/DistantSingleMetadata.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/metadata-service/src/EcdaaTrustAnchor.php b/web-auth/metadata-service/src/EcdaaTrustAnchor.php index fffc033b1..97a685533 100644 --- a/web-auth/metadata-service/src/EcdaaTrustAnchor.php +++ b/web-auth/metadata-service/src/EcdaaTrustAnchor.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/metadata-service/src/ExtensionDescriptor.php b/web-auth/metadata-service/src/ExtensionDescriptor.php index e161d2007..3a5203047 100644 --- a/web-auth/metadata-service/src/ExtensionDescriptor.php +++ b/web-auth/metadata-service/src/ExtensionDescriptor.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/metadata-service/src/MetadataService.php b/web-auth/metadata-service/src/MetadataService.php index c576bd823..2912e0984 100644 --- a/web-auth/metadata-service/src/MetadataService.php +++ b/web-auth/metadata-service/src/MetadataService.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/metadata-service/src/MetadataStatement.php b/web-auth/metadata-service/src/MetadataStatement.php index b67ed8926..5b915bf67 100644 --- a/web-auth/metadata-service/src/MetadataStatement.php +++ b/web-auth/metadata-service/src/MetadataStatement.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/metadata-service/src/MetadataStatementFetcher.php b/web-auth/metadata-service/src/MetadataStatementFetcher.php index 483b212e9..b8ab63792 100644 --- a/web-auth/metadata-service/src/MetadataStatementFetcher.php +++ b/web-auth/metadata-service/src/MetadataStatementFetcher.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/metadata-service/src/MetadataStatementRepository.php b/web-auth/metadata-service/src/MetadataStatementRepository.php index 79cb976d3..c1bd69133 100644 --- a/web-auth/metadata-service/src/MetadataStatementRepository.php +++ b/web-auth/metadata-service/src/MetadataStatementRepository.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/metadata-service/src/MetadataTOCPayload.php b/web-auth/metadata-service/src/MetadataTOCPayload.php index 5a9da9aa2..94693c599 100644 --- a/web-auth/metadata-service/src/MetadataTOCPayload.php +++ b/web-auth/metadata-service/src/MetadataTOCPayload.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/metadata-service/src/MetadataTOCPayloadEntry.php b/web-auth/metadata-service/src/MetadataTOCPayloadEntry.php index be16df130..16b1a3110 100644 --- a/web-auth/metadata-service/src/MetadataTOCPayloadEntry.php +++ b/web-auth/metadata-service/src/MetadataTOCPayloadEntry.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/metadata-service/src/PatternAccuracyDescriptor.php b/web-auth/metadata-service/src/PatternAccuracyDescriptor.php index d9757b3b6..6f401b8f5 100644 --- a/web-auth/metadata-service/src/PatternAccuracyDescriptor.php +++ b/web-auth/metadata-service/src/PatternAccuracyDescriptor.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/metadata-service/src/RgbPaletteEntry.php b/web-auth/metadata-service/src/RgbPaletteEntry.php index 77de6ca79..d5eb58671 100644 --- a/web-auth/metadata-service/src/RgbPaletteEntry.php +++ b/web-auth/metadata-service/src/RgbPaletteEntry.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/metadata-service/src/RogueListEntry.php b/web-auth/metadata-service/src/RogueListEntry.php index 7fd63b39a..83c1d4472 100644 --- a/web-auth/metadata-service/src/RogueListEntry.php +++ b/web-auth/metadata-service/src/RogueListEntry.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/metadata-service/src/SingleMetadata.php b/web-auth/metadata-service/src/SingleMetadata.php index 057ec1813..f3e3cd4c0 100644 --- a/web-auth/metadata-service/src/SingleMetadata.php +++ b/web-auth/metadata-service/src/SingleMetadata.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/metadata-service/src/StatusReport.php b/web-auth/metadata-service/src/StatusReport.php index d82c06e80..60166384a 100644 --- a/web-auth/metadata-service/src/StatusReport.php +++ b/web-auth/metadata-service/src/StatusReport.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/metadata-service/src/Utils.php b/web-auth/metadata-service/src/Utils.php index afc5fa0d2..469475a86 100644 --- a/web-auth/metadata-service/src/Utils.php +++ b/web-auth/metadata-service/src/Utils.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/metadata-service/src/VerificationMethodANDCombinations.php b/web-auth/metadata-service/src/VerificationMethodANDCombinations.php index f115d2d65..081c8c8f6 100644 --- a/web-auth/metadata-service/src/VerificationMethodANDCombinations.php +++ b/web-auth/metadata-service/src/VerificationMethodANDCombinations.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/metadata-service/src/VerificationMethodDescriptor.php b/web-auth/metadata-service/src/VerificationMethodDescriptor.php index 6cbd494d3..0105900d0 100644 --- a/web-auth/metadata-service/src/VerificationMethodDescriptor.php +++ b/web-auth/metadata-service/src/VerificationMethodDescriptor.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/metadata-service/src/Version.php b/web-auth/metadata-service/src/Version.php index d8480711d..53efda8a2 100644 --- a/web-auth/metadata-service/src/Version.php +++ b/web-auth/metadata-service/src/Version.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/AttestationStatement/AndroidKeyAttestationStatementSupport.php b/web-auth/webauthn-lib/src/AttestationStatement/AndroidKeyAttestationStatementSupport.php index deac2ba93..308bd9559 100644 --- a/web-auth/webauthn-lib/src/AttestationStatement/AndroidKeyAttestationStatementSupport.php +++ b/web-auth/webauthn-lib/src/AttestationStatement/AndroidKeyAttestationStatementSupport.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/AttestationStatement/AndroidSafetyNetAttestationStatementSupport.php b/web-auth/webauthn-lib/src/AttestationStatement/AndroidSafetyNetAttestationStatementSupport.php index 6ef7de681..29286ba70 100644 --- a/web-auth/webauthn-lib/src/AttestationStatement/AndroidSafetyNetAttestationStatementSupport.php +++ b/web-auth/webauthn-lib/src/AttestationStatement/AndroidSafetyNetAttestationStatementSupport.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -231,13 +231,13 @@ private function getResponseBody(ResponseInterface $response): string { $responseBody = ''; $response->getBody()->rewind(); - do { + while (true) { $tmp = $response->getBody()->read(1024); if ('' === $tmp) { break; } $responseBody .= $tmp; - } while (true); + } return $responseBody; } diff --git a/web-auth/webauthn-lib/src/AttestationStatement/AppleAttestationStatementSupport.php b/web-auth/webauthn-lib/src/AttestationStatement/AppleAttestationStatementSupport.php index 3f942e472..53ee6480a 100644 --- a/web-auth/webauthn-lib/src/AttestationStatement/AppleAttestationStatementSupport.php +++ b/web-auth/webauthn-lib/src/AttestationStatement/AppleAttestationStatementSupport.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -21,7 +21,6 @@ use Cose\Key\Key; use Cose\Key\RsaKey; use function count; -use FG\ASN1\Universal\Sequence; use function Safe\openssl_pkey_get_public; use function Safe\sprintf; use Webauthn\AuthenticatorData; diff --git a/web-auth/webauthn-lib/src/AttestationStatement/AttestationObject.php b/web-auth/webauthn-lib/src/AttestationStatement/AttestationObject.php index 1a0869f9d..47d0bc938 100644 --- a/web-auth/webauthn-lib/src/AttestationStatement/AttestationObject.php +++ b/web-auth/webauthn-lib/src/AttestationStatement/AttestationObject.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/AttestationStatement/AttestationObjectLoader.php b/web-auth/webauthn-lib/src/AttestationStatement/AttestationObjectLoader.php index 5c00b0a39..f02e19e7c 100644 --- a/web-auth/webauthn-lib/src/AttestationStatement/AttestationObjectLoader.php +++ b/web-auth/webauthn-lib/src/AttestationStatement/AttestationObjectLoader.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/AttestationStatement/AttestationStatement.php b/web-auth/webauthn-lib/src/AttestationStatement/AttestationStatement.php index 3de8bfb05..1622f64bd 100644 --- a/web-auth/webauthn-lib/src/AttestationStatement/AttestationStatement.php +++ b/web-auth/webauthn-lib/src/AttestationStatement/AttestationStatement.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/AttestationStatement/AttestationStatementSupport.php b/web-auth/webauthn-lib/src/AttestationStatement/AttestationStatementSupport.php index 95f1d55f1..76f1dd43a 100644 --- a/web-auth/webauthn-lib/src/AttestationStatement/AttestationStatementSupport.php +++ b/web-auth/webauthn-lib/src/AttestationStatement/AttestationStatementSupport.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/AttestationStatement/AttestationStatementSupportManager.php b/web-auth/webauthn-lib/src/AttestationStatement/AttestationStatementSupportManager.php index be3bc2030..e7cbf75e0 100644 --- a/web-auth/webauthn-lib/src/AttestationStatement/AttestationStatementSupportManager.php +++ b/web-auth/webauthn-lib/src/AttestationStatement/AttestationStatementSupportManager.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/AttestationStatement/FidoU2FAttestationStatementSupport.php b/web-auth/webauthn-lib/src/AttestationStatement/FidoU2FAttestationStatementSupport.php index 5e31bd59c..7fe326d87 100644 --- a/web-auth/webauthn-lib/src/AttestationStatement/FidoU2FAttestationStatementSupport.php +++ b/web-auth/webauthn-lib/src/AttestationStatement/FidoU2FAttestationStatementSupport.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/AttestationStatement/NoneAttestationStatementSupport.php b/web-auth/webauthn-lib/src/AttestationStatement/NoneAttestationStatementSupport.php index 610fb443e..8719ae7d1 100644 --- a/web-auth/webauthn-lib/src/AttestationStatement/NoneAttestationStatementSupport.php +++ b/web-auth/webauthn-lib/src/AttestationStatement/NoneAttestationStatementSupport.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/AttestationStatement/PackedAttestationStatementSupport.php b/web-auth/webauthn-lib/src/AttestationStatement/PackedAttestationStatementSupport.php index bea42c43a..58fb6370e 100644 --- a/web-auth/webauthn-lib/src/AttestationStatement/PackedAttestationStatementSupport.php +++ b/web-auth/webauthn-lib/src/AttestationStatement/PackedAttestationStatementSupport.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/AttestationStatement/TPMAttestationStatementSupport.php b/web-auth/webauthn-lib/src/AttestationStatement/TPMAttestationStatementSupport.php index 59e5503fc..b43effb49 100644 --- a/web-auth/webauthn-lib/src/AttestationStatement/TPMAttestationStatementSupport.php +++ b/web-auth/webauthn-lib/src/AttestationStatement/TPMAttestationStatementSupport.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/AttestedCredentialData.php b/web-auth/webauthn-lib/src/AttestedCredentialData.php index 24ac5e34c..329f2c6b1 100644 --- a/web-auth/webauthn-lib/src/AttestedCredentialData.php +++ b/web-auth/webauthn-lib/src/AttestedCredentialData.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/AuthenticationExtensions/AuthenticationExtension.php b/web-auth/webauthn-lib/src/AuthenticationExtensions/AuthenticationExtension.php index 74b8bc50a..8a29b1c6d 100644 --- a/web-auth/webauthn-lib/src/AuthenticationExtensions/AuthenticationExtension.php +++ b/web-auth/webauthn-lib/src/AuthenticationExtensions/AuthenticationExtension.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/AuthenticationExtensions/AuthenticationExtensionsClientInputs.php b/web-auth/webauthn-lib/src/AuthenticationExtensions/AuthenticationExtensionsClientInputs.php index c2c5a1cec..2f171e7f7 100644 --- a/web-auth/webauthn-lib/src/AuthenticationExtensions/AuthenticationExtensionsClientInputs.php +++ b/web-auth/webauthn-lib/src/AuthenticationExtensions/AuthenticationExtensionsClientInputs.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/AuthenticationExtensions/AuthenticationExtensionsClientOutputs.php b/web-auth/webauthn-lib/src/AuthenticationExtensions/AuthenticationExtensionsClientOutputs.php index 509178f56..d6ed0ffbc 100644 --- a/web-auth/webauthn-lib/src/AuthenticationExtensions/AuthenticationExtensionsClientOutputs.php +++ b/web-auth/webauthn-lib/src/AuthenticationExtensions/AuthenticationExtensionsClientOutputs.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/AuthenticationExtensions/AuthenticationExtensionsClientOutputsLoader.php b/web-auth/webauthn-lib/src/AuthenticationExtensions/AuthenticationExtensionsClientOutputsLoader.php index 1bb46590f..b4f69bf91 100644 --- a/web-auth/webauthn-lib/src/AuthenticationExtensions/AuthenticationExtensionsClientOutputsLoader.php +++ b/web-auth/webauthn-lib/src/AuthenticationExtensions/AuthenticationExtensionsClientOutputsLoader.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/AuthenticationExtensions/ExtensionOutputChecker.php b/web-auth/webauthn-lib/src/AuthenticationExtensions/ExtensionOutputChecker.php index 16f656102..e53c88e57 100644 --- a/web-auth/webauthn-lib/src/AuthenticationExtensions/ExtensionOutputChecker.php +++ b/web-auth/webauthn-lib/src/AuthenticationExtensions/ExtensionOutputChecker.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/AuthenticationExtensions/ExtensionOutputCheckerHandler.php b/web-auth/webauthn-lib/src/AuthenticationExtensions/ExtensionOutputCheckerHandler.php index 7d84e7f85..8b78c3534 100644 --- a/web-auth/webauthn-lib/src/AuthenticationExtensions/ExtensionOutputCheckerHandler.php +++ b/web-auth/webauthn-lib/src/AuthenticationExtensions/ExtensionOutputCheckerHandler.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/AuthenticationExtensions/ExtensionOutputError.php b/web-auth/webauthn-lib/src/AuthenticationExtensions/ExtensionOutputError.php index 8aef6b21b..f16072f66 100644 --- a/web-auth/webauthn-lib/src/AuthenticationExtensions/ExtensionOutputError.php +++ b/web-auth/webauthn-lib/src/AuthenticationExtensions/ExtensionOutputError.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/AuthenticatorAssertionResponse.php b/web-auth/webauthn-lib/src/AuthenticatorAssertionResponse.php index 0a5bf15ef..ec325e6e0 100644 --- a/web-auth/webauthn-lib/src/AuthenticatorAssertionResponse.php +++ b/web-auth/webauthn-lib/src/AuthenticatorAssertionResponse.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/AuthenticatorAssertionResponseValidator.php b/web-auth/webauthn-lib/src/AuthenticatorAssertionResponseValidator.php index f196b1ea2..7550243a2 100644 --- a/web-auth/webauthn-lib/src/AuthenticatorAssertionResponseValidator.php +++ b/web-auth/webauthn-lib/src/AuthenticatorAssertionResponseValidator.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -62,10 +62,12 @@ class AuthenticatorAssertionResponseValidator * @var Manager|null */ private $algorithmManager; + /** * @var CounterChecker */ private $counterChecker; + /** * @var LoggerInterface|null */ @@ -101,21 +103,21 @@ public function check(string $credentialId, AuthenticatorAssertionResponse $auth 'host' => $request->getUri()->getHost(), 'userHandle' => $userHandle, ]); - /* @see 7.2.1 */ + /** @see 7.2.1 */ if (0 !== count($publicKeyCredentialRequestOptions->getAllowCredentials())) { Assertion::true($this->isCredentialIdAllowed($credentialId, $publicKeyCredentialRequestOptions->getAllowCredentials()), 'The credential ID is not allowed.'); } - /* @see 7.2.2 */ + /** @see 7.2.2 */ $publicKeyCredentialSource = $this->publicKeyCredentialSourceRepository->findOneByCredentialId($credentialId); Assertion::notNull($publicKeyCredentialSource, 'The credential ID is invalid.'); - /* @see 7.2.3 */ + /** @see 7.2.3 */ $attestedCredentialData = $publicKeyCredentialSource->getAttestedCredentialData(); $credentialUserHandle = $publicKeyCredentialSource->getUserHandle(); $responseUserHandle = $authenticatorAssertionResponse->getUserHandle(); - /* @see 7.2.2 User Handle*/ + /** @see 7.2.2 User Handle*/ if (null !== $userHandle) { //If the user was identified before the authentication ceremony was initiated, Assertion::eq($credentialUserHandle, $userHandle, 'Invalid user handle'); if (null !== $responseUserHandle && '' !== $responseUserHandle) { @@ -127,6 +129,10 @@ public function check(string $credentialId, AuthenticatorAssertionResponse $auth } $credentialPublicKey = $attestedCredentialData->getCredentialPublicKey(); + $isU2F = U2FPublicKey::isU2FKey($credentialPublicKey); + if ($isU2F) { + $credentialPublicKey = U2FPublicKey::createCOSEKey($credentialPublicKey); + } Assertion::notNull($credentialPublicKey, 'No public key available.'); $stream = new StringStream($credentialPublicKey); $credentialPublicKeyStream = $this->decoder->decode($stream); @@ -140,10 +146,10 @@ public function check(string $credentialId, AuthenticatorAssertionResponse $auth /** @see 7.2.6 */ $C = $authenticatorAssertionResponse->getClientDataJSON(); - /* @see 7.2.7 */ + /** @see 7.2.7 */ Assertion::eq('webauthn.get', $C->getType(), 'The client data type is not "webauthn.get".'); - /* @see 7.2.8 */ + /** @see 7.2.8 */ Assertion::true(hash_equals($publicKeyCredentialRequestOptions->getChallenge(), $C->getChallenge()), 'Invalid challenge.'); /** @see 7.2.9 */ @@ -160,23 +166,25 @@ public function check(string $credentialId, AuthenticatorAssertionResponse $auth $rpIdLength = mb_strlen($facetId); Assertion::eq(mb_substr('.'.$clientDataRpId, -($rpIdLength + 1)), '.'.$facetId, 'rpId mismatch.'); - /* @see 7.2.10 */ + /** @see 7.2.10 */ if (null !== $C->getTokenBinding()) { $this->tokenBindingHandler->check($C->getTokenBinding(), $request); } + $expectedRpIdHash = $isU2F ? $C->getOrigin() : $facetId; + // u2f response has full origin in rpIdHash /** @see 7.2.11 */ - $rpIdHash = hash('sha256', $facetId, true); + $rpIdHash = hash('sha256', $expectedRpIdHash, true); Assertion::true(hash_equals($rpIdHash, $authenticatorAssertionResponse->getAuthenticatorData()->getRpIdHash()), 'rpId hash mismatch.'); - /* @see 7.2.12 */ + /** @see 7.2.12 */ Assertion::true($authenticatorAssertionResponse->getAuthenticatorData()->isUserPresent(), 'User was not present'); - /* @see 7.2.13 */ + /** @see 7.2.13 */ if (AuthenticatorSelectionCriteria::USER_VERIFICATION_REQUIREMENT_REQUIRED === $publicKeyCredentialRequestOptions->getUserVerification()) { Assertion::true($authenticatorAssertionResponse->getAuthenticatorData()->isUserVerified(), 'User authentication required.'); } - /* @see 7.2.14 */ + /** @see 7.2.14 */ $extensionsClientOutputs = $authenticatorAssertionResponse->getAuthenticatorData()->getExtensions(); if (null !== $extensionsClientOutputs) { $this->extensionOutputCheckerHandler->check( @@ -188,7 +196,7 @@ public function check(string $credentialId, AuthenticatorAssertionResponse $auth /** @see 7.2.15 */ $getClientDataJSONHash = hash('sha256', $authenticatorAssertionResponse->getClientDataJSON()->getRawData(), true); - /* @see 7.2.16 */ + /** @see 7.2.16 */ $dataToVerify = $authenticatorAssertionResponse->getAuthenticatorData()->getAuthData().$getClientDataJSONHash; $signature = $authenticatorAssertionResponse->getSignature(); $coseKey = new Key($credentialPublicKeyStream->getNormalizedData()); @@ -197,7 +205,7 @@ public function check(string $credentialId, AuthenticatorAssertionResponse $auth $signature = CoseSignatureFixer::fix($signature, $algorithm); Assertion::true($algorithm->verify($dataToVerify, $coseKey, $signature), 'Invalid signature.'); - /* @see 7.2.17 */ + /** @see 7.2.17 */ $storedCounter = $publicKeyCredentialSource->getCounter(); $responseCounter = $authenticatorAssertionResponse->getAuthenticatorData()->getSignCount(); if (0 !== $responseCounter || 0 !== $storedCounter) { @@ -206,7 +214,7 @@ public function check(string $credentialId, AuthenticatorAssertionResponse $auth $publicKeyCredentialSource->setCounter($responseCounter); $this->publicKeyCredentialSourceRepository->saveCredentialSource($publicKeyCredentialSource); - /* @see 7.2.18 */ + /** @see 7.2.18 */ //All good. We can continue. $this->logger->info('The assertion is valid'); $this->logger->debug('Public Key Credential Source', ['publicKeyCredentialSource' => $publicKeyCredentialSource]); diff --git a/web-auth/webauthn-lib/src/AuthenticatorAttestationResponse.php b/web-auth/webauthn-lib/src/AuthenticatorAttestationResponse.php index 2c827c135..7ac9e19fc 100644 --- a/web-auth/webauthn-lib/src/AuthenticatorAttestationResponse.php +++ b/web-auth/webauthn-lib/src/AuthenticatorAttestationResponse.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/AuthenticatorAttestationResponseValidator.php b/web-auth/webauthn-lib/src/AuthenticatorAttestationResponseValidator.php index b6ee834e4..47fb4d289 100644 --- a/web-auth/webauthn-lib/src/AuthenticatorAttestationResponseValidator.php +++ b/web-auth/webauthn-lib/src/AuthenticatorAttestationResponseValidator.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -131,10 +131,10 @@ public function check(AuthenticatorAttestationResponse $authenticatorAttestation /** @see 7.1.2 */ $C = $authenticatorAttestationResponse->getClientDataJSON(); - /* @see 7.1.3 */ + /** @see 7.1.3 */ Assertion::eq('webauthn.create', $C->getType(), 'The client data type is not "webauthn.create".'); - /* @see 7.1.4 */ + /** @see 7.1.4 */ Assertion::true(hash_equals($publicKeyCredentialCreationOptions->getChallenge(), $C->getChallenge()), 'Invalid challenge.'); /** @see 7.1.5 */ @@ -154,7 +154,7 @@ public function check(AuthenticatorAttestationResponse $authenticatorAttestation Assertion::eq('https', $scheme, 'Invalid scheme. HTTPS required.'); } - /* @see 7.1.6 */ + /** @see 7.1.6 */ if (null !== $C->getTokenBinding()) { $this->tokenBindingHandler->check($C->getTokenBinding(), $request); } @@ -169,14 +169,14 @@ public function check(AuthenticatorAttestationResponse $authenticatorAttestation $rpIdHash = hash('sha256', $facetId, true); Assertion::true(hash_equals($rpIdHash, $attestationObject->getAuthData()->getRpIdHash()), 'rpId hash mismatch.'); - /* @see 7.1.10 */ + /** @see 7.1.10 */ Assertion::true($attestationObject->getAuthData()->isUserPresent(), 'User was not present'); - /* @see 7.1.11 */ + /** @see 7.1.11 */ if (AuthenticatorSelectionCriteria::USER_VERIFICATION_REQUIREMENT_REQUIRED === $publicKeyCredentialCreationOptions->getAuthenticatorSelection()->getUserVerification()) { Assertion::true($attestationObject->getAuthData()->isUserVerified(), 'User authentication required.'); } - /* @see 7.1.12 */ + /** @see 7.1.12 */ $extensionsClientOutputs = $attestationObject->getAuthData()->getExtensions(); if (null !== $extensionsClientOutputs) { $this->extensionOutputCheckerHandler->check( @@ -185,26 +185,26 @@ public function check(AuthenticatorAttestationResponse $authenticatorAttestation ); } - /* @see 7.1.13 */ + /** @see 7.1.13 */ $this->checkMetadataStatement($publicKeyCredentialCreationOptions, $attestationObject); $fmt = $attestationObject->getAttStmt()->getFmt(); Assertion::true($this->attestationStatementSupportManager->has($fmt), 'Unsupported attestation statement format.'); - /* @see 7.1.14 */ + /** @see 7.1.14 */ $attestationStatementSupport = $this->attestationStatementSupportManager->get($fmt); Assertion::true($attestationStatementSupport->isValid($clientDataJSONHash, $attestationObject->getAttStmt(), $attestationObject->getAuthData()), 'Invalid attestation statement.'); - /* @see 7.1.15 */ - /* @see 7.1.16 */ - /* @see 7.1.17 */ + /** @see 7.1.15 */ + /** @see 7.1.16 */ + /** @see 7.1.17 */ Assertion::true($attestationObject->getAuthData()->hasAttestedCredentialData(), 'There is no attested credential data.'); $attestedCredentialData = $attestationObject->getAuthData()->getAttestedCredentialData(); Assertion::notNull($attestedCredentialData, 'There is no attested credential data.'); $credentialId = $attestedCredentialData->getCredentialId(); Assertion::null($this->publicKeyCredentialSource->findOneByCredentialId($credentialId), 'The credential ID already exists.'); - /* @see 7.1.18 */ - /* @see 7.1.19 */ + /** @see 7.1.18 */ + /** @see 7.1.19 */ $publicKeyCredentialSource = $this->createPublicKeyCredentialSource( $credentialId, $attestedCredentialData, diff --git a/web-auth/webauthn-lib/src/AuthenticatorData.php b/web-auth/webauthn-lib/src/AuthenticatorData.php index e14cc6452..086ae50b8 100644 --- a/web-auth/webauthn-lib/src/AuthenticatorData.php +++ b/web-auth/webauthn-lib/src/AuthenticatorData.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/AuthenticatorResponse.php b/web-auth/webauthn-lib/src/AuthenticatorResponse.php index 6e9f553e6..2bcee456c 100644 --- a/web-auth/webauthn-lib/src/AuthenticatorResponse.php +++ b/web-auth/webauthn-lib/src/AuthenticatorResponse.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/AuthenticatorSelectionCriteria.php b/web-auth/webauthn-lib/src/AuthenticatorSelectionCriteria.php index 31e47d6b5..7f700dd00 100644 --- a/web-auth/webauthn-lib/src/AuthenticatorSelectionCriteria.php +++ b/web-auth/webauthn-lib/src/AuthenticatorSelectionCriteria.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/CertificateChainChecker/CertificateChainChecker.php b/web-auth/webauthn-lib/src/CertificateChainChecker/CertificateChainChecker.php index fb33b47df..12e9974e4 100644 --- a/web-auth/webauthn-lib/src/CertificateChainChecker/CertificateChainChecker.php +++ b/web-auth/webauthn-lib/src/CertificateChainChecker/CertificateChainChecker.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/CertificateChainChecker/OpenSSLCertificateChainChecker.php b/web-auth/webauthn-lib/src/CertificateChainChecker/OpenSSLCertificateChainChecker.php index 132358ce7..39a038d67 100644 --- a/web-auth/webauthn-lib/src/CertificateChainChecker/OpenSSLCertificateChainChecker.php +++ b/web-auth/webauthn-lib/src/CertificateChainChecker/OpenSSLCertificateChainChecker.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/CertificateToolbox.php b/web-auth/webauthn-lib/src/CertificateToolbox.php index cfa405457..51a08ab9e 100644 --- a/web-auth/webauthn-lib/src/CertificateToolbox.php +++ b/web-auth/webauthn-lib/src/CertificateToolbox.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/CollectedClientData.php b/web-auth/webauthn-lib/src/CollectedClientData.php index d2e528759..d020cca85 100644 --- a/web-auth/webauthn-lib/src/CollectedClientData.php +++ b/web-auth/webauthn-lib/src/CollectedClientData.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/Counter/CounterChecker.php b/web-auth/webauthn-lib/src/Counter/CounterChecker.php index d0e10e698..ed128bb11 100644 --- a/web-auth/webauthn-lib/src/Counter/CounterChecker.php +++ b/web-auth/webauthn-lib/src/Counter/CounterChecker.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/Counter/ThrowExceptionIfInvalid.php b/web-auth/webauthn-lib/src/Counter/ThrowExceptionIfInvalid.php index 0bf043687..801ee3b8a 100644 --- a/web-auth/webauthn-lib/src/Counter/ThrowExceptionIfInvalid.php +++ b/web-auth/webauthn-lib/src/Counter/ThrowExceptionIfInvalid.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/Credential.php b/web-auth/webauthn-lib/src/Credential.php index 072123952..bfaaadd7a 100644 --- a/web-auth/webauthn-lib/src/Credential.php +++ b/web-auth/webauthn-lib/src/Credential.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/PublicKeyCredential.php b/web-auth/webauthn-lib/src/PublicKeyCredential.php index b8aba479a..66758a9e5 100644 --- a/web-auth/webauthn-lib/src/PublicKeyCredential.php +++ b/web-auth/webauthn-lib/src/PublicKeyCredential.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/PublicKeyCredentialCreationOptions.php b/web-auth/webauthn-lib/src/PublicKeyCredentialCreationOptions.php index 6506934ba..84a3d2873 100644 --- a/web-auth/webauthn-lib/src/PublicKeyCredentialCreationOptions.php +++ b/web-auth/webauthn-lib/src/PublicKeyCredentialCreationOptions.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -212,18 +212,17 @@ public static function createFromArray(array $json): PublicKeyCredentialOptions } } - return self - ::create( + return self::create( PublicKeyCredentialRpEntity::createFromArray($json['rp']), PublicKeyCredentialUserEntity::createFromArray($json['user']), Base64Url::decode($json['challenge']), $pubKeyCredParams ) - ->excludeCredentials($excludeCredentials) - ->setAuthenticatorSelection(AuthenticatorSelectionCriteria::createFromArray($json['authenticatorSelection'])) - ->setAttestation($json['attestation']) - ->setTimeout($json['timeout'] ?? null) - ->setExtensions(isset($json['extensions']) ? AuthenticationExtensionsClientInputs::createFromArray($json['extensions']) : new AuthenticationExtensionsClientInputs()) + ->excludeCredentials($excludeCredentials) + ->setAuthenticatorSelection(AuthenticatorSelectionCriteria::createFromArray($json['authenticatorSelection'])) + ->setAttestation($json['attestation']) + ->setTimeout($json['timeout'] ?? null) + ->setExtensions(isset($json['extensions']) ? AuthenticationExtensionsClientInputs::createFromArray($json['extensions']) : new AuthenticationExtensionsClientInputs()) ; } diff --git a/web-auth/webauthn-lib/src/PublicKeyCredentialDescriptor.php b/web-auth/webauthn-lib/src/PublicKeyCredentialDescriptor.php index ed0fa920d..0008f1057 100644 --- a/web-auth/webauthn-lib/src/PublicKeyCredentialDescriptor.php +++ b/web-auth/webauthn-lib/src/PublicKeyCredentialDescriptor.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/PublicKeyCredentialDescriptorCollection.php b/web-auth/webauthn-lib/src/PublicKeyCredentialDescriptorCollection.php index d6660a2f0..822b47314 100644 --- a/web-auth/webauthn-lib/src/PublicKeyCredentialDescriptorCollection.php +++ b/web-auth/webauthn-lib/src/PublicKeyCredentialDescriptorCollection.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/PublicKeyCredentialEntity.php b/web-auth/webauthn-lib/src/PublicKeyCredentialEntity.php index 74f65b7c7..8e7533d3e 100644 --- a/web-auth/webauthn-lib/src/PublicKeyCredentialEntity.php +++ b/web-auth/webauthn-lib/src/PublicKeyCredentialEntity.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/PublicKeyCredentialLoader.php b/web-auth/webauthn-lib/src/PublicKeyCredentialLoader.php index cd759c3a8..8fef7fe9f 100644 --- a/web-auth/webauthn-lib/src/PublicKeyCredentialLoader.php +++ b/web-auth/webauthn-lib/src/PublicKeyCredentialLoader.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/PublicKeyCredentialOptions.php b/web-auth/webauthn-lib/src/PublicKeyCredentialOptions.php index 5a8e97874..6d5e79d74 100644 --- a/web-auth/webauthn-lib/src/PublicKeyCredentialOptions.php +++ b/web-auth/webauthn-lib/src/PublicKeyCredentialOptions.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/PublicKeyCredentialParameters.php b/web-auth/webauthn-lib/src/PublicKeyCredentialParameters.php index e808d3c79..9b422450f 100644 --- a/web-auth/webauthn-lib/src/PublicKeyCredentialParameters.php +++ b/web-auth/webauthn-lib/src/PublicKeyCredentialParameters.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/PublicKeyCredentialRequestOptions.php b/web-auth/webauthn-lib/src/PublicKeyCredentialRequestOptions.php index 58accef2a..f11d1c015 100644 --- a/web-auth/webauthn-lib/src/PublicKeyCredentialRequestOptions.php +++ b/web-auth/webauthn-lib/src/PublicKeyCredentialRequestOptions.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/PublicKeyCredentialRpEntity.php b/web-auth/webauthn-lib/src/PublicKeyCredentialRpEntity.php index 94ebbc08e..336ce5149 100644 --- a/web-auth/webauthn-lib/src/PublicKeyCredentialRpEntity.php +++ b/web-auth/webauthn-lib/src/PublicKeyCredentialRpEntity.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/PublicKeyCredentialSource.php b/web-auth/webauthn-lib/src/PublicKeyCredentialSource.php index 68f958ddb..8c8ad323f 100644 --- a/web-auth/webauthn-lib/src/PublicKeyCredentialSource.php +++ b/web-auth/webauthn-lib/src/PublicKeyCredentialSource.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/PublicKeyCredentialSourceRepository.php b/web-auth/webauthn-lib/src/PublicKeyCredentialSourceRepository.php index 34a122ff6..66a0734e8 100644 --- a/web-auth/webauthn-lib/src/PublicKeyCredentialSourceRepository.php +++ b/web-auth/webauthn-lib/src/PublicKeyCredentialSourceRepository.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/PublicKeyCredentialUserEntity.php b/web-auth/webauthn-lib/src/PublicKeyCredentialUserEntity.php index b0446e26f..cc3cdd4b4 100644 --- a/web-auth/webauthn-lib/src/PublicKeyCredentialUserEntity.php +++ b/web-auth/webauthn-lib/src/PublicKeyCredentialUserEntity.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/Server.php b/web-auth/webauthn-lib/src/Server.php index 662c41ade..b1c0dca7e 100644 --- a/web-auth/webauthn-lib/src/Server.php +++ b/web-auth/webauthn-lib/src/Server.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -215,18 +215,17 @@ public function generatePublicKeyCredentialCreationOptions(PublicKeyCredentialUs $extensions = $extensions ?? new AuthenticationExtensionsClientInputs(); $challenge = random_bytes($this->challengeSize); - return PublicKeyCredentialCreationOptions - ::create( + return PublicKeyCredentialCreationOptions::create( $this->rpEntity, $userEntity, $challenge, $publicKeyCredentialParametersList ) - ->excludeCredentials($excludedPublicKeyDescriptors) - ->setAuthenticatorSelection($criteria) - ->setAttestation($attestationMode ?? PublicKeyCredentialCreationOptions::ATTESTATION_CONVEYANCE_PREFERENCE_NONE) - ->setExtensions($extensions) - ->setTimeout($this->timeout) + ->excludeCredentials($excludedPublicKeyDescriptors) + ->setAuthenticatorSelection($criteria) + ->setAttestation($attestationMode ?? PublicKeyCredentialCreationOptions::ATTESTATION_CONVEYANCE_PREFERENCE_NONE) + ->setExtensions($extensions) + ->setTimeout($this->timeout) ; } @@ -235,13 +234,12 @@ public function generatePublicKeyCredentialCreationOptions(PublicKeyCredentialUs */ public function generatePublicKeyCredentialRequestOptions(?string $userVerification = null, array $allowedPublicKeyDescriptors = [], ?AuthenticationExtensionsClientInputs $extensions = null): PublicKeyCredentialRequestOptions { - return PublicKeyCredentialRequestOptions - ::create(random_bytes($this->challengeSize)) - ->setRpId($this->rpEntity->getId()) - ->setUserVerification($userVerification ?? PublicKeyCredentialRequestOptions::USER_VERIFICATION_REQUIREMENT_PREFERRED) - ->allowCredentials($allowedPublicKeyDescriptors) - ->setTimeout($this->timeout) - ->setExtensions($extensions ?? new AuthenticationExtensionsClientInputs()) + return PublicKeyCredentialRequestOptions::create(random_bytes($this->challengeSize)) + ->setRpId($this->rpEntity->getId()) + ->setUserVerification($userVerification ?? PublicKeyCredentialRequestOptions::USER_VERIFICATION_REQUIREMENT_PREFERRED) + ->allowCredentials($allowedPublicKeyDescriptors) + ->setTimeout($this->timeout) + ->setExtensions($extensions ?? new AuthenticationExtensionsClientInputs()) ; } diff --git a/web-auth/webauthn-lib/src/StringStream.php b/web-auth/webauthn-lib/src/StringStream.php index 8c9693ce6..b60acee44 100644 --- a/web-auth/webauthn-lib/src/StringStream.php +++ b/web-auth/webauthn-lib/src/StringStream.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/TokenBinding/IgnoreTokenBindingHandler.php b/web-auth/webauthn-lib/src/TokenBinding/IgnoreTokenBindingHandler.php index 463686b27..4272acf07 100644 --- a/web-auth/webauthn-lib/src/TokenBinding/IgnoreTokenBindingHandler.php +++ b/web-auth/webauthn-lib/src/TokenBinding/IgnoreTokenBindingHandler.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/TokenBinding/SecTokenBindingHandler.php b/web-auth/webauthn-lib/src/TokenBinding/SecTokenBindingHandler.php index 223b6b987..7ddb2a9a6 100644 --- a/web-auth/webauthn-lib/src/TokenBinding/SecTokenBindingHandler.php +++ b/web-auth/webauthn-lib/src/TokenBinding/SecTokenBindingHandler.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/TokenBinding/TokenBinding.php b/web-auth/webauthn-lib/src/TokenBinding/TokenBinding.php index c6d2e9bb4..1a0adf734 100644 --- a/web-auth/webauthn-lib/src/TokenBinding/TokenBinding.php +++ b/web-auth/webauthn-lib/src/TokenBinding/TokenBinding.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/TokenBinding/TokenBindingHandler.php b/web-auth/webauthn-lib/src/TokenBinding/TokenBindingHandler.php index 53790c006..e81386ae9 100644 --- a/web-auth/webauthn-lib/src/TokenBinding/TokenBindingHandler.php +++ b/web-auth/webauthn-lib/src/TokenBinding/TokenBindingHandler.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/TokenBinding/TokenBindingNotSupportedHandler.php b/web-auth/webauthn-lib/src/TokenBinding/TokenBindingNotSupportedHandler.php index 4ef4b9e16..98c483e6d 100644 --- a/web-auth/webauthn-lib/src/TokenBinding/TokenBindingNotSupportedHandler.php +++ b/web-auth/webauthn-lib/src/TokenBinding/TokenBindingNotSupportedHandler.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/TrustPath/CertificateTrustPath.php b/web-auth/webauthn-lib/src/TrustPath/CertificateTrustPath.php index 47ea38178..b2916ae03 100644 --- a/web-auth/webauthn-lib/src/TrustPath/CertificateTrustPath.php +++ b/web-auth/webauthn-lib/src/TrustPath/CertificateTrustPath.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/TrustPath/EcdaaKeyIdTrustPath.php b/web-auth/webauthn-lib/src/TrustPath/EcdaaKeyIdTrustPath.php index 73d4fa45b..0a575566a 100644 --- a/web-auth/webauthn-lib/src/TrustPath/EcdaaKeyIdTrustPath.php +++ b/web-auth/webauthn-lib/src/TrustPath/EcdaaKeyIdTrustPath.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/TrustPath/EmptyTrustPath.php b/web-auth/webauthn-lib/src/TrustPath/EmptyTrustPath.php index 61fd32b89..518ab0b97 100644 --- a/web-auth/webauthn-lib/src/TrustPath/EmptyTrustPath.php +++ b/web-auth/webauthn-lib/src/TrustPath/EmptyTrustPath.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/TrustPath/TrustPath.php b/web-auth/webauthn-lib/src/TrustPath/TrustPath.php index ce5b05448..f83cfd94d 100644 --- a/web-auth/webauthn-lib/src/TrustPath/TrustPath.php +++ b/web-auth/webauthn-lib/src/TrustPath/TrustPath.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/TrustPath/TrustPathLoader.php b/web-auth/webauthn-lib/src/TrustPath/TrustPathLoader.php index f60333c67..5153ac10c 100644 --- a/web-auth/webauthn-lib/src/TrustPath/TrustPathLoader.php +++ b/web-auth/webauthn-lib/src/TrustPath/TrustPathLoader.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/web-auth/webauthn-lib/src/U2FPublicKey.php b/web-auth/webauthn-lib/src/U2FPublicKey.php new file mode 100644 index 000000000..2bba5148c --- /dev/null +++ b/web-auth/webauthn-lib/src/U2FPublicKey.php @@ -0,0 +1,46 @@ + MapItem::create( + new UnsignedIntegerObject(1, null), + new UnsignedIntegerObject(2, null) + ), + 3 => MapItem::create( + new UnsignedIntegerObject(3, null), + new NegativeIntegerObject(6, null) + ), + -1 => MapItem::create( + new NegativeIntegerObject(0, null), + new UnsignedIntegerObject(1, null) + ), + -2 => MapItem::create( + new NegativeIntegerObject(1, null), + new ByteStringObject(substr($publicKey, 1, 32)) + ), + -3 => MapItem::create( + new NegativeIntegerObject(2, null), + new ByteStringObject(substr($publicKey, 33)) + ), + ]); + + return $mapObject->__toString(); + } +} diff --git a/web-auth/webauthn-lib/src/Util/CoseSignatureFixer.php b/web-auth/webauthn-lib/src/Util/CoseSignatureFixer.php index ea3d12cf9..3a01fba39 100644 --- a/web-auth/webauthn-lib/src/Util/CoseSignatureFixer.php +++ b/web-auth/webauthn-lib/src/Util/CoseSignatureFixer.php @@ -5,7 +5,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2014-2020 Spomky-Labs + * Copyright (c) 2014-2021 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details.