1
0
Fork 0
mirror of https://github.com/DanielnetoDotCom/YouPHPTube synced 2025-10-03 09:49:28 +02:00

Update comments

This commit is contained in:
Daniel Neto 2024-08-21 09:11:05 -03:00
parent 91ac7ba018
commit d7965a01b8
302 changed files with 56587 additions and 763 deletions

3
.gitignore vendored
View file

@ -103,4 +103,5 @@ plugin/Vdatait/
plugin/VideoPlaylistScheduler/ plugin/VideoPlaylistScheduler/
install/bulkCreateUser.php install/bulkCreateUser.php
/plugin/CertifyComplete/ /plugin/CertifyComplete/
plugin/WebAuthnLogin/ plugin/WebAuthnLogin/
plugin/UserOTPLogin/

View file

@ -49,6 +49,8 @@
"phpseclib/phpseclib": "^3.0", "phpseclib/phpseclib": "^3.0",
"bunnycdn/storage": "^3.0", "bunnycdn/storage": "^3.0",
"chillerlan/php-qrcode": "^5.0", "chillerlan/php-qrcode": "^5.0",
"erusev/parsedown": "^1.7" "erusev/parsedown": "^1.7",
"spomky-labs/otphp": "^10.0",
"christian-riesen/base32": "^1.6"
} }
} }

683
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -4125,12 +4125,18 @@ function getInputCopyToClipboard($id, $value, $attributes = 'class="form-control
$('#copyToClipboard_<?php echo $id; ?>').find('i').addClass("fa-clipboard"); $('#copyToClipboard_<?php echo $id; ?>').find('i').addClass("fa-clipboard");
}, 3000); }, 3000);
copyToClipboard($('#<?php echo $id; ?>').val()); copyToClipboard($('#<?php echo $id; ?>').val());
}) });
// Auto-select the input text when the input is focused or clicked
$('#<?php echo $id; ?>').on('focus click', function() {
$(this).select();
});
}); });
</script> </script>
<?php <?php
} }
function getButtontCopyToClipboard($elemToCopyId, $attributes = 'class="btn btn-default btn-sm btn-xs pull-right"', $label = "Copy to Clipboard") function getButtontCopyToClipboard($elemToCopyId, $attributes = 'class="btn btn-default btn-sm btn-xs pull-right"', $label = "Copy to Clipboard")
{ {
$id = "getButtontCopyToClipboard" . uniqid(); $id = "getButtontCopyToClipboard" . uniqid();

View file

@ -15,6 +15,8 @@ use Aws\AwsClient;
* @method \GuzzleHttp\Promise\Promise createModelCopyJobAsync(array $args = []) * @method \GuzzleHttp\Promise\Promise createModelCopyJobAsync(array $args = [])
* @method \Aws\Result createModelCustomizationJob(array $args = []) * @method \Aws\Result createModelCustomizationJob(array $args = [])
* @method \GuzzleHttp\Promise\Promise createModelCustomizationJobAsync(array $args = []) * @method \GuzzleHttp\Promise\Promise createModelCustomizationJobAsync(array $args = [])
* @method \Aws\Result createModelInvocationJob(array $args = [])
* @method \GuzzleHttp\Promise\Promise createModelInvocationJobAsync(array $args = [])
* @method \Aws\Result createProvisionedModelThroughput(array $args = []) * @method \Aws\Result createProvisionedModelThroughput(array $args = [])
* @method \GuzzleHttp\Promise\Promise createProvisionedModelThroughputAsync(array $args = []) * @method \GuzzleHttp\Promise\Promise createProvisionedModelThroughputAsync(array $args = [])
* @method \Aws\Result deleteCustomModel(array $args = []) * @method \Aws\Result deleteCustomModel(array $args = [])
@ -37,6 +39,8 @@ use Aws\AwsClient;
* @method \GuzzleHttp\Promise\Promise getModelCopyJobAsync(array $args = []) * @method \GuzzleHttp\Promise\Promise getModelCopyJobAsync(array $args = [])
* @method \Aws\Result getModelCustomizationJob(array $args = []) * @method \Aws\Result getModelCustomizationJob(array $args = [])
* @method \GuzzleHttp\Promise\Promise getModelCustomizationJobAsync(array $args = []) * @method \GuzzleHttp\Promise\Promise getModelCustomizationJobAsync(array $args = [])
* @method \Aws\Result getModelInvocationJob(array $args = [])
* @method \GuzzleHttp\Promise\Promise getModelInvocationJobAsync(array $args = [])
* @method \Aws\Result getModelInvocationLoggingConfiguration(array $args = []) * @method \Aws\Result getModelInvocationLoggingConfiguration(array $args = [])
* @method \GuzzleHttp\Promise\Promise getModelInvocationLoggingConfigurationAsync(array $args = []) * @method \GuzzleHttp\Promise\Promise getModelInvocationLoggingConfigurationAsync(array $args = [])
* @method \Aws\Result getProvisionedModelThroughput(array $args = []) * @method \Aws\Result getProvisionedModelThroughput(array $args = [])
@ -53,6 +57,8 @@ use Aws\AwsClient;
* @method \GuzzleHttp\Promise\Promise listModelCopyJobsAsync(array $args = []) * @method \GuzzleHttp\Promise\Promise listModelCopyJobsAsync(array $args = [])
* @method \Aws\Result listModelCustomizationJobs(array $args = []) * @method \Aws\Result listModelCustomizationJobs(array $args = [])
* @method \GuzzleHttp\Promise\Promise listModelCustomizationJobsAsync(array $args = []) * @method \GuzzleHttp\Promise\Promise listModelCustomizationJobsAsync(array $args = [])
* @method \Aws\Result listModelInvocationJobs(array $args = [])
* @method \GuzzleHttp\Promise\Promise listModelInvocationJobsAsync(array $args = [])
* @method \Aws\Result listProvisionedModelThroughputs(array $args = []) * @method \Aws\Result listProvisionedModelThroughputs(array $args = [])
* @method \GuzzleHttp\Promise\Promise listProvisionedModelThroughputsAsync(array $args = []) * @method \GuzzleHttp\Promise\Promise listProvisionedModelThroughputsAsync(array $args = [])
* @method \Aws\Result listTagsForResource(array $args = []) * @method \Aws\Result listTagsForResource(array $args = [])
@ -63,6 +69,8 @@ use Aws\AwsClient;
* @method \GuzzleHttp\Promise\Promise stopEvaluationJobAsync(array $args = []) * @method \GuzzleHttp\Promise\Promise stopEvaluationJobAsync(array $args = [])
* @method \Aws\Result stopModelCustomizationJob(array $args = []) * @method \Aws\Result stopModelCustomizationJob(array $args = [])
* @method \GuzzleHttp\Promise\Promise stopModelCustomizationJobAsync(array $args = []) * @method \GuzzleHttp\Promise\Promise stopModelCustomizationJobAsync(array $args = [])
* @method \Aws\Result stopModelInvocationJob(array $args = [])
* @method \GuzzleHttp\Promise\Promise stopModelInvocationJobAsync(array $args = [])
* @method \Aws\Result tagResource(array $args = []) * @method \Aws\Result tagResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise tagResourceAsync(array $args = []) * @method \GuzzleHttp\Promise\Promise tagResourceAsync(array $args = [])
* @method \Aws\Result untagResource(array $args = []) * @method \Aws\Result untagResource(array $args = [])

View file

@ -60,6 +60,8 @@ use Aws\Middleware;
* @method \GuzzleHttp\Promise\Promise getFunctionConfigurationAsync(array $args = []) * @method \GuzzleHttp\Promise\Promise getFunctionConfigurationAsync(array $args = [])
* @method \Aws\Result getFunctionEventInvokeConfig(array $args = []) * @method \Aws\Result getFunctionEventInvokeConfig(array $args = [])
* @method \GuzzleHttp\Promise\Promise getFunctionEventInvokeConfigAsync(array $args = []) * @method \GuzzleHttp\Promise\Promise getFunctionEventInvokeConfigAsync(array $args = [])
* @method \Aws\Result getFunctionRecursionConfig(array $args = [])
* @method \GuzzleHttp\Promise\Promise getFunctionRecursionConfigAsync(array $args = [])
* @method \Aws\Result getFunctionUrlConfig(array $args = []) * @method \Aws\Result getFunctionUrlConfig(array $args = [])
* @method \GuzzleHttp\Promise\Promise getFunctionUrlConfigAsync(array $args = []) * @method \GuzzleHttp\Promise\Promise getFunctionUrlConfigAsync(array $args = [])
* @method \Aws\Result getLayerVersion(array $args = []) * @method \Aws\Result getLayerVersion(array $args = [])
@ -114,6 +116,8 @@ use Aws\Middleware;
* @method \GuzzleHttp\Promise\Promise putFunctionConcurrencyAsync(array $args = []) * @method \GuzzleHttp\Promise\Promise putFunctionConcurrencyAsync(array $args = [])
* @method \Aws\Result putFunctionEventInvokeConfig(array $args = []) * @method \Aws\Result putFunctionEventInvokeConfig(array $args = [])
* @method \GuzzleHttp\Promise\Promise putFunctionEventInvokeConfigAsync(array $args = []) * @method \GuzzleHttp\Promise\Promise putFunctionEventInvokeConfigAsync(array $args = [])
* @method \Aws\Result putFunctionRecursionConfig(array $args = [])
* @method \GuzzleHttp\Promise\Promise putFunctionRecursionConfigAsync(array $args = [])
* @method \Aws\Result putProvisionedConcurrencyConfig(array $args = []) * @method \Aws\Result putProvisionedConcurrencyConfig(array $args = [])
* @method \GuzzleHttp\Promise\Promise putProvisionedConcurrencyConfigAsync(array $args = []) * @method \GuzzleHttp\Promise\Promise putProvisionedConcurrencyConfigAsync(array $args = [])
* @method \Aws\Result putRuntimeManagementConfig(array $args = []) * @method \Aws\Result putRuntimeManagementConfig(array $args = [])

View file

@ -777,7 +777,7 @@ namespace Aws;
*/ */
class Sdk class Sdk
{ {
const VERSION = '3.320.2'; const VERSION = '3.320.3';
/** @var array Arguments for creating clients */ /** @var array Arguments for creating clients */
private $args; private $args;

File diff suppressed because one or more lines are too long

View file

@ -1,3 +1,3 @@
<?php <?php
// This file was auto-generated from sdk-root/src/data/bedrock/2023-04-20/paginators-1.json // This file was auto-generated from sdk-root/src/data/bedrock/2023-04-20/paginators-1.json
return [ 'pagination' => [ 'ListCustomModels' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', 'result_key' => 'modelSummaries', ], 'ListEvaluationJobs' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', 'result_key' => 'jobSummaries', ], 'ListGuardrails' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', 'result_key' => 'guardrails', ], 'ListModelCopyJobs' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', 'result_key' => 'modelCopyJobSummaries', ], 'ListModelCustomizationJobs' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', 'result_key' => 'modelCustomizationJobSummaries', ], 'ListProvisionedModelThroughputs' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', 'result_key' => 'provisionedModelSummaries', ], ],]; return [ 'pagination' => [ 'ListCustomModels' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', 'result_key' => 'modelSummaries', ], 'ListEvaluationJobs' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', 'result_key' => 'jobSummaries', ], 'ListGuardrails' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', 'result_key' => 'guardrails', ], 'ListModelCopyJobs' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', 'result_key' => 'modelCopyJobSummaries', ], 'ListModelCustomizationJobs' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', 'result_key' => 'modelCustomizationJobSummaries', ], 'ListModelInvocationJobs' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', 'result_key' => 'invocationJobSummaries', ], 'ListProvisionedModelThroughputs' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', 'result_key' => 'provisionedModelSummaries', ], ],];

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,64 @@
on: [push, pull_request]
name: CI
jobs:
tests:
name: Tests
runs-on: ubuntu-latest
strategy:
matrix:
php-versions: ['7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1']
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-versions }}
tools: "cs2pr"
- name: "Cache dependencies installed with composer"
uses: "actions/cache@v1"
with:
path: "~/.composer/cache"
key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}"
restore-keys: "php-${{ matrix.php-version }}-composer-locked-"
- name: "Composer"
run: "composer update --prefer-stable"
- name: "PHPUnit"
run: "php vendor/bin/phpunit"
# lint:
# name: Lint
# runs-on: ubuntu-latest
# steps:
# - name: Checkout
# uses: actions/checkout@v1
# - name: Setup PHP
# uses: shivammathur/setup-php@v2
# with:
# php-version: 7.4
# - name: "Cache dependencies installed with composer"
# uses: "actions/cache@v1"
# with:
# path: "~/.composer/cache"
# key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}"
# restore-keys: "php-${{ matrix.php-version }}-composer-locked-"
# - name: "Composer"
# run: "composer update --prefer-stable"
# - name: "assert:cs-lint"
# run: "composer assert:cs-lint"
# - name: "assert:sa-code"
# run: "composer assert:sa-code"
# - name: "assert:sa-tests"
# run: "composer assert:sa-tests"

11
vendor/beberlei/assert/LICENSE vendored Normal file
View file

@ -0,0 +1,11 @@
Copyright (c) 2011-2013, Benjamin Eberlei
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

64
vendor/beberlei/assert/composer.json vendored Normal file
View file

@ -0,0 +1,64 @@
{
"name": "beberlei/assert",
"description": "Thin assertion library for input validation in business models.",
"authors": [
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de",
"role": "Lead Developer"
},
{
"name": "Richard Quadling",
"email": "rquadling@gmail.com",
"role": "Collaborator"
}
],
"license": "BSD-2-Clause",
"keywords": [
"assert",
"assertion",
"validation"
],
"config": {
"sort-packages": true
},
"require": {
"php": "^7.0 || ^8.0",
"ext-simplexml": "*",
"ext-mbstring": "*",
"ext-ctype": "*",
"ext-json": "*"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "*",
"phpstan/phpstan": "*",
"phpunit/phpunit": ">=6.0.0",
"yoast/phpunit-polyfills": "^0.1.0"
},
"autoload": {
"psr-4": {
"Assert\\": "lib/Assert"
},
"files": [
"lib/Assert/functions.php"
]
},
"autoload-dev": {
"psr-4": {
"Assert\\Tests\\": "tests/Assert/Tests"
},
"files": [
"tests/Assert/Tests/Fixtures/functions.php"
]
},
"scripts": {
"assert:generate-docs": "php bin/generate_method_docs.php",
"assert:cs-lint": "php-cs-fixer fix --diff -vvv --dry-run",
"assert:cs-fix": "php-cs-fixer fix . -vvv || true",
"assert:sa-code": "vendor/bin/phpstan analyse --configuration=phpstan-code.neon --no-progress --ansi -l 7 bin lib",
"assert:sa-tests": "vendor/bin/phpstan analyse --configuration=phpstan-tests.neon --no-progress --ansi -l 7 tests"
},
"suggest": {
"ext-intl": "Needed to allow Assertion::count(), Assertion::isCountable(), Assertion::minCount(), and Assertion::maxCount() to operate on ResourceBundles"
}
}

View file

@ -0,0 +1,85 @@
<?php
/**
* Assert
*
* LICENSE
*
* This source file is subject to the MIT license that is bundled
* with this package in the file LICENSE.txt.
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to kontakt@beberlei.de so I can send you a copy immediately.
*/
namespace Assert;
/**
* AssertionChain factory.
*/
abstract class Assert
{
/** @var string */
protected static $lazyAssertionExceptionClass = LazyAssertionException::class;
/** @var string */
protected static $assertionClass = Assertion::class;
/**
* Start validation on a value, returns {@link AssertionChain}.
*
* The invocation of this method starts an assertion chain
* that is happening on the passed value.
*
* @param mixed $value
* @param string|callable|null $defaultMessage
*
* @example
*
* Assert::that($value)->notEmpty()->integer();
* Assert::that($value)->nullOr()->string()->startsWith("Foo");
*
* The assertion chain can be stateful, that means be careful when you reuse
* it. You should never pass around the chain.
*/
public static function that($value, $defaultMessage = null, string $defaultPropertyPath = null): AssertionChain
{
$assertionChain = new AssertionChain($value, $defaultMessage, $defaultPropertyPath);
return $assertionChain->setAssertionClassName(static::$assertionClass);
}
/**
* Start validation on a set of values, returns {@link AssertionChain}.
*
* @param mixed $values
* @param string|callable|null $defaultMessage
*/
public static function thatAll($values, $defaultMessage = null, string $defaultPropertyPath = null): AssertionChain
{
return static::that($values, $defaultMessage, $defaultPropertyPath)->all();
}
/**
* Start validation and allow NULL, returns {@link AssertionChain}.
*
* @param mixed $value
* @param string|callable|null $defaultMessage
*/
public static function thatNullOr($value, $defaultMessage = null, string $defaultPropertyPath = null): AssertionChain
{
return static::that($value, $defaultMessage, $defaultPropertyPath)->nullOr();
}
/**
* Create a lazy assertion object.
*/
public static function lazy(): LazyAssertion
{
$lazyAssertion = new LazyAssertion();
return $lazyAssertion
->setAssertClass(\get_called_class())
->setExceptionClass(static::$lazyAssertionExceptionClass);
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,247 @@
<?php
/**
* Assert
*
* LICENSE
*
* This source file is subject to the MIT license that is bundled
* with this package in the file LICENSE.txt.
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to kontakt@beberlei.de so I can send you a copy immediately.
*/
namespace Assert;
use LogicException;
/**
* Chaining builder for assertions.
*
* @author Benjamin Eberlei <kontakt@beberlei.de>
*
* @method AssertionChain alnum(string|callable $message = null, string $propertyPath = null) Assert that value is alphanumeric.
* @method AssertionChain base64(string|callable $message = null, string $propertyPath = null) Assert that a constant is defined.
* @method AssertionChain between(mixed $lowerLimit, mixed $upperLimit, string|callable $message = null, string $propertyPath = null) Assert that a value is greater or equal than a lower limit, and less than or equal to an upper limit.
* @method AssertionChain betweenExclusive(mixed $lowerLimit, mixed $upperLimit, string|callable $message = null, string $propertyPath = null) Assert that a value is greater than a lower limit, and less than an upper limit.
* @method AssertionChain betweenLength(int $minLength, int $maxLength, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string length is between min and max lengths.
* @method AssertionChain boolean(string|callable $message = null, string $propertyPath = null) Assert that value is php boolean.
* @method AssertionChain choice(array $choices, string|callable $message = null, string $propertyPath = null) Assert that value is in array of choices.
* @method AssertionChain choicesNotEmpty(array $choices, string|callable $message = null, string $propertyPath = null) Determines if the values array has every choice as key and that this choice has content.
* @method AssertionChain classExists(string|callable $message = null, string $propertyPath = null) Assert that the class exists.
* @method AssertionChain contains(string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string contains a sequence of chars.
* @method AssertionChain count(int $count, string|callable $message = null, string $propertyPath = null) Assert that the count of countable is equal to count.
* @method AssertionChain date(string $format, string|callable $message = null, string $propertyPath = null) Assert that date is valid and corresponds to the given format.
* @method AssertionChain defined(string|callable $message = null, string $propertyPath = null) Assert that a constant is defined.
* @method AssertionChain digit(string|callable $message = null, string $propertyPath = null) Validates if an integer or integerish is a digit.
* @method AssertionChain directory(string|callable $message = null, string $propertyPath = null) Assert that a directory exists.
* @method AssertionChain e164(string|callable $message = null, string $propertyPath = null) Assert that the given string is a valid E164 Phone Number.
* @method AssertionChain email(string|callable $message = null, string $propertyPath = null) Assert that value is an email address (using input_filter/FILTER_VALIDATE_EMAIL).
* @method AssertionChain endsWith(string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string ends with a sequence of chars.
* @method AssertionChain eq(mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are equal (using ==).
* @method AssertionChain eqArraySubset(mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that the array contains the subset.
* @method AssertionChain extensionLoaded(string|callable $message = null, string $propertyPath = null) Assert that extension is loaded.
* @method AssertionChain extensionVersion(string $operator, mixed $version, string|callable $message = null, string $propertyPath = null) Assert that extension is loaded and a specific version is installed.
* @method AssertionChain false(string|callable $message = null, string $propertyPath = null) Assert that the value is boolean False.
* @method AssertionChain file(string|callable $message = null, string $propertyPath = null) Assert that a file exists.
* @method AssertionChain float(string|callable $message = null, string $propertyPath = null) Assert that value is a php float.
* @method AssertionChain greaterOrEqualThan(mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is greater or equal than given limit.
* @method AssertionChain greaterThan(mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is greater than given limit.
* @method AssertionChain implementsInterface(string $interfaceName, string|callable $message = null, string $propertyPath = null) Assert that the class implements the interface.
* @method AssertionChain inArray(array $choices, string|callable $message = null, string $propertyPath = null) Assert that value is in array of choices. This is an alias of Assertion::choice().
* @method AssertionChain integer(string|callable $message = null, string $propertyPath = null) Assert that value is a php integer.
* @method AssertionChain integerish(string|callable $message = null, string $propertyPath = null) Assert that value is a php integer'ish.
* @method AssertionChain interfaceExists(string|callable $message = null, string $propertyPath = null) Assert that the interface exists.
* @method AssertionChain ip(int $flag = null, string|callable $message = null, string $propertyPath = null) Assert that value is an IPv4 or IPv6 address.
* @method AssertionChain ipv4(int $flag = null, string|callable $message = null, string $propertyPath = null) Assert that value is an IPv4 address.
* @method AssertionChain ipv6(int $flag = null, string|callable $message = null, string $propertyPath = null) Assert that value is an IPv6 address.
* @method AssertionChain isArray(string|callable $message = null, string $propertyPath = null) Assert that value is an array.
* @method AssertionChain isArrayAccessible(string|callable $message = null, string $propertyPath = null) Assert that value is an array or an array-accessible object.
* @method AssertionChain isCallable(string|callable $message = null, string $propertyPath = null) Determines that the provided value is callable.
* @method AssertionChain isCountable(string|callable $message = null, string $propertyPath = null) Assert that value is countable.
* @method AssertionChain isInstanceOf(string $className, string|callable $message = null, string $propertyPath = null) Assert that value is instance of given class-name.
* @method AssertionChain isJsonString(string|callable $message = null, string $propertyPath = null) Assert that the given string is a valid json string.
* @method AssertionChain isObject(string|callable $message = null, string $propertyPath = null) Determines that the provided value is an object.
* @method AssertionChain isResource(string|callable $message = null, string $propertyPath = null) Assert that value is a resource.
* @method AssertionChain isTraversable(string|callable $message = null, string $propertyPath = null) Assert that value is an array or a traversable object.
* @method AssertionChain keyExists(string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key exists in an array.
* @method AssertionChain keyIsset(string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key exists in an array/array-accessible object using isset().
* @method AssertionChain keyNotExists(string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key does not exist in an array.
* @method AssertionChain length(int $length, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string has a given length.
* @method AssertionChain lessOrEqualThan(mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is less or equal than given limit.
* @method AssertionChain lessThan(mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is less than given limit.
* @method AssertionChain max(mixed $maxValue, string|callable $message = null, string $propertyPath = null) Assert that a number is smaller as a given limit.
* @method AssertionChain maxCount(int $count, string|callable $message = null, string $propertyPath = null) Assert that the countable have at most $count elements.
* @method AssertionChain maxLength(int $maxLength, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string value is not longer than $maxLength chars.
* @method AssertionChain methodExists(mixed $object, string|callable $message = null, string $propertyPath = null) Determines that the named method is defined in the provided object.
* @method AssertionChain min(mixed $minValue, string|callable $message = null, string $propertyPath = null) Assert that a value is at least as big as a given limit.
* @method AssertionChain minCount(int $count, string|callable $message = null, string $propertyPath = null) Assert that the countable have at least $count elements.
* @method AssertionChain minLength(int $minLength, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that a string is at least $minLength chars long.
* @method AssertionChain noContent(string|callable $message = null, string $propertyPath = null) Assert that value is empty.
* @method AssertionChain notBlank(string|callable $message = null, string $propertyPath = null) Assert that value is not blank.
* @method AssertionChain notContains(string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string does not contains a sequence of chars.
* @method AssertionChain notEmpty(string|callable $message = null, string $propertyPath = null) Assert that value is not empty.
* @method AssertionChain notEmptyKey(string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key exists in an array/array-accessible object and its value is not empty.
* @method AssertionChain notEq(mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are not equal (using ==).
* @method AssertionChain notInArray(array $choices, string|callable $message = null, string $propertyPath = null) Assert that value is not in array of choices.
* @method AssertionChain notIsInstanceOf(string $className, string|callable $message = null, string $propertyPath = null) Assert that value is not instance of given class-name.
* @method AssertionChain notNull(string|callable $message = null, string $propertyPath = null) Assert that value is not null.
* @method AssertionChain notRegex(string $pattern, string|callable $message = null, string $propertyPath = null) Assert that value does not match a regex.
* @method AssertionChain notSame(mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are not the same (using ===).
* @method AssertionChain null(string|callable $message = null, string $propertyPath = null) Assert that value is null.
* @method AssertionChain numeric(string|callable $message = null, string $propertyPath = null) Assert that value is numeric.
* @method AssertionChain objectOrClass(string|callable $message = null, string $propertyPath = null) Assert that the value is an object, or a class that exists.
* @method AssertionChain phpVersion(mixed $version, string|callable $message = null, string $propertyPath = null) Assert on PHP version.
* @method AssertionChain propertiesExist(array $properties, string|callable $message = null, string $propertyPath = null) Assert that the value is an object or class, and that the properties all exist.
* @method AssertionChain propertyExists(string $property, string|callable $message = null, string $propertyPath = null) Assert that the value is an object or class, and that the property exists.
* @method AssertionChain range(mixed $minValue, mixed $maxValue, string|callable $message = null, string $propertyPath = null) Assert that value is in range of numbers.
* @method AssertionChain readable(string|callable $message = null, string $propertyPath = null) Assert that the value is something readable.
* @method AssertionChain regex(string $pattern, string|callable $message = null, string $propertyPath = null) Assert that value matches a regex.
* @method AssertionChain same(mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are the same (using ===).
* @method AssertionChain satisfy(callable $callback, string|callable $message = null, string $propertyPath = null) Assert that the provided value is valid according to a callback.
* @method AssertionChain scalar(string|callable $message = null, string $propertyPath = null) Assert that value is a PHP scalar.
* @method AssertionChain startsWith(string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string starts with a sequence of chars.
* @method AssertionChain string(string|callable $message = null, string $propertyPath = null) Assert that value is a string.
* @method AssertionChain subclassOf(string $className, string|callable $message = null, string $propertyPath = null) Assert that value is subclass of given class-name.
* @method AssertionChain true(string|callable $message = null, string $propertyPath = null) Assert that the value is boolean True.
* @method AssertionChain uniqueValues(string|callable $message = null, string $propertyPath = null) Assert that values in array are unique (using strict equality).
* @method AssertionChain url(string|callable $message = null, string $propertyPath = null) Assert that value is an URL.
* @method AssertionChain uuid(string|callable $message = null, string $propertyPath = null) Assert that the given string is a valid UUID.
* @method AssertionChain version(string $operator, string $version2, string|callable $message = null, string $propertyPath = null) Assert comparison of two versions.
* @method AssertionChain writeable(string|callable $message = null, string $propertyPath = null) Assert that the value is something writeable.
*/
class AssertionChain
{
/**
* @var mixed
*/
private $value;
/**
* @var string|callable|null
*/
private $defaultMessage;
/**
* @var string|null
*/
private $defaultPropertyPath;
/**
* Return each assertion as always valid.
*
* @var bool
*/
private $alwaysValid = false;
/**
* Perform assertion on every element of array or traversable.
*
* @var bool
*/
private $all = false;
/** @var string|Assertion Class to use for assertion calls */
private $assertionClassName = 'Assert\Assertion';
/**
* AssertionChain constructor.
*
* @param mixed $value
* @param string|callable|null $defaultMessage
*/
public function __construct($value, $defaultMessage = null, string $defaultPropertyPath = null)
{
$this->value = $value;
$this->defaultMessage = $defaultMessage;
$this->defaultPropertyPath = $defaultPropertyPath;
}
/**
* Call assertion on the current value in the chain.
*
* @param string $methodName
* @param array $args
*/
public function __call($methodName, $args): AssertionChain
{
if (true === $this->alwaysValid) {
return $this;
}
try {
$method = new \ReflectionMethod($this->assertionClassName, $methodName);
} catch (\ReflectionException $exception) {
throw new \RuntimeException("Assertion '".$methodName."' does not exist.");
}
\array_unshift($args, $this->value);
$params = $method->getParameters();
foreach ($params as $idx => $param) {
if (isset($args[$idx])) {
continue;
}
switch ($param->getName()) {
case 'message':
$args[$idx] = $this->defaultMessage;
break;
case 'propertyPath':
$args[$idx] = $this->defaultPropertyPath;
break;
}
}
if ($this->all) {
$methodName = 'all'.$methodName;
}
\call_user_func_array([$this->assertionClassName, $methodName], $args);
return $this;
}
/**
* Switch chain into validation mode for an array of values.
*/
public function all(): AssertionChain
{
$this->all = true;
return $this;
}
/**
* Switch chain into mode allowing nulls, ignoring further assertions.
*/
public function nullOr(): AssertionChain
{
if (null === $this->value) {
$this->alwaysValid = true;
}
return $this;
}
/**
* @param string $className
*
* @return $this
*/
public function setAssertionClassName($className): AssertionChain
{
if (!\is_string($className)) {
throw new LogicException('Exception class name must be passed as a string');
}
if (Assertion::class !== $className && !\is_subclass_of($className, Assertion::class)) {
throw new LogicException($className.' is not (a subclass of) '.Assertion::class);
}
$this->assertionClassName = $className;
return $this;
}
}

View file

@ -0,0 +1,32 @@
<?php
/**
* Assert
*
* LICENSE
*
* This source file is subject to the MIT license that is bundled
* with this package in the file LICENSE.txt.
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to kontakt@beberlei.de so I can send you a copy immediately.
*/
namespace Assert;
use Throwable;
interface AssertionFailedException extends Throwable
{
/**
* @return string|null
*/
public function getPropertyPath();
/**
* @return mixed
*/
public function getValue();
public function getConstraints(): array;
}

View file

@ -0,0 +1,74 @@
<?php
/**
* Assert
*
* LICENSE
*
* This source file is subject to the MIT license that is bundled
* with this package in the file LICENSE.txt.
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to kontakt@beberlei.de so I can send you a copy immediately.
*/
namespace Assert;
class InvalidArgumentException extends \InvalidArgumentException implements AssertionFailedException
{
/**
* @var string|null
*/
private $propertyPath;
/**
* @var mixed
*/
private $value;
/**
* @var array
*/
private $constraints;
public function __construct($message, $code, string $propertyPath = null, $value = null, array $constraints = [])
{
parent::__construct($message, $code);
$this->propertyPath = $propertyPath;
$this->value = $value;
$this->constraints = $constraints;
}
/**
* User controlled way to define a sub-property causing
* the failure of a currently asserted objects.
*
* Useful to transport information about the nature of the error
* back to higher layers.
*
* @return string|null
*/
public function getPropertyPath()
{
return $this->propertyPath;
}
/**
* Get the value that caused the assertion to fail.
*
* @return mixed
*/
public function getValue()
{
return $this->value;
}
/**
* Get the constraints that applied to the failed assertion.
*/
public function getConstraints(): array
{
return $this->constraints;
}
}

View file

@ -0,0 +1,228 @@
<?php
/**
* Assert
*
* LICENSE
*
* This source file is subject to the MIT license that is bundled
* with this package in the file LICENSE.txt.
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to kontakt@beberlei.de so I can send you a copy immediately.
*/
namespace Assert;
use LogicException;
/**
* Chaining builder for lazy assertions.
*
* @author Benjamin Eberlei <kontakt@beberlei.de>
*
* @method LazyAssertion alnum(string|callable $message = null, string $propertyPath = null) Assert that value is alphanumeric.
* @method LazyAssertion base64(string|callable $message = null, string $propertyPath = null) Assert that a constant is defined.
* @method LazyAssertion between(mixed $lowerLimit, mixed $upperLimit, string|callable $message = null, string $propertyPath = null) Assert that a value is greater or equal than a lower limit, and less than or equal to an upper limit.
* @method LazyAssertion betweenExclusive(mixed $lowerLimit, mixed $upperLimit, string|callable $message = null, string $propertyPath = null) Assert that a value is greater than a lower limit, and less than an upper limit.
* @method LazyAssertion betweenLength(int $minLength, int $maxLength, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string length is between min and max lengths.
* @method LazyAssertion boolean(string|callable $message = null, string $propertyPath = null) Assert that value is php boolean.
* @method LazyAssertion choice(array $choices, string|callable $message = null, string $propertyPath = null) Assert that value is in array of choices.
* @method LazyAssertion choicesNotEmpty(array $choices, string|callable $message = null, string $propertyPath = null) Determines if the values array has every choice as key and that this choice has content.
* @method LazyAssertion classExists(string|callable $message = null, string $propertyPath = null) Assert that the class exists.
* @method LazyAssertion contains(string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string contains a sequence of chars.
* @method LazyAssertion count(int $count, string|callable $message = null, string $propertyPath = null) Assert that the count of countable is equal to count.
* @method LazyAssertion date(string $format, string|callable $message = null, string $propertyPath = null) Assert that date is valid and corresponds to the given format.
* @method LazyAssertion defined(string|callable $message = null, string $propertyPath = null) Assert that a constant is defined.
* @method LazyAssertion digit(string|callable $message = null, string $propertyPath = null) Validates if an integer or integerish is a digit.
* @method LazyAssertion directory(string|callable $message = null, string $propertyPath = null) Assert that a directory exists.
* @method LazyAssertion e164(string|callable $message = null, string $propertyPath = null) Assert that the given string is a valid E164 Phone Number.
* @method LazyAssertion email(string|callable $message = null, string $propertyPath = null) Assert that value is an email address (using input_filter/FILTER_VALIDATE_EMAIL).
* @method LazyAssertion endsWith(string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string ends with a sequence of chars.
* @method LazyAssertion eq(mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are equal (using ==).
* @method LazyAssertion eqArraySubset(mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that the array contains the subset.
* @method LazyAssertion extensionLoaded(string|callable $message = null, string $propertyPath = null) Assert that extension is loaded.
* @method LazyAssertion extensionVersion(string $operator, mixed $version, string|callable $message = null, string $propertyPath = null) Assert that extension is loaded and a specific version is installed.
* @method LazyAssertion false(string|callable $message = null, string $propertyPath = null) Assert that the value is boolean False.
* @method LazyAssertion file(string|callable $message = null, string $propertyPath = null) Assert that a file exists.
* @method LazyAssertion float(string|callable $message = null, string $propertyPath = null) Assert that value is a php float.
* @method LazyAssertion greaterOrEqualThan(mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is greater or equal than given limit.
* @method LazyAssertion greaterThan(mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is greater than given limit.
* @method LazyAssertion implementsInterface(string $interfaceName, string|callable $message = null, string $propertyPath = null) Assert that the class implements the interface.
* @method LazyAssertion inArray(array $choices, string|callable $message = null, string $propertyPath = null) Assert that value is in array of choices. This is an alias of Assertion::choice().
* @method LazyAssertion integer(string|callable $message = null, string $propertyPath = null) Assert that value is a php integer.
* @method LazyAssertion integerish(string|callable $message = null, string $propertyPath = null) Assert that value is a php integer'ish.
* @method LazyAssertion interfaceExists(string|callable $message = null, string $propertyPath = null) Assert that the interface exists.
* @method LazyAssertion ip(int $flag = null, string|callable $message = null, string $propertyPath = null) Assert that value is an IPv4 or IPv6 address.
* @method LazyAssertion ipv4(int $flag = null, string|callable $message = null, string $propertyPath = null) Assert that value is an IPv4 address.
* @method LazyAssertion ipv6(int $flag = null, string|callable $message = null, string $propertyPath = null) Assert that value is an IPv6 address.
* @method LazyAssertion isArray(string|callable $message = null, string $propertyPath = null) Assert that value is an array.
* @method LazyAssertion isArrayAccessible(string|callable $message = null, string $propertyPath = null) Assert that value is an array or an array-accessible object.
* @method LazyAssertion isCallable(string|callable $message = null, string $propertyPath = null) Determines that the provided value is callable.
* @method LazyAssertion isCountable(string|callable $message = null, string $propertyPath = null) Assert that value is countable.
* @method LazyAssertion isInstanceOf(string $className, string|callable $message = null, string $propertyPath = null) Assert that value is instance of given class-name.
* @method LazyAssertion isJsonString(string|callable $message = null, string $propertyPath = null) Assert that the given string is a valid json string.
* @method LazyAssertion isObject(string|callable $message = null, string $propertyPath = null) Determines that the provided value is an object.
* @method LazyAssertion isResource(string|callable $message = null, string $propertyPath = null) Assert that value is a resource.
* @method LazyAssertion isTraversable(string|callable $message = null, string $propertyPath = null) Assert that value is an array or a traversable object.
* @method LazyAssertion keyExists(string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key exists in an array.
* @method LazyAssertion keyIsset(string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key exists in an array/array-accessible object using isset().
* @method LazyAssertion keyNotExists(string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key does not exist in an array.
* @method LazyAssertion length(int $length, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string has a given length.
* @method LazyAssertion lessOrEqualThan(mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is less or equal than given limit.
* @method LazyAssertion lessThan(mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is less than given limit.
* @method LazyAssertion max(mixed $maxValue, string|callable $message = null, string $propertyPath = null) Assert that a number is smaller as a given limit.
* @method LazyAssertion maxCount(int $count, string|callable $message = null, string $propertyPath = null) Assert that the countable have at most $count elements.
* @method LazyAssertion maxLength(int $maxLength, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string value is not longer than $maxLength chars.
* @method LazyAssertion methodExists(mixed $object, string|callable $message = null, string $propertyPath = null) Determines that the named method is defined in the provided object.
* @method LazyAssertion min(mixed $minValue, string|callable $message = null, string $propertyPath = null) Assert that a value is at least as big as a given limit.
* @method LazyAssertion minCount(int $count, string|callable $message = null, string $propertyPath = null) Assert that the countable have at least $count elements.
* @method LazyAssertion minLength(int $minLength, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that a string is at least $minLength chars long.
* @method LazyAssertion noContent(string|callable $message = null, string $propertyPath = null) Assert that value is empty.
* @method LazyAssertion notBlank(string|callable $message = null, string $propertyPath = null) Assert that value is not blank.
* @method LazyAssertion notContains(string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string does not contains a sequence of chars.
* @method LazyAssertion notEmpty(string|callable $message = null, string $propertyPath = null) Assert that value is not empty.
* @method LazyAssertion notEmptyKey(string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key exists in an array/array-accessible object and its value is not empty.
* @method LazyAssertion notEq(mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are not equal (using ==).
* @method LazyAssertion notInArray(array $choices, string|callable $message = null, string $propertyPath = null) Assert that value is not in array of choices.
* @method LazyAssertion notIsInstanceOf(string $className, string|callable $message = null, string $propertyPath = null) Assert that value is not instance of given class-name.
* @method LazyAssertion notNull(string|callable $message = null, string $propertyPath = null) Assert that value is not null.
* @method LazyAssertion notRegex(string $pattern, string|callable $message = null, string $propertyPath = null) Assert that value does not match a regex.
* @method LazyAssertion notSame(mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are not the same (using ===).
* @method LazyAssertion null(string|callable $message = null, string $propertyPath = null) Assert that value is null.
* @method LazyAssertion numeric(string|callable $message = null, string $propertyPath = null) Assert that value is numeric.
* @method LazyAssertion objectOrClass(string|callable $message = null, string $propertyPath = null) Assert that the value is an object, or a class that exists.
* @method LazyAssertion phpVersion(mixed $version, string|callable $message = null, string $propertyPath = null) Assert on PHP version.
* @method LazyAssertion propertiesExist(array $properties, string|callable $message = null, string $propertyPath = null) Assert that the value is an object or class, and that the properties all exist.
* @method LazyAssertion propertyExists(string $property, string|callable $message = null, string $propertyPath = null) Assert that the value is an object or class, and that the property exists.
* @method LazyAssertion range(mixed $minValue, mixed $maxValue, string|callable $message = null, string $propertyPath = null) Assert that value is in range of numbers.
* @method LazyAssertion readable(string|callable $message = null, string $propertyPath = null) Assert that the value is something readable.
* @method LazyAssertion regex(string $pattern, string|callable $message = null, string $propertyPath = null) Assert that value matches a regex.
* @method LazyAssertion same(mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are the same (using ===).
* @method LazyAssertion satisfy(callable $callback, string|callable $message = null, string $propertyPath = null) Assert that the provided value is valid according to a callback.
* @method LazyAssertion scalar(string|callable $message = null, string $propertyPath = null) Assert that value is a PHP scalar.
* @method LazyAssertion startsWith(string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string starts with a sequence of chars.
* @method LazyAssertion string(string|callable $message = null, string $propertyPath = null) Assert that value is a string.
* @method LazyAssertion subclassOf(string $className, string|callable $message = null, string $propertyPath = null) Assert that value is subclass of given class-name.
* @method LazyAssertion true(string|callable $message = null, string $propertyPath = null) Assert that the value is boolean True.
* @method LazyAssertion uniqueValues(string|callable $message = null, string $propertyPath = null) Assert that values in array are unique (using strict equality).
* @method LazyAssertion url(string|callable $message = null, string $propertyPath = null) Assert that value is an URL.
* @method LazyAssertion uuid(string|callable $message = null, string $propertyPath = null) Assert that the given string is a valid UUID.
* @method LazyAssertion version(string $operator, string $version2, string|callable $message = null, string $propertyPath = null) Assert comparison of two versions.
* @method LazyAssertion writeable(string|callable $message = null, string $propertyPath = null) Assert that the value is something writeable.
* @method LazyAssertion all() Switch chain into validation mode for an array of values.
* @method LazyAssertion nullOr() Switch chain into mode allowing nulls, ignoring further assertions.
*/
class LazyAssertion
{
private $currentChainFailed = false;
private $alwaysTryAll = false;
private $thisChainTryAll = false;
private $currentChain;
private $errors = [];
/** @var string The class to use as AssertionChain factory */
private $assertClass = Assert::class;
/** @var string|LazyAssertionException The class to use for exceptions */
private $exceptionClass = LazyAssertionException::class;
/**
* @param mixed $value
* @param string|callable|null $defaultMessage
*
* @return static
*/
public function that($value, string $propertyPath = null, $defaultMessage = null)
{
$this->currentChainFailed = false;
$this->thisChainTryAll = false;
$assertClass = $this->assertClass;
$this->currentChain = $assertClass::that($value, $defaultMessage, $propertyPath);
return $this;
}
/**
* @return static
*/
public function tryAll()
{
if (!$this->currentChain) {
$this->alwaysTryAll = true;
}
$this->thisChainTryAll = true;
return $this;
}
/**
* @param string $method
* @param array $args
*
* @return static
*/
public function __call($method, $args)
{
if (false === $this->alwaysTryAll
&& false === $this->thisChainTryAll
&& true === $this->currentChainFailed
) {
return $this;
}
try {
\call_user_func_array([$this->currentChain, $method], $args);
} catch (AssertionFailedException $e) {
$this->errors[] = $e;
$this->currentChainFailed = true;
}
return $this;
}
/**
* @throws LazyAssertionException
*/
public function verifyNow(): bool
{
if ($this->errors) {
throw \call_user_func([$this->exceptionClass, 'fromErrors'], $this->errors);
}
return true;
}
/**
* @param string $className
*
* @return static
*/
public function setAssertClass(string $className): LazyAssertion
{
if (Assert::class !== $className && !\is_subclass_of($className, Assert::class)) {
throw new LogicException($className.' is not (a subclass of) '.Assert::class);
}
$this->assertClass = $className;
return $this;
}
/**
* @param string $className
*
* @return static
*/
public function setExceptionClass(string $className): LazyAssertion
{
if (LazyAssertionException::class !== $className && !\is_subclass_of($className, LazyAssertionException::class)) {
throw new LogicException($className.' is not (a subclass of) '.LazyAssertionException::class);
}
$this->exceptionClass = $className;
return $this;
}
}

View file

@ -0,0 +1,53 @@
<?php
/**
* Assert
*
* LICENSE
*
* This source file is subject to the MIT license that is bundled
* with this package in the file LICENSE.txt.
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to kontakt@beberlei.de so I can send you a copy immediately.
*/
namespace Assert;
class LazyAssertionException extends InvalidArgumentException
{
/**
* @var InvalidArgumentException[]
*/
private $errors = [];
/**
* @param InvalidArgumentException[] $errors
*/
public static function fromErrors(array $errors): self
{
$message = \sprintf('The following %d assertions failed:', \count($errors))."\n";
$i = 1;
foreach ($errors as $error) {
$message .= \sprintf("%d) %s: %s\n", $i++, $error->getPropertyPath(), $error->getMessage());
}
return new static($message, $errors);
}
public function __construct($message, array $errors)
{
parent::__construct($message, 0, null, null);
$this->errors = $errors;
}
/**
* @return InvalidArgumentException[]
*/
public function getErrorExceptions(): array
{
return $this->errors;
}
}

View file

@ -0,0 +1,72 @@
<?php
/**
* Assert
*
* LICENSE
*
* This source file is subject to the MIT license that is bundled
* with this package in the file LICENSE.txt.
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to kontakt@beberlei.de so I can send you a copy immediately.
*/
namespace Assert;
/**
* Start validation on a value, returns {@link AssertionChain}.
*
* The invocation of this method starts an assertion chain
* that is happening on the passed value.
*
* @param mixed $value
* @param string|callable|null $defaultMessage
* @param string $defaultPropertyPath
*
* @example
*
* \Assert\that($value)->notEmpty()->integer();
* \Assert\that($value)->nullOr()->string()->startsWith("Foo");
*
* The assertion chain can be stateful, that means be careful when you reuse
* it. You should never pass around the chain.
*/
function that($value, $defaultMessage = null, string $defaultPropertyPath = null): AssertionChain
{
return Assert::that($value, $defaultMessage, $defaultPropertyPath);
}
/**
* Start validation on a set of values, returns {@link AssertionChain}.
*
* @param mixed $values
* @param string|callable|null $defaultMessage
* @param string $defaultPropertyPath
*/
function thatAll($values, $defaultMessage = null, string $defaultPropertyPath = null): AssertionChain
{
return Assert::thatAll($values, $defaultMessage, $defaultPropertyPath);
}
/**
* Start validation and allow NULL, returns {@link AssertionChain}.
*
* @param mixed $value
* @param string|callable|null $defaultMessage
* @param string $defaultPropertyPath
*
* @deprecated In favour of Assert::thatNullOr($value, $defaultMessage = null, $defaultPropertyPath = null)
*/
function thatNullOr($value, $defaultMessage = null, string $defaultPropertyPath = null): AssertionChain
{
return Assert::thatNullOr($value, $defaultMessage, $defaultPropertyPath);
}
/**
* Create a lazy assertion object.
*/
function lazy(): LazyAssertion
{
return Assert::lazy();
}

19
vendor/christian-riesen/base32/LICENSE vendored Normal file
View file

@ -0,0 +1,19 @@
Copyright (c) 2013-2014 Christian Riesen
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.

View file

@ -0,0 +1,64 @@
base32
======
Base32 Encoder/Decoder for PHP according to [RFC 4648](https://tools.ietf.org/html/rfc4648).
![CI](https://github.com/ChristianRiesen/base32/workflows/CI/badge.svg)
[![Latest Stable Version](https://poser.pugx.org/christian-riesen/base32/v/stable.png)](https://packagist.org/packages/christian-riesen/base32) [![Total Downloads](https://poser.pugx.org/christian-riesen/base32/downloads.png)](https://packagist.org/packages/christian-riesen/base32) [![Latest Unstable Version](https://poser.pugx.org/christian-riesen/base32/v/unstable.png)](https://packagist.org/packages/christian-riesen/base32) [![License](https://poser.pugx.org/christian-riesen/base32/license.png)](https://packagist.org/packages/christian-riesen/base32)
Installation
-----
Use composer:
```bash
composer require christian-riesen/base32
```
Usage
-----
```php
<?php
// Include class or user autoloader
use Base32\Base32;
$string = 'fooba';
// $encoded contains now 'MZXW6YTB'
$encoded = Base32::encode($string);
// $decoded is again 'fooba'
$decoded = Base32::decode($encoded);
```
You can also use the extended hex alphabet by using the `Base32Hex` class instead.
About
=====
Initially created to work with the [one time password project](https://github.com/ChristianRiesen/otp), yet it can stand alone just as well as [Jordi Boggiano](http://seld.be/) kindly pointed out. It's the only Base32 implementation that passes the test vectors and contains unit tests as well.
Goal
----
Have a RFC compliant Base32 encoder and decoder. The implementation could be improved, but for now, it does the job and has unit tests. Ideally, the class can be enhanced while the unit tests keep passing.
Requirements
------------
Works on PHP 7.2 and later, including PHP 8.0.
Tests run on PHPUnit 9.5, with PHP 7.3 and later. For PHP 7.2, tests use an older PHPUnit version.
Author
------
Christian Riesen <chris.riesen@gmail.com> http://christianriesen.com
Acknowledgements
----------------
Base32 is mostly based on the work of https://github.com/NTICompass/PHP-Base32

View file

@ -0,0 +1,168 @@
<?php
declare(strict_types=1);
namespace Base32;
/**
* Base32 encoder and decoder.
*
* RFC 4648 compliant
*
* @see http://www.ietf.org/rfc/rfc4648.txt
* Some groundwork based on this class
* https://github.com/NTICompass/PHP-Base32
*
* @author Christian Riesen <chris.riesen@gmail.com>
* @author Sam Williams <sam@badcow.co>
*
* @see http://christianriesen.com
*
* @license MIT License see LICENSE file
*/
class Base32
{
/**
* Alphabet for encoding and decoding base32.
*
* @var string
*/
protected const ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=';
protected const BASE32HEX_PATTERN = '/[^A-Z2-7]/';
/**
* Maps the Base32 character to its corresponding bit value.
*/
protected const MAPPING = [
'=' => 0b00000,
'A' => 0b00000,
'B' => 0b00001,
'C' => 0b00010,
'D' => 0b00011,
'E' => 0b00100,
'F' => 0b00101,
'G' => 0b00110,
'H' => 0b00111,
'I' => 0b01000,
'J' => 0b01001,
'K' => 0b01010,
'L' => 0b01011,
'M' => 0b01100,
'N' => 0b01101,
'O' => 0b01110,
'P' => 0b01111,
'Q' => 0b10000,
'R' => 0b10001,
'S' => 0b10010,
'T' => 0b10011,
'U' => 0b10100,
'V' => 0b10101,
'W' => 0b10110,
'X' => 0b10111,
'Y' => 0b11000,
'Z' => 0b11001,
'2' => 0b11010,
'3' => 0b11011,
'4' => 0b11100,
'5' => 0b11101,
'6' => 0b11110,
'7' => 0b11111,
];
/**
* Encodes into base32.
*
* @param string $string Clear text string
*
* @return string Base32 encoded string
*/
public static function encode(string $string): string
{
// Empty string results in empty string
if ('' === $string) {
return '';
}
$encoded = '';
//Set the initial values
$n = $bitLen = $val = 0;
$len = \strlen($string);
//Pad the end of the string - this ensures that there are enough zeros
$string .= \str_repeat(\chr(0), 4);
//Explode string into integers
$chars = (array) \unpack('C*', $string, 0);
while ($n < $len || 0 !== $bitLen) {
//If the bit length has fallen below 5, shift left 8 and add the next character.
if ($bitLen < 5) {
$val = $val << 8;
$bitLen += 8;
$n++;
$val += $chars[$n];
}
$shift = $bitLen - 5;
$encoded .= ($n - (int)($bitLen > 8) > $len && 0 == $val) ? '=' : static::ALPHABET[$val >> $shift];
$val = $val & ((1 << $shift) - 1);
$bitLen -= 5;
}
return $encoded;
}
/**
* Decodes base32.
*
* @param string $base32String Base32 encoded string
*
* @return string Clear text string
*/
public static function decode(string $base32String): string
{
// Only work in upper cases
$base32String = \strtoupper($base32String);
// Remove anything that is not base32 alphabet
$base32String = \preg_replace(static::BASE32HEX_PATTERN, '', $base32String);
// Empty string results in empty string
if ('' === $base32String || null === $base32String) {
return '';
}
$decoded = '';
//Set the initial values
$len = \strlen($base32String);
$n = 0;
$bitLen = 5;
$val = static::MAPPING[$base32String[0]];
while ($n < $len) {
//If the bit length has fallen below 8, shift left 5 and add the next pentet.
if ($bitLen < 8) {
$val = $val << 5;
$bitLen += 5;
$n++;
$pentet = $base32String[$n] ?? '=';
//If the new pentet is padding, make this the last iteration.
if ('=' === $pentet) {
$n = $len;
}
$val += static::MAPPING[$pentet];
continue;
}
$shift = $bitLen - 8;
$decoded .= \chr($val >> $shift);
$val = $val & ((1 << $shift) - 1);
$bitLen -= 8;
}
return $decoded;
}
}

View file

@ -0,0 +1,68 @@
<?php
declare(strict_types=1);
namespace Base32;
/**
* Base32Hex encoder and decoder.
*
* RFC 4648 compliant
* @see http://www.ietf.org/rfc/rfc4648.txt
*
* @author Sam Williams <sam@badcow.co>
*
* @see http://christianriesen.com
*
* @license MIT License see LICENSE file
*/
class Base32Hex extends Base32
{
/**
* Alphabet for encoding and decoding base32 extended hex.
*
* @var string
*/
protected const ALPHABET = '0123456789ABCDEFGHIJKLMNOPQRSTUV=';
protected const BASE32HEX_PATTERN = '/[^0-9A-V]/';
/**
* Maps the Base32 character to its corresponding bit value.
*/
protected const MAPPING = [
'=' => 0b00000,
'0' => 0b00000,
'1' => 0b00001,
'2' => 0b00010,
'3' => 0b00011,
'4' => 0b00100,
'5' => 0b00101,
'6' => 0b00110,
'7' => 0b00111,
'8' => 0b01000,
'9' => 0b01001,
'A' => 0b01010,
'B' => 0b01011,
'C' => 0b01100,
'D' => 0b01101,
'E' => 0b01110,
'F' => 0b01111,
'G' => 0b10000,
'H' => 0b10001,
'I' => 0b10010,
'J' => 0b10011,
'K' => 0b10100,
'L' => 0b10101,
'M' => 0b10110,
'N' => 0b10111,
'O' => 0b11000,
'P' => 0b11001,
'Q' => 0b11010,
'R' => 0b11011,
'S' => 0b11100,
'T' => 0b11101,
'U' => 0b11110,
'V' => 0b11111,
];
}

View file

@ -111,6 +111,93 @@ return array(
'PHP_ICO' => $vendorDir . '/chrisjean/php-ico/class-php-ico.php', 'PHP_ICO' => $vendorDir . '/chrisjean/php-ico/class-php-ico.php',
'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php', 'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
'ReturnTypeWillChange' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php', 'ReturnTypeWillChange' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php',
'Safe\\DateTime' => $vendorDir . '/thecodingmachine/safe/lib/DateTime.php',
'Safe\\DateTimeImmutable' => $vendorDir . '/thecodingmachine/safe/lib/DateTimeImmutable.php',
'Safe\\Exceptions\\ApacheException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/ApacheException.php',
'Safe\\Exceptions\\ApcException' => $vendorDir . '/thecodingmachine/safe/deprecated/Exceptions/ApcException.php',
'Safe\\Exceptions\\ApcuException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/ApcuException.php',
'Safe\\Exceptions\\ArrayException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/ArrayException.php',
'Safe\\Exceptions\\Bzip2Exception' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/Bzip2Exception.php',
'Safe\\Exceptions\\CalendarException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/CalendarException.php',
'Safe\\Exceptions\\ClassobjException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/ClassobjException.php',
'Safe\\Exceptions\\ComException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/ComException.php',
'Safe\\Exceptions\\CubridException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/CubridException.php',
'Safe\\Exceptions\\CurlException' => $vendorDir . '/thecodingmachine/safe/lib/Exceptions/CurlException.php',
'Safe\\Exceptions\\DatetimeException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/DatetimeException.php',
'Safe\\Exceptions\\DirException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/DirException.php',
'Safe\\Exceptions\\EioException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/EioException.php',
'Safe\\Exceptions\\ErrorfuncException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/ErrorfuncException.php',
'Safe\\Exceptions\\ExecException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/ExecException.php',
'Safe\\Exceptions\\FileinfoException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/FileinfoException.php',
'Safe\\Exceptions\\FilesystemException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/FilesystemException.php',
'Safe\\Exceptions\\FilterException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/FilterException.php',
'Safe\\Exceptions\\FpmException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/FpmException.php',
'Safe\\Exceptions\\FtpException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/FtpException.php',
'Safe\\Exceptions\\FunchandException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/FunchandException.php',
'Safe\\Exceptions\\GettextException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/GettextException.php',
'Safe\\Exceptions\\GmpException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/GmpException.php',
'Safe\\Exceptions\\GnupgException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/GnupgException.php',
'Safe\\Exceptions\\HashException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/HashException.php',
'Safe\\Exceptions\\IbaseException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/IbaseException.php',
'Safe\\Exceptions\\IbmDb2Exception' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/IbmDb2Exception.php',
'Safe\\Exceptions\\IconvException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/IconvException.php',
'Safe\\Exceptions\\ImageException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/ImageException.php',
'Safe\\Exceptions\\ImapException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/ImapException.php',
'Safe\\Exceptions\\InfoException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/InfoException.php',
'Safe\\Exceptions\\InotifyException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/InotifyException.php',
'Safe\\Exceptions\\JsonException' => $vendorDir . '/thecodingmachine/safe/lib/Exceptions/JsonException.php',
'Safe\\Exceptions\\LdapException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/LdapException.php',
'Safe\\Exceptions\\LibeventException' => $vendorDir . '/thecodingmachine/safe/deprecated/Exceptions/LibeventException.php',
'Safe\\Exceptions\\LibxmlException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/LibxmlException.php',
'Safe\\Exceptions\\LzfException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/LzfException.php',
'Safe\\Exceptions\\MailparseException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/MailparseException.php',
'Safe\\Exceptions\\MbstringException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/MbstringException.php',
'Safe\\Exceptions\\MiscException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/MiscException.php',
'Safe\\Exceptions\\MssqlException' => $vendorDir . '/thecodingmachine/safe/deprecated/Exceptions/MssqlException.php',
'Safe\\Exceptions\\MysqlException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/MysqlException.php',
'Safe\\Exceptions\\MysqliException' => $vendorDir . '/thecodingmachine/safe/deprecated/Exceptions/MysqliException.php',
'Safe\\Exceptions\\NetworkException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/NetworkException.php',
'Safe\\Exceptions\\Oci8Exception' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/Oci8Exception.php',
'Safe\\Exceptions\\OpcacheException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/OpcacheException.php',
'Safe\\Exceptions\\OpensslException' => $vendorDir . '/thecodingmachine/safe/lib/Exceptions/OpensslException.php',
'Safe\\Exceptions\\OutcontrolException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/OutcontrolException.php',
'Safe\\Exceptions\\PasswordException' => $vendorDir . '/thecodingmachine/safe/deprecated/Exceptions/PasswordException.php',
'Safe\\Exceptions\\PcntlException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/PcntlException.php',
'Safe\\Exceptions\\PcreException' => $vendorDir . '/thecodingmachine/safe/lib/Exceptions/PcreException.php',
'Safe\\Exceptions\\PgsqlException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/PgsqlException.php',
'Safe\\Exceptions\\PosixException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/PosixException.php',
'Safe\\Exceptions\\PsException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/PsException.php',
'Safe\\Exceptions\\PspellException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/PspellException.php',
'Safe\\Exceptions\\ReadlineException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/ReadlineException.php',
'Safe\\Exceptions\\RpminfoException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/RpminfoException.php',
'Safe\\Exceptions\\RrdException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/RrdException.php',
'Safe\\Exceptions\\SafeExceptionInterface' => $vendorDir . '/thecodingmachine/safe/lib/Exceptions/SafeExceptionInterface.php',
'Safe\\Exceptions\\SemException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/SemException.php',
'Safe\\Exceptions\\SessionException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/SessionException.php',
'Safe\\Exceptions\\ShmopException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/ShmopException.php',
'Safe\\Exceptions\\SimplexmlException' => $vendorDir . '/thecodingmachine/safe/lib/Exceptions/SimplexmlException.php',
'Safe\\Exceptions\\SocketsException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/SocketsException.php',
'Safe\\Exceptions\\SodiumException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/SodiumException.php',
'Safe\\Exceptions\\SolrException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/SolrException.php',
'Safe\\Exceptions\\SplException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/SplException.php',
'Safe\\Exceptions\\SqlsrvException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/SqlsrvException.php',
'Safe\\Exceptions\\SsdeepException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/SsdeepException.php',
'Safe\\Exceptions\\Ssh2Exception' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/Ssh2Exception.php',
'Safe\\Exceptions\\StatsException' => $vendorDir . '/thecodingmachine/safe/deprecated/Exceptions/StatsException.php',
'Safe\\Exceptions\\StreamException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/StreamException.php',
'Safe\\Exceptions\\StringsException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/StringsException.php',
'Safe\\Exceptions\\SwooleException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/SwooleException.php',
'Safe\\Exceptions\\UodbcException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/UodbcException.php',
'Safe\\Exceptions\\UopzException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/UopzException.php',
'Safe\\Exceptions\\UrlException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/UrlException.php',
'Safe\\Exceptions\\VarException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/VarException.php',
'Safe\\Exceptions\\XdiffException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/XdiffException.php',
'Safe\\Exceptions\\XmlException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/XmlException.php',
'Safe\\Exceptions\\XmlrpcException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/XmlrpcException.php',
'Safe\\Exceptions\\YamlException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/YamlException.php',
'Safe\\Exceptions\\YazException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/YazException.php',
'Safe\\Exceptions\\ZipException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/ZipException.php',
'Safe\\Exceptions\\ZlibException' => $vendorDir . '/thecodingmachine/safe/generated/Exceptions/ZlibException.php',
'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php', 'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php', 'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php', 'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',

View file

@ -23,8 +23,97 @@ return array(
'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php', 'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php',
'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php', 'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
'e39a8b23c42d4e1452234d762b03835a' => $vendorDir . '/ramsey/uuid/src/functions.php', 'e39a8b23c42d4e1452234d762b03835a' => $vendorDir . '/ramsey/uuid/src/functions.php',
'a4ecaeafb8cfb009ad0e052c90355e98' => $vendorDir . '/beberlei/assert/lib/Assert/functions.php',
'1f87db08236948d07391152dccb70f04' => $vendorDir . '/google/apiclient-services/autoload.php', '1f87db08236948d07391152dccb70f04' => $vendorDir . '/google/apiclient-services/autoload.php',
'b067bc7112e384b61c701452d53a14a8' => $vendorDir . '/mtdowling/jmespath.php/src/JmesPath.php', 'b067bc7112e384b61c701452d53a14a8' => $vendorDir . '/mtdowling/jmespath.php/src/JmesPath.php',
'51fcf4e06c07cc00c920b44bcd900e7a' => $vendorDir . '/thecodingmachine/safe/deprecated/apc.php',
'288267919fedd3829a7732b5fb202197' => $vendorDir . '/thecodingmachine/safe/deprecated/array.php',
'a88cd08cfbf1600f7d5de6e587eee1fa' => $vendorDir . '/thecodingmachine/safe/deprecated/datetime.php',
'47f619d9197b36cf5ab70738d7743fe2' => $vendorDir . '/thecodingmachine/safe/deprecated/libevent.php',
'f1f7d69cca064c8f779d4a4cba463e11' => $vendorDir . '/thecodingmachine/safe/deprecated/misc.php',
'213c1c2258e2e5aa409a0af3e993b3a9' => $vendorDir . '/thecodingmachine/safe/deprecated/password.php',
'ea6bb8a12ef9b68f6ada99058e530760' => $vendorDir . '/thecodingmachine/safe/deprecated/mssql.php',
'9a29089eb3ce41a446744c68a00f118c' => $vendorDir . '/thecodingmachine/safe/deprecated/stats.php',
'd5947c9df62650029c674c79176af68d' => $vendorDir . '/thecodingmachine/safe/deprecated/strings.php',
'72243e5536b63e298acb6476f01f1aff' => $vendorDir . '/thecodingmachine/safe/lib/special_cases.php',
'09f92ed6301edc510574c196c2b7d1af' => $vendorDir . '/thecodingmachine/safe/deprecated/mysqli.php',
'3f648889e687f31c52f949ba8a9d0873' => $vendorDir . '/thecodingmachine/safe/generated/apache.php',
'eeb4581d958421a4244aaa4167c6a575' => $vendorDir . '/thecodingmachine/safe/generated/apcu.php',
'04cb0b3c1dac5b5ddb23c14e3d66dbe9' => $vendorDir . '/thecodingmachine/safe/generated/array.php',
'450b332a74a9a21e043c5e953485a791' => $vendorDir . '/thecodingmachine/safe/generated/bzip2.php',
'6e9b7954ecfd7cbb9ca239319d1acdb6' => $vendorDir . '/thecodingmachine/safe/generated/calendar.php',
'2c6d7e8bd2de9a272a9d4d43b0a4304a' => $vendorDir . '/thecodingmachine/safe/generated/classobj.php',
'0b8231c1ad0865447c988a4c16b4001f' => $vendorDir . '/thecodingmachine/safe/generated/com.php',
'7643a71fe1c3256058c8fee234cb86e5' => $vendorDir . '/thecodingmachine/safe/generated/cubrid.php',
'68e1365710575942efc1d55000032cee' => $vendorDir . '/thecodingmachine/safe/generated/curl.php',
'02fd26bca803106c5b942a7197c3ad8b' => $vendorDir . '/thecodingmachine/safe/generated/datetime.php',
'f4817dcbd956cd221b1c31f6fbd5749c' => $vendorDir . '/thecodingmachine/safe/generated/dir.php',
'51c3f2d10ca61a70dbcea0e38d8e902d' => $vendorDir . '/thecodingmachine/safe/generated/eio.php',
'1d34f34327ca3e81535963016e3be2c3' => $vendorDir . '/thecodingmachine/safe/generated/errorfunc.php',
'4fd0ba2d3717b0424d474bebfdafa2b4' => $vendorDir . '/thecodingmachine/safe/generated/exec.php',
'98f4dae054bc7fb19c13be14935cbdd3' => $vendorDir . '/thecodingmachine/safe/generated/fileinfo.php',
'5530ae063ba88323eaf0a07904efdf85' => $vendorDir . '/thecodingmachine/safe/generated/filesystem.php',
'633f4f134975d70e97bddad83348e91a' => $vendorDir . '/thecodingmachine/safe/generated/filter.php',
'fbd163fc68c5faf73d5ed4002ffd836d' => $vendorDir . '/thecodingmachine/safe/generated/fpm.php',
'21b511999d61411fab0692ff8795bbed' => $vendorDir . '/thecodingmachine/safe/generated/ftp.php',
'85fbd73fc92365cd90526b0ea03cae3a' => $vendorDir . '/thecodingmachine/safe/generated/funchand.php',
'a2e4c6dfdbf36f56f1945ddcbd54e289' => $vendorDir . '/thecodingmachine/safe/generated/gettext.php',
'51df9c146e0b7dcbdf358d8abd24dbdc' => $vendorDir . '/thecodingmachine/safe/generated/gmp.php',
'93bb7fe678d7dcfb1322f8e3475a48b0' => $vendorDir . '/thecodingmachine/safe/generated/gnupg.php',
'c171ba99cf316379ff66468392bf4950' => $vendorDir . '/thecodingmachine/safe/generated/hash.php',
'5ab4aad4c28e468209fbfcceb2e5e6a5' => $vendorDir . '/thecodingmachine/safe/generated/ibase.php',
'4d57409c5e8e576b0c64c08d9d731cfb' => $vendorDir . '/thecodingmachine/safe/generated/ibmDb2.php',
'eeb246d5403972a9d62106e4a4883496' => $vendorDir . '/thecodingmachine/safe/generated/iconv.php',
'c28a05f498c01b810a714f7214b7a8da' => $vendorDir . '/thecodingmachine/safe/generated/image.php',
'8063cd92acdf00fd978b5599eb7cc142' => $vendorDir . '/thecodingmachine/safe/generated/imap.php',
'8bd26dbe768e9c9599edad7b198e5446' => $vendorDir . '/thecodingmachine/safe/generated/info.php',
'd4362910bde43c0f956b52527effd7d4' => $vendorDir . '/thecodingmachine/safe/generated/inotify.php',
'696ba49197d9b55f0428a12bb5a818e1' => $vendorDir . '/thecodingmachine/safe/generated/json.php',
'9818aaa99c8647c63f8ef62b7a368160' => $vendorDir . '/thecodingmachine/safe/generated/ldap.php',
'bcf523ff2a195eb08e0fbb668ed784d0' => $vendorDir . '/thecodingmachine/safe/generated/libxml.php',
'68be68a9a8b95bb56cab6109ff03bc88' => $vendorDir . '/thecodingmachine/safe/generated/lzf.php',
'bdca804bb0904ea9f53f328dfc0bb8a5' => $vendorDir . '/thecodingmachine/safe/generated/mailparse.php',
'b0a3fcac3eaf55445796d6af26b89366' => $vendorDir . '/thecodingmachine/safe/generated/mbstring.php',
'98de16b8db03eb0cb4d318b4402215a6' => $vendorDir . '/thecodingmachine/safe/generated/misc.php',
'7cefd81607cd21b8b3a15656eb6465f5' => $vendorDir . '/thecodingmachine/safe/generated/mysql.php',
'cbac956836b72483dcff1ac39d5c0a0f' => $vendorDir . '/thecodingmachine/safe/generated/network.php',
'6c8f89dfbdc117d7871f572269363f25' => $vendorDir . '/thecodingmachine/safe/generated/oci8.php',
'169a669966a45c06bf55ed029122729b' => $vendorDir . '/thecodingmachine/safe/generated/opcache.php',
'def61bf4fecd4d4bca7354919cd69302' => $vendorDir . '/thecodingmachine/safe/generated/openssl.php',
'26bb010649a6d32d4120181458aa6ef2' => $vendorDir . '/thecodingmachine/safe/generated/outcontrol.php',
'002ebcb842e2c0d5b7f67fe64cc93158' => $vendorDir . '/thecodingmachine/safe/generated/pcntl.php',
'86df38612982dade72c7085ce7eca81f' => $vendorDir . '/thecodingmachine/safe/generated/pcre.php',
'1fc22f445c69ea8706e82fce301c0831' => $vendorDir . '/thecodingmachine/safe/generated/pgsql.php',
'c70b42561584f7144bff38cd63c4eef3' => $vendorDir . '/thecodingmachine/safe/generated/posix.php',
'9923214639c32ca5173db03a177d3b63' => $vendorDir . '/thecodingmachine/safe/generated/ps.php',
'7e9c3f8eae2b5bf42205c4f1295cb7a7' => $vendorDir . '/thecodingmachine/safe/generated/pspell.php',
'91aa91f6245c349c2e2e88bd0025f199' => $vendorDir . '/thecodingmachine/safe/generated/readline.php',
'd43773cacb9e5e8e897aa255e32007d1' => $vendorDir . '/thecodingmachine/safe/generated/rpminfo.php',
'f053a3849e9e8383762b34b91db0320b' => $vendorDir . '/thecodingmachine/safe/generated/rrd.php',
'775b964f72f827a1bf87c65ab5b10800' => $vendorDir . '/thecodingmachine/safe/generated/sem.php',
'816428bd69c29ab5e1ed622af5dca0cd' => $vendorDir . '/thecodingmachine/safe/generated/session.php',
'5093e233bedbefaef0df262bfbab0a5c' => $vendorDir . '/thecodingmachine/safe/generated/shmop.php',
'b080617b1d949683c2e37f8f01dc0e15' => $vendorDir . '/thecodingmachine/safe/generated/sockets.php',
'2708aa182ddcfe6ce27c96acaaa40f69' => $vendorDir . '/thecodingmachine/safe/generated/sodium.php',
'f1b96cb260a5baeea9a7285cda82a1ec' => $vendorDir . '/thecodingmachine/safe/generated/solr.php',
'3fd8853757d0fe3557c179efb807afeb' => $vendorDir . '/thecodingmachine/safe/generated/spl.php',
'9312ce96a51c846913fcda5f186d58dd' => $vendorDir . '/thecodingmachine/safe/generated/sqlsrv.php',
'd3eb383ad0b8b962b29dc4afd29d6715' => $vendorDir . '/thecodingmachine/safe/generated/ssdeep.php',
'42a09bc448f441a0b9f9367ea975c0bf' => $vendorDir . '/thecodingmachine/safe/generated/ssh2.php',
'ef711077d356d1b33ca0b10b67b0be8f' => $vendorDir . '/thecodingmachine/safe/generated/stream.php',
'764b09f6df081cbb2807b97c6ace3866' => $vendorDir . '/thecodingmachine/safe/generated/strings.php',
'ef241678769fee4a44aaa288f3b78aa1' => $vendorDir . '/thecodingmachine/safe/generated/swoole.php',
'0efc8f6778cba932b9e2a89e28de2452' => $vendorDir . '/thecodingmachine/safe/generated/uodbc.php',
'd383d32907b98af53ee9208c62204fd0' => $vendorDir . '/thecodingmachine/safe/generated/uopz.php',
'2fd2e4060f7fe772660f002ce38f0b71' => $vendorDir . '/thecodingmachine/safe/generated/url.php',
'782249e03deebeaf57b9991ff5493aa0' => $vendorDir . '/thecodingmachine/safe/generated/var.php',
'344440cd1cd7200fdb4f12af0d3c587f' => $vendorDir . '/thecodingmachine/safe/generated/xdiff.php',
'3599f369219c658a5fb6c4fe66832f62' => $vendorDir . '/thecodingmachine/safe/generated/xml.php',
'7fcd313da9fae337051b091b3492c21b' => $vendorDir . '/thecodingmachine/safe/generated/xmlrpc.php',
'd668c74cfa92d893b582356733d9a80e' => $vendorDir . '/thecodingmachine/safe/generated/yaml.php',
'4af1dca6db8c527c6eed27bff85ff0e5' => $vendorDir . '/thecodingmachine/safe/generated/yaz.php',
'fe43ca06499ac37bc2dedd823af71eb5' => $vendorDir . '/thecodingmachine/safe/generated/zip.php',
'356736db98a6834f0a886b8d509b0ecd' => $vendorDir . '/thecodingmachine/safe/generated/zlib.php',
'e8aa6e4b5a1db2f56ae794f1505391a8' => $vendorDir . '/amphp/amp/lib/functions.php', 'e8aa6e4b5a1db2f56ae794f1505391a8' => $vendorDir . '/amphp/amp/lib/functions.php',
'76cd0796156622033397994f25b0d8fc' => $vendorDir . '/amphp/amp/lib/Internal/functions.php', '76cd0796156622033397994f25b0d8fc' => $vendorDir . '/amphp/amp/lib/Internal/functions.php',
'8a9dc1de0ca7e01f3e08231539562f61' => $vendorDir . '/aws/aws-sdk-php/src/functions.php', '8a9dc1de0ca7e01f3e08231539562f61' => $vendorDir . '/aws/aws-sdk-php/src/functions.php',

View file

@ -61,6 +61,7 @@ return array(
'ParagonIE\\ConstantTime\\' => array($vendorDir . '/paragonie/constant_time_encoding/src'), 'ParagonIE\\ConstantTime\\' => array($vendorDir . '/paragonie/constant_time_encoding/src'),
'PHPMailer\\PHPMailer\\' => array($vendorDir . '/phpmailer/phpmailer/src'), 'PHPMailer\\PHPMailer\\' => array($vendorDir . '/phpmailer/phpmailer/src'),
'OneSignal\\' => array($vendorDir . '/norkunas/onesignal-php-api/src'), 'OneSignal\\' => array($vendorDir . '/norkunas/onesignal-php-api/src'),
'OTPHP\\' => array($vendorDir . '/spomky-labs/otphp/src'),
'Nyholm\\Psr7\\' => array($vendorDir . '/nyholm/psr7/src'), 'Nyholm\\Psr7\\' => array($vendorDir . '/nyholm/psr7/src'),
'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'), 'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
'JmesPath\\' => array($vendorDir . '/mtdowling/jmespath.php/src'), 'JmesPath\\' => array($vendorDir . '/mtdowling/jmespath.php/src'),
@ -79,8 +80,10 @@ return array(
'Carbon\\' => array($vendorDir . '/nesbot/carbon/src/Carbon'), 'Carbon\\' => array($vendorDir . '/nesbot/carbon/src/Carbon'),
'Bunny\\Storage\\' => array($vendorDir . '/bunnycdn/storage/src'), 'Bunny\\Storage\\' => array($vendorDir . '/bunnycdn/storage/src'),
'Brick\\Math\\' => array($vendorDir . '/brick/math/src'), 'Brick\\Math\\' => array($vendorDir . '/brick/math/src'),
'Base32\\' => array($vendorDir . '/christian-riesen/base32/src'),
'BackblazeB2\\' => array($vendorDir . '/gliterd/backblaze-b2/src'), 'BackblazeB2\\' => array($vendorDir . '/gliterd/backblaze-b2/src'),
'Aws\\' => array($vendorDir . '/aws/aws-sdk-php/src'), 'Aws\\' => array($vendorDir . '/aws/aws-sdk-php/src'),
'Assert\\' => array($vendorDir . '/beberlei/assert/lib/Assert'),
'Amp\\' => array($vendorDir . '/amphp/amp/lib'), 'Amp\\' => array($vendorDir . '/amphp/amp/lib'),
'Abraham\\TwitterOAuth\\' => array($vendorDir . '/abraham/twitteroauth/src'), 'Abraham\\TwitterOAuth\\' => array($vendorDir . '/abraham/twitteroauth/src'),
); );

View file

@ -24,8 +24,97 @@ class ComposerStaticInitc3a61dba26daada128f5891f1a57c504
'b6b991a57620e2fb6b2f66f03fe9ddc2' => __DIR__ . '/..' . '/symfony/string/Resources/functions.php', 'b6b991a57620e2fb6b2f66f03fe9ddc2' => __DIR__ . '/..' . '/symfony/string/Resources/functions.php',
'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php', 'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
'e39a8b23c42d4e1452234d762b03835a' => __DIR__ . '/..' . '/ramsey/uuid/src/functions.php', 'e39a8b23c42d4e1452234d762b03835a' => __DIR__ . '/..' . '/ramsey/uuid/src/functions.php',
'a4ecaeafb8cfb009ad0e052c90355e98' => __DIR__ . '/..' . '/beberlei/assert/lib/Assert/functions.php',
'1f87db08236948d07391152dccb70f04' => __DIR__ . '/..' . '/google/apiclient-services/autoload.php', '1f87db08236948d07391152dccb70f04' => __DIR__ . '/..' . '/google/apiclient-services/autoload.php',
'b067bc7112e384b61c701452d53a14a8' => __DIR__ . '/..' . '/mtdowling/jmespath.php/src/JmesPath.php', 'b067bc7112e384b61c701452d53a14a8' => __DIR__ . '/..' . '/mtdowling/jmespath.php/src/JmesPath.php',
'51fcf4e06c07cc00c920b44bcd900e7a' => __DIR__ . '/..' . '/thecodingmachine/safe/deprecated/apc.php',
'288267919fedd3829a7732b5fb202197' => __DIR__ . '/..' . '/thecodingmachine/safe/deprecated/array.php',
'a88cd08cfbf1600f7d5de6e587eee1fa' => __DIR__ . '/..' . '/thecodingmachine/safe/deprecated/datetime.php',
'47f619d9197b36cf5ab70738d7743fe2' => __DIR__ . '/..' . '/thecodingmachine/safe/deprecated/libevent.php',
'f1f7d69cca064c8f779d4a4cba463e11' => __DIR__ . '/..' . '/thecodingmachine/safe/deprecated/misc.php',
'213c1c2258e2e5aa409a0af3e993b3a9' => __DIR__ . '/..' . '/thecodingmachine/safe/deprecated/password.php',
'ea6bb8a12ef9b68f6ada99058e530760' => __DIR__ . '/..' . '/thecodingmachine/safe/deprecated/mssql.php',
'9a29089eb3ce41a446744c68a00f118c' => __DIR__ . '/..' . '/thecodingmachine/safe/deprecated/stats.php',
'd5947c9df62650029c674c79176af68d' => __DIR__ . '/..' . '/thecodingmachine/safe/deprecated/strings.php',
'72243e5536b63e298acb6476f01f1aff' => __DIR__ . '/..' . '/thecodingmachine/safe/lib/special_cases.php',
'09f92ed6301edc510574c196c2b7d1af' => __DIR__ . '/..' . '/thecodingmachine/safe/deprecated/mysqli.php',
'3f648889e687f31c52f949ba8a9d0873' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/apache.php',
'eeb4581d958421a4244aaa4167c6a575' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/apcu.php',
'04cb0b3c1dac5b5ddb23c14e3d66dbe9' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/array.php',
'450b332a74a9a21e043c5e953485a791' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/bzip2.php',
'6e9b7954ecfd7cbb9ca239319d1acdb6' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/calendar.php',
'2c6d7e8bd2de9a272a9d4d43b0a4304a' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/classobj.php',
'0b8231c1ad0865447c988a4c16b4001f' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/com.php',
'7643a71fe1c3256058c8fee234cb86e5' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/cubrid.php',
'68e1365710575942efc1d55000032cee' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/curl.php',
'02fd26bca803106c5b942a7197c3ad8b' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/datetime.php',
'f4817dcbd956cd221b1c31f6fbd5749c' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/dir.php',
'51c3f2d10ca61a70dbcea0e38d8e902d' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/eio.php',
'1d34f34327ca3e81535963016e3be2c3' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/errorfunc.php',
'4fd0ba2d3717b0424d474bebfdafa2b4' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/exec.php',
'98f4dae054bc7fb19c13be14935cbdd3' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/fileinfo.php',
'5530ae063ba88323eaf0a07904efdf85' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/filesystem.php',
'633f4f134975d70e97bddad83348e91a' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/filter.php',
'fbd163fc68c5faf73d5ed4002ffd836d' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/fpm.php',
'21b511999d61411fab0692ff8795bbed' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/ftp.php',
'85fbd73fc92365cd90526b0ea03cae3a' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/funchand.php',
'a2e4c6dfdbf36f56f1945ddcbd54e289' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/gettext.php',
'51df9c146e0b7dcbdf358d8abd24dbdc' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/gmp.php',
'93bb7fe678d7dcfb1322f8e3475a48b0' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/gnupg.php',
'c171ba99cf316379ff66468392bf4950' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/hash.php',
'5ab4aad4c28e468209fbfcceb2e5e6a5' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/ibase.php',
'4d57409c5e8e576b0c64c08d9d731cfb' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/ibmDb2.php',
'eeb246d5403972a9d62106e4a4883496' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/iconv.php',
'c28a05f498c01b810a714f7214b7a8da' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/image.php',
'8063cd92acdf00fd978b5599eb7cc142' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/imap.php',
'8bd26dbe768e9c9599edad7b198e5446' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/info.php',
'd4362910bde43c0f956b52527effd7d4' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/inotify.php',
'696ba49197d9b55f0428a12bb5a818e1' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/json.php',
'9818aaa99c8647c63f8ef62b7a368160' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/ldap.php',
'bcf523ff2a195eb08e0fbb668ed784d0' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/libxml.php',
'68be68a9a8b95bb56cab6109ff03bc88' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/lzf.php',
'bdca804bb0904ea9f53f328dfc0bb8a5' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/mailparse.php',
'b0a3fcac3eaf55445796d6af26b89366' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/mbstring.php',
'98de16b8db03eb0cb4d318b4402215a6' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/misc.php',
'7cefd81607cd21b8b3a15656eb6465f5' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/mysql.php',
'cbac956836b72483dcff1ac39d5c0a0f' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/network.php',
'6c8f89dfbdc117d7871f572269363f25' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/oci8.php',
'169a669966a45c06bf55ed029122729b' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/opcache.php',
'def61bf4fecd4d4bca7354919cd69302' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/openssl.php',
'26bb010649a6d32d4120181458aa6ef2' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/outcontrol.php',
'002ebcb842e2c0d5b7f67fe64cc93158' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/pcntl.php',
'86df38612982dade72c7085ce7eca81f' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/pcre.php',
'1fc22f445c69ea8706e82fce301c0831' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/pgsql.php',
'c70b42561584f7144bff38cd63c4eef3' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/posix.php',
'9923214639c32ca5173db03a177d3b63' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/ps.php',
'7e9c3f8eae2b5bf42205c4f1295cb7a7' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/pspell.php',
'91aa91f6245c349c2e2e88bd0025f199' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/readline.php',
'd43773cacb9e5e8e897aa255e32007d1' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/rpminfo.php',
'f053a3849e9e8383762b34b91db0320b' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/rrd.php',
'775b964f72f827a1bf87c65ab5b10800' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/sem.php',
'816428bd69c29ab5e1ed622af5dca0cd' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/session.php',
'5093e233bedbefaef0df262bfbab0a5c' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/shmop.php',
'b080617b1d949683c2e37f8f01dc0e15' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/sockets.php',
'2708aa182ddcfe6ce27c96acaaa40f69' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/sodium.php',
'f1b96cb260a5baeea9a7285cda82a1ec' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/solr.php',
'3fd8853757d0fe3557c179efb807afeb' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/spl.php',
'9312ce96a51c846913fcda5f186d58dd' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/sqlsrv.php',
'd3eb383ad0b8b962b29dc4afd29d6715' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/ssdeep.php',
'42a09bc448f441a0b9f9367ea975c0bf' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/ssh2.php',
'ef711077d356d1b33ca0b10b67b0be8f' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/stream.php',
'764b09f6df081cbb2807b97c6ace3866' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/strings.php',
'ef241678769fee4a44aaa288f3b78aa1' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/swoole.php',
'0efc8f6778cba932b9e2a89e28de2452' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/uodbc.php',
'd383d32907b98af53ee9208c62204fd0' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/uopz.php',
'2fd2e4060f7fe772660f002ce38f0b71' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/url.php',
'782249e03deebeaf57b9991ff5493aa0' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/var.php',
'344440cd1cd7200fdb4f12af0d3c587f' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/xdiff.php',
'3599f369219c658a5fb6c4fe66832f62' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/xml.php',
'7fcd313da9fae337051b091b3492c21b' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/xmlrpc.php',
'd668c74cfa92d893b582356733d9a80e' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/yaml.php',
'4af1dca6db8c527c6eed27bff85ff0e5' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/yaz.php',
'fe43ca06499ac37bc2dedd823af71eb5' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/zip.php',
'356736db98a6834f0a886b8d509b0ecd' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/zlib.php',
'e8aa6e4b5a1db2f56ae794f1505391a8' => __DIR__ . '/..' . '/amphp/amp/lib/functions.php', 'e8aa6e4b5a1db2f56ae794f1505391a8' => __DIR__ . '/..' . '/amphp/amp/lib/functions.php',
'76cd0796156622033397994f25b0d8fc' => __DIR__ . '/..' . '/amphp/amp/lib/Internal/functions.php', '76cd0796156622033397994f25b0d8fc' => __DIR__ . '/..' . '/amphp/amp/lib/Internal/functions.php',
'8a9dc1de0ca7e01f3e08231539562f61' => __DIR__ . '/..' . '/aws/aws-sdk-php/src/functions.php', '8a9dc1de0ca7e01f3e08231539562f61' => __DIR__ . '/..' . '/aws/aws-sdk-php/src/functions.php',
@ -113,6 +202,7 @@ class ComposerStaticInitc3a61dba26daada128f5891f1a57c504
'O' => 'O' =>
array ( array (
'OneSignal\\' => 10, 'OneSignal\\' => 10,
'OTPHP\\' => 6,
), ),
'N' => 'N' =>
array ( array (
@ -158,11 +248,13 @@ class ComposerStaticInitc3a61dba26daada128f5891f1a57c504
array ( array (
'Bunny\\Storage\\' => 14, 'Bunny\\Storage\\' => 14,
'Brick\\Math\\' => 11, 'Brick\\Math\\' => 11,
'Base32\\' => 7,
'BackblazeB2\\' => 12, 'BackblazeB2\\' => 12,
), ),
'A' => 'A' =>
array ( array (
'Aws\\' => 4, 'Aws\\' => 4,
'Assert\\' => 7,
'Amp\\' => 4, 'Amp\\' => 4,
'Abraham\\TwitterOAuth\\' => 21, 'Abraham\\TwitterOAuth\\' => 21,
), ),
@ -391,6 +483,10 @@ class ComposerStaticInitc3a61dba26daada128f5891f1a57c504
array ( array (
0 => __DIR__ . '/..' . '/norkunas/onesignal-php-api/src', 0 => __DIR__ . '/..' . '/norkunas/onesignal-php-api/src',
), ),
'OTPHP\\' =>
array (
0 => __DIR__ . '/..' . '/spomky-labs/otphp/src',
),
'Nyholm\\Psr7\\' => 'Nyholm\\Psr7\\' =>
array ( array (
0 => __DIR__ . '/..' . '/nyholm/psr7/src', 0 => __DIR__ . '/..' . '/nyholm/psr7/src',
@ -463,6 +559,10 @@ class ComposerStaticInitc3a61dba26daada128f5891f1a57c504
array ( array (
0 => __DIR__ . '/..' . '/brick/math/src', 0 => __DIR__ . '/..' . '/brick/math/src',
), ),
'Base32\\' =>
array (
0 => __DIR__ . '/..' . '/christian-riesen/base32/src',
),
'BackblazeB2\\' => 'BackblazeB2\\' =>
array ( array (
0 => __DIR__ . '/..' . '/gliterd/backblaze-b2/src', 0 => __DIR__ . '/..' . '/gliterd/backblaze-b2/src',
@ -471,6 +571,10 @@ class ComposerStaticInitc3a61dba26daada128f5891f1a57c504
array ( array (
0 => __DIR__ . '/..' . '/aws/aws-sdk-php/src', 0 => __DIR__ . '/..' . '/aws/aws-sdk-php/src',
), ),
'Assert\\' =>
array (
0 => __DIR__ . '/..' . '/beberlei/assert/lib/Assert',
),
'Amp\\' => 'Amp\\' =>
array ( array (
0 => __DIR__ . '/..' . '/amphp/amp/lib', 0 => __DIR__ . '/..' . '/amphp/amp/lib',
@ -608,6 +712,93 @@ class ComposerStaticInitc3a61dba26daada128f5891f1a57c504
'PHP_ICO' => __DIR__ . '/..' . '/chrisjean/php-ico/class-php-ico.php', 'PHP_ICO' => __DIR__ . '/..' . '/chrisjean/php-ico/class-php-ico.php',
'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php', 'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
'ReturnTypeWillChange' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php', 'ReturnTypeWillChange' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php',
'Safe\\DateTime' => __DIR__ . '/..' . '/thecodingmachine/safe/lib/DateTime.php',
'Safe\\DateTimeImmutable' => __DIR__ . '/..' . '/thecodingmachine/safe/lib/DateTimeImmutable.php',
'Safe\\Exceptions\\ApacheException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/ApacheException.php',
'Safe\\Exceptions\\ApcException' => __DIR__ . '/..' . '/thecodingmachine/safe/deprecated/Exceptions/ApcException.php',
'Safe\\Exceptions\\ApcuException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/ApcuException.php',
'Safe\\Exceptions\\ArrayException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/ArrayException.php',
'Safe\\Exceptions\\Bzip2Exception' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/Bzip2Exception.php',
'Safe\\Exceptions\\CalendarException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/CalendarException.php',
'Safe\\Exceptions\\ClassobjException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/ClassobjException.php',
'Safe\\Exceptions\\ComException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/ComException.php',
'Safe\\Exceptions\\CubridException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/CubridException.php',
'Safe\\Exceptions\\CurlException' => __DIR__ . '/..' . '/thecodingmachine/safe/lib/Exceptions/CurlException.php',
'Safe\\Exceptions\\DatetimeException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/DatetimeException.php',
'Safe\\Exceptions\\DirException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/DirException.php',
'Safe\\Exceptions\\EioException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/EioException.php',
'Safe\\Exceptions\\ErrorfuncException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/ErrorfuncException.php',
'Safe\\Exceptions\\ExecException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/ExecException.php',
'Safe\\Exceptions\\FileinfoException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/FileinfoException.php',
'Safe\\Exceptions\\FilesystemException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/FilesystemException.php',
'Safe\\Exceptions\\FilterException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/FilterException.php',
'Safe\\Exceptions\\FpmException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/FpmException.php',
'Safe\\Exceptions\\FtpException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/FtpException.php',
'Safe\\Exceptions\\FunchandException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/FunchandException.php',
'Safe\\Exceptions\\GettextException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/GettextException.php',
'Safe\\Exceptions\\GmpException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/GmpException.php',
'Safe\\Exceptions\\GnupgException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/GnupgException.php',
'Safe\\Exceptions\\HashException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/HashException.php',
'Safe\\Exceptions\\IbaseException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/IbaseException.php',
'Safe\\Exceptions\\IbmDb2Exception' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/IbmDb2Exception.php',
'Safe\\Exceptions\\IconvException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/IconvException.php',
'Safe\\Exceptions\\ImageException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/ImageException.php',
'Safe\\Exceptions\\ImapException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/ImapException.php',
'Safe\\Exceptions\\InfoException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/InfoException.php',
'Safe\\Exceptions\\InotifyException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/InotifyException.php',
'Safe\\Exceptions\\JsonException' => __DIR__ . '/..' . '/thecodingmachine/safe/lib/Exceptions/JsonException.php',
'Safe\\Exceptions\\LdapException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/LdapException.php',
'Safe\\Exceptions\\LibeventException' => __DIR__ . '/..' . '/thecodingmachine/safe/deprecated/Exceptions/LibeventException.php',
'Safe\\Exceptions\\LibxmlException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/LibxmlException.php',
'Safe\\Exceptions\\LzfException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/LzfException.php',
'Safe\\Exceptions\\MailparseException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/MailparseException.php',
'Safe\\Exceptions\\MbstringException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/MbstringException.php',
'Safe\\Exceptions\\MiscException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/MiscException.php',
'Safe\\Exceptions\\MssqlException' => __DIR__ . '/..' . '/thecodingmachine/safe/deprecated/Exceptions/MssqlException.php',
'Safe\\Exceptions\\MysqlException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/MysqlException.php',
'Safe\\Exceptions\\MysqliException' => __DIR__ . '/..' . '/thecodingmachine/safe/deprecated/Exceptions/MysqliException.php',
'Safe\\Exceptions\\NetworkException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/NetworkException.php',
'Safe\\Exceptions\\Oci8Exception' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/Oci8Exception.php',
'Safe\\Exceptions\\OpcacheException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/OpcacheException.php',
'Safe\\Exceptions\\OpensslException' => __DIR__ . '/..' . '/thecodingmachine/safe/lib/Exceptions/OpensslException.php',
'Safe\\Exceptions\\OutcontrolException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/OutcontrolException.php',
'Safe\\Exceptions\\PasswordException' => __DIR__ . '/..' . '/thecodingmachine/safe/deprecated/Exceptions/PasswordException.php',
'Safe\\Exceptions\\PcntlException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/PcntlException.php',
'Safe\\Exceptions\\PcreException' => __DIR__ . '/..' . '/thecodingmachine/safe/lib/Exceptions/PcreException.php',
'Safe\\Exceptions\\PgsqlException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/PgsqlException.php',
'Safe\\Exceptions\\PosixException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/PosixException.php',
'Safe\\Exceptions\\PsException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/PsException.php',
'Safe\\Exceptions\\PspellException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/PspellException.php',
'Safe\\Exceptions\\ReadlineException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/ReadlineException.php',
'Safe\\Exceptions\\RpminfoException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/RpminfoException.php',
'Safe\\Exceptions\\RrdException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/RrdException.php',
'Safe\\Exceptions\\SafeExceptionInterface' => __DIR__ . '/..' . '/thecodingmachine/safe/lib/Exceptions/SafeExceptionInterface.php',
'Safe\\Exceptions\\SemException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/SemException.php',
'Safe\\Exceptions\\SessionException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/SessionException.php',
'Safe\\Exceptions\\ShmopException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/ShmopException.php',
'Safe\\Exceptions\\SimplexmlException' => __DIR__ . '/..' . '/thecodingmachine/safe/lib/Exceptions/SimplexmlException.php',
'Safe\\Exceptions\\SocketsException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/SocketsException.php',
'Safe\\Exceptions\\SodiumException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/SodiumException.php',
'Safe\\Exceptions\\SolrException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/SolrException.php',
'Safe\\Exceptions\\SplException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/SplException.php',
'Safe\\Exceptions\\SqlsrvException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/SqlsrvException.php',
'Safe\\Exceptions\\SsdeepException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/SsdeepException.php',
'Safe\\Exceptions\\Ssh2Exception' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/Ssh2Exception.php',
'Safe\\Exceptions\\StatsException' => __DIR__ . '/..' . '/thecodingmachine/safe/deprecated/Exceptions/StatsException.php',
'Safe\\Exceptions\\StreamException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/StreamException.php',
'Safe\\Exceptions\\StringsException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/StringsException.php',
'Safe\\Exceptions\\SwooleException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/SwooleException.php',
'Safe\\Exceptions\\UodbcException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/UodbcException.php',
'Safe\\Exceptions\\UopzException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/UopzException.php',
'Safe\\Exceptions\\UrlException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/UrlException.php',
'Safe\\Exceptions\\VarException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/VarException.php',
'Safe\\Exceptions\\XdiffException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/XdiffException.php',
'Safe\\Exceptions\\XmlException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/XmlException.php',
'Safe\\Exceptions\\XmlrpcException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/XmlrpcException.php',
'Safe\\Exceptions\\YamlException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/YamlException.php',
'Safe\\Exceptions\\YazException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/YazException.php',
'Safe\\Exceptions\\ZipException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/ZipException.php',
'Safe\\Exceptions\\ZlibException' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/Exceptions/ZlibException.php',
'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php', 'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php', 'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php', 'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',

View file

@ -24,13 +24,13 @@
"require": { "require": {
"ext-openssl": "*", "ext-openssl": "*",
"ext-pcre": "*", "ext-pcre": "*",
"php": "^5.3.2 || ^7.0 || ^8.0" "php": "^7.2 || ^8.0"
}, },
"require-dev": { "require-dev": {
"symfony/phpunit-bridge": "^4.2 || ^5", "symfony/phpunit-bridge": "^4.2 || ^5",
"phpstan/phpstan": "^0.12.55", "phpstan/phpstan": "^1.10",
"psr/log": "^1.0", "psr/log": "^1.0 || ^2.0 || ^3.0",
"symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0" "symfony/process": "^4.0 || ^5.0 || ^6.0 || ^7.0"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
@ -48,7 +48,7 @@
} }
}, },
"scripts": { "scripts": {
"test": "SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT=1 vendor/bin/simple-phpunit", "test": "vendor/bin/simple-phpunit",
"phpstan": "vendor/bin/phpstan analyse" "phpstan": "vendor/bin/phpstan analyse"
} }
} }

View file

@ -1,7 +1,7 @@
## ##
## Bundle of CA Root Certificates ## Bundle of CA Root Certificates
## ##
## Certificate data from Mozilla as of: Tue Dec 12 04:12:04 2023 GMT ## Certificate data from Mozilla as of: Tue Jul 2 03:12:04 2024 GMT
## ##
## This is a bundle of X.509 certificates of public Certificate Authorities ## This is a bundle of X.509 certificates of public Certificate Authorities
## (CA). These were automatically extracted from Mozilla's root certificates ## (CA). These were automatically extracted from Mozilla's root certificates
@ -14,7 +14,7 @@
## Just configure this file as the SSLCACertificateFile. ## Just configure this file as the SSLCACertificateFile.
## ##
## Conversion done with mk-ca-bundle.pl version 1.29. ## Conversion done with mk-ca-bundle.pl version 1.29.
## SHA256: 1970dd65858925d68498d2356aea6d03f764422523c5887deca8ce3ba9e1f845 ## SHA256: 456ff095dde6dd73354c5c28c73d9c06f53b61a803963414cb91a1d92945cdd3
## ##
@ -2600,36 +2600,6 @@ vLtoURMMA/cVi4RguYv/Uo7njLwcAjA8+RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+
CAezNIm8BZ/3Hobui3A= CAezNIm8BZ/3Hobui3A=
-----END CERTIFICATE----- -----END CERTIFICATE-----
GLOBALTRUST 2020
================
-----BEGIN CERTIFICATE-----
MIIFgjCCA2qgAwIBAgILWku9WvtPilv6ZeUwDQYJKoZIhvcNAQELBQAwTTELMAkGA1UEBhMCQVQx
IzAhBgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVT
VCAyMDIwMB4XDTIwMDIxMDAwMDAwMFoXDTQwMDYxMDAwMDAwMFowTTELMAkGA1UEBhMCQVQxIzAh
BgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVTVCAy
MDIwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAri5WrRsc7/aVj6B3GyvTY4+ETUWi
D59bRatZe1E0+eyLinjF3WuvvcTfk0Uev5E4C64OFudBc/jbu9G4UeDLgztzOG53ig9ZYybNpyrO
VPu44sB8R85gfD+yc/LAGbaKkoc1DZAoouQVBGM+uq/ufF7MpotQsjj3QWPKzv9pj2gOlTblzLmM
CcpL3TGQlsjMH/1WljTbjhzqLL6FLmPdqqmV0/0plRPwyJiT2S0WR5ARg6I6IqIoV6Lr/sCMKKCm
fecqQjuCgGOlYx8ZzHyyZqjC0203b+J+BlHZRYQfEs4kUmSFC0iAToexIiIwquuuvuAC4EDosEKA
A1GqtH6qRNdDYfOiaxaJSaSjpCuKAsR49GiKweR6NrFvG5Ybd0mN1MkGco/PU+PcF4UgStyYJ9OR
JitHHmkHr96i5OTUawuzXnzUJIBHKWk7buis/UDr2O1xcSvy6Fgd60GXIsUf1DnQJ4+H4xj04KlG
DfV0OoIu0G4skaMxXDtG6nsEEFZegB31pWXogvziB4xiRfUg3kZwhqG8k9MedKZssCz3AwyIDMvU
clOGvGBG85hqwvG/Q/lwIHfKN0F5VVJjjVsSn8VoxIidrPIwq7ejMZdnrY8XD2zHc+0klGvIg5rQ
mjdJBKuxFshsSUktq6HQjJLyQUp5ISXbY9e2nKd+Qmn7OmMCAwEAAaNjMGEwDwYDVR0TAQH/BAUw
AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNwuH9FhN3nkq9XVsxJxaD1qaJwiMB8GA1Ud
IwQYMBaAFNwuH9FhN3nkq9XVsxJxaD1qaJwiMA0GCSqGSIb3DQEBCwUAA4ICAQCR8EICaEDuw2jA
VC/f7GLDw56KoDEoqoOOpFaWEhCGVrqXctJUMHytGdUdaG/7FELYjQ7ztdGl4wJCXtzoRlgHNQIw
4Lx0SsFDKv/bGtCwr2zD/cuz9X9tAy5ZVp0tLTWMstZDFyySCstd6IwPS3BD0IL/qMy/pJTAvoe9
iuOTe8aPmxadJ2W8esVCgmxcB9CpwYhgROmYhRZf+I/KARDOJcP5YBugxZfD0yyIMaK9MOzQ0MAS
8cE54+X1+NZK3TTN+2/BT+MAi1bikvcoskJ3ciNnxz8RFbLEAwW+uxF7Cr+obuf/WEPPm2eggAe2
HcqtbepBEX4tdJP7wry+UUTF72glJ4DjyKDUEuzZpTcdN3y0kcra1LGWge9oXHYQSa9+pTeAsRxS
vTOBTI/53WXZFM2KJVj04sWDpQmQ1GwUY7VA3+vA/MRYfg0UFodUJ25W5HCEuGwyEn6CMUO+1918
oa2u1qsgEu8KwxCMSZY13At1XrFP1U80DhEgB3VDRemjEdqso5nCtnkn4rnvyOL2NSl6dPrFf4IF
YqYK6miyeUcGbvJXqBUzxvd4Sj1Ce2t+/vdG6tHrju+IaFvowdlxfv1k7/9nR4hYJS8+hge9+6jl
gqispdNpQ80xiEmEU5LAsTkbOYMBMMTyqfrQA71yN2BWHzZ8vTmR9W0Nv3vXkg==
-----END CERTIFICATE-----
ANF Secure Server Root CA ANF Secure Server Root CA
========================= =========================
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
@ -3532,3 +3502,67 @@ dVwPaFsdZcJfMw8eD/A7hvWwTruc9+olBdytoptLFwG+Qt81IR2tq670v64fG9PiO/yzcnMcmyiQ
iRM9HcEARwmWmjgb3bHPDcK0RPOWlc4yOo80nOAXx17Org3bhzjlP1v9mxnhMUF6cKojawHhRUzN iRM9HcEARwmWmjgb3bHPDcK0RPOWlc4yOo80nOAXx17Org3bhzjlP1v9mxnhMUF6cKojawHhRUzN
lM47ni3niAIi9G7oyOzWPPO5std3eqx7 lM47ni3niAIi9G7oyOzWPPO5std3eqx7
-----END CERTIFICATE----- -----END CERTIFICATE-----
Telekom Security TLS ECC Root 2020
==================================
-----BEGIN CERTIFICATE-----
MIICQjCCAcmgAwIBAgIQNjqWjMlcsljN0AFdxeVXADAKBggqhkjOPQQDAzBjMQswCQYDVQQGEwJE
RTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBHbWJIMSswKQYDVQQDDCJUZWxl
a29tIFNlY3VyaXR5IFRMUyBFQ0MgUm9vdCAyMDIwMB4XDTIwMDgyNTA3NDgyMFoXDTQ1MDgyNTIz
NTk1OVowYzELMAkGA1UEBhMCREUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkg
R21iSDErMCkGA1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgRUNDIFJvb3QgMjAyMDB2MBAGByqG
SM49AgEGBSuBBAAiA2IABM6//leov9Wq9xCazbzREaK9Z0LMkOsVGJDZos0MKiXrPk/OtdKPD/M1
2kOLAoC+b1EkHQ9rK8qfwm9QMuU3ILYg/4gND21Ju9sGpIeQkpT0CdDPf8iAC8GXs7s1J8nCG6NC
MEAwHQYDVR0OBBYEFONyzG6VmUex5rNhTNHLq+O6zd6fMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
AQH/BAQDAgEGMAoGCCqGSM49BAMDA2cAMGQCMHVSi7ekEE+uShCLsoRbQuHmKjYC2qBuGT8lv9pZ
Mo7k+5Dck2TOrbRBR2Diz6fLHgIwN0GMZt9Ba9aDAEH9L1r3ULRn0SyocddDypwnJJGDSA3PzfdU
ga/sf+Rn27iQ7t0l
-----END CERTIFICATE-----
Telekom Security TLS RSA Root 2023
==================================
-----BEGIN CERTIFICATE-----
MIIFszCCA5ugAwIBAgIQIZxULej27HF3+k7ow3BXlzANBgkqhkiG9w0BAQwFADBjMQswCQYDVQQG
EwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBHbWJIMSswKQYDVQQDDCJU
ZWxla29tIFNlY3VyaXR5IFRMUyBSU0EgUm9vdCAyMDIzMB4XDTIzMDMyODEyMTY0NVoXDTQ4MDMy
NzIzNTk1OVowYzELMAkGA1UEBhMCREUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJp
dHkgR21iSDErMCkGA1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgUlNBIFJvb3QgMjAyMzCCAiIw
DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAO01oYGA88tKaVvC+1GDrib94W7zgRJ9cUD/h3VC
KSHtgVIs3xLBGYSJwb3FKNXVS2xE1kzbB5ZKVXrKNoIENqil/Cf2SfHVcp6R+SPWcHu79ZvB7JPP
GeplfohwoHP89v+1VmLhc2o0mD6CuKyVU/QBoCcHcqMAU6DksquDOFczJZSfvkgdmOGjup5czQRx
UX11eKvzWarE4GC+j4NSuHUaQTXtvPM6Y+mpFEXX5lLRbtLevOP1Czvm4MS9Q2QTps70mDdsipWo
l8hHD/BeEIvnHRz+sTugBTNoBUGCwQMrAcjnj02r6LX2zWtEtefdi+zqJbQAIldNsLGyMcEWzv/9
FIS3R/qy8XDe24tsNlikfLMR0cN3f1+2JeANxdKz+bi4d9s3cXFH42AYTyS2dTd4uaNir73Jco4v
zLuu2+QVUhkHM/tqty1LkCiCc/4YizWN26cEar7qwU02OxY2kTLvtkCJkUPg8qKrBC7m8kwOFjQg
rIfBLX7JZkcXFBGk8/ehJImr2BrIoVyxo/eMbcgByU/J7MT8rFEz0ciD0cmfHdRHNCk+y7AO+oML
KFjlKdw/fKifybYKu6boRhYPluV75Gp6SG12mAWl3G0eQh5C2hrgUve1g8Aae3g1LDj1H/1Joy7S
WWO/gLCMk3PLNaaZlSJhZQNg+y+TS/qanIA7AgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAdBgNV
HQ4EFgQUtqeXgj10hZv3PJ+TmpV5dVKMbUcwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS2
p5eCPXSFm/c8n5OalXl1UoxtRzANBgkqhkiG9w0BAQwFAAOCAgEAqMxhpr51nhVQpGv7qHBFfLp+
sVr8WyP6Cnf4mHGCDG3gXkaqk/QeoMPhk9tLrbKmXauw1GLLXrtm9S3ul0A8Yute1hTWjOKWi0Fp
kzXmuZlrYrShF2Y0pmtjxrlO8iLpWA1WQdH6DErwM807u20hOq6OcrXDSvvpfeWxm4bu4uB9tPcy
/SKE8YXJN3nptT+/XOR0so8RYgDdGGah2XsjX/GO1WfoVNpbOms2b/mBsTNHM3dA+VKq3dSDz4V4
mZqTuXNnQkYRIer+CqkbGmVps4+uFrb2S1ayLfmlyOw7YqPta9BO1UAJpB+Y1zqlklkg5LB9zVtz
aL1txKITDmcZuI1CfmwMmm6gJC3VRRvcxAIU/oVbZZfKTpBQCHpCNfnqwmbU+AGuHrS+w6jv/naa
oqYfRvaE7fzbzsQCzndILIyy7MMAo+wsVRjBfhnu4S/yrYObnqsZ38aKL4x35bcF7DvB7L6Gs4a8
wPfc5+pbrrLMtTWGS9DiP7bY+A4A7l3j941Y/8+LN+ljX273CXE2whJdV/LItM3z7gLfEdxquVeE
HVlNjM7IDiPCtyaaEBRx/pOyiriA8A4QntOoUAw3gi/q4Iqd4Sw5/7W0cwDk90imc6y/st53BIe0
o82bNSQ3+pCTE4FCxpgmdTdmQRCsu/WU48IxK63nI1bMNSWSs1A=
-----END CERTIFICATE-----
FIRMAPROFESIONAL CA ROOT-A WEB
==============================
-----BEGIN CERTIFICATE-----
MIICejCCAgCgAwIBAgIQMZch7a+JQn81QYehZ1ZMbTAKBggqhkjOPQQDAzBuMQswCQYDVQQGEwJF
UzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25hbCBTQTEYMBYGA1UEYQwPVkFURVMtQTYyNjM0MDY4
MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFMIENBIFJPT1QtQSBXRUIwHhcNMjIwNDA2MDkwMTM2
WhcNNDcwMzMxMDkwMTM2WjBuMQswCQYDVQQGEwJFUzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25h
bCBTQTEYMBYGA1UEYQwPVkFURVMtQTYyNjM0MDY4MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFM
IENBIFJPT1QtQSBXRUIwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARHU+osEaR3xyrq89Zfe9MEkVz6
iMYiuYMQYneEMy3pA4jU4DP37XcsSmDq5G+tbbT4TIqk5B/K6k84Si6CcyvHZpsKjECcfIr28jlg
st7L7Ljkb+qbXbdTkBgyVcUgt5SjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUk+FD
Y1w8ndYn81LsF7Kpryz3dvgwHQYDVR0OBBYEFJPhQ2NcPJ3WJ/NS7Beyqa8s93b4MA4GA1UdDwEB
/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjAdfKR7w4l1M+E7qUW/Runpod3JIha3RxEL2Jq68cgL
cFBTApFwhVmpHqTm6iMxoAACMQD94vizrxa5HnPEluPBMBnYfubDl94cT7iJLzPrSA8Z94dGXSaQ
pYXFuXqUPoeovQA=
-----END CERTIFICATE-----

View file

@ -24,8 +24,6 @@ class CaBundle
private static $caPath; private static $caPath;
/** @var array<string, bool> */ /** @var array<string, bool> */
private static $caFileValidity = array(); private static $caFileValidity = array();
/** @var bool|null */
private static $useOpensslParse;
/** /**
* Returns the system CA bundle path, or a path to the bundled one * Returns the system CA bundle path, or a path to the bundled one
@ -64,7 +62,7 @@ class CaBundle
* @param LoggerInterface $logger optional logger for information about which CA files were loaded * @param LoggerInterface $logger optional logger for information about which CA files were loaded
* @return string path to a CA bundle file or directory * @return string path to a CA bundle file or directory
*/ */
public static function getSystemCaRootBundlePath(LoggerInterface $logger = null) public static function getSystemCaRootBundlePath(?LoggerInterface $logger = null)
{ {
if (self::$caPath !== null) { if (self::$caPath !== null) {
return self::$caPath; return self::$caPath;
@ -160,7 +158,7 @@ class CaBundle
* *
* @return bool * @return bool
*/ */
public static function validateCaFile($filename, LoggerInterface $logger = null) public static function validateCaFile($filename, ?LoggerInterface $logger = null)
{ {
static $warned = false; static $warned = false;
@ -170,19 +168,7 @@ class CaBundle
$contents = file_get_contents($filename); $contents = file_get_contents($filename);
// assume the CA is valid if php is vulnerable to if (is_string($contents) && strlen($contents) > 0) {
// https://www.sektioneins.de/advisories/advisory-012013-php-openssl_x509_parse-memory-corruption-vulnerability.html
if (!static::isOpensslParseSafe()) {
if (!$warned && $logger) {
$logger->warning(sprintf(
'Your version of PHP, %s, is affected by CVE-2013-6420 and cannot safely perform certificate validation, we strongly suggest you upgrade.',
PHP_VERSION
));
$warned = true;
}
$isValid = !empty($contents);
} elseif (is_string($contents) && strlen($contents) > 0) {
$contents = preg_replace("/^(\\-+(?:BEGIN|END))\\s+TRUSTED\\s+(CERTIFICATE\\-+)\$/m", '$1 $2', $contents); $contents = preg_replace("/^(\\-+(?:BEGIN|END))\\s+TRUSTED\\s+(CERTIFICATE\\-+)\$/m", '$1 $2', $contents);
if (null === $contents) { if (null === $contents) {
// regex extraction failed // regex extraction failed
@ -211,100 +197,7 @@ class CaBundle
*/ */
public static function isOpensslParseSafe() public static function isOpensslParseSafe()
{ {
if (null !== self::$useOpensslParse) { return true;
return self::$useOpensslParse;
}
if (PHP_VERSION_ID >= 50600) {
return self::$useOpensslParse = true;
}
// Vulnerable:
// PHP 5.3.0 - PHP 5.3.27
// PHP 5.4.0 - PHP 5.4.22
// PHP 5.5.0 - PHP 5.5.6
if (
(PHP_VERSION_ID < 50400 && PHP_VERSION_ID >= 50328)
|| (PHP_VERSION_ID < 50500 && PHP_VERSION_ID >= 50423)
|| PHP_VERSION_ID >= 50507
) {
// This version of PHP has the fix for CVE-2013-6420 applied.
return self::$useOpensslParse = true;
}
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
// Windows is probably insecure in this case.
return self::$useOpensslParse = false;
}
$compareDistroVersionPrefix = function ($prefix, $fixedVersion) {
$regex = '{^'.preg_quote($prefix).'([0-9]+)$}';
if (preg_match($regex, PHP_VERSION, $m)) {
return ((int) $m[1]) >= $fixedVersion;
}
return false;
};
// Hard coded list of PHP distributions with the fix backported.
if (
$compareDistroVersionPrefix('5.3.3-7+squeeze', 18) // Debian 6 (Squeeze)
|| $compareDistroVersionPrefix('5.4.4-14+deb7u', 7) // Debian 7 (Wheezy)
|| $compareDistroVersionPrefix('5.3.10-1ubuntu3.', 9) // Ubuntu 12.04 (Precise)
) {
return self::$useOpensslParse = true;
}
// Symfony Process component is missing so we assume it is unsafe at this point
if (!class_exists('Symfony\Component\Process\PhpProcess')) {
return self::$useOpensslParse = false;
}
// This is where things get crazy, because distros backport security
// fixes the chances are on NIX systems the fix has been applied but
// it's not possible to verify that from the PHP version.
//
// To verify exec a new PHP process and run the issue testcase with
// known safe input that replicates the bug.
// Based on testcase in https://github.com/php/php-src/commit/c1224573c773b6845e83505f717fbf820fc18415
// changes in https://github.com/php/php-src/commit/76a7fd893b7d6101300cc656058704a73254d593
$cert = 'LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVwRENDQTR5Z0F3SUJBZ0lKQUp6dThyNnU2ZUJjTUEwR0NTcUdTSWIzRFFFQkJRVUFNSUhETVFzd0NRWUQKVlFRR0V3SkVSVEVjTUJvR0ExVUVDQXdUVG05eVpISm9aV2x1TFZkbGMzUm1ZV3hsYmpFUU1BNEdBMVVFQnd3SApTOE9Ed3Jac2JqRVVNQklHQTFVRUNnd0xVMlZyZEdsdmJrVnBibk14SHpBZEJnTlZCQXNNRmsxaGJHbGphVzkxCmN5QkRaWEowSUZObFkzUnBiMjR4SVRBZkJnTlZCQU1NR0cxaGJHbGphVzkxY3k1elpXdDBhVzl1WldsdWN5NWsKWlRFcU1DZ0dDU3FHU0liM0RRRUpBUlliYzNSbFptRnVMbVZ6YzJWeVFITmxhM1JwYjI1bGFXNXpMbVJsTUhVWQpaREU1TnpBd01UQXhNREF3TURBd1dnQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBCkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUEKQUFBQUFBQVhEVEUwTVRFeU9ERXhNemt6TlZvd2djTXhDekFKQmdOVkJBWVRBa1JGTVJ3d0dnWURWUVFJREJOTwpiM0prY21obGFXNHRWMlZ6ZEdaaGJHVnVNUkF3RGdZRFZRUUhEQWRMdzRQQ3RteHVNUlF3RWdZRFZRUUtEQXRUClpXdDBhVzl1UldsdWN6RWZNQjBHQTFVRUN3d1dUV0ZzYVdOcGIzVnpJRU5sY25RZ1UyVmpkR2x2YmpFaE1COEcKQTFVRUF3d1liV0ZzYVdOcGIzVnpMbk5sYTNScGIyNWxhVzV6TG1SbE1Tb3dLQVlKS29aSWh2Y05BUWtCRmh0egpkR1ZtWVc0dVpYTnpaWEpBYzJWcmRHbHZibVZwYm5NdVpHVXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCCkR3QXdnZ0VLQW9JQkFRRERBZjNobDdKWTBYY0ZuaXlFSnBTU0RxbjBPcUJyNlFQNjV1c0pQUnQvOFBhRG9xQnUKd0VZVC9OYSs2ZnNnUGpDMHVLOURaZ1dnMnRIV1dvYW5TYmxBTW96NVBINlorUzRTSFJaN2UyZERJalBqZGhqaAowbUxnMlVNTzV5cDBWNzk3R2dzOWxOdDZKUmZIODFNTjJvYlhXczROdHp0TE11RDZlZ3FwcjhkRGJyMzRhT3M4CnBrZHVpNVVhd1Raa3N5NXBMUEhxNWNNaEZHbTA2djY1Q0xvMFYyUGQ5K0tBb2tQclBjTjVLTEtlYno3bUxwazYKU01lRVhPS1A0aWRFcXh5UTdPN2ZCdUhNZWRzUWh1K3ByWTNzaTNCVXlLZlF0UDVDWm5YMmJwMHdLSHhYMTJEWAoxbmZGSXQ5RGJHdkhUY3lPdU4rblpMUEJtM3ZXeG50eUlJdlZBZ01CQUFHalFqQkFNQWtHQTFVZEV3UUNNQUF3CkVRWUpZSVpJQVliNFFnRUJCQVFEQWdlQU1Bc0dBMVVkRHdRRUF3SUZvREFUQmdOVkhTVUVEREFLQmdnckJnRUYKQlFjREFqQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFHMGZaWVlDVGJkajFYWWMrMVNub2FQUit2SThDOENhRAo4KzBVWWhkbnlVNGdnYTBCQWNEclk5ZTk0ZUVBdTZacXljRjZGakxxWFhkQWJvcHBXb2NyNlQ2R0QxeDMzQ2tsClZBcnpHL0t4UW9oR0QySmVxa2hJTWxEb214SE83a2EzOStPYThpMnZXTFZ5alU4QVp2V01BcnVIYTRFRU55RzcKbFcyQWFnYUZLRkNyOVRuWFRmcmR4R1ZFYnY3S1ZRNmJkaGc1cDVTanBXSDErTXEwM3VSM1pYUEJZZHlWODMxOQpvMGxWajFLRkkyRENML2xpV2lzSlJvb2YrMWNSMzVDdGQwd1lCY3BCNlRac2xNY09QbDc2ZHdLd0pnZUpvMlFnClpzZm1jMnZDMS9xT2xOdU5xLzBUenprVkd2OEVUVDNDZ2FVK1VYZTRYT1Z2a2NjZWJKbjJkZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K';
$script = <<<'EOT'
error_reporting(-1);
$info = openssl_x509_parse(base64_decode('%s'));
var_dump(PHP_VERSION, $info['issuer']['emailAddress'], $info['validFrom_time_t']);
EOT;
$script = '<'."?php\n".sprintf($script, $cert);
try {
$process = new PhpProcess($script);
$process->mustRun();
} catch (\Exception $e) {
// In the case of any exceptions just accept it is not possible to
// determine the safety of openssl_x509_parse and bail out.
return self::$useOpensslParse = false;
}
$output = preg_split('{\r?\n}', trim($process->getOutput()));
$errorOutput = trim($process->getErrorOutput());
if (
is_array($output)
&& count($output) === 3
&& $output[0] === sprintf('string(%d) "%s"', strlen(PHP_VERSION), PHP_VERSION)
&& $output[1] === 'string(27) "stefan.esser@sektioneins.de"'
&& $output[2] === 'int(-1)'
&& preg_match('{openssl_x509_parse\(\): illegal (?:ASN1 data type for|length in) timestamp in - on line \d+}', $errorOutput)
) {
// This PHP has the fix backported probably by a distro security team.
return self::$useOpensslParse = true;
}
return self::$useOpensslParse = false;
} }
/** /**
@ -315,7 +208,6 @@ EOT;
{ {
self::$caFileValidity = array(); self::$caFileValidity = array();
self::$caPath = null; self::$caPath = null;
self::$useOpensslParse = null;
} }
/** /**
@ -340,12 +232,12 @@ EOT;
* @param LoggerInterface|null $logger * @param LoggerInterface|null $logger
* @return bool * @return bool
*/ */
private static function caFileUsable($certFile, LoggerInterface $logger = null) private static function caFileUsable($certFile, ?LoggerInterface $logger = null)
{ {
return $certFile return $certFile
&& static::isFile($certFile, $logger) && self::isFile($certFile, $logger)
&& static::isReadable($certFile, $logger) && self::isReadable($certFile, $logger)
&& static::validateCaFile($certFile, $logger); && self::validateCaFile($certFile, $logger);
} }
/** /**
@ -353,12 +245,12 @@ EOT;
* @param LoggerInterface|null $logger * @param LoggerInterface|null $logger
* @return bool * @return bool
*/ */
private static function caDirUsable($certDir, LoggerInterface $logger = null) private static function caDirUsable($certDir, ?LoggerInterface $logger = null)
{ {
return $certDir return $certDir
&& static::isDir($certDir, $logger) && self::isDir($certDir, $logger)
&& static::isReadable($certDir, $logger) && self::isReadable($certDir, $logger)
&& static::glob($certDir . '/*', $logger); && self::glob($certDir . '/*', $logger);
} }
/** /**
@ -366,7 +258,7 @@ EOT;
* @param LoggerInterface|null $logger * @param LoggerInterface|null $logger
* @return bool * @return bool
*/ */
private static function isFile($certFile, LoggerInterface $logger = null) private static function isFile($certFile, ?LoggerInterface $logger = null)
{ {
$isFile = @is_file($certFile); $isFile = @is_file($certFile);
if (!$isFile && $logger) { if (!$isFile && $logger) {
@ -381,7 +273,7 @@ EOT;
* @param LoggerInterface|null $logger * @param LoggerInterface|null $logger
* @return bool * @return bool
*/ */
private static function isDir($certDir, LoggerInterface $logger = null) private static function isDir($certDir, ?LoggerInterface $logger = null)
{ {
$isDir = @is_dir($certDir); $isDir = @is_dir($certDir);
if (!$isDir && $logger) { if (!$isDir && $logger) {
@ -396,7 +288,7 @@ EOT;
* @param LoggerInterface|null $logger * @param LoggerInterface|null $logger
* @return bool * @return bool
*/ */
private static function isReadable($certFileOrDir, LoggerInterface $logger = null) private static function isReadable($certFileOrDir, ?LoggerInterface $logger = null)
{ {
$isReadable = @is_readable($certFileOrDir); $isReadable = @is_readable($certFileOrDir);
if (!$isReadable && $logger) { if (!$isReadable && $logger) {
@ -411,7 +303,7 @@ EOT;
* @param LoggerInterface|null $logger * @param LoggerInterface|null $logger
* @return bool * @return bool
*/ */
private static function glob($pattern, LoggerInterface $logger = null) private static function glob($pattern, ?LoggerInterface $logger = null)
{ {
$certs = glob($pattern); $certs = glob($pattern);
if ($certs === false) { if ($certs === false) {

File diff suppressed because it is too large Load diff

View file

@ -5,7 +5,7 @@
'type' => 'project', 'type' => 'project',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),
'reference' => 'e3d28d11ab04cb6b6caeab81295bd055d66e3a0c', 'reference' => '91ac7ba0187c463139a1b2d19483ab2d8b74eab2',
'name' => 'wwbn/avideo', 'name' => 'wwbn/avideo',
'dev' => true, 'dev' => true,
), ),
@ -47,12 +47,21 @@
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'aws/aws-sdk-php' => array( 'aws/aws-sdk-php' => array(
'pretty_version' => '3.320.2', 'pretty_version' => '3.320.3',
'version' => '3.320.2.0', 'version' => '3.320.3.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../aws/aws-sdk-php', 'install_path' => __DIR__ . '/../aws/aws-sdk-php',
'aliases' => array(), 'aliases' => array(),
'reference' => 'dbae075b861316237d63418715f8bf4bfdd9d33d', 'reference' => 'afe137e61b0b536c93a71ce3bb3cdac2e92ae789',
'dev_requirement' => false,
),
'beberlei/assert' => array(
'pretty_version' => 'v3.3.2',
'version' => '3.3.2.0',
'type' => 'library',
'install_path' => __DIR__ . '/../beberlei/assert',
'aliases' => array(),
'reference' => 'cb70015c04be1baee6f5f5c953703347c0ac1655',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'brick/math' => array( 'brick/math' => array(
@ -118,13 +127,22 @@
'reference' => 'ccd5c0d56554f3ddcd7a823e695be83e0d1e43b6', 'reference' => 'ccd5c0d56554f3ddcd7a823e695be83e0d1e43b6',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'christian-riesen/base32' => array(
'pretty_version' => '1.6.0',
'version' => '1.6.0.0',
'type' => 'library',
'install_path' => __DIR__ . '/../christian-riesen/base32',
'aliases' => array(),
'reference' => '2e82dab3baa008e24a505649b0d583c31d31e894',
'dev_requirement' => false,
),
'composer/ca-bundle' => array( 'composer/ca-bundle' => array(
'pretty_version' => '1.4.1', 'pretty_version' => '1.5.1',
'version' => '1.4.1.0', 'version' => '1.5.1.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/./ca-bundle', 'install_path' => __DIR__ . '/./ca-bundle',
'aliases' => array(), 'aliases' => array(),
'reference' => '3ce240142f6d59b808dd65c1f52f7a1c252e6cfd', 'reference' => '063d9aa8696582f5a41dffbbaf3c81024f0a604a',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'emojione/assets' => array( 'emojione/assets' => array(
@ -290,12 +308,12 @@
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'nesbot/carbon' => array( 'nesbot/carbon' => array(
'pretty_version' => '2.72.3', 'pretty_version' => '2.72.5',
'version' => '2.72.3.0', 'version' => '2.72.5.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../nesbot/carbon', 'install_path' => __DIR__ . '/../nesbot/carbon',
'aliases' => array(), 'aliases' => array(),
'reference' => '0c6fd108360c562f6e4fd1dedb8233b423e91c83', 'reference' => 'afd46589c216118ecd48ff2b95d77596af1e57ed',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'norkunas/onesignal-php-api' => array( 'norkunas/onesignal-php-api' => array(
@ -317,12 +335,12 @@
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'paragonie/constant_time_encoding' => array( 'paragonie/constant_time_encoding' => array(
'pretty_version' => 'v3.0.0', 'pretty_version' => 'v2.7.0',
'version' => '3.0.0.0', 'version' => '2.7.0.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../paragonie/constant_time_encoding', 'install_path' => __DIR__ . '/../paragonie/constant_time_encoding',
'aliases' => array(), 'aliases' => array(),
'reference' => 'df1e7fde177501eee2037dd159cf04f5f301a512', 'reference' => '52a0d99e69f56b9ec27ace92ba56897fe6993105',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'paragonie/random_compat' => array( 'paragonie/random_compat' => array(
@ -543,12 +561,12 @@
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'ramsey/uuid' => array( 'ramsey/uuid' => array(
'pretty_version' => '4.7.5', 'pretty_version' => '4.7.6',
'version' => '4.7.5.0', 'version' => '4.7.6.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../ramsey/uuid', 'install_path' => __DIR__ . '/../ramsey/uuid',
'aliases' => array(), 'aliases' => array(),
'reference' => '5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e', 'reference' => '91039bc1faa45ba123c4328958e620d382ec7088',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'ratchet/pawl' => array( 'ratchet/pawl' => array(
@ -579,12 +597,12 @@
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'react/dns' => array( 'react/dns' => array(
'pretty_version' => 'v1.12.0', 'pretty_version' => 'v1.13.0',
'version' => '1.12.0.0', 'version' => '1.13.0.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../react/dns', 'install_path' => __DIR__ . '/../react/dns',
'aliases' => array(), 'aliases' => array(),
'reference' => 'c134600642fa615b46b41237ef243daa65bb64ec', 'reference' => 'eb8ae001b5a455665c89c1df97f6fb682f8fb0f5',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'react/event-loop' => array( 'react/event-loop' => array(
@ -597,36 +615,36 @@
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'react/promise' => array( 'react/promise' => array(
'pretty_version' => 'v3.1.0', 'pretty_version' => 'v3.2.0',
'version' => '3.1.0.0', 'version' => '3.2.0.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../react/promise', 'install_path' => __DIR__ . '/../react/promise',
'aliases' => array(), 'aliases' => array(),
'reference' => 'e563d55d1641de1dea9f5e84f3cccc66d2bfe02c', 'reference' => '8a164643313c71354582dc850b42b33fa12a4b63',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'react/socket' => array( 'react/socket' => array(
'pretty_version' => 'v1.15.0', 'pretty_version' => 'v1.16.0',
'version' => '1.15.0.0', 'version' => '1.16.0.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../react/socket', 'install_path' => __DIR__ . '/../react/socket',
'aliases' => array(), 'aliases' => array(),
'reference' => '216d3aec0b87f04a40ca04f481e6af01bdd1d038', 'reference' => '23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'react/stream' => array( 'react/stream' => array(
'pretty_version' => 'v1.3.0', 'pretty_version' => 'v1.4.0',
'version' => '1.3.0.0', 'version' => '1.4.0.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../react/stream', 'install_path' => __DIR__ . '/../react/stream',
'aliases' => array(), 'aliases' => array(),
'reference' => '6fbc9672905c7d5a885f2da2fc696f65840f4a66', 'reference' => '1e5b0acb8fe55143b5b426817155190eb6f5b18d',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'rhumsaa/uuid' => array( 'rhumsaa/uuid' => array(
'dev_requirement' => false, 'dev_requirement' => false,
'replaced' => array( 'replaced' => array(
0 => '4.7.5', 0 => '4.7.6',
), ),
), ),
'scssphp/scssphp' => array( 'scssphp/scssphp' => array(
@ -647,6 +665,15 @@
'reference' => 'b55996c1942bf676d4531c9b4c0ed226f7fe2b60', 'reference' => 'b55996c1942bf676d4531c9b4c0ed226f7fe2b60',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'spomky-labs/otphp' => array(
'pretty_version' => 'v10.0.3',
'version' => '10.0.3.0',
'type' => 'library',
'install_path' => __DIR__ . '/../spomky-labs/otphp',
'aliases' => array(),
'reference' => '9784d9f7c790eed26e102d6c78f12c754036c366',
'dev_requirement' => false,
),
'stripe/stripe-php' => array( 'stripe/stripe-php' => array(
'pretty_version' => 'v15.7.0', 'pretty_version' => 'v15.7.0',
'version' => '15.7.0.0', 'version' => '15.7.0.0',
@ -657,12 +684,12 @@
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'symfony/console' => array( 'symfony/console' => array(
'pretty_version' => 'v5.4.36', 'pretty_version' => 'v5.4.42',
'version' => '5.4.36.0', 'version' => '5.4.42.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../symfony/console', 'install_path' => __DIR__ . '/../symfony/console',
'aliases' => array(), 'aliases' => array(),
'reference' => '39f75d9d73d0c11952fdcecf4877b4d0f62a8f6e', 'reference' => 'cef62396a0477e94fc52e87a17c6e5c32e226b7f',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'symfony/deprecation-contracts' => array( 'symfony/deprecation-contracts' => array(
@ -675,21 +702,21 @@
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'symfony/event-dispatcher' => array( 'symfony/event-dispatcher' => array(
'pretty_version' => 'v5.4.35', 'pretty_version' => 'v5.4.40',
'version' => '5.4.35.0', 'version' => '5.4.40.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../symfony/event-dispatcher', 'install_path' => __DIR__ . '/../symfony/event-dispatcher',
'aliases' => array(), 'aliases' => array(),
'reference' => '7a69a85c7ea5bdd1e875806a99c51a87d3a74b38', 'reference' => 'a54e2a8a114065f31020d6a89ede83e34c3b27a4',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'symfony/event-dispatcher-contracts' => array( 'symfony/event-dispatcher-contracts' => array(
'pretty_version' => 'v2.5.2', 'pretty_version' => 'v2.5.3',
'version' => '2.5.2.0', 'version' => '2.5.3.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../symfony/event-dispatcher-contracts', 'install_path' => __DIR__ . '/../symfony/event-dispatcher-contracts',
'aliases' => array(), 'aliases' => array(),
'reference' => 'f98b54df6ad059855739db6fcbc2d36995283fe1', 'reference' => '540f4c73e87fd0c71ca44a6aa305d024ac68cb73',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'symfony/event-dispatcher-implementation' => array( 'symfony/event-dispatcher-implementation' => array(
@ -699,12 +726,12 @@
), ),
), ),
'symfony/http-client' => array( 'symfony/http-client' => array(
'pretty_version' => 'v5.4.41', 'pretty_version' => 'v5.4.42',
'version' => '5.4.41.0', 'version' => '5.4.42.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../symfony/http-client', 'install_path' => __DIR__ . '/../symfony/http-client',
'aliases' => array(), 'aliases' => array(),
'reference' => '87ca825717928d178de8a3458f163100925fb675', 'reference' => 'ed17728617f53903ac684aa4f7a1739f121798d3',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'symfony/http-client-contracts' => array( 'symfony/http-client-contracts' => array(
@ -723,66 +750,66 @@
), ),
), ),
'symfony/http-foundation' => array( 'symfony/http-foundation' => array(
'pretty_version' => 'v5.4.35', 'pretty_version' => 'v5.4.42',
'version' => '5.4.35.0', 'version' => '5.4.42.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../symfony/http-foundation', 'install_path' => __DIR__ . '/../symfony/http-foundation',
'aliases' => array(), 'aliases' => array(),
'reference' => 'f2ab692a22aef1cd54beb893aa0068bdfb093928', 'reference' => '9c375b2abef0b657aa0b7612b763df5c12a465ab',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'symfony/mime' => array( 'symfony/mime' => array(
'pretty_version' => 'v5.4.35', 'pretty_version' => 'v5.4.41',
'version' => '5.4.35.0', 'version' => '5.4.41.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../symfony/mime', 'install_path' => __DIR__ . '/../symfony/mime',
'aliases' => array(), 'aliases' => array(),
'reference' => 'ee94d9b538f93abbbc1ee4ccff374593117b04a9', 'reference' => 'c71c7a1aeed60b22d05e738197e31daf2120bd42',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'symfony/options-resolver' => array( 'symfony/options-resolver' => array(
'pretty_version' => 'v5.4.21', 'pretty_version' => 'v5.4.40',
'version' => '5.4.21.0', 'version' => '5.4.40.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../symfony/options-resolver', 'install_path' => __DIR__ . '/../symfony/options-resolver',
'aliases' => array(), 'aliases' => array(),
'reference' => '4fe5cf6ede71096839f0e4b4444d65dd3a7c1eb9', 'reference' => 'bd1afbde6613a8d6b956115e0e14b196191fd0c4',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'symfony/polyfill-ctype' => array( 'symfony/polyfill-ctype' => array(
'pretty_version' => 'v1.29.0', 'pretty_version' => 'v1.30.0',
'version' => '1.29.0.0', 'version' => '1.30.0.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-ctype', 'install_path' => __DIR__ . '/../symfony/polyfill-ctype',
'aliases' => array(), 'aliases' => array(),
'reference' => 'ef4d7e442ca910c4764bce785146269b30cb5fc4', 'reference' => '0424dff1c58f028c451efff2045f5d92410bd540',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'symfony/polyfill-intl-grapheme' => array( 'symfony/polyfill-intl-grapheme' => array(
'pretty_version' => 'v1.29.0', 'pretty_version' => 'v1.30.0',
'version' => '1.29.0.0', 'version' => '1.30.0.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-intl-grapheme', 'install_path' => __DIR__ . '/../symfony/polyfill-intl-grapheme',
'aliases' => array(), 'aliases' => array(),
'reference' => '32a9da87d7b3245e09ac426c83d334ae9f06f80f', 'reference' => '64647a7c30b2283f5d49b874d84a18fc22054b7a',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'symfony/polyfill-intl-idn' => array( 'symfony/polyfill-intl-idn' => array(
'pretty_version' => 'v1.29.0', 'pretty_version' => 'v1.30.0',
'version' => '1.29.0.0', 'version' => '1.30.0.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-intl-idn', 'install_path' => __DIR__ . '/../symfony/polyfill-intl-idn',
'aliases' => array(), 'aliases' => array(),
'reference' => 'a287ed7475f85bf6f61890146edbc932c0fff919', 'reference' => 'a6e83bdeb3c84391d1dfe16f42e40727ce524a5c',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'symfony/polyfill-intl-normalizer' => array( 'symfony/polyfill-intl-normalizer' => array(
'pretty_version' => 'v1.29.0', 'pretty_version' => 'v1.30.0',
'version' => '1.29.0.0', 'version' => '1.30.0.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-intl-normalizer', 'install_path' => __DIR__ . '/../symfony/polyfill-intl-normalizer',
'aliases' => array(), 'aliases' => array(),
'reference' => 'bc45c394692b948b4d383a08d7753968bed9a83d', 'reference' => 'a95281b0be0d9ab48050ebd988b967875cdb9fdb',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'symfony/polyfill-mbstring' => array( 'symfony/polyfill-mbstring' => array(
@ -795,12 +822,12 @@
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'symfony/polyfill-php72' => array( 'symfony/polyfill-php72' => array(
'pretty_version' => 'v1.29.0', 'pretty_version' => 'v1.30.0',
'version' => '1.29.0.0', 'version' => '1.30.0.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php72', 'install_path' => __DIR__ . '/../symfony/polyfill-php72',
'aliases' => array(), 'aliases' => array(),
'reference' => '861391a8da9a04cbad2d232ddd9e4893220d6e25', 'reference' => '10112722600777e02d2745716b70c5db4ca70442',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'symfony/polyfill-php73' => array( 'symfony/polyfill-php73' => array(
@ -822,21 +849,21 @@
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'symfony/polyfill-php81' => array( 'symfony/polyfill-php81' => array(
'pretty_version' => 'v1.29.0', 'pretty_version' => 'v1.30.0',
'version' => '1.29.0.0', 'version' => '1.30.0.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php81', 'install_path' => __DIR__ . '/../symfony/polyfill-php81',
'aliases' => array(), 'aliases' => array(),
'reference' => 'c565ad1e63f30e7477fc40738343c62b40bc672d', 'reference' => '3fb075789fb91f9ad9af537c4012d523085bd5af',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'symfony/routing' => array( 'symfony/routing' => array(
'pretty_version' => 'v5.4.37', 'pretty_version' => 'v5.4.42',
'version' => '5.4.37.0', 'version' => '5.4.42.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../symfony/routing', 'install_path' => __DIR__ . '/../symfony/routing',
'aliases' => array(), 'aliases' => array(),
'reference' => '48ae43e443693ddb4e574f7c12f0d17ce287694e', 'reference' => 'f8dd6f80c96aeec9b13fc13757842342e05c4878',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'symfony/service-contracts' => array( 'symfony/service-contracts' => array(
@ -849,21 +876,21 @@
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'symfony/string' => array( 'symfony/string' => array(
'pretty_version' => 'v5.4.36', 'pretty_version' => 'v5.4.42',
'version' => '5.4.36.0', 'version' => '5.4.42.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../symfony/string', 'install_path' => __DIR__ . '/../symfony/string',
'aliases' => array(), 'aliases' => array(),
'reference' => '4e232c83622bd8cd32b794216aa29d0d266d353b', 'reference' => '909cec913edea162a3b2836788228ad45fcab337',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'symfony/translation' => array( 'symfony/translation' => array(
'pretty_version' => 'v5.4.40', 'pretty_version' => 'v5.4.42',
'version' => '5.4.40.0', 'version' => '5.4.42.0',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../symfony/translation', 'install_path' => __DIR__ . '/../symfony/translation',
'aliases' => array(), 'aliases' => array(),
'reference' => 'bb51d7f183756d1ac03f50ea47dc5726518cc7e8', 'reference' => '1d702caccb9f091b738696185f778b1bfef7b5b2',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'symfony/translation-contracts' => array( 'symfony/translation-contracts' => array(
@ -881,6 +908,15 @@
0 => '2.3', 0 => '2.3',
), ),
), ),
'thecodingmachine/safe' => array(
'pretty_version' => 'v2.5.0',
'version' => '2.5.0.0',
'type' => 'library',
'install_path' => __DIR__ . '/../thecodingmachine/safe',
'aliases' => array(),
'reference' => '3115ecd6b4391662b4931daac4eba6b07a2ac1f0',
'dev_requirement' => false,
),
'vimeo/vimeo-api' => array( 'vimeo/vimeo-api' => array(
'pretty_version' => '3.0.10', 'pretty_version' => '3.0.10',
'version' => '3.0.10.0', 'version' => '3.0.10.0',
@ -896,7 +932,7 @@
'type' => 'project', 'type' => 'project',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),
'reference' => 'e3d28d11ab04cb6b6caeab81295bd055d66e3a0c', 'reference' => '91ac7ba0187c463139a1b2d19483ab2d8b74eab2',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
), ),

View file

@ -92,8 +92,8 @@
}, },
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-3.x": "3.x-dev", "dev-master": "3.x-dev",
"dev-master": "2.x-dev" "dev-2.x": "2.x-dev"
}, },
"laravel": { "laravel": {
"providers": [ "providers": [

View file

@ -123,8 +123,8 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
<a title="Онлайн казино 777 Україна" href="https://777.ua/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Онлайн казино" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/7e572d50-1ce8-4d69-ae12-86cc80371373/ok-ua-777.png" width="64" height="64"></a> <a title="Онлайн казино 777 Україна" href="https://777.ua/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Онлайн казино" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/7e572d50-1ce8-4d69-ae12-86cc80371373/ok-ua-777.png" width="64" height="64"></a>
<a title="#1 Guide To Online Gambling In Canada" href="https://casinohex.org/canada/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="CasinoHex Canada" src="https://opencollective-production.s3.us-west-1.amazonaws.com/79fdbcc0-a997-11eb-abbc-25e48b63c6dc.jpg" width="85" height="64"></a> <a title="#1 Guide To Online Gambling In Canada" href="https://casinohex.org/canada/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="CasinoHex Canada" src="https://opencollective-production.s3.us-west-1.amazonaws.com/79fdbcc0-a997-11eb-abbc-25e48b63c6dc.jpg" width="85" height="64"></a>
<a title="Znajdź najlepsze zakłady bukmacherskie w Polsce w 2023 roku. Probukmacher.pl to Twoje kompendium wiedzy na temat bukmacherów!" href="https://www.probukmacher.pl?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Probukmacher" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/caf50271-4560-4ffe-a434-ea15239168db/Screenshot_1.png" width="89" height="64"></a> <a title="Znajdź najlepsze zakłady bukmacherskie w Polsce w 2023 roku. Probukmacher.pl to Twoje kompendium wiedzy na temat bukmacherów!" href="https://www.probukmacher.pl?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Probukmacher" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/caf50271-4560-4ffe-a434-ea15239168db/Screenshot_1.png" width="89" height="64"></a>
<a title="Gives a fun for our users" href="https://slotoking.ua/games/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Игровые автоматы" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/94601d07-3205-4c60-9c2d-9b8194dbefb7/skg-blue.png" width="64" height="64"></a>
<a title="Casino-portugal.pt" href="https://casino-portugal.pt/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Casino-portugal.pt" src="https://logo.clearbit.com/casino-portugal.pt" width="64" height="64"></a> <a title="Casino-portugal.pt" href="https://casino-portugal.pt/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Casino-portugal.pt" src="https://logo.clearbit.com/casino-portugal.pt" width="64" height="64"></a>
<a title="Gives a fun for our users" href="https://slotoking.ua/games/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Игровые автоматы" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/94601d07-3205-4c60-9c2d-9b8194dbefb7/skg-blue.png" width="64" height="64"></a>
<a title="Slots City® ➢ Лучшее лицензионно казино онлайн и оффлайн на гривны в Украине. 【 Более1500 игровых автоматов и слотов】✅ Официально и Безопасно" href="https://slotscity.ua/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Slots City" src="https://opencollective-production.s3.us-west-1.amazonaws.com/d7e298c0-7abe-11ed-8553-230872f5e54d.png" width="90" height="64"></a> <a title="Slots City® ➢ Лучшее лицензионно казино онлайн и оффлайн на гривны в Украине. 【 Более1500 игровых автоматов и слотов】✅ Официально и Безопасно" href="https://slotscity.ua/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Slots City" src="https://opencollective-production.s3.us-west-1.amazonaws.com/d7e298c0-7abe-11ed-8553-230872f5e54d.png" width="90" height="64"></a>
<a title="inkedin" href="https://inkedin.com?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="inkedin" src="https://logo.clearbit.com/inkedin.com" width="64" height="64"></a> <a title="inkedin" href="https://inkedin.com?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="inkedin" src="https://logo.clearbit.com/inkedin.com" width="64" height="64"></a>
<a title="Актуальний та повносправний рейтинг онлайн казино України, ґрунтований на відгуках реальних гравців." href="https://uk.onlinecasino.in.ua/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Онлайн казино України" src="https://opencollective-production.s3.us-west-1.amazonaws.com/c0b4b090-eef8-11ec-9cb7-0527a205b226.png" width="64" height="64"></a> <a title="Актуальний та повносправний рейтинг онлайн казино України, ґрунтований на відгуках реальних гравців." href="https://uk.onlinecasino.in.ua/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Онлайн казино України" src="https://opencollective-production.s3.us-west-1.amazonaws.com/c0b4b090-eef8-11ec-9cb7-0527a205b226.png" width="64" height="64"></a>
@ -142,10 +142,11 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
<a title="Siti Non AAMS" href="https://www.outlookindia.com/outlook-spotlight/migliori-siti-non-aams-siti-scommesse-senza-licenza-sicuri-news-294715?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Migliori Siti Non AAMS" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/392810da-6cb6-4938-a3cb-38bd0e1eb7de/migliori-siti-non-aams.png" width="42" height="42"></a> <a title="Siti Non AAMS" href="https://www.outlookindia.com/outlook-spotlight/migliori-siti-non-aams-siti-scommesse-senza-licenza-sicuri-news-294715?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Migliori Siti Non AAMS" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/392810da-6cb6-4938-a3cb-38bd0e1eb7de/migliori-siti-non-aams.png" width="42" height="42"></a>
<a title="List of trusted non GamStop casino reviews" href="https://nongamstopcasinos.org?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="UK NonGamStopCasinos" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/cbda0ee1-26ea-4252-9580-f1f9b317b1f7/nongamstopcasinos-uk.png" width="42" height="42"></a> <a title="List of trusted non GamStop casino reviews" href="https://nongamstopcasinos.org?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="UK NonGamStopCasinos" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/cbda0ee1-26ea-4252-9580-f1f9b317b1f7/nongamstopcasinos-uk.png" width="42" height="42"></a>
<a title="Online TikTok Video Download Tool" href="https://snaptik.pro?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="SnapTik" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/546bcd53-6615-457d-ab21-1db1c52b3af5/logo.jpg" width="42" height="42"></a> <a title="Online TikTok Video Download Tool" href="https://snaptik.pro?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="SnapTik" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/546bcd53-6615-457d-ab21-1db1c52b3af5/logo.jpg" width="42" height="42"></a>
<a title="IG Downloader is an Instagram Downloader service that offers a variety of tools to download Instagram content for free. Listed below are all the tools" href="https://indownloader.app/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="IG Downloader" src="https://logo.clearbit.com/indownloader.app" width="42" height="42"></a>
<a title="Proxidize is a mobile proxy creation and management platform that provides all needed components from hardware to cloud software and SIM cards." href="https://proxidize.com/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Proxidize" src="https://logo.clearbit.com/proxidize.com" width="42" height="42"></a> <a title="Proxidize is a mobile proxy creation and management platform that provides all needed components from hardware to cloud software and SIM cards." href="https://proxidize.com/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Proxidize" src="https://logo.clearbit.com/proxidize.com" width="42" height="42"></a>
<a title="Blastup offers Instagram growth services like buying likes, views, and followers, emphasizing real user engagement and instant delivery." href="https://blastup.com/buy-instagram-likes?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Blastup" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/955a0beb-9fe8-4753-ad92-fae8ef5382fc/favicon--dark.jpg" width="42" height="42"></a> <a title="IG Downloader is an Instagram Downloader service that offers a variety of tools to download Instagram content for free. Listed below are all the tools" href="https://indownloader.app/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="IG Downloader" src="https://logo.clearbit.com/indownloader.app" width="42" height="42"></a>
<a title="A self-hosted web radio management suite, including turnkey installer tools and an easy-to-use web app to manage your stations." href="https://azuracast.com?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="AzuraCast" src="https://opencollective-production.s3.us-west-1.amazonaws.com/3c12ea10-cdfb-11eb-9cf4-3760b386b76d.png" width="42" height="42"></a> <a title="Buy Instagram Likes - Real Likes &amp; Instant Delivery!" href="https://blastup.com/buy-instagram-likes?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Blastup" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/955a0beb-9fe8-4753-ad92-fae8ef5382fc/favicon--dark.jpg" width="42" height="42"></a>
<a title="We will boost your Social Media Likes, Followers , Comments &amp; Views. 24/7 hour support. Privacy Assured." href="https://organicsocialboost.com/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Organic Social Boost" src="https://logo.clearbit.com/organicsocialboost.com" width="84" height="42"></a>
<a title="A self-hosted web radio management suite, including turnkey installer tools and an easy-to-use web app to manage your stations." href="https://azuracast.com/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="AzuraCast" src="https://opencollective-production.s3.us-west-1.amazonaws.com/3c12ea10-cdfb-11eb-9cf4-3760b386b76d.png" width="42" height="42"></a>
<a title="Triplebyte is the first software engineering job platform that is on the developer&#039;s side. Take our coding quiz!" href="https://triplebyte.com/os/opencollective?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Triplebyte" src="https://opencollective-production.s3.us-west-1.amazonaws.com/43e4f9d0-30cd-11ea-9c6b-e1142996e8b2.png" width="42" height="42"></a> <a title="Triplebyte is the first software engineering job platform that is on the developer&#039;s side. Take our coding quiz!" href="https://triplebyte.com/os/opencollective?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Triplebyte" src="https://opencollective-production.s3.us-west-1.amazonaws.com/43e4f9d0-30cd-11ea-9c6b-e1142996e8b2.png" width="42" height="42"></a>
<a title="Connect your Collective to GitHub Sponsors: https://docs.opencollective.com/help/collectives/github-sponsors" href="https://github.com/sponsors/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="GitHub Sponsors" src="https://opencollective-production.s3.us-west-1.amazonaws.com/87b1d240-f617-11ea-9960-fd7e8ab20fe4.png" width="48" height="42"></a> <a title="Connect your Collective to GitHub Sponsors: https://docs.opencollective.com/help/collectives/github-sponsors" href="https://github.com/sponsors/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="GitHub Sponsors" src="https://opencollective-production.s3.us-west-1.amazonaws.com/87b1d240-f617-11ea-9960-fd7e8ab20fe4.png" width="48" height="42"></a>
<a title="Salesforce" href="https://engineering.salesforce.com?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Salesforce" src="https://opencollective-production.s3.us-west-1.amazonaws.com/24d34880-df8d-11e9-949c-6bc2037b6bd5.png" width="42" height="42"></a> <a title="Salesforce" href="https://engineering.salesforce.com?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Salesforce" src="https://opencollective-production.s3.us-west-1.amazonaws.com/24d34880-df8d-11e9-949c-6bc2037b6bd5.png" width="42" height="42"></a>

View file

@ -994,6 +994,10 @@ trait Comparison
return $this->year === (int) $tester; return $this->year === (int) $tester;
} }
if (preg_match('/^(?:Jan|January|Feb|February|Mar|March|Apr|April|May|Jun|June|Jul|July|Aug|August|Sep|September|Oct|October|Nov|November|Dec|December)$/i', $tester)) {
return $this->isSameMonth(static::parse($tester), false);
}
if (preg_match('/^\d{3,}-\d{1,2}$/', $tester)) { if (preg_match('/^\d{3,}-\d{1,2}$/', $tester)) {
return $this->isSameMonth(static::parse($tester)); return $this->isSameMonth(static::parse($tester));
} }

View file

@ -96,9 +96,9 @@ trait Options
'v' => '([0-9]{1,3})', 'v' => '([0-9]{1,3})',
'e' => '([a-zA-Z]{1,5})|([a-zA-Z]*\\/[a-zA-Z]*)', 'e' => '([a-zA-Z]{1,5})|([a-zA-Z]*\\/[a-zA-Z]*)',
'I' => '(0|1)', 'I' => '(0|1)',
'O' => '([+-](1[012]|0[0-9])[0134][05])', 'O' => '([+-](1[0123]|0[0-9])[0134][05])',
'P' => '([+-](1[012]|0[0-9]):[0134][05])', 'P' => '([+-](1[0123]|0[0-9]):[0134][05])',
'p' => '(Z|[+-](1[012]|0[0-9]):[0134][05])', 'p' => '(Z|[+-](1[0123]|0[0-9]):[0134][05])',
'T' => '([a-zA-Z]{1,5})', 'T' => '([a-zA-Z]{1,5})',
'Z' => '(-?[1-5]?[0-9]{1,4})', 'Z' => '(-?[1-5]?[0-9]{1,4})',
'U' => '([0-9]*)', 'U' => '([0-9]*)',

View file

@ -1,7 +1,6 @@
# Constant-Time Encoding # Constant-Time Encoding
[![Build Status](https://github.com/paragonie/constant_time_encoding/actions/workflows/ci.yml/badge.svg)](https://github.com/paragonie/constant_time_encoding/actions) [![Build Status](https://github.com/paragonie/constant_time_encoding/actions/workflows/ci.yml/badge.svg)](https://github.com/paragonie/constant_time_encoding/actions)
[![Static Analysis](https://github.com/paragonie/constant_time_encoding/actions/workflows/psalm.yml/badge.svg)](https://github.com/paragonie/constant_time_encoding/actions)
[![Latest Stable Version](https://poser.pugx.org/paragonie/constant_time_encoding/v/stable)](https://packagist.org/packages/paragonie/constant_time_encoding) [![Latest Stable Version](https://poser.pugx.org/paragonie/constant_time_encoding/v/stable)](https://packagist.org/packages/paragonie/constant_time_encoding)
[![Latest Unstable Version](https://poser.pugx.org/paragonie/constant_time_encoding/v/unstable)](https://packagist.org/packages/paragonie/constant_time_encoding) [![Latest Unstable Version](https://poser.pugx.org/paragonie/constant_time_encoding/v/unstable)](https://packagist.org/packages/paragonie/constant_time_encoding)
[![License](https://poser.pugx.org/paragonie/constant_time_encoding/license)](https://packagist.org/packages/paragonie/constant_time_encoding) [![License](https://poser.pugx.org/paragonie/constant_time_encoding/license)](https://packagist.org/packages/paragonie/constant_time_encoding)
@ -23,13 +22,10 @@ Our fork offers the following enhancements:
## PHP Version Requirements ## PHP Version Requirements
Version 3 of this library should work on **PHP 8** or newer. Version 2 of this library should work on **PHP 7** or newer. For PHP 5
support, see [the v1.x branch](https://github.com/paragonie/constant_time_encoding/tree/v1.x).
Version 2 of this library should work on **PHP 7** or newer. See [the v2.x branch](https://github.com/paragonie/constant_time_encoding/tree/v2.x). If you are adding this as a dependency to a project intended to work on both PHP 5 and PHP 7, please set the required version to `^1|^2` instead of just `^1` or `^2`.
For PHP 5 support, see [the v1.x branch](https://github.com/paragonie/constant_time_encoding/tree/v1.x).
If you are adding this as a dependency to a project intended to work on PHP 5 through 8.4, please set the required version to `^1|^2|^3`.
## How to Install ## How to Install

View file

@ -37,11 +37,11 @@
"source": "https://github.com/paragonie/constant_time_encoding" "source": "https://github.com/paragonie/constant_time_encoding"
}, },
"require": { "require": {
"php": "^8" "php": "^7|^8"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^9", "phpunit/phpunit": "^6|^7|^8|^9",
"vimeo/psalm": "^4|^5" "vimeo/psalm": "^1|^2|^3|^4"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {

View file

@ -75,7 +75,7 @@ abstract class Binary
#[\SensitiveParameter] #[\SensitiveParameter]
string $str, string $str,
int $start = 0, int $start = 0,
?int $length = null $length = null
): string { ): string {
if ($length === 0) { if ($length === 0) {
return ''; return '';

View file

@ -11,7 +11,7 @@
"require": { "require": {
"php": "^8.0", "php": "^8.0",
"ext-json": "*", "ext-json": "*",
"brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11", "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12",
"ramsey/collection": "^1.2 || ^2.0" "ramsey/collection": "^1.2 || ^2.0"
}, },
"require-dev": { "require-dev": {

View file

@ -136,9 +136,11 @@ final class BrickMathCalculator implements CalculatorInterface
/** /**
* Maps ramsey/uuid rounding modes to those used by brick/math * 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;
} }
} }

View file

@ -1,5 +1,10 @@
# Changelog # Changelog
## 1.13.0 (2024-06-13)
* Feature: Improve PHP 8.4+ support by avoiding implicitly nullable type declarations.
(#224 by @WyriHaximus)
## 1.12.0 (2023-11-29) ## 1.12.0 (2023-11-29)
* Feature: Full PHP 8.3 compatibility. * Feature: Full PHP 8.3 compatibility.

View file

@ -410,7 +410,7 @@ This project follows [SemVer](https://semver.org/).
This will install the latest supported version: This will install the latest supported version:
```bash ```bash
composer require react/dns:^1.12 composer require react/dns:^1.13
``` ```
See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades. See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades.

View file

@ -29,12 +29,12 @@
"php": ">=5.3.0", "php": ">=5.3.0",
"react/cache": "^1.0 || ^0.6 || ^0.5", "react/cache": "^1.0 || ^0.6 || ^0.5",
"react/event-loop": "^1.2", "react/event-loop": "^1.2",
"react/promise": "^3.0 || ^2.7 || ^1.2.1" "react/promise": "^3.2 || ^2.7 || ^1.2.1"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36",
"react/async": "^4 || ^3 || ^2", "react/async": "^4.3 || ^3 || ^2",
"react/promise-timer": "^1.9" "react/promise-timer": "^1.11"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {

View file

@ -134,7 +134,7 @@ class TcpTransportExecutor implements ExecutorInterface
* @param string $nameserver * @param string $nameserver
* @param ?LoopInterface $loop * @param ?LoopInterface $loop
*/ */
public function __construct($nameserver, LoopInterface $loop = null) public function __construct($nameserver, $loop = null)
{ {
if (\strpos($nameserver, '[') === false && \substr_count($nameserver, ':') >= 2 && \strpos($nameserver, '://') === false) { if (\strpos($nameserver, '[') === false && \substr_count($nameserver, ':') >= 2 && \strpos($nameserver, '://') === false) {
// several colons, but not enclosed in square brackets => enclose IPv6 address in square brackets // several colons, but not enclosed in square brackets => enclose IPv6 address in square brackets
@ -146,6 +146,10 @@ class TcpTransportExecutor implements ExecutorInterface
throw new \InvalidArgumentException('Invalid nameserver address given'); throw new \InvalidArgumentException('Invalid nameserver address given');
} }
if ($loop !== null && !$loop instanceof LoopInterface) { // manual type check to support legacy PHP < 7.1
throw new \InvalidArgumentException('Argument #2 ($loop) expected null|React\EventLoop\LoopInterface');
}
$this->nameserver = 'tcp://' . $parts['host'] . ':' . (isset($parts['port']) ? $parts['port'] : 53); $this->nameserver = 'tcp://' . $parts['host'] . ':' . (isset($parts['port']) ? $parts['port'] : 53);
$this->loop = $loop ?: Loop::get(); $this->loop = $loop ?: Loop::get();
$this->parser = new Parser(); $this->parser = new Parser();

View file

@ -12,8 +12,17 @@ final class TimeoutExecutor implements ExecutorInterface
private $loop; private $loop;
private $timeout; private $timeout;
public function __construct(ExecutorInterface $executor, $timeout, LoopInterface $loop = null) /**
* @param ExecutorInterface $executor
* @param float $timeout
* @param ?LoopInterface $loop
*/
public function __construct(ExecutorInterface $executor, $timeout, $loop = null)
{ {
if ($loop !== null && !$loop instanceof LoopInterface) { // manual type check to support legacy PHP < 7.1
throw new \InvalidArgumentException('Argument #3 ($loop) expected null|React\EventLoop\LoopInterface');
}
$this->executor = $executor; $this->executor = $executor;
$this->loop = $loop ?: Loop::get(); $this->loop = $loop ?: Loop::get();
$this->timeout = $timeout; $this->timeout = $timeout;

View file

@ -98,7 +98,7 @@ final class UdpTransportExecutor implements ExecutorInterface
* @param string $nameserver * @param string $nameserver
* @param ?LoopInterface $loop * @param ?LoopInterface $loop
*/ */
public function __construct($nameserver, LoopInterface $loop = null) public function __construct($nameserver, $loop = null)
{ {
if (\strpos($nameserver, '[') === false && \substr_count($nameserver, ':') >= 2 && \strpos($nameserver, '://') === false) { if (\strpos($nameserver, '[') === false && \substr_count($nameserver, ':') >= 2 && \strpos($nameserver, '://') === false) {
// several colons, but not enclosed in square brackets => enclose IPv6 address in square brackets // several colons, but not enclosed in square brackets => enclose IPv6 address in square brackets
@ -110,6 +110,10 @@ final class UdpTransportExecutor implements ExecutorInterface
throw new \InvalidArgumentException('Invalid nameserver address given'); throw new \InvalidArgumentException('Invalid nameserver address given');
} }
if ($loop !== null && !$loop instanceof LoopInterface) { // manual type check to support legacy PHP < 7.1
throw new \InvalidArgumentException('Argument #2 ($loop) expected null|React\EventLoop\LoopInterface');
}
$this->nameserver = 'udp://' . $parts['host'] . ':' . (isset($parts['port']) ? $parts['port'] : 53); $this->nameserver = 'udp://' . $parts['host'] . ':' . (isset($parts['port']) ? $parts['port'] : 53);
$this->loop = $loop ?: Loop::get(); $this->loop = $loop ?: Loop::get();
$this->parser = new Parser(); $this->parser = new Parser();

View file

@ -36,8 +36,12 @@ final class Factory
* @throws \InvalidArgumentException for invalid DNS server address * @throws \InvalidArgumentException for invalid DNS server address
* @throws \UnderflowException when given DNS Config object has an empty list of nameservers * @throws \UnderflowException when given DNS Config object has an empty list of nameservers
*/ */
public function create($config, LoopInterface $loop = null) public function create($config, $loop = null)
{ {
if ($loop !== null && !$loop instanceof LoopInterface) { // manual type check to support legacy PHP < 7.1
throw new \InvalidArgumentException('Argument #2 ($loop) expected null|React\EventLoop\LoopInterface');
}
$executor = $this->decorateHostsFileExecutor($this->createExecutor($config, $loop ?: Loop::get())); $executor = $this->decorateHostsFileExecutor($this->createExecutor($config, $loop ?: Loop::get()));
return new Resolver($executor); return new Resolver($executor);
@ -59,8 +63,16 @@ final class Factory
* @throws \InvalidArgumentException for invalid DNS server address * @throws \InvalidArgumentException for invalid DNS server address
* @throws \UnderflowException when given DNS Config object has an empty list of nameservers * @throws \UnderflowException when given DNS Config object has an empty list of nameservers
*/ */
public function createCached($config, LoopInterface $loop = null, CacheInterface $cache = null) public function createCached($config, $loop = null, $cache = null)
{ {
if ($loop !== null && !$loop instanceof LoopInterface) { // manual type check to support legacy PHP < 7.1
throw new \InvalidArgumentException('Argument #2 ($loop) expected null|React\EventLoop\LoopInterface');
}
if ($cache !== null && !$cache instanceof CacheInterface) { // manual type check to support legacy PHP < 7.1
throw new \InvalidArgumentException('Argument #3 ($cache) expected null|React\Cache\CacheInterface');
}
// default to keeping maximum of 256 responses in cache unless explicitly given // default to keeping maximum of 256 responses in cache unless explicitly given
if (!($cache instanceof CacheInterface)) { if (!($cache instanceof CacheInterface)) {
$cache = new ArrayCache(256); $cache = new ArrayCache(256);

View file

@ -1,5 +1,16 @@
# Changelog # Changelog
## 3.2.0 (2024-05-24)
* Feature: Improve PHP 8.4+ support by avoiding implicitly nullable type declarations.
(#260 by @Ayesh)
* Feature: Include previous exceptions when reporting unhandled promise rejections.
(#262 by @clue)
* Update test suite to improve PHP 8.4+ support.
(#261 by @SimonFrings)
## 3.1.0 (2023-11-16) ## 3.1.0 (2023-11-16)
* Feature: Full PHP 8.3 compatibility. * Feature: Full PHP 8.3 compatibility.

View file

@ -664,7 +664,7 @@ This project follows [SemVer](https://semver.org/).
This will install the latest supported version from this branch: This will install the latest supported version from this branch:
```bash ```bash
composer require react/promise:^3.1 composer require react/promise:^3.2
``` ```
See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades. See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades.

View file

@ -21,7 +21,7 @@ final class Deferred
/** /**
* @param (callable(callable(T):void,callable(\Throwable):void):void)|null $canceller * @param (callable(callable(T):void,callable(\Throwable):void):void)|null $canceller
*/ */
public function __construct(callable $canceller = null) public function __construct(?callable $canceller = null)
{ {
$this->promise = new Promise(function ($resolve, $reject): void { $this->promise = new Promise(function ($resolve, $reject): void {
$this->resolveCallback = $resolve; $this->resolveCallback = $resolve;

View file

@ -34,7 +34,7 @@ final class FulfilledPromise implements PromiseInterface
* @param ?(callable((T is void ? null : T)): (PromiseInterface<TFulfilled>|TFulfilled)) $onFulfilled * @param ?(callable((T is void ? null : T)): (PromiseInterface<TFulfilled>|TFulfilled)) $onFulfilled
* @return PromiseInterface<($onFulfilled is null ? T : TFulfilled)> * @return PromiseInterface<($onFulfilled is null ? T : TFulfilled)>
*/ */
public function then(callable $onFulfilled = null, callable $onRejected = null): PromiseInterface public function then(?callable $onFulfilled = null, ?callable $onRejected = null): PromiseInterface
{ {
if (null === $onFulfilled) { if (null === $onFulfilled) {
return $this; return $this;

View file

@ -37,8 +37,7 @@ final class RejectedPromise implements PromiseInterface
$handler = set_rejection_handler(null); $handler = set_rejection_handler(null);
if ($handler === null) { if ($handler === null) {
$message = 'Unhandled promise rejection with ' . \get_class($this->reason) . ': ' . $this->reason->getMessage() . ' in ' . $this->reason->getFile() . ':' . $this->reason->getLine() . PHP_EOL; $message = 'Unhandled promise rejection with ' . $this->reason;
$message .= 'Stack trace:' . PHP_EOL . $this->reason->getTraceAsString();
\error_log($message); \error_log($message);
return; return;
@ -47,8 +46,9 @@ final class RejectedPromise implements PromiseInterface
try { try {
$handler($this->reason); $handler($this->reason);
} catch (\Throwable $e) { } catch (\Throwable $e) {
$message = 'Fatal error: Uncaught ' . \get_class($e) . ' from unhandled promise rejection handler: ' . $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine() . PHP_EOL; \preg_match('/^([^:\s]++)(.*+)$/sm', (string) $e, $match);
$message .= 'Stack trace:' . PHP_EOL . $e->getTraceAsString(); \assert(isset($match[1], $match[2]));
$message = 'Fatal error: Uncaught ' . $match[1] . ' from unhandled promise rejection handler' . $match[2];
\error_log($message); \error_log($message);
exit(255); exit(255);
@ -61,7 +61,7 @@ final class RejectedPromise implements PromiseInterface
* @param ?(callable(\Throwable): (PromiseInterface<TRejected>|TRejected)) $onRejected * @param ?(callable(\Throwable): (PromiseInterface<TRejected>|TRejected)) $onRejected
* @return PromiseInterface<($onRejected is null ? never : TRejected)> * @return PromiseInterface<($onRejected is null ? never : TRejected)>
*/ */
public function then(callable $onFulfilled = null, callable $onRejected = null): PromiseInterface public function then(?callable $onFulfilled = null, ?callable $onRejected = null): PromiseInterface
{ {
if (null === $onRejected) { if (null === $onRejected) {
return $this; return $this;

View file

@ -29,7 +29,7 @@ final class Promise implements PromiseInterface
* @param callable(callable(T):void,callable(\Throwable):void):void $resolver * @param callable(callable(T):void,callable(\Throwable):void):void $resolver
* @param (callable(callable(T):void,callable(\Throwable):void):void)|null $canceller * @param (callable(callable(T):void,callable(\Throwable):void):void)|null $canceller
*/ */
public function __construct(callable $resolver, callable $canceller = null) public function __construct(callable $resolver, ?callable $canceller = null)
{ {
$this->canceller = $canceller; $this->canceller = $canceller;
@ -41,7 +41,7 @@ final class Promise implements PromiseInterface
$this->call($cb); $this->call($cb);
} }
public function then(callable $onFulfilled = null, callable $onRejected = null): PromiseInterface public function then(?callable $onFulfilled = null, ?callable $onRejected = null): PromiseInterface
{ {
if (null !== $this->result) { if (null !== $this->result) {
return $this->result->then($onFulfilled, $onRejected); return $this->result->then($onFulfilled, $onRejected);
@ -166,7 +166,7 @@ final class Promise implements PromiseInterface
return $this->finally($onFulfilledOrRejected); return $this->finally($onFulfilledOrRejected);
} }
private function resolver(callable $onFulfilled = null, callable $onRejected = null): callable private function resolver(?callable $onFulfilled = null, ?callable $onRejected = null): callable
{ {
return function (callable $resolve, callable $reject) use ($onFulfilled, $onRejected): void { return function (callable $resolve, callable $reject) use ($onFulfilled, $onRejected): void {
$this->handlers[] = static function (PromiseInterface $promise) use ($onFulfilled, $onRejected, $resolve, $reject): void { $this->handlers[] = static function (PromiseInterface $promise) use ($onFulfilled, $onRejected, $resolve, $reject): void {

View file

@ -1,5 +1,10 @@
# Changelog # Changelog
## 1.16.0 (2024-07-26)
* Feature: Improve PHP 8.4+ support by avoiding implicitly nullable type declarations.
(#318 by @clue)
## 1.15.0 (2023-12-15) ## 1.15.0 (2023-12-15)
* Feature: Full PHP 8.3 compatibility. * Feature: Full PHP 8.3 compatibility.

View file

@ -1494,7 +1494,7 @@ This project follows [SemVer](https://semver.org/).
This will install the latest supported version: This will install the latest supported version:
```bash ```bash
composer require react/socket:^1.15 composer require react/socket:^1.16
``` ```
See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades. See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades.

View file

@ -28,16 +28,16 @@
"require": { "require": {
"php": ">=5.3.0", "php": ">=5.3.0",
"evenement/evenement": "^3.0 || ^2.0 || ^1.0", "evenement/evenement": "^3.0 || ^2.0 || ^1.0",
"react/dns": "^1.11", "react/dns": "^1.13",
"react/event-loop": "^1.2", "react/event-loop": "^1.2",
"react/promise": "^3 || ^2.6 || ^1.2.1", "react/promise": "^3.2 || ^2.6 || ^1.2.1",
"react/stream": "^1.2" "react/stream": "^1.4"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36",
"react/async": "^4 || ^3 || ^2", "react/async": "^4.3 || ^3.3 || ^2",
"react/promise-stream": "^1.4", "react/promise-stream": "^1.4",
"react/promise-timer": "^1.10" "react/promise-timer": "^1.11"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {

View file

@ -75,7 +75,7 @@ final class FdServer extends EventEmitter implements ServerInterface
* @throws \InvalidArgumentException if the listening address is invalid * @throws \InvalidArgumentException if the listening address is invalid
* @throws \RuntimeException if listening on this address fails (already in use etc.) * @throws \RuntimeException if listening on this address fails (already in use etc.)
*/ */
public function __construct($fd, LoopInterface $loop = null) public function __construct($fd, $loop = null)
{ {
if (\preg_match('#^php://fd/(\d+)$#', $fd, $m)) { if (\preg_match('#^php://fd/(\d+)$#', $fd, $m)) {
$fd = (int) $m[1]; $fd = (int) $m[1];
@ -87,6 +87,10 @@ final class FdServer extends EventEmitter implements ServerInterface
); );
} }
if ($loop !== null && !$loop instanceof LoopInterface) { // manual type check to support legacy PHP < 7.1
throw new \InvalidArgumentException('Argument #2 ($loop) expected null|React\EventLoop\LoopInterface');
}
$this->loop = $loop ?: Loop::get(); $this->loop = $loop ?: Loop::get();
$errno = 0; $errno = 0;

View file

@ -13,15 +13,26 @@ final class HappyEyeBallsConnector implements ConnectorInterface
private $connector; private $connector;
private $resolver; private $resolver;
public function __construct(LoopInterface $loop = null, ConnectorInterface $connector = null, ResolverInterface $resolver = null) /**
* @param ?LoopInterface $loop
* @param ConnectorInterface $connector
* @param ResolverInterface $resolver
*/
public function __construct($loop = null, $connector = null, $resolver = null)
{ {
// $connector and $resolver arguments are actually required, marked // $connector and $resolver arguments are actually required, marked
// optional for technical reasons only. Nullable $loop without default // optional for technical reasons only. Nullable $loop without default
// requires PHP 7.1, null default is also supported in legacy PHP // requires PHP 7.1, null default is also supported in legacy PHP
// versions, but required parameters are not allowed after arguments // versions, but required parameters are not allowed after arguments
// with null default. Mark all parameters optional and check accordingly. // with null default. Mark all parameters optional and check accordingly.
if ($connector === null || $resolver === null) { if ($loop !== null && !$loop instanceof LoopInterface) { // manual type check to support legacy PHP < 7.1
throw new \InvalidArgumentException('Missing required $connector or $resolver argument'); throw new \InvalidArgumentException('Argument #1 ($loop) expected null|React\EventLoop\LoopInterface');
}
if (!$connector instanceof ConnectorInterface) { // manual type check to support legacy PHP < 7.1
throw new \InvalidArgumentException('Argument #2 ($connector) expected React\Socket\ConnectorInterface');
}
if (!$resolver instanceof ResolverInterface) { // manual type check to support legacy PHP < 7.1
throw new \InvalidArgumentException('Argument #3 ($resolver) expected React\Dns\Resolver\ResolverInterface');
} }
$this->loop = $loop ?: Loop::get(); $this->loop = $loop ?: Loop::get();

View file

@ -15,8 +15,17 @@ final class SecureConnector implements ConnectorInterface
private $streamEncryption; private $streamEncryption;
private $context; private $context;
public function __construct(ConnectorInterface $connector, LoopInterface $loop = null, array $context = array()) /**
* @param ConnectorInterface $connector
* @param ?LoopInterface $loop
* @param array $context
*/
public function __construct(ConnectorInterface $connector, $loop = null, array $context = array())
{ {
if ($loop !== null && !$loop instanceof LoopInterface) { // manual type check to support legacy PHP < 7.1
throw new \InvalidArgumentException('Argument #2 ($loop) expected null|React\EventLoop\LoopInterface');
}
$this->connector = $connector; $this->connector = $connector;
$this->streamEncryption = new StreamEncryption($loop ?: Loop::get(), false); $this->streamEncryption = new StreamEncryption($loop ?: Loop::get(), false);
$this->context = $context; $this->context = $context;

View file

@ -122,8 +122,12 @@ final class SecureServer extends EventEmitter implements ServerInterface
* @see TcpServer * @see TcpServer
* @link https://www.php.net/manual/en/context.ssl.php for TLS context options * @link https://www.php.net/manual/en/context.ssl.php for TLS context options
*/ */
public function __construct(ServerInterface $tcp, LoopInterface $loop = null, array $context = array()) public function __construct(ServerInterface $tcp, $loop = null, array $context = array())
{ {
if ($loop !== null && !$loop instanceof LoopInterface) { // manual type check to support legacy PHP < 7.1
throw new \InvalidArgumentException('Argument #2 ($loop) expected null|React\EventLoop\LoopInterface');
}
if (!\function_exists('stream_socket_enable_crypto')) { if (!\function_exists('stream_socket_enable_crypto')) {
throw new \BadMethodCallException('Encryption not supported on your platform (HHVM < 3.8?)'); // @codeCoverageIgnore throw new \BadMethodCallException('Encryption not supported on your platform (HHVM < 3.8?)'); // @codeCoverageIgnore
} }

View file

@ -43,14 +43,18 @@ final class Server extends EventEmitter implements ServerInterface
* For BC reasons, you can also pass the TCP socket context options as a simple * For BC reasons, you can also pass the TCP socket context options as a simple
* array without wrapping this in another array under the `tcp` key. * array without wrapping this in another array under the `tcp` key.
* *
* @param string|int $uri * @param string|int $uri
* @param LoopInterface $loop * @param ?LoopInterface $loop
* @param array $context * @param array $context
* @deprecated 1.9.0 See `SocketServer` instead * @deprecated 1.9.0 See `SocketServer` instead
* @see SocketServer * @see SocketServer
*/ */
public function __construct($uri, LoopInterface $loop = null, array $context = array()) public function __construct($uri, $loop = null, array $context = array())
{ {
if ($loop !== null && !$loop instanceof LoopInterface) { // manual type check to support legacy PHP < 7.1
throw new \InvalidArgumentException('Argument #2 ($loop) expected null|React\EventLoop\LoopInterface');
}
$loop = $loop ?: Loop::get(); $loop = $loop ?: Loop::get();
// sanitize TCP context options if not properly wrapped // sanitize TCP context options if not properly wrapped

View file

@ -31,8 +31,12 @@ final class SocketServer extends EventEmitter implements ServerInterface
* @throws \InvalidArgumentException if the listening address is invalid * @throws \InvalidArgumentException if the listening address is invalid
* @throws \RuntimeException if listening on this address fails (already in use etc.) * @throws \RuntimeException if listening on this address fails (already in use etc.)
*/ */
public function __construct($uri, array $context = array(), LoopInterface $loop = null) public function __construct($uri, array $context = array(), $loop = null)
{ {
if ($loop !== null && !$loop instanceof LoopInterface) { // manual type check to support legacy PHP < 7.1
throw new \InvalidArgumentException('Argument #3 ($loop) expected null|React\EventLoop\LoopInterface');
}
// apply default options if not explicitly given // apply default options if not explicitly given
$context += array( $context += array(
'tcp' => array(), 'tcp' => array(),

View file

@ -13,8 +13,16 @@ final class TcpConnector implements ConnectorInterface
private $loop; private $loop;
private $context; private $context;
public function __construct(LoopInterface $loop = null, array $context = array()) /**
* @param ?LoopInterface $loop
* @param array $context
*/
public function __construct($loop = null, array $context = array())
{ {
if ($loop !== null && !$loop instanceof LoopInterface) { // manual type check to support legacy PHP < 7.1
throw new \InvalidArgumentException('Argument #1 ($loop) expected null|React\EventLoop\LoopInterface');
}
$this->loop = $loop ?: Loop::get(); $this->loop = $loop ?: Loop::get();
$this->context = $context; $this->context = $context;
} }

View file

@ -128,8 +128,12 @@ final class TcpServer extends EventEmitter implements ServerInterface
* @throws InvalidArgumentException if the listening address is invalid * @throws InvalidArgumentException if the listening address is invalid
* @throws RuntimeException if listening on this address fails (already in use etc.) * @throws RuntimeException if listening on this address fails (already in use etc.)
*/ */
public function __construct($uri, LoopInterface $loop = null, array $context = array()) public function __construct($uri, $loop = null, array $context = array())
{ {
if ($loop !== null && !$loop instanceof LoopInterface) { // manual type check to support legacy PHP < 7.1
throw new \InvalidArgumentException('Argument #2 ($loop) expected null|React\EventLoop\LoopInterface');
}
$this->loop = $loop ?: Loop::get(); $this->loop = $loop ?: Loop::get();
// a single port has been given => assume localhost // a single port has been given => assume localhost

View file

@ -12,8 +12,17 @@ final class TimeoutConnector implements ConnectorInterface
private $timeout; private $timeout;
private $loop; private $loop;
public function __construct(ConnectorInterface $connector, $timeout, LoopInterface $loop = null) /**
* @param ConnectorInterface $connector
* @param float $timeout
* @param ?LoopInterface $loop
*/
public function __construct(ConnectorInterface $connector, $timeout, $loop = null)
{ {
if ($loop !== null && !$loop instanceof LoopInterface) { // manual type check to support legacy PHP < 7.1
throw new \InvalidArgumentException('Argument #3 ($loop) expected null|React\EventLoop\LoopInterface');
}
$this->connector = $connector; $this->connector = $connector;
$this->timeout = $timeout; $this->timeout = $timeout;
$this->loop = $loop ?: Loop::get(); $this->loop = $loop ?: Loop::get();

View file

@ -18,8 +18,15 @@ final class UnixConnector implements ConnectorInterface
{ {
private $loop; private $loop;
public function __construct(LoopInterface $loop = null) /**
* @param ?LoopInterface $loop
*/
public function __construct($loop = null)
{ {
if ($loop !== null && !$loop instanceof LoopInterface) { // manual type check to support legacy PHP < 7.1
throw new \InvalidArgumentException('Argument #1 ($loop) expected null|React\EventLoop\LoopInterface');
}
$this->loop = $loop ?: Loop::get(); $this->loop = $loop ?: Loop::get();
} }

View file

@ -50,8 +50,12 @@ final class UnixServer extends EventEmitter implements ServerInterface
* @throws InvalidArgumentException if the listening address is invalid * @throws InvalidArgumentException if the listening address is invalid
* @throws RuntimeException if listening on this address fails (already in use etc.) * @throws RuntimeException if listening on this address fails (already in use etc.)
*/ */
public function __construct($path, LoopInterface $loop = null, array $context = array()) public function __construct($path, $loop = null, array $context = array())
{ {
if ($loop !== null && !$loop instanceof LoopInterface) { // manual type check to support legacy PHP < 7.1
throw new \InvalidArgumentException('Argument #2 ($loop) expected null|React\EventLoop\LoopInterface');
}
$this->loop = $loop ?: Loop::get(); $this->loop = $loop ?: Loop::get();
if (\strpos($path, '://') === false) { if (\strpos($path, '://') === false) {

View file

@ -1,5 +1,16 @@
# Changelog # Changelog
## 1.4.0 (2024-06-11)
* Feature: Improve PHP 8.4+ support by avoiding implicitly nullable type declarations.
(#179 by @clue)
* Feature: Full PHP 8.3 compatibility.
(#172 by @clue)
* Fix: Fix `drain` event of `ThroughStream` to handle potential race condition.
(#171 by @clue)
## 1.3.0 (2023-06-16) ## 1.3.0 (2023-06-16)
* Feature: Full PHP 8.1 and PHP 8.2 compatibility. * Feature: Full PHP 8.1 and PHP 8.2 compatibility.

View file

@ -1203,7 +1203,7 @@ This project follows [SemVer](https://semver.org/).
This will install the latest supported version: This will install the latest supported version:
```bash ```bash
composer require react/stream:^1.3 composer require react/stream:^1.4
``` ```
See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades. See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades.

View file

@ -31,7 +31,7 @@
"evenement/evenement": "^3.0 || ^2.0 || ^1.0" "evenement/evenement": "^3.0 || ^2.0 || ^1.0"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35", "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36",
"clue/stream-filter": "~1.2" "clue/stream-filter": "~1.2"
}, },
"autoload": { "autoload": {

View file

@ -38,7 +38,13 @@ final class DuplexResourceStream extends EventEmitter implements DuplexStreamInt
private $closing = false; private $closing = false;
private $listening = false; private $listening = false;
public function __construct($stream, LoopInterface $loop = null, $readChunkSize = null, WritableStreamInterface $buffer = null) /**
* @param resource $stream
* @param ?LoopInterface $loop
* @param ?int $readChunkSize
* @param ?WritableStreamInterface $buffer
*/
public function __construct($stream, $loop = null, $readChunkSize = null, $buffer = null)
{ {
if (!\is_resource($stream) || \get_resource_type($stream) !== "stream") { if (!\is_resource($stream) || \get_resource_type($stream) !== "stream") {
throw new InvalidArgumentException('First parameter must be a valid stream resource'); throw new InvalidArgumentException('First parameter must be a valid stream resource');
@ -56,6 +62,13 @@ final class DuplexResourceStream extends EventEmitter implements DuplexStreamInt
throw new \RuntimeException('Unable to set stream resource to non-blocking mode'); throw new \RuntimeException('Unable to set stream resource to non-blocking mode');
} }
if ($loop !== null && !$loop instanceof LoopInterface) { // manual type check to support legacy PHP < 7.1
throw new \InvalidArgumentException('Argument #2 ($loop) expected null|React\EventLoop\LoopInterface');
}
if ($buffer !== null && !$buffer instanceof WritableStreamInterface) { // manual type check to support legacy PHP < 7.1
throw new \InvalidArgumentException('Argument #4 ($buffer) expected null|React\Stream\WritableStreamInterface');
}
// Use unbuffered read operations on the underlying stream resource. // Use unbuffered read operations on the underlying stream resource.
// Reading chunks from the stream may otherwise leave unread bytes in // Reading chunks from the stream may otherwise leave unread bytes in
// PHP's stream buffers which some event loop implementations do not // PHP's stream buffers which some event loop implementations do not

View file

@ -40,7 +40,12 @@ final class ReadableResourceStream extends EventEmitter implements ReadableStrea
private $closed = false; private $closed = false;
private $listening = false; private $listening = false;
public function __construct($stream, LoopInterface $loop = null, $readChunkSize = null) /**
* @param resource $stream
* @param ?LoopInterface $loop
* @param ?int $readChunkSize
*/
public function __construct($stream, $loop = null, $readChunkSize = null)
{ {
if (!\is_resource($stream) || \get_resource_type($stream) !== "stream") { if (!\is_resource($stream) || \get_resource_type($stream) !== "stream") {
throw new InvalidArgumentException('First parameter must be a valid stream resource'); throw new InvalidArgumentException('First parameter must be a valid stream resource');
@ -58,6 +63,10 @@ final class ReadableResourceStream extends EventEmitter implements ReadableStrea
throw new \RuntimeException('Unable to set stream resource to non-blocking mode'); throw new \RuntimeException('Unable to set stream resource to non-blocking mode');
} }
if ($loop !== null && !$loop instanceof LoopInterface) { // manual type check to support legacy PHP < 7.1
throw new \InvalidArgumentException('Argument #2 ($loop) expected null|React\EventLoop\LoopInterface');
}
// Use unbuffered read operations on the underlying stream resource. // Use unbuffered read operations on the underlying stream resource.
// Reading chunks from the stream may otherwise leave unread bytes in // Reading chunks from the stream may otherwise leave unread bytes in
// PHP's stream buffers which some event loop implementations do not // PHP's stream buffers which some event loop implementations do not

View file

@ -93,16 +93,19 @@ final class ThroughStream extends EventEmitter implements DuplexStreamInterface
public function pause() public function pause()
{ {
$this->paused = true; // only allow pause if still readable, false otherwise
$this->paused = $this->readable;
} }
public function resume() public function resume()
{ {
$this->paused = false;
// emit drain event if previous write was paused (throttled)
if ($this->drain) { if ($this->drain) {
$this->drain = false; $this->drain = false;
$this->emit('drain'); $this->emit('drain');
} }
$this->paused = false;
} }
public function pipe(WritableStreamInterface $dest, array $options = array()) public function pipe(WritableStreamInterface $dest, array $options = array())
@ -139,12 +142,13 @@ final class ThroughStream extends EventEmitter implements DuplexStreamInterface
$this->emit('data', array($data)); $this->emit('data', array($data));
// emit drain event on next resume if currently paused (throttled)
if ($this->paused) { if ($this->paused) {
$this->drain = true; $this->drain = true;
return false;
} }
return true; // continue writing if still writable and not paused (throttled), false otherwise
return $this->writable && !$this->paused;
} }
public function end($data = null) public function end($data = null)
@ -164,7 +168,7 @@ final class ThroughStream extends EventEmitter implements DuplexStreamInterface
$this->readable = false; $this->readable = false;
$this->writable = false; $this->writable = false;
$this->paused = true; $this->paused = false;
$this->drain = false; $this->drain = false;
$this->emit('end'); $this->emit('end');
@ -179,9 +183,10 @@ final class ThroughStream extends EventEmitter implements DuplexStreamInterface
$this->readable = false; $this->readable = false;
$this->writable = false; $this->writable = false;
$this->closed = true; $this->paused = false;
$this->paused = true;
$this->drain = false; $this->drain = false;
$this->closed = true;
$this->callback = null; $this->callback = null;
$this->emit('close'); $this->emit('close');

View file

@ -28,7 +28,13 @@ final class WritableResourceStream extends EventEmitter implements WritableStrea
private $closed = false; private $closed = false;
private $data = ''; private $data = '';
public function __construct($stream, LoopInterface $loop = null, $writeBufferSoftLimit = null, $writeChunkSize = null) /**
* @param resource $stream
* @param ?LoopInterface $loop
* @param ?int $writeBufferSoftLimit
* @param ?int $writeChunkSize
*/
public function __construct($stream, $loop = null, $writeBufferSoftLimit = null, $writeChunkSize = null)
{ {
if (!\is_resource($stream) || \get_resource_type($stream) !== "stream") { if (!\is_resource($stream) || \get_resource_type($stream) !== "stream") {
throw new \InvalidArgumentException('First parameter must be a valid stream resource'); throw new \InvalidArgumentException('First parameter must be a valid stream resource');
@ -46,6 +52,10 @@ final class WritableResourceStream extends EventEmitter implements WritableStrea
throw new \RuntimeException('Unable to set stream resource to non-blocking mode'); throw new \RuntimeException('Unable to set stream resource to non-blocking mode');
} }
if ($loop !== null && !$loop instanceof LoopInterface) { // manual type check to support legacy PHP < 7.1
throw new \InvalidArgumentException('Argument #2 ($loop) expected null|React\EventLoop\LoopInterface');
}
$this->stream = $stream; $this->stream = $stream;
$this->loop = $loop ?: Loop::get(); $this->loop = $loop ?: Loop::get();
$this->softLimit = ($writeBufferSoftLimit === null) ? 65536 : (int)$writeBufferSoftLimit; $this->softLimit = ($writeBufferSoftLimit === null) ? 65536 : (int)$writeBufferSoftLimit;

61
vendor/spomky-labs/otphp/.php_cs.dist vendored Normal file
View file

@ -0,0 +1,61 @@
<?php
$header = 'The MIT License (MIT)
Copyright (c) 2014-2019 Spomky-Labs
This software may be modified and distributed under the terms
of the MIT license. See the LICENSE file for details.';
$finder = PhpCsFixer\Finder::create()
->in(__DIR__.'/src')
->in(__DIR__.'/tests')
;
return PhpCsFixer\Config::create()
->setRules([
'@PSR1' => true,
'@PSR2' => true,
'@Symfony' => true,
'@DoctrineAnnotation' => true,
'@PHP70Migration' => true,
'@PHP71Migration' => true,
'strict_param' => true,
'strict_comparison' => true,
'array_syntax' => ['syntax' => 'short'],
'array_indentation' => true,
'ordered_imports' => true,
'protected_to_private' => true,
'declare_strict_types' => true,
'native_function_invocation' => [
'include' => ['@compiler_optimized'],
'scope' => 'namespaced',
],
'mb_str_functions' => true,
'method_chaining_indentation' => true,
'linebreak_after_opening_tag' => true,
'combine_consecutive_issets' => true,
'combine_consecutive_unsets' => true,
'compact_nullable_typehint' => true,
'no_superfluous_phpdoc_tags' => true,
'no_superfluous_elseif' => true,
'phpdoc_trim_consecutive_blank_line_separation' => true,
'phpdoc_order' => true,
'pow_to_exponentiation' => true,
'simplified_null_return' => true,
'header_comment' => [
'header' => $header,
],
'align_multiline_comment' => [
'comment_type' => 'all_multiline',
],
'php_unit_test_annotation' => [
'case' => 'snake',
'style' => 'annotation',
],
'php_unit_test_case_static_method_calls' => true,
])
->setRiskyAllowed(true)
->setUsingCache(true)
->setFinder($finder)
;

View file

@ -0,0 +1,46 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at contact@spomky-labs.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

20
vendor/spomky-labs/otphp/LICENSE vendored Normal file
View file

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2014-2016 Florent Morselli
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.

88
vendor/spomky-labs/otphp/SECURITY.md vendored Normal file
View file

@ -0,0 +1,88 @@
# Security Policy
## Supported Versions
| Version | Supported |
| ------- | ------------------ |
| 11.0.x | :white_check_mark: |
| 10.0.x | :white_check_mark: |
| < 10.0 | :x: |
## Reporting a Vulnerability
Please send an email to `security@spomky-labs.com`.
If deemed necessary, you can encrypt your message using one of the following GPG key
```
-----BEGIN PGP PUBLIC KEY BLOCK-----
xjMEXTsJVxYJKwYBBAHaRw8BAQdAZCS93eHRx97V+LQbAWuAaeKIdUZ9YIkn
QH5pQ7dDU0TNMWNvbnRhY3RAc3BvbWt5LWxhYnMuY29tIDxjb250YWN0QHNw
b21reS1sYWJzLmNvbT7CdwQQFgoAHwUCXTsJVwYLCQcIAwIEFQgKAgMWAgEC
GQECGwMCHgEACgkQG6hbCDSDj+1/tgEAoy11uHvDV7kkG/iN2/0ylV72hU8y
c/xoqGd7qFaKD6ABANcthlg63OrQVTf0dUPOT9Y2BJpOOA88JJWgILtuUPIO
zjgEXTsJVxIKKwYBBAGXVQEFAQEHQKiX7nldkmICePhzwReZnBPmjpsmNt7V
Y8xHdICKsr8cAwEIB8JhBBgWCAAJBQJdOwlXAhsMAAoJEBuoWwg0g4/t0KgA
/31ucb/bL/MGpWFrpSjTs6uQhZWlBmcFoeMhwCYepIpZAQDd65UBqFDKXJWv
Xy3zoMQQzD9Z6fUATnFrWkzjHwhvDQ==
=j4dw
-----END PGP PUBLIC KEY BLOCK-----
```
```
-----BEGIN PGP PUBLIC KEY BLOCK-----
xsFNBGILZFoBEADo9pzAMRVxL5typ22Ywifdyi3CMHgg7zptfb8otrQci8IX
m7B8/NTA0I9EkenzSW/Mf4k2iPNCwXc+qVEHPvPNvr3WazcdiDQJjXqMtkxG
l2dvdQHdBxN46v+mvWDVGf9anYQxIAmZrj7CDLOfD/cG/8STL4hSbFjRBOKs
xAP8wgRA/amcrf9WcCDxURGIq8mDPcECR8fca+iukTmMe2NDEc56pJi0KVoF
pFhOMMfjgP/XvtGjjSNZNGRgHSLTQs8UiK+5BjPh+iWFIPV5+ZPLpbSOcoma
GyeX5i1DmAh7cWx/FphvFzOun6to3ERuy82+zW54iA9zS8+kIfV4Wjr2qE7l
Ctc9l8RIv/6dMXoW2Y42CTuywlAMnlP7XaaUgE++CXTIuO7+6Gp0E5NlmqB5
lb+CZLV/LS27gUcajs23ve5B3UId2bGUflvTtY/J0VPzrJMoEErVnkCsnD7W
Oiwe8GiSNMJmTGu/A45xf5nuYNcuU7blA5XXwPoHZuALj1zv6eCWVxWz02l9
Fc/T+gNkOEErlXOcldyXxQ5Qb99TU5NgdqzbibyR9QAqdfwtgg19oFbiSP7t
8b5P2qAIW2GaOCkX007cBCzTXNrcQNruTwUD59LZQLhdGz5WJo/gefC/3ZvR
vKoJKCRlk7s43aUjeZzE+Engpr5e1wl63WjAzQARAQABzTNzZWN1cml0eUBz
cG9ta3ktbGFicy5jb20gPHNlY3VyaXR5QHNwb21reS1sYWJzLmNvbT7CwY0E
EAEIACAFAmILZFoGCwkHCAMCBBUICgIEFgIBAAIZAQIbAwIeAQAhCRBy14gx
FHv4aBYhBKgF8zJv89FYVv0RFHLXiDEUe/hoA+YP/ijaePtilKURzNVrPWfc
gDw/ZNCR+dVAgwGo9VcbOvkyZmyqD6yBjuDWvG96KQs0LRrqWKonAvnewNtp
wQruuvrlcCuNE6TTfvx0wh2+lwKD7MH5dKutHUCowVNAsZ5uZxHVF9RGLBh+
JRofklupcGqUx+Jtx4uq2gAGOqV4/QdvneMjkLwqVu8FGIM59LfdNfp/iA3p
wX2DvfxBO58Gu6hilmf7R+b9nX0U7xYJM6QJb7H89cV3/AoTh2kf1wtFY+Py
Di6VZTMUBYOoz2iSnvCE8KlBWDu98/A2EJ7kDGQdmnuIgsURsyap3yKioaUr
LGTaG0OiC/gkXkKisH6eff6Gw06qelBarf5N/GgoeAN/amE8twy3a+Hx1pyw
ZzkjPsL7uWg3Koy5mPuCtWfPtIBcJaTLS5d8ESlJ8/CfaVaDludzYQZo70Xn
m4KzjPnptm3djpZNwoFEUxrHVREOEe69/MnEL2PNcEMQkapg16PnH4phajnC
7bYOPDteMJlHjNmQzz9d25ZwzVBHDDT50mHDijR2D/OgKx3NQr88fiFAWhKG
lEu1ZuOkKIKV5VIFbocTWSoV7bkzIfrll49xWou+4VOxgRuqjquFC4RV8fea
lLbHOcJlOR00aFDmoOWQ3/QNvajaWJFzDdocGbgbnEBMDFRoUkuhqOBcnzA+
apW/zsFNBGILZFoBEADSwiM49wObRpxOyas91M6WvJ4Gt3iXqj+L8dmcw0FW
UdDpwOxy8tuZx+OfXEBBH3eJHOobC66vN+E9WYobVkJ5zfbGxfQruTuvUZNl
X9Lo0UwoP+AP21AKUUvsf48iZGWzmlkxgPnhAQS4ECkkWCKPf7nFTk+V+jIN
nf6ZDZLXaRUnG0nLvzs0raG1eTVrGvPSCC8u3R2zIh9SvoeEgTnT/Re0mhCu
ah3fwG+4vXc6VIjR1ZtpM9+Y8sl+PFZ/Oiisc+46oU5qXVVLtHfLdxYZ4vl2
IflHDKKmrfbfGY1hJl/foBLglT3Cd8GTu3FjiAJX9PpkiWbsflc0OUBQf9aC
73W5FLS4P4clm4nNzVGkNucWHvk+urM6nEUf02bhsfF0TPeos3QcJorfKNUS
TvuGYccENuK5cVOzEcU+VhN08GT0pr0CpqJnsw+zV8vD4k3aPmMFmSVog+bY
NhfB7AgwbOjd6MhQJcP7YjYTHaa6YsnKMSg4RhkDjvMa3421hfaWsVvlIb0f
AZJ8BnXgfE0uI8CKA9dc6I2Posl33zC8HI2sS1MEJ90Am68P+uJt61LdJeD5
VXSrCkzBhUBds0hbGR6+DF20UD496m7Lw3VBoWOl2bMeLdERDarFMDYsPH47
rie9wlrnPNR57HUqK4bpkFwqTStRkRFUhFv7LLWZ1QARAQABwsF2BBgBCAAJ
BQJiC2RaAhsMACEJEHLXiDEUe/hoFiEEqAXzMm/z0VhW/REUcteIMRR7+GhI
lQ/9GbSwIdGue6Gw0msYAEoER9HhpYB//9/GG7/c4ZW60nLSSYuhNWIo0Akl
10CzeApezf/O9/1EExqZ9ygj4wtUphcQOdRJVhXPt+gskw7/NHoXUJ+Z1rbb
EWbKle9YufZ4PAKYhlxdqTlWyQvPVxrRvbuhYeQG4S412VzKjH0/x1Fh2CfV
hFuyOaRjg89T6rihXL1rCSJ/PDQeQtvtXeJ30yFj+aapCj+VqUl+2D+N0bzS
LL18kEPQnJw4BOHOXrw349dAKmHN/QkRH8DINlXLyaOlABglnSViDQL3Q1t3
sBuIeClsl3brQNJRp/RKOdTBMNAX+BhAjqodbwwT+UkJl9xJKw0Cla4wtbs2
T0yoK/Z1iFfvPdufkK4q6ocAHJUp3+XckFIZxsHQvhQPbm9XoOt1RTO29MOw
EYo8UjFQCnXJVsj1/6XMgIUe5tPYvS/ZZZNJFF4j+OE8xRKLKqg/DFcpEipC
LCmzzr/hhWx0XP4CIK2tYsAMk3ieCZuk1Wa+NGLL4WfALWsNHq3wg5Wzv+yJ
dp14fv711BVYlriI+VKggGFgBdz0dWkgrBk4+thLatJFcjFYr8BLkbtPraa3
sFI/cGxvOXSIy4GEALdfnozyU3RJtMNtVi3IzGeIFAOb457y/IrMqpWLp1FX
BUqlX5YJHneD9Q8Sfz/HKDQDCqg=
=o+4z
-----END PGP PUBLIC KEY BLOCK-----
```

50
vendor/spomky-labs/otphp/composer.json vendored Normal file
View file

@ -0,0 +1,50 @@
{
"name": "spomky-labs/otphp",
"type": "library",
"description": "A PHP library for generating one time passwords according to RFC 4226 (HOTP Algorithm) and the RFC 6238 (TOTP Algorithm) and compatible with Google Authenticator",
"license": "MIT",
"keywords": ["otp", "hotp", "totp", "RFC 4226", "RFC 6238", "Google Authenticator", "FreeOTP"],
"homepage": "https://github.com/Spomky-Labs/otphp",
"authors": [
{
"name": "Florent Morselli",
"homepage": "https://github.com/Spomky"
},
{
"name": "All contributors",
"homepage": "https://github.com/Spomky-Labs/otphp/contributors"
}
],
"require": {
"php": "^7.2|^8.0",
"ext-mbstring": "*",
"paragonie/constant_time_encoding": "^2.0",
"beberlei/assert": "^3.0",
"thecodingmachine/safe": "^0.1.14|^1.0|^2.0"
},
"require-dev": {
"phpunit/phpunit": "^8.0",
"php-coveralls/php-coveralls": "^2.0",
"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",
"thecodingmachine/phpstan-safe-rule": "^1.0 || ^2.0"
},
"suggest": {
},
"autoload": {
"psr-4": { "OTPHP\\": "src/" }
},
"autoload-dev": {
"psr-4": { "OTPHP\\Test\\": "tests/" }
},
"extra": {
"branch-alias": {
"v10.0": "10.0.x-dev",
"v9.0": "9.0.x-dev",
"v8.3": "8.3.x-dev"
}
}
}

13
vendor/spomky-labs/otphp/phpstan.neon vendored Normal file
View file

@ -0,0 +1,13 @@
parameters:
level: 7
paths:
- src
- tests
ignoreErrors:
- '#Variable property access on \$this\(OTPHP\\OTP\)\.#'
includes:
- vendor/phpstan/phpstan-strict-rules/rules.neon
- vendor/phpstan/phpstan-phpunit/extension.neon
- vendor/phpstan/phpstan-deprecation-rules/rules.neon
- vendor/thecodingmachine/phpstan-safe-rule/phpstan-safe-rule.neon
- vendor/phpstan/phpstan-beberlei-assert/extension.neon

115
vendor/spomky-labs/otphp/src/Factory.php vendored Normal file
View file

@ -0,0 +1,115 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2019 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace OTPHP;
use Assert\Assertion;
use InvalidArgumentException;
use function Safe\parse_url;
use function Safe\sprintf;
use Throwable;
/**
* This class is used to load OTP object from a provisioning Uri.
*/
final class Factory implements FactoryInterface
{
public static function loadFromProvisioningUri(string $uri): OTPInterface
{
try {
$parsed_url = parse_url($uri);
} catch (Throwable $throwable) {
throw new InvalidArgumentException('Not a valid OTP provisioning URI', $throwable->getCode(), $throwable);
}
Assertion::isArray($parsed_url, 'Not a valid OTP provisioning URI');
self::checkData($parsed_url);
$otp = self::createOTP($parsed_url);
self::populateOTP($otp, $parsed_url);
return $otp;
}
/**
* @param array<string, mixed> $data
*/
private static function populateParameters(OTPInterface &$otp, array $data): void
{
foreach ($data['query'] as $key => $value) {
$otp->setParameter($key, $value);
}
}
/**
* @param array<string, mixed> $data
*/
private static function populateOTP(OTPInterface &$otp, array $data): void
{
self::populateParameters($otp, $data);
$result = explode(':', rawurldecode(mb_substr($data['path'], 1)));
if (2 > \count($result)) {
$otp->setIssuerIncludedAsParameter(false);
return;
}
if (null !== $otp->getIssuer()) {
Assertion::eq($result[0], $otp->getIssuer(), 'Invalid OTP: invalid issuer in parameter');
$otp->setIssuerIncludedAsParameter(true);
}
$otp->setIssuer($result[0]);
}
/**
* @param array<string, mixed> $data
*/
private static function checkData(array &$data): void
{
foreach (['scheme', 'host', 'path', 'query'] as $key) {
Assertion::keyExists($data, $key, 'Not a valid OTP provisioning URI');
}
Assertion::eq('otpauth', $data['scheme'], 'Not a valid OTP provisioning URI');
parse_str($data['query'], $data['query']);
Assertion::keyExists($data['query'], 'secret', 'Not a valid OTP provisioning URI');
}
/**
* @param array<string, mixed> $parsed_url
*/
private static function createOTP(array $parsed_url): OTPInterface
{
switch ($parsed_url['host']) {
case 'totp':
$totp = TOTP::create($parsed_url['query']['secret']);
$totp->setLabel(self::getLabel($parsed_url['path']));
return $totp;
case 'hotp':
$hotp = HOTP::create($parsed_url['query']['secret']);
$hotp->setLabel(self::getLabel($parsed_url['path']));
return $hotp;
default:
throw new InvalidArgumentException(sprintf('Unsupported "%s" OTP type', $parsed_url['host']));
}
}
private static function getLabel(string $data): string
{
$result = explode(':', rawurldecode(mb_substr($data, 1)));
return 2 === \count($result) ? $result[1] : $result[0];
}
}

View file

@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2019 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace OTPHP;
interface FactoryInterface
{
/**
* This method is the unique public method of the class.
* It can load a provisioning Uri and convert it into an OTP object.
*/
public static function loadFromProvisioningUri(string $uri): OTPInterface;
}

103
vendor/spomky-labs/otphp/src/HOTP.php vendored Normal file
View file

@ -0,0 +1,103 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2019 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace OTPHP;
use Assert\Assertion;
final class HOTP extends OTP implements HOTPInterface
{
protected function __construct(?string $secret, int $counter, string $digest, int $digits)
{
parent::__construct($secret, $digest, $digits);
$this->setCounter($counter);
}
public static function create(?string $secret = null, int $counter = 0, string $digest = 'sha1', int $digits = 6): HOTPInterface
{
return new self($secret, $counter, $digest, $digits);
}
protected function setCounter(int $counter): void
{
$this->setParameter('counter', $counter);
}
public function getCounter(): int
{
return $this->getParameter('counter');
}
private function updateCounter(int $counter): void
{
$this->setCounter($counter);
}
public function getProvisioningUri(): string
{
return $this->generateURI('hotp', ['counter' => $this->getCounter()]);
}
/**
* If the counter is not provided, the OTP is verified at the actual counter.
*/
public function verify(string $otp, ?int $counter = null, ?int $window = null): bool
{
Assertion::greaterOrEqualThan($counter, 0, 'The counter must be at least 0.');
if (null === $counter) {
$counter = $this->getCounter();
} elseif ($counter < $this->getCounter()) {
return false;
}
return $this->verifyOtpWithWindow($otp, $counter, $window);
}
private function getWindow(?int $window): int
{
return abs($window ?? 0);
}
private function verifyOtpWithWindow(string $otp, int $counter, ?int $window): bool
{
$window = $this->getWindow($window);
for ($i = $counter; $i <= $counter + $window; ++$i) {
if ($this->compareOTP($this->at($i), $otp)) {
$this->updateCounter($i + 1);
return true;
}
}
return false;
}
/**
* @return array<string, mixed>
*/
protected function getParameterMap(): array
{
$v = array_merge(
parent::getParameterMap(),
['counter' => function ($value): int {
Assertion::greaterOrEqualThan((int) $value, 0, 'Counter must be at least 0.');
return (int) $value;
}]
);
return $v;
}
}

View file

@ -0,0 +1,29 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2019 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace OTPHP;
interface HOTPInterface extends OTPInterface
{
/**
* The initial counter (a positive integer).
*/
public function getCounter(): int;
/**
* Create a new TOTP object.
*
* If the secret is null, a random 64 bytes secret will be generated.
*/
public static function create(?string $secret = null, int $counter = 0, string $digest = 'sha1', int $digits = 6): self;
}

114
vendor/spomky-labs/otphp/src/OTP.php vendored Normal file
View file

@ -0,0 +1,114 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2019 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace OTPHP;
use Assert\Assertion;
use ParagonIE\ConstantTime\Base32;
use RuntimeException;
use function Safe\ksort;
use function Safe\sprintf;
abstract class OTP implements OTPInterface
{
use ParameterTrait;
protected function __construct(?string $secret, string $digest, int $digits)
{
$this->setSecret($secret);
$this->setDigest($digest);
$this->setDigits($digits);
}
public function getQrCodeUri(string $uri, string $placeholder): string
{
$provisioning_uri = urlencode($this->getProvisioningUri());
return str_replace($placeholder, $provisioning_uri, $uri);
}
/**
* The OTP at the specified input.
*/
protected function generateOTP(int $input): string
{
$hash = hash_hmac($this->getDigest(), $this->intToByteString($input), $this->getDecodedSecret(), true);
$hmac = array_values(unpack('C*', $hash));
$offset = ($hmac[\count($hmac) - 1] & 0xF);
$code = ($hmac[$offset + 0] & 0x7F) << 24 | ($hmac[$offset + 1] & 0xFF) << 16 | ($hmac[$offset + 2] & 0xFF) << 8 | ($hmac[$offset + 3] & 0xFF);
$otp = $code % (10 ** $this->getDigits());
return str_pad((string) $otp, $this->getDigits(), '0', STR_PAD_LEFT);
}
public function at(int $timestamp): string
{
return $this->generateOTP($timestamp);
}
/**
* @param array<string, mixed> $options
*/
protected function filterOptions(array &$options): void
{
foreach (['algorithm' => 'sha1', 'period' => 30, 'digits' => 6] as $key => $default) {
if (isset($options[$key]) && $default === $options[$key]) {
unset($options[$key]);
}
}
ksort($options);
}
/**
* @param array<string, mixed> $options
*/
protected function generateURI(string $type, array $options): string
{
$label = $this->getLabel();
Assertion::string($label, 'The label is not set.');
Assertion::false($this->hasColon($label), 'Label must not contain a colon.');
$options = array_merge($options, $this->getParameters());
$this->filterOptions($options);
$params = str_replace(['+', '%7E'], ['%20', '~'], http_build_query($options));
return sprintf('otpauth://%s/%s?%s', $type, rawurlencode((null !== $this->getIssuer() ? $this->getIssuer().':' : '').$label), $params);
}
private function getDecodedSecret(): string
{
try {
return Base32::decodeUpper($this->getSecret());
} catch (\Exception $e) {
throw new RuntimeException('Unable to decode the secret. Is it correctly base32 encoded?');
}
}
private function intToByteString(int $int): string
{
$result = [];
while (0 !== $int) {
$result[] = \chr($int & 0xFF);
$int >>= 8;
}
return str_pad(implode(array_reverse($result)), 8, "\000", STR_PAD_LEFT);
}
protected function compareOTP(string $safe, string $user): bool
{
return hash_equals($safe, $user);
}
}

View file

@ -0,0 +1,97 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2019 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace OTPHP;
interface OTPInterface
{
/**
* @return string Return the OTP at the specified timestamp
*/
public function at(int $timestamp): string;
/**
* Verify that the OTP is valid with the specified input.
* If no input is provided, the input is set to a default value or false is returned.
*/
public function verify(string $otp, ?int $input = null, ?int $window = null): bool;
/**
* @return string The secret of the OTP
*/
public function getSecret(): string;
/**
* @param string $label The label of the OTP
*/
public function setLabel(string $label): void;
/**
* @return string|null The label of the OTP
*/
public function getLabel(): ?string;
/**
* @return string|null The issuer
*/
public function getIssuer(): ?string;
public function setIssuer(string $issuer): void;
/**
* @return bool If true, the issuer will be added as a parameter in the provisioning URI
*/
public function isIssuerIncludedAsParameter(): bool;
public function setIssuerIncludedAsParameter(bool $issuer_included_as_parameter): void;
/**
* @return int Number of digits in the OTP
*/
public function getDigits(): int;
/**
* @return string Digest algorithm used to calculate the OTP. Possible values are 'md5', 'sha1', 'sha256' and 'sha512'
*/
public function getDigest(): string;
/**
* @return mixed|null
*/
public function getParameter(string $parameter);
public function hasParameter(string $parameter): bool;
/**
* @return array<string, mixed>
*/
public function getParameters(): array;
/**
* @param mixed|null $value
*/
public function setParameter(string $parameter, $value): void;
/**
* Get the provisioning URI.
*/
public function getProvisioningUri(): string;
/**
* Get the provisioning URI.
*
* @param string $uri The Uri of the QRCode generator with all parameters. This Uri MUST contain a placeholder that will be replaced by the method.
* @param string $placeholder the placeholder to be replaced in the QR Code generator URI
*/
public function getQrCodeUri(string $uri, string $placeholder): string;
}

View file

@ -0,0 +1,196 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2019 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace OTPHP;
use Assert\Assertion;
use InvalidArgumentException;
use ParagonIE\ConstantTime\Base32;
use function Safe\sprintf;
trait ParameterTrait
{
/**
* @var array<string, mixed>
*/
private $parameters = [];
/**
* @var string|null
*/
private $issuer;
/**
* @var string|null
*/
private $label;
/**
* @var bool
*/
private $issuer_included_as_parameter = true;
/**
* @return array<string, mixed>
*/
public function getParameters(): array
{
$parameters = $this->parameters;
if (null !== $this->getIssuer() && true === $this->isIssuerIncludedAsParameter()) {
$parameters['issuer'] = $this->getIssuer();
}
return $parameters;
}
public function getSecret(): string
{
return $this->getParameter('secret');
}
public function setSecret(?string $secret): void
{
$this->setParameter('secret', $secret);
}
public function getLabel(): ?string
{
return $this->label;
}
public function setLabel(string $label): void
{
$this->setParameter('label', $label);
}
public function getIssuer(): ?string
{
return $this->issuer;
}
public function setIssuer(string $issuer): void
{
$this->setParameter('issuer', $issuer);
}
public function isIssuerIncludedAsParameter(): bool
{
return $this->issuer_included_as_parameter;
}
public function setIssuerIncludedAsParameter(bool $issuer_included_as_parameter): void
{
$this->issuer_included_as_parameter = $issuer_included_as_parameter;
}
public function getDigits(): int
{
return $this->getParameter('digits');
}
private function setDigits(int $digits): void
{
$this->setParameter('digits', $digits);
}
public function getDigest(): string
{
return $this->getParameter('algorithm');
}
private function setDigest(string $digest): void
{
$this->setParameter('algorithm', $digest);
}
public function hasParameter(string $parameter): bool
{
return \array_key_exists($parameter, $this->parameters);
}
public function getParameter(string $parameter)
{
if ($this->hasParameter($parameter)) {
return $this->getParameters()[$parameter];
}
throw new InvalidArgumentException(sprintf('Parameter "%s" does not exist', $parameter));
}
public function setParameter(string $parameter, $value): void
{
$map = $this->getParameterMap();
if (true === \array_key_exists($parameter, $map)) {
$callback = $map[$parameter];
$value = $callback($value);
}
if (property_exists($this, $parameter)) {
$this->$parameter = $value;
} else {
$this->parameters[$parameter] = $value;
}
}
/**
* @return array<string, mixed>
*/
protected function getParameterMap(): array
{
return [
'label' => function ($value) {
Assertion::false($this->hasColon($value), 'Label must not contain a colon.');
return $value;
},
'secret' => function ($value): string {
if (null === $value) {
$value = Base32::encodeUpper(random_bytes(64));
}
$value = trim(mb_strtoupper($value), '=');
return $value;
},
'algorithm' => function ($value): string {
$value = mb_strtolower($value);
Assertion::inArray($value, hash_algos(), sprintf('The "%s" digest is not supported.', $value));
return $value;
},
'digits' => function ($value): int {
Assertion::greaterThan($value, 0, 'Digits must be at least 1.');
return (int) $value;
},
'issuer' => function ($value) {
Assertion::false($this->hasColon($value), 'Issuer must not contain a colon.');
return $value;
},
];
}
private function hasColon(string $value): bool
{
$colons = [':', '%3A', '%3a'];
foreach ($colons as $colon) {
if (false !== mb_strpos($value, $colon)) {
return true;
}
}
return false;
}
}

159
vendor/spomky-labs/otphp/src/TOTP.php vendored Normal file
View file

@ -0,0 +1,159 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2019 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace OTPHP;
use Assert\Assertion;
use function Safe\ksort;
final class TOTP extends OTP implements TOTPInterface
{
protected function __construct(?string $secret, int $period, string $digest, int $digits, int $epoch = 0)
{
parent::__construct($secret, $digest, $digits);
$this->setPeriod($period);
$this->setEpoch($epoch);
}
public static function create(?string $secret = null, int $period = 30, string $digest = 'sha1', int $digits = 6, int $epoch = 0): TOTPInterface
{
return new self($secret, $period, $digest, $digits, $epoch);
}
protected function setPeriod(int $period): void
{
$this->setParameter('period', $period);
}
public function getPeriod(): int
{
return $this->getParameter('period');
}
private function setEpoch(int $epoch): void
{
$this->setParameter('epoch', $epoch);
}
public function getEpoch(): int
{
return $this->getParameter('epoch');
}
public function at(int $timestamp): string
{
return $this->generateOTP($this->timecode($timestamp));
}
public function now(): string
{
return $this->at(time());
}
/**
* If no timestamp is provided, the OTP is verified at the actual timestamp.
*/
public function verify(string $otp, ?int $timestamp = null, ?int $window = null): bool
{
$timestamp = $this->getTimestamp($timestamp);
if (null === $window) {
return $this->compareOTP($this->at($timestamp), $otp);
}
return $this->verifyOtpWithWindow($otp, $timestamp, $window);
}
private function verifyOtpWithWindow(string $otp, int $timestamp, int $window): bool
{
$window = abs($window);
for ($i = 0; $i <= $window; ++$i) {
$next = $i * $this->getPeriod() + $timestamp;
$previous = -$i * $this->getPeriod() + $timestamp;
$valid = $this->compareOTP($this->at($next), $otp) ||
$this->compareOTP($this->at($previous), $otp);
if ($valid) {
return true;
}
}
return false;
}
private function getTimestamp(?int $timestamp): int
{
$timestamp = $timestamp ?? time();
Assertion::greaterOrEqualThan($timestamp, 0, 'Timestamp must be at least 0.');
return $timestamp;
}
public function getProvisioningUri(): string
{
$params = [];
if (30 !== $this->getPeriod()) {
$params['period'] = $this->getPeriod();
}
if (0 !== $this->getEpoch()) {
$params['epoch'] = $this->getEpoch();
}
return $this->generateURI('totp', $params);
}
private function timecode(int $timestamp): int
{
return (int) floor(($timestamp - $this->getEpoch()) / $this->getPeriod());
}
/**
* @return array<string, mixed>
*/
protected function getParameterMap(): array
{
$v = array_merge(
parent::getParameterMap(),
[
'period' => function ($value): int {
Assertion::greaterThan((int) $value, 0, 'Period must be at least 1.');
return (int) $value;
},
'epoch' => function ($value): int {
Assertion::greaterOrEqualThan((int) $value, 0, 'Epoch must be greater than or equal to 0.');
return (int) $value;
},
]
);
return $v;
}
/**
* @param array<string, mixed> $options
*/
protected function filterOptions(array &$options): void
{
parent::filterOptions($options);
if (isset($options['epoch']) && 0 === $options['epoch']) {
unset($options['epoch']);
}
ksort($options);
}
}

View file

@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2019 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace OTPHP;
interface TOTPInterface extends OTPInterface
{
/**
* Create a new TOTP object.
*
* If the secret is null, a random 64 bytes secret will be generated.
*/
public static function create(?string $secret = null, int $period = 30, string $digest = 'sha1', int $digits = 6): self;
/**
* Return the TOTP at the current time.
*/
public function now(): string;
/**
* Get the period of time for OTP generation (a non-null positive integer, in second).
*/
public function getPeriod(): int;
public function getEpoch(): int;
}

View file

@ -53,7 +53,7 @@ final class CompletionInput extends ArgvInput
* Create an input based on an COMP_WORDS token list. * Create an input based on an COMP_WORDS token list.
* *
* @param string[] $tokens the set of split tokens (e.g. COMP_WORDS or argv) * @param string[] $tokens the set of split tokens (e.g. COMP_WORDS or argv)
* @param $currentIndex the index of the cursor (e.g. COMP_CWORD) * @param int $currentIndex the index of the cursor (e.g. COMP_CWORD)
*/ */
public static function fromTokens(array $tokens, int $currentIndex): self public static function fromTokens(array $tokens, int $currentIndex): self
{ {

View file

@ -169,9 +169,12 @@ final class ProgressBar
$this->messages[$name] = $message; $this->messages[$name] = $message;
} }
/**
* @return string|null
*/
public function getMessage(string $name = 'message') public function getMessage(string $name = 'message')
{ {
return $this->messages[$name]; return $this->messages[$name] ?? null;
} }
public function getStartTime(): int public function getStartTime(): int

View file

@ -91,7 +91,7 @@ class StreamOutput extends Output
protected function hasColorSupport() protected function hasColorSupport()
{ {
// Follow https://no-color.org/ // Follow https://no-color.org/
if (isset($_SERVER['NO_COLOR']) || false !== getenv('NO_COLOR')) { if ('' !== ($_SERVER['NO_COLOR'] ?? getenv('NO_COLOR') ?: '')) {
return false; return false;
} }

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more