Update composer dependencies
This commit is contained in:
parent
a93b8e10f5
commit
8e6476b402
|
|
@ -35,12 +35,12 @@
|
|||
"fguillot/simpleLogger" : "1.0.1",
|
||||
"fguillot/simple-validator" : "1.0.1",
|
||||
"fguillot/simple-queue" : "1.0.1",
|
||||
"paragonie/random_compat": "2.0.2",
|
||||
"pimple/pimple" : "3.0.2",
|
||||
"swiftmailer/swiftmailer" : "5.4.5",
|
||||
"paragonie/random_compat": "2.0.11",
|
||||
"pimple/pimple" : "3.2.2",
|
||||
"swiftmailer/swiftmailer" : "5.4.8",
|
||||
"symfony/console" : "3.4.2",
|
||||
"symfony/event-dispatcher" : "3.4.2",
|
||||
"gregwar/captcha": "1.1.1",
|
||||
"gregwar/captcha": "1.1.4",
|
||||
"aferrandini/phpqrcode": "1.0.1"
|
||||
},
|
||||
"autoload" : {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "da7b737ec52dbce106228527cf57a97c",
|
||||
"content-hash": "55f5db0718c2a102000edeebf460165e",
|
||||
"packages": [
|
||||
{
|
||||
"name": "aferrandini/phpqrcode",
|
||||
|
|
@ -450,26 +450,31 @@
|
|||
},
|
||||
{
|
||||
"name": "gregwar/captcha",
|
||||
"version": "v1.1.1",
|
||||
"version": "v1.1.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Gregwar/Captcha.git",
|
||||
"reference": "1240ab993ca713680573b2d4166900da5f758623"
|
||||
"reference": "0185f4a64faef65612792f0d9a48dbe8d70c585c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Gregwar/Captcha/zipball/1240ab993ca713680573b2d4166900da5f758623",
|
||||
"reference": "1240ab993ca713680573b2d4166900da5f758623",
|
||||
"url": "https://api.github.com/repos/Gregwar/Captcha/zipball/0185f4a64faef65612792f0d9a48dbe8d70c585c",
|
||||
"reference": "0185f4a64faef65612792f0d9a48dbe8d70c585c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-gd": "*",
|
||||
"php": ">=5.3.0"
|
||||
"ext-mbstring": "*",
|
||||
"php": ">=5.3.0",
|
||||
"symfony/finder": "~3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6.4"
|
||||
},
|
||||
"type": "captcha",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Gregwar\\Captcha\\": "/"
|
||||
"Gregwar\\": "src/Gregwar"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
|
|
@ -494,7 +499,7 @@
|
|||
"captcha",
|
||||
"spam"
|
||||
],
|
||||
"time": "2015-09-11T15:23:20+00:00"
|
||||
"time": "2017-12-01T13:59:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "miniflux/picofeed",
|
||||
|
|
@ -551,16 +556,16 @@
|
|||
},
|
||||
{
|
||||
"name": "paragonie/random_compat",
|
||||
"version": "v2.0.2",
|
||||
"version": "v2.0.11",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/random_compat.git",
|
||||
"reference": "088c04e2f261c33bed6ca5245491cfca69195ccf"
|
||||
"reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/088c04e2f261c33bed6ca5245491cfca69195ccf",
|
||||
"reference": "088c04e2f261c33bed6ca5245491cfca69195ccf",
|
||||
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/5da4d3c796c275c55f057af5a643ae297d96b4d8",
|
||||
"reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -595,29 +600,33 @@
|
|||
"pseudorandom",
|
||||
"random"
|
||||
],
|
||||
"time": "2016-04-03T06:00:07+00:00"
|
||||
"time": "2017-09-27T21:40:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pimple/pimple",
|
||||
"version": "v3.0.2",
|
||||
"version": "v3.2.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/silexphp/Pimple.git",
|
||||
"reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a"
|
||||
"reference": "4d45fb62d96418396ec58ba76e6f065bca16e10a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/silexphp/Pimple/zipball/a30f7d6e57565a2e1a316e1baf2a483f788b258a",
|
||||
"reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a",
|
||||
"url": "https://api.github.com/repos/silexphp/Pimple/zipball/4d45fb62d96418396ec58ba76e6f065bca16e10a",
|
||||
"reference": "4d45fb62d96418396ec58ba76e6f065bca16e10a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
"php": ">=5.3.0",
|
||||
"psr/container": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "^3.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.0.x-dev"
|
||||
"dev-master": "3.2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -641,7 +650,56 @@
|
|||
"container",
|
||||
"dependency injection"
|
||||
],
|
||||
"time": "2015-09-11T15:10:35+00:00"
|
||||
"time": "2017-07-23T07:32:15+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
"version": "1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/container.git",
|
||||
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
|
||||
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Container\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common Container Interface (PHP FIG PSR-11)",
|
||||
"homepage": "https://github.com/php-fig/container",
|
||||
"keywords": [
|
||||
"PSR-11",
|
||||
"container",
|
||||
"container-interface",
|
||||
"container-interop",
|
||||
"psr"
|
||||
],
|
||||
"time": "2017-02-14T16:28:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
|
|
@ -692,16 +750,16 @@
|
|||
},
|
||||
{
|
||||
"name": "swiftmailer/swiftmailer",
|
||||
"version": "v5.4.5",
|
||||
"version": "v5.4.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/swiftmailer/swiftmailer.git",
|
||||
"reference": "cd142238a339459b10da3d8234220963f392540c"
|
||||
"reference": "9a06dc570a0367850280eefd3f1dc2da45aef517"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/cd142238a339459b10da3d8234220963f392540c",
|
||||
"reference": "cd142238a339459b10da3d8234220963f392540c",
|
||||
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/9a06dc570a0367850280eefd3f1dc2da45aef517",
|
||||
"reference": "9a06dc570a0367850280eefd3f1dc2da45aef517",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -742,7 +800,7 @@
|
|||
"mail",
|
||||
"mailer"
|
||||
],
|
||||
"time": "2016-12-29T10:02:40+00:00"
|
||||
"time": "2017-05-01T15:54:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
|
|
@ -932,6 +990,55 @@
|
|||
"homepage": "https://symfony.com",
|
||||
"time": "2017-12-14T19:40:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v3.4.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/finder.git",
|
||||
"reference": "dac8d7db537bac7ad8143eb11360a8c2231f251a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/dac8d7db537bac7ad8143eb11360a8c2231f251a",
|
||||
"reference": "dac8d7db537bac7ad8143eb11360a8c2231f251a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.5.9|>=7.0.8"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.4-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Finder\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Finder Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2017-11-05T16:10:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.6.0",
|
||||
|
|
|
|||
|
|
@ -29,11 +29,11 @@ return array(
|
|||
'Eluceo\\iCal\\Util\\ComponentUtil' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Util/ComponentUtil.php',
|
||||
'Eluceo\\iCal\\Util\\DateUtil' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Util/DateUtil.php',
|
||||
'Eluceo\\iCal\\Util\\PropertyValueUtil' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Util/PropertyValueUtil.php',
|
||||
'Gregwar\\Captcha\\CaptchaBuilder' => $vendorDir . '/gregwar/captcha/CaptchaBuilder.php',
|
||||
'Gregwar\\Captcha\\CaptchaBuilderInterface' => $vendorDir . '/gregwar/captcha/CaptchaBuilderInterface.php',
|
||||
'Gregwar\\Captcha\\ImageFileHandler' => $vendorDir . '/gregwar/captcha/ImageFileHandler.php',
|
||||
'Gregwar\\Captcha\\PhraseBuilder' => $vendorDir . '/gregwar/captcha/PhraseBuilder.php',
|
||||
'Gregwar\\Captcha\\PhraseBuilderInterface' => $vendorDir . '/gregwar/captcha/PhraseBuilderInterface.php',
|
||||
'Gregwar\\Captcha\\CaptchaBuilder' => $vendorDir . '/gregwar/captcha/src/Gregwar/Captcha/CaptchaBuilder.php',
|
||||
'Gregwar\\Captcha\\CaptchaBuilderInterface' => $vendorDir . '/gregwar/captcha/src/Gregwar/Captcha/CaptchaBuilderInterface.php',
|
||||
'Gregwar\\Captcha\\ImageFileHandler' => $vendorDir . '/gregwar/captcha/src/Gregwar/Captcha/ImageFileHandler.php',
|
||||
'Gregwar\\Captcha\\PhraseBuilder' => $vendorDir . '/gregwar/captcha/src/Gregwar/Captcha/PhraseBuilder.php',
|
||||
'Gregwar\\Captcha\\PhraseBuilderInterface' => $vendorDir . '/gregwar/captcha/src/Gregwar/Captcha/PhraseBuilderInterface.php',
|
||||
'JsonRPC\\Client' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Client.php',
|
||||
'JsonRPC\\Exception\\AccessDeniedException' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Exception/AccessDeniedException.php',
|
||||
'JsonRPC\\Exception\\AuthenticationFailureException' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Exception/AuthenticationFailureException.php',
|
||||
|
|
@ -767,6 +767,13 @@ return array(
|
|||
'PicoFeed\\Syndication\\Rss20Helper' => $vendorDir . '/miniflux/picofeed/lib/PicoFeed/Syndication/Rss20Helper.php',
|
||||
'PicoFeed\\Syndication\\Rss20ItemBuilder' => $vendorDir . '/miniflux/picofeed/lib/PicoFeed/Syndication/Rss20ItemBuilder.php',
|
||||
'Pimple\\Container' => $vendorDir . '/pimple/pimple/src/Pimple/Container.php',
|
||||
'Pimple\\Exception\\ExpectedInvokableException' => $vendorDir . '/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php',
|
||||
'Pimple\\Exception\\FrozenServiceException' => $vendorDir . '/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php',
|
||||
'Pimple\\Exception\\InvalidServiceIdentifierException' => $vendorDir . '/pimple/pimple/src/Pimple/Exception/InvalidServiceIdentifierException.php',
|
||||
'Pimple\\Exception\\UnknownIdentifierException' => $vendorDir . '/pimple/pimple/src/Pimple/Exception/UnknownIdentifierException.php',
|
||||
'Pimple\\Psr11\\Container' => $vendorDir . '/pimple/pimple/src/Pimple/Psr11/Container.php',
|
||||
'Pimple\\Psr11\\ServiceLocator' => $vendorDir . '/pimple/pimple/src/Pimple/Psr11/ServiceLocator.php',
|
||||
'Pimple\\ServiceIterator' => $vendorDir . '/pimple/pimple/src/Pimple/ServiceIterator.php',
|
||||
'Pimple\\ServiceProviderInterface' => $vendorDir . '/pimple/pimple/src/Pimple/ServiceProviderInterface.php',
|
||||
'Pimple\\Tests\\Fixtures\\Invokable' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Fixtures/Invokable.php',
|
||||
'Pimple\\Tests\\Fixtures\\NonInvokable' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Fixtures/NonInvokable.php',
|
||||
|
|
@ -774,6 +781,12 @@ return array(
|
|||
'Pimple\\Tests\\Fixtures\\Service' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Fixtures/Service.php',
|
||||
'Pimple\\Tests\\PimpleServiceProviderInterfaceTest' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/PimpleServiceProviderInterfaceTest.php',
|
||||
'Pimple\\Tests\\PimpleTest' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/PimpleTest.php',
|
||||
'Pimple\\Tests\\Psr11\\ContainerTest' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Psr11/ContainerTest.php',
|
||||
'Pimple\\Tests\\Psr11\\ServiceLocatorTest' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Psr11/ServiceLocatorTest.php',
|
||||
'Pimple\\Tests\\ServiceIteratorTest' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/ServiceIteratorTest.php',
|
||||
'Psr\\Container\\ContainerExceptionInterface' => $vendorDir . '/psr/container/src/ContainerExceptionInterface.php',
|
||||
'Psr\\Container\\ContainerInterface' => $vendorDir . '/psr/container/src/ContainerInterface.php',
|
||||
'Psr\\Container\\NotFoundExceptionInterface' => $vendorDir . '/psr/container/src/NotFoundExceptionInterface.php',
|
||||
'Psr\\Log\\AbstractLogger' => $vendorDir . '/psr/log/Psr/Log/AbstractLogger.php',
|
||||
'Psr\\Log\\InvalidArgumentException' => $vendorDir . '/psr/log/Psr/Log/InvalidArgumentException.php',
|
||||
'Psr\\Log\\LogLevel' => $vendorDir . '/psr/log/Psr/Log/LogLevel.php',
|
||||
|
|
@ -928,6 +941,27 @@ return array(
|
|||
'Symfony\\Component\\EventDispatcher\\EventSubscriberInterface' => $vendorDir . '/symfony/event-dispatcher/EventSubscriberInterface.php',
|
||||
'Symfony\\Component\\EventDispatcher\\GenericEvent' => $vendorDir . '/symfony/event-dispatcher/GenericEvent.php',
|
||||
'Symfony\\Component\\EventDispatcher\\ImmutableEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/ImmutableEventDispatcher.php',
|
||||
'Symfony\\Component\\Finder\\Comparator\\Comparator' => $vendorDir . '/symfony/finder/Comparator/Comparator.php',
|
||||
'Symfony\\Component\\Finder\\Comparator\\DateComparator' => $vendorDir . '/symfony/finder/Comparator/DateComparator.php',
|
||||
'Symfony\\Component\\Finder\\Comparator\\NumberComparator' => $vendorDir . '/symfony/finder/Comparator/NumberComparator.php',
|
||||
'Symfony\\Component\\Finder\\Exception\\AccessDeniedException' => $vendorDir . '/symfony/finder/Exception/AccessDeniedException.php',
|
||||
'Symfony\\Component\\Finder\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/finder/Exception/ExceptionInterface.php',
|
||||
'Symfony\\Component\\Finder\\Finder' => $vendorDir . '/symfony/finder/Finder.php',
|
||||
'Symfony\\Component\\Finder\\Glob' => $vendorDir . '/symfony/finder/Glob.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\CustomFilterIterator' => $vendorDir . '/symfony/finder/Iterator/CustomFilterIterator.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\DateRangeFilterIterator' => $vendorDir . '/symfony/finder/Iterator/DateRangeFilterIterator.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\DepthRangeFilterIterator' => $vendorDir . '/symfony/finder/Iterator/DepthRangeFilterIterator.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\ExcludeDirectoryFilterIterator' => $vendorDir . '/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\FileTypeFilterIterator' => $vendorDir . '/symfony/finder/Iterator/FileTypeFilterIterator.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\FilecontentFilterIterator' => $vendorDir . '/symfony/finder/Iterator/FilecontentFilterIterator.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\FilenameFilterIterator' => $vendorDir . '/symfony/finder/Iterator/FilenameFilterIterator.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\FilterIterator' => $vendorDir . '/symfony/finder/Iterator/FilterIterator.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\MultiplePcreFilterIterator' => $vendorDir . '/symfony/finder/Iterator/MultiplePcreFilterIterator.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\PathFilterIterator' => $vendorDir . '/symfony/finder/Iterator/PathFilterIterator.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\RecursiveDirectoryIterator' => $vendorDir . '/symfony/finder/Iterator/RecursiveDirectoryIterator.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\SizeRangeFilterIterator' => $vendorDir . '/symfony/finder/Iterator/SizeRangeFilterIterator.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\SortableIterator' => $vendorDir . '/symfony/finder/Iterator/SortableIterator.php',
|
||||
'Symfony\\Component\\Finder\\SplFileInfo' => $vendorDir . '/symfony/finder/SplFileInfo.php',
|
||||
'Symfony\\Polyfill\\Mbstring\\Mbstring' => $vendorDir . '/symfony/polyfill-mbstring/Mbstring.php',
|
||||
'ZendXml\\Exception\\ExceptionInterface' => $vendorDir . '/zendframework/zendxml/library/ZendXml/Exception/ExceptionInterface.php',
|
||||
'ZendXml\\Exception\\InvalidArgumentException' => $vendorDir . '/zendframework/zendxml/library/ZendXml/Exception/InvalidArgumentException.php',
|
||||
|
|
|
|||
|
|
@ -7,12 +7,14 @@ $baseDir = dirname($vendorDir);
|
|||
|
||||
return array(
|
||||
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
|
||||
'Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'),
|
||||
'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'),
|
||||
'Symfony\\Component\\Debug\\' => array($vendorDir . '/symfony/debug'),
|
||||
'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
|
||||
'SimpleQueue\\' => array($vendorDir . '/fguillot/simple-queue/src'),
|
||||
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
|
||||
'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
|
||||
'Kanboard\\' => array($baseDir . '/app'),
|
||||
'Gregwar\\Captcha\\' => array($vendorDir . '/gregwar/captcha'),
|
||||
'Gregwar\\' => array($vendorDir . '/gregwar/captcha/src/Gregwar'),
|
||||
'Base32\\' => array($vendorDir . '/christian-riesen/base32/src'),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ class ComposerStaticInit6edea6294a88689e3f5c56484bb70c9b
|
|||
'S' =>
|
||||
array (
|
||||
'Symfony\\Polyfill\\Mbstring\\' => 26,
|
||||
'Symfony\\Component\\Finder\\' => 25,
|
||||
'Symfony\\Component\\EventDispatcher\\' => 34,
|
||||
'Symfony\\Component\\Debug\\' => 24,
|
||||
'Symfony\\Component\\Console\\' => 26,
|
||||
|
|
@ -25,6 +26,7 @@ class ComposerStaticInit6edea6294a88689e3f5c56484bb70c9b
|
|||
'P' =>
|
||||
array (
|
||||
'Psr\\Log\\' => 8,
|
||||
'Psr\\Container\\' => 14,
|
||||
),
|
||||
'K' =>
|
||||
array (
|
||||
|
|
@ -32,7 +34,7 @@ class ComposerStaticInit6edea6294a88689e3f5c56484bb70c9b
|
|||
),
|
||||
'G' =>
|
||||
array (
|
||||
'Gregwar\\Captcha\\' => 16,
|
||||
'Gregwar\\' => 8,
|
||||
),
|
||||
'B' =>
|
||||
array (
|
||||
|
|
@ -45,6 +47,10 @@ class ComposerStaticInit6edea6294a88689e3f5c56484bb70c9b
|
|||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
|
||||
),
|
||||
'Symfony\\Component\\Finder\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/finder',
|
||||
),
|
||||
'Symfony\\Component\\EventDispatcher\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/event-dispatcher',
|
||||
|
|
@ -65,13 +71,17 @@ class ComposerStaticInit6edea6294a88689e3f5c56484bb70c9b
|
|||
array (
|
||||
0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
|
||||
),
|
||||
'Psr\\Container\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/psr/container/src',
|
||||
),
|
||||
'Kanboard\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/../..' . '/app',
|
||||
),
|
||||
'Gregwar\\Captcha\\' =>
|
||||
'Gregwar\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/gregwar/captcha',
|
||||
0 => __DIR__ . '/..' . '/gregwar/captcha/src/Gregwar',
|
||||
),
|
||||
'Base32\\' =>
|
||||
array (
|
||||
|
|
@ -168,11 +178,11 @@ class ComposerStaticInit6edea6294a88689e3f5c56484bb70c9b
|
|||
'Eluceo\\iCal\\Util\\ComponentUtil' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/Util/ComponentUtil.php',
|
||||
'Eluceo\\iCal\\Util\\DateUtil' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/Util/DateUtil.php',
|
||||
'Eluceo\\iCal\\Util\\PropertyValueUtil' => __DIR__ . '/..' . '/eluceo/ical/src/Eluceo/iCal/Util/PropertyValueUtil.php',
|
||||
'Gregwar\\Captcha\\CaptchaBuilder' => __DIR__ . '/..' . '/gregwar/captcha/CaptchaBuilder.php',
|
||||
'Gregwar\\Captcha\\CaptchaBuilderInterface' => __DIR__ . '/..' . '/gregwar/captcha/CaptchaBuilderInterface.php',
|
||||
'Gregwar\\Captcha\\ImageFileHandler' => __DIR__ . '/..' . '/gregwar/captcha/ImageFileHandler.php',
|
||||
'Gregwar\\Captcha\\PhraseBuilder' => __DIR__ . '/..' . '/gregwar/captcha/PhraseBuilder.php',
|
||||
'Gregwar\\Captcha\\PhraseBuilderInterface' => __DIR__ . '/..' . '/gregwar/captcha/PhraseBuilderInterface.php',
|
||||
'Gregwar\\Captcha\\CaptchaBuilder' => __DIR__ . '/..' . '/gregwar/captcha/src/Gregwar/Captcha/CaptchaBuilder.php',
|
||||
'Gregwar\\Captcha\\CaptchaBuilderInterface' => __DIR__ . '/..' . '/gregwar/captcha/src/Gregwar/Captcha/CaptchaBuilderInterface.php',
|
||||
'Gregwar\\Captcha\\ImageFileHandler' => __DIR__ . '/..' . '/gregwar/captcha/src/Gregwar/Captcha/ImageFileHandler.php',
|
||||
'Gregwar\\Captcha\\PhraseBuilder' => __DIR__ . '/..' . '/gregwar/captcha/src/Gregwar/Captcha/PhraseBuilder.php',
|
||||
'Gregwar\\Captcha\\PhraseBuilderInterface' => __DIR__ . '/..' . '/gregwar/captcha/src/Gregwar/Captcha/PhraseBuilderInterface.php',
|
||||
'JsonRPC\\Client' => __DIR__ . '/..' . '/fguillot/json-rpc/src/JsonRPC/Client.php',
|
||||
'JsonRPC\\Exception\\AccessDeniedException' => __DIR__ . '/..' . '/fguillot/json-rpc/src/JsonRPC/Exception/AccessDeniedException.php',
|
||||
'JsonRPC\\Exception\\AuthenticationFailureException' => __DIR__ . '/..' . '/fguillot/json-rpc/src/JsonRPC/Exception/AuthenticationFailureException.php',
|
||||
|
|
@ -906,6 +916,13 @@ class ComposerStaticInit6edea6294a88689e3f5c56484bb70c9b
|
|||
'PicoFeed\\Syndication\\Rss20Helper' => __DIR__ . '/..' . '/miniflux/picofeed/lib/PicoFeed/Syndication/Rss20Helper.php',
|
||||
'PicoFeed\\Syndication\\Rss20ItemBuilder' => __DIR__ . '/..' . '/miniflux/picofeed/lib/PicoFeed/Syndication/Rss20ItemBuilder.php',
|
||||
'Pimple\\Container' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Container.php',
|
||||
'Pimple\\Exception\\ExpectedInvokableException' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php',
|
||||
'Pimple\\Exception\\FrozenServiceException' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php',
|
||||
'Pimple\\Exception\\InvalidServiceIdentifierException' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Exception/InvalidServiceIdentifierException.php',
|
||||
'Pimple\\Exception\\UnknownIdentifierException' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Exception/UnknownIdentifierException.php',
|
||||
'Pimple\\Psr11\\Container' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Psr11/Container.php',
|
||||
'Pimple\\Psr11\\ServiceLocator' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Psr11/ServiceLocator.php',
|
||||
'Pimple\\ServiceIterator' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/ServiceIterator.php',
|
||||
'Pimple\\ServiceProviderInterface' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/ServiceProviderInterface.php',
|
||||
'Pimple\\Tests\\Fixtures\\Invokable' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/Fixtures/Invokable.php',
|
||||
'Pimple\\Tests\\Fixtures\\NonInvokable' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/Fixtures/NonInvokable.php',
|
||||
|
|
@ -913,6 +930,12 @@ class ComposerStaticInit6edea6294a88689e3f5c56484bb70c9b
|
|||
'Pimple\\Tests\\Fixtures\\Service' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/Fixtures/Service.php',
|
||||
'Pimple\\Tests\\PimpleServiceProviderInterfaceTest' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/PimpleServiceProviderInterfaceTest.php',
|
||||
'Pimple\\Tests\\PimpleTest' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/PimpleTest.php',
|
||||
'Pimple\\Tests\\Psr11\\ContainerTest' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/Psr11/ContainerTest.php',
|
||||
'Pimple\\Tests\\Psr11\\ServiceLocatorTest' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/Psr11/ServiceLocatorTest.php',
|
||||
'Pimple\\Tests\\ServiceIteratorTest' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/ServiceIteratorTest.php',
|
||||
'Psr\\Container\\ContainerExceptionInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerExceptionInterface.php',
|
||||
'Psr\\Container\\ContainerInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerInterface.php',
|
||||
'Psr\\Container\\NotFoundExceptionInterface' => __DIR__ . '/..' . '/psr/container/src/NotFoundExceptionInterface.php',
|
||||
'Psr\\Log\\AbstractLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/AbstractLogger.php',
|
||||
'Psr\\Log\\InvalidArgumentException' => __DIR__ . '/..' . '/psr/log/Psr/Log/InvalidArgumentException.php',
|
||||
'Psr\\Log\\LogLevel' => __DIR__ . '/..' . '/psr/log/Psr/Log/LogLevel.php',
|
||||
|
|
@ -1067,6 +1090,27 @@ class ComposerStaticInit6edea6294a88689e3f5c56484bb70c9b
|
|||
'Symfony\\Component\\EventDispatcher\\EventSubscriberInterface' => __DIR__ . '/..' . '/symfony/event-dispatcher/EventSubscriberInterface.php',
|
||||
'Symfony\\Component\\EventDispatcher\\GenericEvent' => __DIR__ . '/..' . '/symfony/event-dispatcher/GenericEvent.php',
|
||||
'Symfony\\Component\\EventDispatcher\\ImmutableEventDispatcher' => __DIR__ . '/..' . '/symfony/event-dispatcher/ImmutableEventDispatcher.php',
|
||||
'Symfony\\Component\\Finder\\Comparator\\Comparator' => __DIR__ . '/..' . '/symfony/finder/Comparator/Comparator.php',
|
||||
'Symfony\\Component\\Finder\\Comparator\\DateComparator' => __DIR__ . '/..' . '/symfony/finder/Comparator/DateComparator.php',
|
||||
'Symfony\\Component\\Finder\\Comparator\\NumberComparator' => __DIR__ . '/..' . '/symfony/finder/Comparator/NumberComparator.php',
|
||||
'Symfony\\Component\\Finder\\Exception\\AccessDeniedException' => __DIR__ . '/..' . '/symfony/finder/Exception/AccessDeniedException.php',
|
||||
'Symfony\\Component\\Finder\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/finder/Exception/ExceptionInterface.php',
|
||||
'Symfony\\Component\\Finder\\Finder' => __DIR__ . '/..' . '/symfony/finder/Finder.php',
|
||||
'Symfony\\Component\\Finder\\Glob' => __DIR__ . '/..' . '/symfony/finder/Glob.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\CustomFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/CustomFilterIterator.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\DateRangeFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/DateRangeFilterIterator.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\DepthRangeFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/DepthRangeFilterIterator.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\ExcludeDirectoryFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\FileTypeFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/FileTypeFilterIterator.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\FilecontentFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/FilecontentFilterIterator.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\FilenameFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/FilenameFilterIterator.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\FilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/FilterIterator.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\MultiplePcreFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/MultiplePcreFilterIterator.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\PathFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/PathFilterIterator.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\RecursiveDirectoryIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/RecursiveDirectoryIterator.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\SizeRangeFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/SizeRangeFilterIterator.php',
|
||||
'Symfony\\Component\\Finder\\Iterator\\SortableIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/SortableIterator.php',
|
||||
'Symfony\\Component\\Finder\\SplFileInfo' => __DIR__ . '/..' . '/symfony/finder/SplFileInfo.php',
|
||||
'Symfony\\Polyfill\\Mbstring\\Mbstring' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/Mbstring.php',
|
||||
'ZendXml\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/zendframework/zendxml/library/ZendXml/Exception/ExceptionInterface.php',
|
||||
'ZendXml\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/zendframework/zendxml/library/ZendXml/Exception/InvalidArgumentException.php',
|
||||
|
|
|
|||
|
|
@ -510,56 +510,6 @@
|
|||
"description": "PHP library to write logs (compatible with PSR-3)",
|
||||
"homepage": "https://github.com/fguillot/simpleLogger"
|
||||
},
|
||||
{
|
||||
"name": "gregwar/captcha",
|
||||
"version": "v1.1.1",
|
||||
"version_normalized": "1.1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Gregwar/Captcha.git",
|
||||
"reference": "1240ab993ca713680573b2d4166900da5f758623"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Gregwar/Captcha/zipball/1240ab993ca713680573b2d4166900da5f758623",
|
||||
"reference": "1240ab993ca713680573b2d4166900da5f758623",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-gd": "*",
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"time": "2015-09-11T15:23:20+00:00",
|
||||
"type": "captcha",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Gregwar\\Captcha\\": "/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Grégoire Passault",
|
||||
"email": "g.passault@gmail.com",
|
||||
"homepage": "http://www.gregwar.com/"
|
||||
},
|
||||
{
|
||||
"name": "Jeremy Livingston",
|
||||
"email": "jeremy.j.livingston@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Captcha generator",
|
||||
"homepage": "https://github.com/Gregwar/Captcha",
|
||||
"keywords": [
|
||||
"bot",
|
||||
"captcha",
|
||||
"spam"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "zendframework/zendxml",
|
||||
"version": "1.0.2",
|
||||
|
|
@ -662,160 +612,6 @@
|
|||
"description": "Modern library to handle RSS/Atom feeds",
|
||||
"homepage": "https://github.com/miniflux/picoFeed"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/random_compat",
|
||||
"version": "v2.0.2",
|
||||
"version_normalized": "2.0.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/random_compat.git",
|
||||
"reference": "088c04e2f261c33bed6ca5245491cfca69195ccf"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/088c04e2f261c33bed6ca5245491cfca69195ccf",
|
||||
"reference": "088c04e2f261c33bed6ca5245491cfca69195ccf",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "4.*|5.*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
|
||||
},
|
||||
"time": "2016-04-03T06:00:07+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"lib/random.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Paragon Initiative Enterprises",
|
||||
"email": "security@paragonie.com",
|
||||
"homepage": "https://paragonie.com"
|
||||
}
|
||||
],
|
||||
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
|
||||
"keywords": [
|
||||
"csprng",
|
||||
"pseudorandom",
|
||||
"random"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "pimple/pimple",
|
||||
"version": "v3.0.2",
|
||||
"version_normalized": "3.0.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/silexphp/Pimple.git",
|
||||
"reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/silexphp/Pimple/zipball/a30f7d6e57565a2e1a316e1baf2a483f788b258a",
|
||||
"reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"time": "2015-09-11T15:10:35+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.0.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Pimple": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
}
|
||||
],
|
||||
"description": "Pimple, a simple Dependency Injection Container",
|
||||
"homepage": "http://pimple.sensiolabs.org",
|
||||
"keywords": [
|
||||
"container",
|
||||
"dependency injection"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "swiftmailer/swiftmailer",
|
||||
"version": "v5.4.5",
|
||||
"version_normalized": "5.4.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/swiftmailer/swiftmailer.git",
|
||||
"reference": "cd142238a339459b10da3d8234220963f392540c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/cd142238a339459b10da3d8234220963f392540c",
|
||||
"reference": "cd142238a339459b10da3d8234220963f392540c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "~0.9.1",
|
||||
"symfony/phpunit-bridge": "~3.2"
|
||||
},
|
||||
"time": "2016-12-29T10:02:40+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.4-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"lib/swift_required.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Chris Corbyn"
|
||||
},
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
}
|
||||
],
|
||||
"description": "Swiftmailer, free feature-rich PHP mailer",
|
||||
"homepage": "http://swiftmailer.org",
|
||||
"keywords": [
|
||||
"email",
|
||||
"mail",
|
||||
"mailer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.6.0",
|
||||
|
|
@ -1070,5 +866,320 @@
|
|||
],
|
||||
"description": "Symfony Debug Component",
|
||||
"homepage": "https://symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/random_compat",
|
||||
"version": "v2.0.11",
|
||||
"version_normalized": "2.0.11.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/random_compat.git",
|
||||
"reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/5da4d3c796c275c55f057af5a643ae297d96b4d8",
|
||||
"reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "4.*|5.*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
|
||||
},
|
||||
"time": "2017-09-27T21:40:39+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"lib/random.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Paragon Initiative Enterprises",
|
||||
"email": "security@paragonie.com",
|
||||
"homepage": "https://paragonie.com"
|
||||
}
|
||||
],
|
||||
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
|
||||
"keywords": [
|
||||
"csprng",
|
||||
"pseudorandom",
|
||||
"random"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
"version": "1.0.0",
|
||||
"version_normalized": "1.0.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/container.git",
|
||||
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
|
||||
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"time": "2017-02-14T16:28:37+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Container\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common Container Interface (PHP FIG PSR-11)",
|
||||
"homepage": "https://github.com/php-fig/container",
|
||||
"keywords": [
|
||||
"PSR-11",
|
||||
"container",
|
||||
"container-interface",
|
||||
"container-interop",
|
||||
"psr"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "pimple/pimple",
|
||||
"version": "v3.2.2",
|
||||
"version_normalized": "3.2.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/silexphp/Pimple.git",
|
||||
"reference": "4d45fb62d96418396ec58ba76e6f065bca16e10a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/silexphp/Pimple/zipball/4d45fb62d96418396ec58ba76e6f065bca16e10a",
|
||||
"reference": "4d45fb62d96418396ec58ba76e6f065bca16e10a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0",
|
||||
"psr/container": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "^3.2"
|
||||
},
|
||||
"time": "2017-07-23T07:32:15+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.2.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Pimple": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
}
|
||||
],
|
||||
"description": "Pimple, a simple Dependency Injection Container",
|
||||
"homepage": "http://pimple.sensiolabs.org",
|
||||
"keywords": [
|
||||
"container",
|
||||
"dependency injection"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "swiftmailer/swiftmailer",
|
||||
"version": "v5.4.8",
|
||||
"version_normalized": "5.4.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/swiftmailer/swiftmailer.git",
|
||||
"reference": "9a06dc570a0367850280eefd3f1dc2da45aef517"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/9a06dc570a0367850280eefd3f1dc2da45aef517",
|
||||
"reference": "9a06dc570a0367850280eefd3f1dc2da45aef517",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "~0.9.1",
|
||||
"symfony/phpunit-bridge": "~3.2"
|
||||
},
|
||||
"time": "2017-05-01T15:54:03+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.4-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"lib/swift_required.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Chris Corbyn"
|
||||
},
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
}
|
||||
],
|
||||
"description": "Swiftmailer, free feature-rich PHP mailer",
|
||||
"homepage": "http://swiftmailer.org",
|
||||
"keywords": [
|
||||
"email",
|
||||
"mail",
|
||||
"mailer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v3.4.2",
|
||||
"version_normalized": "3.4.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/finder.git",
|
||||
"reference": "dac8d7db537bac7ad8143eb11360a8c2231f251a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/dac8d7db537bac7ad8143eb11360a8c2231f251a",
|
||||
"reference": "dac8d7db537bac7ad8143eb11360a8c2231f251a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.5.9|>=7.0.8"
|
||||
},
|
||||
"time": "2017-11-05T16:10:10+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.4-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Finder\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Finder Component",
|
||||
"homepage": "https://symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "gregwar/captcha",
|
||||
"version": "v1.1.4",
|
||||
"version_normalized": "1.1.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Gregwar/Captcha.git",
|
||||
"reference": "0185f4a64faef65612792f0d9a48dbe8d70c585c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Gregwar/Captcha/zipball/0185f4a64faef65612792f0d9a48dbe8d70c585c",
|
||||
"reference": "0185f4a64faef65612792f0d9a48dbe8d70c585c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-gd": "*",
|
||||
"ext-mbstring": "*",
|
||||
"php": ">=5.3.0",
|
||||
"symfony/finder": "~3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6.4"
|
||||
},
|
||||
"time": "2017-12-01T13:59:36+00:00",
|
||||
"type": "captcha",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Gregwar\\": "src/Gregwar"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Grégoire Passault",
|
||||
"email": "g.passault@gmail.com",
|
||||
"homepage": "http://www.gregwar.com/"
|
||||
},
|
||||
{
|
||||
"name": "Jeremy Livingston",
|
||||
"email": "jeremy.j.livingston@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Captcha generator",
|
||||
"homepage": "https://github.com/Gregwar/Captcha",
|
||||
"keywords": [
|
||||
"bot",
|
||||
"captcha",
|
||||
"spam"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
demo/*.jpg
|
||||
demo/*.pgm
|
||||
demo/temp/
|
||||
vendor/
|
||||
|
|
|
|||
|
|
@ -6,6 +6,10 @@ php:
|
|||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7.0
|
||||
- 7.1
|
||||
- 7.2
|
||||
- hhvm
|
||||
|
||||
script:
|
||||
- composer install
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) <2012-2015> Grégoire Passault
|
||||
Copyright (c) <2012-2017> Grégoire Passault
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Gregwar\Captcha;
|
||||
|
||||
/**
|
||||
* Generates random phrase
|
||||
*
|
||||
* @author Gregwar <g.passault@gmail.com>
|
||||
*/
|
||||
class PhraseBuilder implements PhraseBuilderInterface
|
||||
{
|
||||
/**
|
||||
* Generates random phrase of given length with given charset
|
||||
*/
|
||||
public function build($length = 5, $charset = 'abcdefghijklmnpqrstuvwxyz123456789')
|
||||
{
|
||||
$phrase = '';
|
||||
$chars = str_split($charset);
|
||||
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$phrase .= $chars[array_rand($chars)];
|
||||
}
|
||||
|
||||
return $phrase;
|
||||
}
|
||||
|
||||
/**
|
||||
* "Niceize" a code
|
||||
*/
|
||||
public function niceize($str)
|
||||
{
|
||||
return strtr(strtolower($str), '01', 'ol');
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ Captcha
|
|||
=======
|
||||
|
||||

|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=YUXRLWHQSWS6L)
|
||||
|
||||
Installation
|
||||
============
|
||||
|
|
@ -96,12 +97,43 @@ You can use theses functions :
|
|||
* **setMaxBehindLines($lines)**, sets the maximum number of lines behind the code
|
||||
* **setMaxFrontLines($lines)**, sets the maximum number of lines on the front of the code
|
||||
|
||||
Symfony 2 Bundle
|
||||
If you want to change the number of character, you can call the phrase builder directly using
|
||||
extra parameters:
|
||||
|
||||
```php
|
||||
use Gregwar\Captcha\CaptchaBuilder;
|
||||
use Gregwar\Captcha\PhraseBuilder;
|
||||
|
||||
// Will build phrases of 3 characters
|
||||
$phraseBuilder = new PhraseBuilder(4)
|
||||
|
||||
// Will build phrases of 5 characters, only digits
|
||||
$phraseBuilder = new PhraseBuilder(5, '0123456789');
|
||||
|
||||
// Pass it as first argument of CaptchaBuilder, passing it the phrase
|
||||
// builder
|
||||
$captcha = new CaptchaBuilder(null, $phraseBuilder);
|
||||
```
|
||||
|
||||
You can also pass directly the wanted phrase to the builder:
|
||||
|
||||
```php
|
||||
// Building a Captcha with the "hello" phrase
|
||||
$captcha = new CaptchaBuilder('hello');
|
||||
```
|
||||
|
||||
Symfony Bundle
|
||||
================
|
||||
|
||||
You can have a look at the following repository to enjoy the Symfony 2 bundle packaging this captcha generator :
|
||||
https://github.com/Gregwar/CaptchaBundle
|
||||
|
||||
Yii2 Extension
|
||||
===============
|
||||
|
||||
You can use the following extension for integrating with Yii2 Framework :
|
||||
https://github.com/juliardi/yii2-captcha
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Registers an autoload for all the classes in Gregwar\Captcha
|
||||
*/
|
||||
spl_autoload_register(function ($className) {
|
||||
$namespace = 'Gregwar\\Captcha';
|
||||
|
||||
if (strpos($className, $namespace) === 0) {
|
||||
$className = str_replace($namespace, '', $className);
|
||||
$fileName = __DIR__ . '/' . str_replace('\\', '/', $className) . '.php';
|
||||
if (file_exists($fileName)) {
|
||||
require($fileName);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -18,11 +18,16 @@
|
|||
],
|
||||
"require": {
|
||||
"php": ">=5.3.0",
|
||||
"ext-gd": "*"
|
||||
"ext-gd": "*",
|
||||
"ext-mbstring": "*",
|
||||
"symfony/finder": "~3.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Gregwar\\Captcha\\": "/"
|
||||
"Gregwar\\": "src/Gregwar"
|
||||
}
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6.4"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
<?php
|
||||
|
||||
include(__DIR__.'/../CaptchaBuilderInterface.php');
|
||||
include(__DIR__.'/../PhraseBuilderInterface.php');
|
||||
include(__DIR__.'/../CaptchaBuilder.php');
|
||||
include(__DIR__.'/../PhraseBuilder.php');
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
use Gregwar\Captcha\CaptchaBuilder;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
<?php
|
||||
|
||||
include(__DIR__.'/../CaptchaBuilderInterface.php');
|
||||
include(__DIR__.'/../PhraseBuilderInterface.php');
|
||||
include(__DIR__.'/../CaptchaBuilder.php');
|
||||
include(__DIR__.'/../PhraseBuilder.php');
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
use Gregwar\Captcha\CaptchaBuilder;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
<?php
|
||||
|
||||
include(__DIR__.'/../CaptchaBuilderInterface.php');
|
||||
include(__DIR__.'/../PhraseBuilderInterface.php');
|
||||
include(__DIR__.'/../CaptchaBuilder.php');
|
||||
include(__DIR__.'/../PhraseBuilder.php');
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
use Gregwar\Captcha\CaptchaBuilder;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
<?php
|
||||
|
||||
include(__DIR__.'/../CaptchaBuilderInterface.php');
|
||||
include(__DIR__.'/../PhraseBuilderInterface.php');
|
||||
include(__DIR__.'/../CaptchaBuilder.php');
|
||||
include(__DIR__.'/../PhraseBuilder.php');
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
use Gregwar\Captcha\CaptchaBuilder;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit colors="true" bootstrap="vendor/autoload.php">
|
||||
<testsuites>
|
||||
<testsuite name="KnpMenu Test Suite">
|
||||
<directory suffix="Test.php">./tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>./src</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
||||
|
|
@ -317,33 +317,34 @@ class CaptchaBuilder implements CaptchaBuilderInterface
|
|||
*/
|
||||
protected function writePhrase($image, $phrase, $font, $width, $height)
|
||||
{
|
||||
$length = strlen($phrase);
|
||||
$length = mb_strlen($phrase);
|
||||
if ($length === 0) {
|
||||
return imagecolorallocate($image, 0, 0, 0);
|
||||
return \imagecolorallocate($image, 0, 0, 0);
|
||||
}
|
||||
|
||||
// Gets the text size and start position
|
||||
$size = $width / $length - $this->rand(0, 3) - 1;
|
||||
$box = imagettfbbox($size, 0, $font, $phrase);
|
||||
$box = \imagettfbbox($size, 0, $font, $phrase);
|
||||
$textWidth = $box[2] - $box[0];
|
||||
$textHeight = $box[1] - $box[7];
|
||||
$x = ($width - $textWidth) / 2;
|
||||
$y = ($height - $textHeight) / 2 + $size;
|
||||
|
||||
if (!count($this->textColor)) {
|
||||
if (!$this->textColor) {
|
||||
$textColor = array($this->rand(0, 150), $this->rand(0, 150), $this->rand(0, 150));
|
||||
} else {
|
||||
$textColor = $this->textColor;
|
||||
}
|
||||
$col = imagecolorallocate($image, $textColor[0], $textColor[1], $textColor[2]);
|
||||
$col = \imagecolorallocate($image, $textColor[0], $textColor[1], $textColor[2]);
|
||||
|
||||
// Write the letters one by one, with random angle
|
||||
for ($i=0; $i<$length; $i++) {
|
||||
$box = imagettfbbox($size, 0, $font, $phrase[$i]);
|
||||
$symbol = mb_substr($phrase, $i, 1);
|
||||
$box = \imagettfbbox($size, 0, $font, $symbol);
|
||||
$w = $box[2] - $box[0];
|
||||
$angle = $this->rand(-$this->maxAngle, $this->maxAngle);
|
||||
$offset = $this->rand(-$this->maxOffset, $this->maxOffset);
|
||||
imagettftext($image, $size, $angle, $x, $y + $offset, $col, $font, $phrase[$i]);
|
||||
\imagettftext($image, $size, $angle, $x, $y + $offset, $col, $font, $symbol);
|
||||
$x += $w;
|
||||
}
|
||||
|
||||
|
|
@ -682,7 +683,7 @@ class CaptchaBuilder implements CaptchaBuilderInterface
|
|||
$imageType = finfo_file($finfo, $backgroundImage);
|
||||
finfo_close($finfo);
|
||||
|
||||
if (!in_array ($imageType, $this->allowedBackgroundImageTypes)) {
|
||||
if (!in_array($imageType, $this->allowedBackgroundImageTypes)) {
|
||||
throw new Exception('Invalid background image type! Allowed types are: ' . join(', ', $this->allowedBackgroundImageTypes));
|
||||
}
|
||||
|
||||
|
|
@ -27,4 +27,3 @@ interface CaptchaBuilderInterface
|
|||
*/
|
||||
public function output($quality);
|
||||
}
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ class ImageFileHandler
|
|||
$finder->in($this->webPath . '/' . $this->imageFolder)
|
||||
->date($criteria);
|
||||
|
||||
foreach($finder->files() as $file) {
|
||||
foreach ($finder->files() as $file) {
|
||||
unlink($file->getPathname());
|
||||
}
|
||||
|
||||
|
|
@ -103,4 +103,3 @@ class ImageFileHandler
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
namespace Gregwar\Captcha;
|
||||
|
||||
/**
|
||||
* Generates random phrase
|
||||
*
|
||||
* @author Gregwar <g.passault@gmail.com>
|
||||
*/
|
||||
class PhraseBuilder implements PhraseBuilderInterface
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $length;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $charset;
|
||||
/**
|
||||
* Constructs a PhraseBuilder with given parameters
|
||||
*/
|
||||
public function __construct($length = 5, $charset = 'abcdefghijklmnpqrstuvwxyz123456789')
|
||||
{
|
||||
$this->length = $length;
|
||||
$this->charset = $charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates random phrase of given length with given charset
|
||||
*/
|
||||
public function build($length = null, $charset = null)
|
||||
{
|
||||
if ($length !== null) {
|
||||
$this->length = $length;
|
||||
}
|
||||
if ($charset !== null) {
|
||||
$this->charset = $charset;
|
||||
}
|
||||
|
||||
$phrase = '';
|
||||
$chars = str_split($this->charset);
|
||||
|
||||
for ($i = 0; $i < $this->length; $i++) {
|
||||
$phrase .= $chars[array_rand($chars)];
|
||||
}
|
||||
|
||||
return $phrase;
|
||||
}
|
||||
|
||||
/**
|
||||
* "Niceize" a code
|
||||
*/
|
||||
public function niceize($str)
|
||||
{
|
||||
return strtr(strtolower($str), '01', 'ol');
|
||||
}
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ interface PhraseBuilderInterface
|
|||
/**
|
||||
* Generates random phrase of given length with given charset
|
||||
*/
|
||||
public function build($length, $charset);
|
||||
public function build();
|
||||
|
||||
/**
|
||||
* "Niceize" a code
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Test;
|
||||
|
||||
use Gregwar\Captcha\CaptchaBuilder;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class CaptchaBuilderTest extends TestCase
|
||||
{
|
||||
public function testDemo()
|
||||
{
|
||||
$captcha = new CaptchaBuilder();
|
||||
$captcha
|
||||
->build()
|
||||
->save('out.jpg')
|
||||
;
|
||||
|
||||
$this->assertTrue(file_exists(__DIR__.'/../out.jpg'));
|
||||
}
|
||||
|
||||
public function testFingerPrint()
|
||||
{
|
||||
$int = count(CaptchaBuilder::create()
|
||||
->build()
|
||||
->getFingerprint()
|
||||
);
|
||||
|
||||
$this->assertTrue(is_int($int));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,260 +0,0 @@
|
|||
### Version 2.0.2 - 2016-04-03
|
||||
|
||||
Added a consistency check (discovered by Taylor Hornby in his
|
||||
[PHP encryption library](https://github.com/defuse/php-encryption)). It
|
||||
wasn't likely causing any trouble for us.
|
||||
|
||||
### Version 2.0.1 - 2016-03-18
|
||||
|
||||
Update comment in random.php
|
||||
|
||||
### Version 2.0.0 - 2016-03-18
|
||||
|
||||
Due to downstream errors, the OpenSSL removal now belongs in version
|
||||
2.0.0.
|
||||
|
||||
### Version 1.3.1 - 2016-03-18
|
||||
|
||||
* Add more possible values to `open_baseir` check.
|
||||
|
||||
### Version 1.3.0 - 2016-03-17
|
||||
|
||||
* Removed `openssl_random_pseudo_bytes()` entirely. If you are using
|
||||
random_compat in PHP on a Unix-like OS but cannot access
|
||||
`/dev/urandom`, version 1.3+ will throw an `Exception`. If you want to
|
||||
trust OpenSSL, feel free to write your own fallback code. e.g.
|
||||
|
||||
```php
|
||||
try {
|
||||
$bytes = random_bytes(32);
|
||||
} catch (Exception $ex) {
|
||||
$strong = false;
|
||||
$bytes = openssl_random_pseudo_bytes(32, $strong);
|
||||
if (!$strong) {
|
||||
throw $ex;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Version 1.2.2 - 2016-03-11
|
||||
|
||||
* To prevent applications from hanging, if `/dev/urandom` is not
|
||||
accessible to PHP, skip mcrypt (which just fails before giving OpenSSL
|
||||
a chance and was morally equivalent to not offering OpenSSL at all).
|
||||
|
||||
### Version 1.2.1 - 2016-02-29
|
||||
|
||||
* PHP 5.6.10 - 5.6.12 will hang when mcrypt is used on Unix-based operating
|
||||
systems ([PHP bug 69833](https://bugs.php.net/bug.php?id=69833)). If you are
|
||||
running one of these versions, please upgrade (or make sure `/dev/urandom` is
|
||||
readable) otherwise you're relying on OpenSSL.
|
||||
|
||||
### Version 1.2.0 - 2016-02-05
|
||||
|
||||
* Whitespace and other cosmetic changes
|
||||
* Added a changelog.
|
||||
* We now ship with a command line utility to build a PHP Archive from the
|
||||
command line.
|
||||
|
||||
Every time we publish a new release, we will also upload a .phar
|
||||
to Github. Our public key is signed by our GPG key.
|
||||
|
||||
### Version 1.1.6 - 2016-01-29
|
||||
|
||||
* Eliminate `open_basedir` warnings by detecting this configuration setting.
|
||||
(Thanks [@oucil](https://github.com/oucil) for reporting this.)
|
||||
* Added install instructions to the README.
|
||||
* Documentation cleanup (there is, in fact, no `MCRYPT_CREATE_IV` constant, I
|
||||
meant to write `MCRYPT_DEV_URANDOM`)
|
||||
|
||||
### Version 1.1.5 - 2016-01-06
|
||||
|
||||
Prevent fatal errors on platforms with older versions of libsodium.
|
||||
|
||||
### Version 1.1.4 - 2015-12-10
|
||||
|
||||
Thanks [@narfbg](https://github.com/narfbg) for [critiquing the previous patch](https://github.com/paragonie/random_compat/issues/79#issuecomment-163590589)
|
||||
and suggesting a fix.
|
||||
|
||||
### Version 1.1.3 - 2015-12-09
|
||||
|
||||
The test for COM in disabled_classes is now case-insensitive.
|
||||
|
||||
### Version 1.1.2 - 2015-12-09
|
||||
|
||||
Don't instantiate COM if it's a disabled class. Removes the E_WARNING on Windows.
|
||||
|
||||
### Version 1.1.1 - 2015-11-30
|
||||
|
||||
Fix a performance issue with `/dev/urandom` buffering.
|
||||
|
||||
### Version 1.1.0 - 2015-11-09
|
||||
|
||||
Fix performance issues with ancient versions of PHP on Windows, but dropped
|
||||
support for PHP < 5.4.1 without mcrypt on Windows 7+ in the process. Since this
|
||||
is a BC break, semver dictates a minor version bump.
|
||||
|
||||
### Version 1.0.10 - 2015-10-23
|
||||
|
||||
* Avoid a performance killer with OpenSSL on Windows PHP 5.3.0 - 5.3.3 that was
|
||||
affecting [WordPress users](https://core.trac.wordpress.org/ticket/34409).
|
||||
* Use `$var = null` instead of `unset($var)` to avoid triggering the garbage
|
||||
collector and slowing things down.
|
||||
|
||||
### Version 1.0.9 - 2015-10-20
|
||||
|
||||
There is an outstanding issue `mcrypt_create_iv()` and PHP 7's `random_bytes()`
|
||||
on Windows reported by [@nicolas-grekas](https://github.com/nicolas-grekas) caused by `proc_open()` and environment
|
||||
variable handling (discovered by Appveyor when developing Symfony).
|
||||
|
||||
Since the break is consistent, it's not our responsibility to fix it, but we
|
||||
should fail the same way PHP 7 will (i.e. throw an `Exception` rather than raise
|
||||
an error and then throw an `Exception`).
|
||||
|
||||
### Version 1.0.8 - 2015-10-18
|
||||
|
||||
* Fix usability issues with Windows (`new COM('CAPICOM.Utilities.1')` is not
|
||||
always available).
|
||||
* You can now test all the possible drivers by running `phpunit.sh each` in the
|
||||
`tests` directory.
|
||||
|
||||
### Version 1.0.7 - 2015-10-16
|
||||
|
||||
Several large integer handling bugfixes were contributed by [@oittaa](https://github.com/oittaa).
|
||||
|
||||
### Version 1.0.6 - 2015-10-15
|
||||
|
||||
Don't let the version number fool you, this was a pretty significant change.
|
||||
|
||||
1. Added support for ext-libsodium, if it exists on the system. This is morally
|
||||
equivalent to adding `getrandom(2)` support without having to expose the
|
||||
syscall interface in PHP-land.
|
||||
2. Relaxed open_basedir restrictions. In previous versions, if open_basedir was
|
||||
set, PHP wouldn't even try to read from `/dev/urandom`. Now it will still do
|
||||
so if you can.
|
||||
3. Fixed integer casting inconsistencies between random_compat and PHP 7.
|
||||
4. Handle edge cases where an integer overflow turns one of the parameters into
|
||||
a float.
|
||||
|
||||
One change that we discussed was making `random_bytes()` and `random_int()`
|
||||
strict typed; meaning you could *only* pass integers to either function. While
|
||||
most veteran programmers are probably only doing this already (we strongly
|
||||
encourage it), it wouldn't be consistent with how these functions behave in PHP
|
||||
7. Please use these functions responsibly.
|
||||
|
||||
We've had even more of the PHP community involved in this release; the
|
||||
contributors list has been updated. If I forgot anybody, I promise you it's not
|
||||
because your contributions (either code or ideas) aren't valued, it's because
|
||||
I'm a bit overloaded with information at the moment. Please let me know
|
||||
immediately and I will correct my oversight.
|
||||
|
||||
Thanks everyone for helping make random_compat better.
|
||||
|
||||
### Version 1.0.5 - 2015-10-08
|
||||
|
||||
Got rid of the methods in the `Throwable` interface, which was causing problems
|
||||
on PHP 5.2. While we would normally not care about 5.2 (since [5.4 and earlier are EOL'd](https://secure.php.net/supported-versions.php)),
|
||||
we do want to encourage widespread adoption (e.g. [Wordpress](https://core.trac.wordpress.org/ticket/28633)).
|
||||
|
||||
### Version 1.0.4 - 2015-10-02
|
||||
|
||||
Removed redundant `if()` checks, since `lib/random.php` is the entrypoint people
|
||||
should use.
|
||||
|
||||
### Version 1.0.3 - 2015-10-02
|
||||
|
||||
This release contains bug fixes contributed by the community.
|
||||
|
||||
* Avoid a PHP Notice when PHP is running without the mbstring extension
|
||||
* Use a compatible version of PHPUnit for testing on older versions of PHP
|
||||
|
||||
Although none of these bugs were outright security-affecting, updating ASAP is
|
||||
still strongly encouraged.
|
||||
|
||||
### Version 1.0.2 - 2015-09-23
|
||||
|
||||
Less strict input validation on `random_int()` parameters. PHP 7's `random_int()`
|
||||
accepts strings and floats that look like numbers, so we should too.
|
||||
|
||||
Thanks [@dd32](https://github.com/@dd32) for correcting this oversight.
|
||||
|
||||
### Version 1.0.1 - 2015-09-10
|
||||
|
||||
Instead of throwing an Exception immediately on insecure platforms, only do so
|
||||
when `random_bytes()` is invoked.
|
||||
|
||||
### Version 1.0.0 - 2015-09-07
|
||||
|
||||
Our API is now stable and forward-compatible with the CSPRNG features in PHP 7
|
||||
(as of 7.0.0 RC3).
|
||||
|
||||
A lot of great people have contributed their time and expertise to make this
|
||||
compatibility library possible. That this library has reached a stable release
|
||||
is more a reflection on the community than it is on PIE.
|
||||
|
||||
We are confident that random_compat will serve as the simplest and most secure
|
||||
CSPRNG interface available for PHP5 projects.
|
||||
|
||||
### Version 0.9.7 (pre-release) - 2015-09-01
|
||||
|
||||
An attempt to achieve compatibility with Error/TypeError in the RFC.
|
||||
|
||||
This should be identical to 1.0.0 sans any last-minute changes or performance enhancements.
|
||||
|
||||
### Version 0.9.6 (pre-release) - 2015-08-06
|
||||
|
||||
* Split the implementations into their own file (for ease of auditing)
|
||||
* Corrected the file type check after `/dev/urandom` has been opened (thanks
|
||||
[@narfbg](https://github.com/narfbg) and [@jedisct1](https://github.com/jedisct1))
|
||||
|
||||
### Version 0.9.5 (pre-release) - 2015-07-31
|
||||
|
||||
* Validate that `/dev/urandom` is a character device
|
||||
* Reported by [@lokdnet](https://twitter.com/lokdnet)
|
||||
* Investigated by [@narfbg](https://github.com/narfbg) and [frymaster](http://stackoverflow.com/users/1226810/frymaster) on [StackOverflow](http://stackoverflow.com/q/31631066/2224584)
|
||||
* Remove support for `/dev/arandom` which is an old OpenBSD feature, thanks [@jedisct1](https://github.com/jedisct1)
|
||||
* Prevent race conditions on the `filetype()` check, thanks [@jedisct1](https://github.com/jedisct1)
|
||||
* Buffer file reads to 8 bytes (performance optimization; PHP defaults to 8192 bytes)
|
||||
|
||||
### Version 0.9.4 (pre-release) - 2015-07-27
|
||||
|
||||
* Add logic to verify that `/dev/arandom` and `/dev/urandom` are actually devices.
|
||||
* Some clean-up in the comments
|
||||
|
||||
### Version 0.9.3 (pre-release) - 2015-07-22
|
||||
|
||||
Unless the Exceptions change to PHP 7 fails, this should be the last pre-release
|
||||
version. If need be, we'll make one more pre-release version with compatible
|
||||
behavior.
|
||||
|
||||
Changes since 0.9.2:
|
||||
|
||||
* Prioritize `/dev/arandom` and `/dev/urandom` over mcrypt.
|
||||
[@oittaa](https://github.com/oittaa) removed the -1 and +1 juggling on `$range` calculations for `random_int()`
|
||||
* Whitespace and comment clean-up, plus better variable names
|
||||
* Actually put a description in the composer.json file...
|
||||
|
||||
### Version 0.9.2 (pre-release) - 2015-07-16
|
||||
|
||||
* Consolidated `$range > PHP_INT_MAX` logic with `$range <= PHP_INT_MAX` (thanks
|
||||
[@oittaa](https://github.com/oittaa) and [@CodesInChaos](https://github.com/CodesInChaos))
|
||||
* `tests/phpunit.sh` now also runs the tests with `mbstring.func_overload` and
|
||||
`open_basedir`
|
||||
* Style consistency, whitespace cleanup, more meaningful variable names
|
||||
|
||||
### Version 0.9.1 (pre-release) - 2015-07-09
|
||||
|
||||
* Return random values on integer ranges > `PHP_INT_MAX` (thanks [@CodesInChaos](https://github.com/CodesInChaos))
|
||||
* Determined CSPRNG preference:
|
||||
1. `mcrypt_create_iv()` with `MCRYPT_DEV_URANDOM`
|
||||
2. `/dev/arandom`
|
||||
3. `/dev/urandom`
|
||||
4. `openssl_random_pseudo_bytes()`
|
||||
* Optimized backend selection (thanks [@lt](https://github.com/lt))
|
||||
* Fix #3 (thanks [@scottchiefbaker](https://github.com/scottchiefbaker))
|
||||
|
||||
### Version 0.9.0 (pre-release) - 2015-07-07
|
||||
|
||||
This should be a sane polyfill for PHP 7's `random_bytes()` and `random_int()`.
|
||||
We hesitate to call it production ready until it has received sufficient third
|
||||
party review.
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
## Errata (Design Decisions)
|
||||
|
||||
### Reasoning Behind the Order of Preferred Random Data Sources
|
||||
|
||||
The order is:
|
||||
|
||||
1. `libsodium if available`
|
||||
2. `fread() /dev/urandom if available`
|
||||
3. `mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM)`
|
||||
4. `COM('CAPICOM.Utilities.1')->GetRandom()`
|
||||
|
||||
If libsodium is available, we get random data from it. This is the preferred
|
||||
method on all OSes, but libsodium is not very widely installed, so other
|
||||
fallbacks are available.
|
||||
|
||||
Next, we read `/dev/urandom` (if it exists). This is the preferred file to read
|
||||
for random data for cryptographic purposes for BSD and Linux.
|
||||
|
||||
Despite [strongly urging people not to use mcrypt in their projects](https://paragonie.com/blog/2015/05/if-you-re-typing-word-mcrypt-into-your-code-you-re-doing-it-wrong),
|
||||
because libmcrypt is abandonware and the API puts too much responsibility on the
|
||||
implementor, we prioritize `mcrypt_create_iv()` with `MCRYPT_DEV_URANDOM` above
|
||||
the remaining implementations.
|
||||
|
||||
The reason is simple: `mcrypt_create_iv()` is part of PHP's `ext/mcrypt` code,
|
||||
and is not part `libmcrypt`. It actually does the right thing:
|
||||
|
||||
* On Unix-based operating systems, it reads from `/dev/urandom`, which unlike `/dev/random`
|
||||
is the sane and correct thing to do.
|
||||
* On Windows, it reads from `CryptGenRandom`, which is an exclusively Windows
|
||||
way to get random bytes.
|
||||
|
||||
If we're on Windows and don't have access to `mcrypt`, we use `CAPICOM.Utilities.1`.
|
||||
|
||||
As of random_compat 1.3, we no longer fall through to OpenSSL.
|
||||
|
|
@ -1,176 +0,0 @@
|
|||
# random_compat
|
||||
|
||||
[](https://travis-ci.org/paragonie/random_compat)
|
||||
[](https://scrutinizer-ci.com/g/paragonie/random_compat)
|
||||
|
||||
PHP 5.x polyfill for `random_bytes()` and `random_int()` created and maintained
|
||||
by [Paragon Initiative Enterprises](https://paragonie.com).
|
||||
|
||||
Although this library *should* function in earlier versions of PHP, we will only
|
||||
consider issues relevant to [supported PHP versions](https://secure.php.net/supported-versions.php).
|
||||
**If you are using an unsupported version of PHP, please upgrade as soon as possible.**
|
||||
|
||||
## Important
|
||||
|
||||
Although this library has been examined by some security experts in the PHP
|
||||
community, there will always be a chance that we overlooked something. Please
|
||||
ask your favorite trusted hackers to hammer it for implementation errors and
|
||||
bugs before even thinking about deploying it in production.
|
||||
|
||||
**Do not use the master branch, use a [stable release](https://github.com/paragonie/random_compat/releases/latest).**
|
||||
|
||||
For the background of this library, please refer to our blog post on
|
||||
[Generating Random Integers and Strings in PHP](https://paragonie.com/blog/2015/07/how-safely-generate-random-strings-and-integers-in-php).
|
||||
|
||||
### Usability Notice
|
||||
|
||||
If PHP cannot safely generate random data, this library will throw an `Exception`.
|
||||
It will never fall back to insecure random data. If this keeps happening, upgrade
|
||||
to a newer version of PHP immediately.
|
||||
|
||||
## Installing
|
||||
|
||||
**With [Composer](https://getcomposer.org):**
|
||||
|
||||
composer require paragonie/random_compat
|
||||
|
||||
**Signed PHP Archive:**
|
||||
|
||||
As of version 1.2.0, we also ship an ECDSA-signed PHP Archive with each stable
|
||||
release on Github.
|
||||
|
||||
1. Download [the `.phar`, `.phar.pubkey`, and `.phar.pubkey.asc`](https://github.com/paragonie/random_compat/releases/latest) files.
|
||||
2. (**Recommended** but not required) Verify the PGP signature of `.phar.pubkey`
|
||||
(contained within the `.asc` file) using the [PGP public key for Paragon Initiative Enterprises](https://paragonie.com/static/gpg-public-key.txt).
|
||||
3. Extract both `.phar` and `.phar.pubkey` files to the same directory.
|
||||
4. `require_once "/path/to/random_compat.phar";`
|
||||
5. When a new version is released, you only need to replace the `.phar` file;
|
||||
the `.pubkey` will not change (unless our signing key is ever compromised).
|
||||
|
||||
**Manual Installation:**
|
||||
|
||||
1. Download [a stable release](https://github.com/paragonie/random_compat/releases/latest).
|
||||
2. Extract the files into your project.
|
||||
3. `require_once "/path/to/random_compat/lib/random.php";`
|
||||
|
||||
## Usage
|
||||
|
||||
This library exposes the [CSPRNG functions added in PHP 7](https://secure.php.net/manual/en/ref.csprng.php)
|
||||
for use in PHP 5 projects. Their behavior should be identical.
|
||||
|
||||
### Generate a string of random bytes
|
||||
|
||||
```php
|
||||
try {
|
||||
$string = random_bytes(32);
|
||||
} catch (TypeError $e) {
|
||||
// Well, it's an integer, so this IS unexpected.
|
||||
die("An unexpected error has occurred");
|
||||
} catch (Error $e) {
|
||||
// This is also unexpected because 32 is a reasonable integer.
|
||||
die("An unexpected error has occurred");
|
||||
} catch (Exception $e) {
|
||||
// If you get this message, the CSPRNG failed hard.
|
||||
die("Could not generate a random string. Is our OS secure?");
|
||||
}
|
||||
|
||||
var_dump(bin2hex($string));
|
||||
// string(64) "5787c41ae124b3b9363b7825104f8bc8cf27c4c3036573e5f0d4a91ad2eeac6f"
|
||||
```
|
||||
|
||||
### Generate a random integer between two given integers (inclusive)
|
||||
|
||||
```php
|
||||
try {
|
||||
$int = random_int(0,255);
|
||||
|
||||
} catch (TypeError $e) {
|
||||
// Well, it's an integer, so this IS unexpected.
|
||||
die("An unexpected error has occurred");
|
||||
} catch (Error $e) {
|
||||
// This is also unexpected because 0 and 255 are both reasonable integers.
|
||||
die("An unexpected error has occurred");
|
||||
} catch (Exception $e) {
|
||||
// If you get this message, the CSPRNG failed hard.
|
||||
die("Could not generate a random string. Is our OS secure?");
|
||||
}
|
||||
|
||||
var_dump($int);
|
||||
// int(47)
|
||||
```
|
||||
|
||||
### Exception handling
|
||||
|
||||
When handling exceptions and errors you must account for differences between
|
||||
PHP 5 and PHP7.
|
||||
|
||||
The differences:
|
||||
|
||||
* Catching `Error` works, so long as it is caught before `Exception`.
|
||||
* Catching `Exception` has different behavior, without previously catching `Error`.
|
||||
* There is *no* portable way to catch all errors/exceptions.
|
||||
|
||||
#### Our recommendation
|
||||
|
||||
**Always** catch `Error` before `Exception`.
|
||||
|
||||
#### Example
|
||||
|
||||
```php
|
||||
try {
|
||||
return random_int(1, $userInput);
|
||||
} catch (TypeError $e) {
|
||||
// This is okay, so long as `Error` is caught before `Exception`.
|
||||
throw new Exception('Please enter a number!');
|
||||
} catch (Error $e) {
|
||||
// This is required, if you do not need to do anything just rethrow.
|
||||
throw $e;
|
||||
} catch (Exception $e) {
|
||||
// This is optional and maybe omitted if you do not want to handle errors
|
||||
// during generation.
|
||||
throw new InternalServerErrorException(
|
||||
'Oops, our server is bust and cannot generate any random data.',
|
||||
500,
|
||||
$e
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Contributors
|
||||
|
||||
This project would not be anywhere near as excellent as it is today if it
|
||||
weren't for the contributions of the following individuals:
|
||||
|
||||
* [@AndrewCarterUK (Andrew Carter)](https://github.com/AndrewCarterUK)
|
||||
* [@asgrim (James Titcumb)](https://github.com/asgrim)
|
||||
* [@bcremer (Benjamin Cremer)](https://github.com/bcremer)
|
||||
* [@CodesInChaos (Christian Winnerlein)](https://github.com/CodesInChaos)
|
||||
* [@chriscct7 (Chris Christoff)](https://github.com/chriscct7)
|
||||
* [@cs278 (Chris Smith)](https://github.com/cs278)
|
||||
* [@cweagans (Cameron Eagans)](https://github.com/cweagans)
|
||||
* [@dd32 (Dion Hulse)](https://github.com/dd32)
|
||||
* [@geggleto (Glenn Eggleton)](https://github.com/geggleto)
|
||||
* [@ircmaxell (Anthony Ferrara)](https://github.com/ircmaxell)
|
||||
* [@jedisct1 (Frank Denis)](https://github.com/jedisct1)
|
||||
* [@juliangut (Julián Gutiérrez)](https://github.com/juliangut)
|
||||
* [@kelunik (Niklas Keller)](https://github.com/kelunik)
|
||||
* [@lt (Leigh)](https://github.com/lt)
|
||||
* [@MasonM (Mason Malone)](https://github.com/MasonM)
|
||||
* [@mmeyer2k (Michael M)](https://github.com/mmeyer2k)
|
||||
* [@narfbg (Andrey Andreev)](https://github.com/narfbg)
|
||||
* [@nicolas-grekas (Nicolas Grekas)](https://github.com/nicolas-grekas)
|
||||
* [@oittaa](https://github.com/oittaa)
|
||||
* [@oucil (Kevin Farley)](https://github.com/oucil)
|
||||
* [@redragonx (Stephen Chavez)](https://github.com/redragonx)
|
||||
* [@rchouinard (Ryan Chouinard)](https://github.com/rchouinard)
|
||||
* [@SammyK (Sammy Kaye Powers)](https://github.com/SammyK)
|
||||
* [@scottchiefbaker (Scott Baker)](https://github.com/scottchiefbaker)
|
||||
* [@skyosev (Stoyan Kyosev)](https://github.com/skyosev)
|
||||
* [@stof (Christophe Coevoet)](https://github.com/stof)
|
||||
* [@teohhanhui (Teoh Han Hui)](https://github.com/teohhanhui)
|
||||
* [@tom-- (Tom Worster)](https://github.com/tom--)
|
||||
* [@tsyr2ko](https://github.com/tsyr2ko)
|
||||
* [@trowski (Aaron Piotrowski)](https://github.com/trowski)
|
||||
* [@twistor (Chris Lepannen)](https://github.com/twistor)
|
||||
* [@voku (Lars Moelleken)](https://github.com/voku)
|
||||
* [@xabbuh (Christian Flothmann)](https://github.com/xabbuh)
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
# An Invitation to Security Researchers
|
||||
|
||||
Every company says they take security "very seriously." Rather than bore anyone
|
||||
with banal boilerplate, here are some quick answers followed by detailed
|
||||
elaboration. If you have any questions about our policies, please email them to
|
||||
`scott@paragonie.com`.
|
||||
|
||||
## Quick Answers
|
||||
|
||||
* There is no compulsion to disclose vulnerabilities privately, but we
|
||||
appreciate a head's up.
|
||||
* `security@paragonie.com` will get your reports to the right person. Our GPG
|
||||
fingerprint, should you decide to encrypt your report, is
|
||||
`7F52 D5C6 1D12 55C7 3136 2E82 6B97 A1C2 8264 04DA`.
|
||||
|
||||
* **YES**, we will reward security researchers who disclose vulnerabilities in
|
||||
our software.
|
||||
* In most cases, **No Proof-of-Concept Required.**
|
||||
|
||||
## How to Report a Security Bug to Paragon Initiative Enterprises
|
||||
|
||||
### There is no compulsion to disclose privately.
|
||||
|
||||
We believe vulnerability disclosure style is a personal choice and enjoy working
|
||||
with a diverse community. We understand and appreciate the importance of Full
|
||||
Disclosure in the history and practice of security research.
|
||||
|
||||
We would *like* to know about high-severity bugs before they become public
|
||||
knowledge, so we can fix them in a timely manner, but **we do not believe in
|
||||
threatening researchers or trying to enforce vulnerability embargoes**.
|
||||
|
||||
Ultimately, if you discover a security-affecting vulnerability, what you do with
|
||||
it is your choice. We would like to work with people, and to celebrate and
|
||||
reward their skill, experience, and dedication. We appreciate being informed of
|
||||
our mistakes so we can learn from them and build a better product. Our goal is
|
||||
to empower the community.
|
||||
|
||||
### Where to Send Security Vulnerabilities
|
||||
|
||||
Our security email address is `security@paragonie.com`. Also feel free to open a
|
||||
new issue on Github if you want to disclose publicly.
|
||||
|
||||
```
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG
|
||||
|
||||
mQENBFUgwRUBCADcIpqNwyYc5UmY/tpx1sF/rQ3knR1YNXYZThzFV+Gmqhp1fDH5
|
||||
qBs9foh1xwI6O7knWmQngnf/nBumI3x6xj7PuOdEZUh2FwCG/VWnglW8rKmoHzHA
|
||||
ivjiu9SLnPIPAgHSHeh2XD7q3Ndm3nenbjAiRFNl2iXcwA2cTQp9Mmfw9vVcw0G0
|
||||
z1o0G3s8cC8ZS6flFySIervvfSRWj7A1acI5eE3+AH/qXJRdEJ+9J8OB65p1JMfk
|
||||
6+fWgOB1XZxMpz70S0rW6IX38WDSRhEK2fXyZJAJjyt+YGuzjZySNSoQR/V6vNYn
|
||||
syrNPCJ2i5CgZQxAkyBBcr7koV9RIhPRzct/ABEBAAG0IVNlY3VyaXR5IDxzZWN1
|
||||
cml0eUBwYXJhZ29uaWUuY29tPokBOQQTAQIAIwUCVSDBFQIbAwcLCQgHAwIBBhUI
|
||||
AgkKCwQWAgMBAh4BAheAAAoJEGuXocKCZATat2YIAIoejNFEQ2c1iaOEtSuB7Pn/
|
||||
WLbsDsHNLDKOV+UnfaCjv/vL7D+5NMChFCi2frde/NQb2TsjqmIH+V+XbnJtlrXD
|
||||
Vj7yvMVal+Jqjwj7v4eOEWcKVcFZk+9cfUgh7t92T2BMX58RpgZF0IQZ6Z1R3FfC
|
||||
9Ub4X6ykW+te1q0/4CoRycniwmlQi6iGSr99LQ5pfJq2Qlmz/luTZ0UX0h575T7d
|
||||
cp2T1sX/zFRk/fHeANWSksipdDBjAXR7NMnYZgw2HghEdFk/xRDY7K1NRWNZBf05
|
||||
WrMHmh6AIVJiWZvI175URxEe268hh+wThBhXQHMhFNJM1qPIuzb4WogxM3UUD7m5
|
||||
AQ0EVSDBFQEIALNkpzSuJsHAHh79sc0AYWztdUe2MzyofQbbOnOCpWZebYsC3EXU
|
||||
335fIg59k0m6f+O7GmEZzzIv5v0i99GS1R8CJm6FvhGqtH8ZqmOGbc71WdJSiNVE
|
||||
0kpQoJlVzRbig6ZyyjzrggbM1eh5OXOk5pw4+23FFEdw7JWU0HJS2o71r1hwp05Z
|
||||
vy21kcUEobz/WWQQyGS0Neo7PJn+9KS6wOxXul/UE0jct/5f7KLMdWMJ1VgniQmm
|
||||
hjvkHLPSICteqCI04RfcmMseW9gueHQXeUu1SNIvsWa2MhxjeBej3pDnrZWszKwy
|
||||
gF45GO9/v4tkIXNMy5J1AtOyRgQ3IUMqp8EAEQEAAYkBHwQYAQIACQUCVSDBFQIb
|
||||
DAAKCRBrl6HCgmQE2jnIB/4/xFz8InpM7eybnBOAir3uGcYfs3DOmaKn7qWVtGzv
|
||||
rKpQPYnVtlU2i6Z5UO4c4jDLT/8Xm1UDz3Lxvqt4xCaDwJvBZexU5BMK8l5DvOzH
|
||||
6o6P2L1UDu6BvmPXpVZz7/qUhOnyf8VQg/dAtYF4/ax19giNUpI5j5o5mX5w80Rx
|
||||
qSXV9NdSL4fdjeG1g/xXv2luhoV53T1bsycI3wjk/x5tV+M2KVhZBvvuOm/zhJje
|
||||
oLWp0saaESkGXIXqurj6gZoujJvSvzl0n9F9VwqMEizDUfrXgtD1siQGhP0sVC6q
|
||||
ha+F/SAEJ0jEquM4TfKWWU2S5V5vgPPpIQSYRnhQW4b1
|
||||
=xJPW
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
```
|
||||
|
||||
### We Will Reward Security Researchers
|
||||
|
||||
**This process has not been formalized; nor have dollar amounts been
|
||||
discussed.**
|
||||
|
||||
However, if you report a valid security-affecting bug, we will compensate you
|
||||
for the time spent finding the vulnerability and reward you for being a good
|
||||
neighbor.
|
||||
|
||||
#### What does a "valid" bug mean?
|
||||
|
||||
There are two sides to this:
|
||||
|
||||
1. Some have spammed projects with invalid bug reports hoping to collect
|
||||
bounties for pressing a button and running an automated analysis tool. This
|
||||
is not cool.
|
||||
2. There is a potential for the developers of a project to declare all security
|
||||
bug reports as invalid to save money.
|
||||
|
||||
Our team members have an established history of reporting vulnerabilities to
|
||||
large open source projects. **We aren't in the business of ripping people off.**
|
||||
When in doubt, our policy is to err on the side of generosity.
|
||||
|
||||
### No Proof-of-Concept Required
|
||||
|
||||
We might ask for one if we feel we do not understand some of the details
|
||||
pertaining to a specific vulnerability. We certainly appreciate them if you
|
||||
include them in your report, but we believe **the burden lies with the developer
|
||||
to prove their software *is* secure** rather than with the researcher to prove
|
||||
that it isn't.
|
||||
|
||||
In our experience, most bugs are simpler to fix than they are to exploit.
|
||||
|
||||
|
|
@ -1,35 +1,37 @@
|
|||
{
|
||||
"name": "paragonie/random_compat",
|
||||
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
|
||||
"keywords": [
|
||||
"csprng",
|
||||
"random",
|
||||
"pseudorandom"
|
||||
],
|
||||
"license": "MIT",
|
||||
"type": "library",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Paragon Initiative Enterprises",
|
||||
"email": "security@paragonie.com",
|
||||
"homepage": "https://paragonie.com"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/paragonie/random_compat/issues",
|
||||
"email": "info@paragonie.com",
|
||||
"source": "https://github.com/paragonie/random_compat"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "4.*|5.*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
|
||||
},
|
||||
"autoload": {
|
||||
"files": ["lib/random.php"]
|
||||
"name": "paragonie/random_compat",
|
||||
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
|
||||
"keywords": [
|
||||
"csprng",
|
||||
"random",
|
||||
"pseudorandom"
|
||||
],
|
||||
"license": "MIT",
|
||||
"type": "library",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Paragon Initiative Enterprises",
|
||||
"email": "security@paragonie.com",
|
||||
"homepage": "https://paragonie.com"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/paragonie/random_compat/issues",
|
||||
"email": "info@paragonie.com",
|
||||
"source": "https://github.com/paragonie/random_compat"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "4.*|5.*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"lib/random.php"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Paragon Initiative Enterprises
|
||||
* Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
if (!function_exists('RandomCompat_strlen')) {
|
||||
if (!is_callable('RandomCompat_strlen')) {
|
||||
if (
|
||||
defined('MB_OVERLOAD_STRING') &&
|
||||
ini_get('mbstring.func_overload') & MB_OVERLOAD_STRING
|
||||
|
|
@ -51,7 +51,7 @@ if (!function_exists('RandomCompat_strlen')) {
|
|||
);
|
||||
}
|
||||
|
||||
return mb_strlen($binary_string, '8bit');
|
||||
return (int) mb_strlen($binary_string, '8bit');
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -73,12 +73,12 @@ if (!function_exists('RandomCompat_strlen')) {
|
|||
'RandomCompat_strlen() expects a string'
|
||||
);
|
||||
}
|
||||
return strlen($binary_string);
|
||||
return (int) strlen($binary_string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('RandomCompat_substr')) {
|
||||
if (!is_callable('RandomCompat_substr')) {
|
||||
|
||||
if (
|
||||
defined('MB_OVERLOAD_STRING')
|
||||
|
|
@ -118,7 +118,7 @@ if (!function_exists('RandomCompat_substr')) {
|
|||
* mb_substr($str, 0, NULL, '8bit') returns an empty string on
|
||||
* PHP 5.3, so we have to find the length ourselves.
|
||||
*/
|
||||
$length = RandomCompat_strlen($length) - $start;
|
||||
$length = RandomCompat_strlen($binary_string) - $start;
|
||||
} elseif (!is_int($length)) {
|
||||
throw new TypeError(
|
||||
'RandomCompat_substr(): Third argument should be an integer, or omitted'
|
||||
|
|
@ -130,10 +130,10 @@ if (!function_exists('RandomCompat_substr')) {
|
|||
return '';
|
||||
}
|
||||
if ($start > RandomCompat_strlen($binary_string)) {
|
||||
return false;
|
||||
return '';
|
||||
}
|
||||
|
||||
return mb_substr($binary_string, $start, $length, '8bit');
|
||||
return (string) mb_substr($binary_string, $start, $length, '8bit');
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -172,10 +172,10 @@ if (!function_exists('RandomCompat_substr')) {
|
|||
);
|
||||
}
|
||||
|
||||
return substr($binary_string, $start, $length);
|
||||
return (string) substr($binary_string, $start, $length);
|
||||
}
|
||||
|
||||
return substr($binary_string, $start);
|
||||
return (string) substr($binary_string, $start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Paragon Initiative Enterprises
|
||||
* Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
if (!function_exists('RandomCompat_intval')) {
|
||||
if (!is_callable('RandomCompat_intval')) {
|
||||
|
||||
/**
|
||||
* Cast to an integer if we can, safely.
|
||||
|
|
@ -38,15 +38,18 @@ if (!function_exists('RandomCompat_intval')) {
|
|||
* through.
|
||||
*
|
||||
* @param int|float $number The number we want to convert to an int
|
||||
* @param boolean $fail_open Set to true to not throw an exception
|
||||
* @param bool $fail_open Set to true to not throw an exception
|
||||
*
|
||||
* @return int (or float if $fail_open)
|
||||
* @return float|int
|
||||
* @psalm-suppress InvalidReturnType
|
||||
*
|
||||
* @throws TypeError
|
||||
*/
|
||||
function RandomCompat_intval($number, $fail_open = false)
|
||||
{
|
||||
if (is_numeric($number)) {
|
||||
if (is_int($number) || is_float($number)) {
|
||||
$number += 0;
|
||||
} elseif (is_numeric($number)) {
|
||||
$number += 0;
|
||||
}
|
||||
|
||||
|
|
@ -60,12 +63,13 @@ if (!function_exists('RandomCompat_intval')) {
|
|||
$number = (int) $number;
|
||||
}
|
||||
|
||||
if (is_int($number) || $fail_open) {
|
||||
return $number;
|
||||
if (is_int($number)) {
|
||||
return (int) $number;
|
||||
} elseif (!$fail_open) {
|
||||
throw new TypeError(
|
||||
'Expected an integer.'
|
||||
);
|
||||
}
|
||||
|
||||
throw new TypeError(
|
||||
'Expected an integer.'
|
||||
);
|
||||
return $number;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Paragon Initiative Enterprises
|
||||
* Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
@ -35,8 +35,15 @@ if (!class_exists('Error', false)) {
|
|||
}
|
||||
|
||||
if (!class_exists('TypeError', false)) {
|
||||
class TypeError extends Error
|
||||
{
|
||||
if (is_subclass_of('Error', 'Exception')) {
|
||||
class TypeError extends Error
|
||||
{
|
||||
|
||||
}
|
||||
} else {
|
||||
class TypeError extends Exception
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@
|
|||
* Random_* Compatibility Library
|
||||
* for using the new PHP 7 random_* API in PHP 5 projects
|
||||
*
|
||||
* @version 2.0.2
|
||||
* @released 2016-04-03
|
||||
* @version 2.0.10
|
||||
* @released 2017-03-13
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Paragon Initiative Enterprises
|
||||
* Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
if (!defined('PHP_VERSION_ID')) {
|
||||
// This constant was introduced in PHP 5.2.7
|
||||
$RandomCompatversion = explode('.', PHP_VERSION);
|
||||
$RandomCompatversion = array_map('intval', explode('.', PHP_VERSION));
|
||||
define(
|
||||
'PHP_VERSION_ID',
|
||||
$RandomCompatversion[0] * 10000
|
||||
|
|
@ -41,157 +41,183 @@ if (!defined('PHP_VERSION_ID')) {
|
|||
$RandomCompatversion = null;
|
||||
}
|
||||
|
||||
if (PHP_VERSION_ID < 70000) {
|
||||
|
||||
if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
|
||||
define('RANDOM_COMPAT_READ_BUFFER', 8);
|
||||
}
|
||||
|
||||
$RandomCompatDIR = dirname(__FILE__);
|
||||
|
||||
require_once $RandomCompatDIR.'/byte_safe_strings.php';
|
||||
require_once $RandomCompatDIR.'/cast_to_int.php';
|
||||
require_once $RandomCompatDIR.'/error_polyfill.php';
|
||||
|
||||
if (!function_exists('random_bytes')) {
|
||||
/**
|
||||
* PHP 5.2.0 - 5.6.x way to implement random_bytes()
|
||||
*
|
||||
* We use conditional statements here to define the function in accordance
|
||||
* to the operating environment. It's a micro-optimization.
|
||||
*
|
||||
* In order of preference:
|
||||
* 1. Use libsodium if available.
|
||||
* 2. fread() /dev/urandom if available (never on Windows)
|
||||
* 3. mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM)
|
||||
* 4. COM('CAPICOM.Utilities.1')->GetRandom()
|
||||
* 5. openssl_random_pseudo_bytes() (absolute last resort)
|
||||
*
|
||||
* See ERRATA.md for our reasoning behind this particular order
|
||||
*/
|
||||
if (extension_loaded('libsodium')) {
|
||||
// See random_bytes_libsodium.php
|
||||
if (PHP_VERSION_ID >= 50300 && function_exists('\\Sodium\\randombytes_buf')) {
|
||||
require_once $RandomCompatDIR.'/random_bytes_libsodium.php';
|
||||
} elseif (method_exists('Sodium', 'randombytes_buf')) {
|
||||
require_once $RandomCompatDIR.'/random_bytes_libsodium_legacy.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reading directly from /dev/urandom:
|
||||
*/
|
||||
if (DIRECTORY_SEPARATOR === '/') {
|
||||
// DIRECTORY_SEPARATOR === '/' on Unix-like OSes -- this is a fast
|
||||
// way to exclude Windows.
|
||||
$RandomCompatUrandom = true;
|
||||
$RandomCompat_basedir = ini_get('open_basedir');
|
||||
|
||||
if (!empty($RandomCompat_basedir)) {
|
||||
$RandomCompat_open_basedir = explode(
|
||||
PATH_SEPARATOR,
|
||||
strtolower($RandomCompat_basedir)
|
||||
);
|
||||
$RandomCompatUrandom = (array() !== array_intersect(
|
||||
array('/dev', '/dev/', '/dev/urandom'),
|
||||
$RandomCompat_open_basedir
|
||||
));
|
||||
$RandomCompat_open_basedir = null;
|
||||
}
|
||||
|
||||
if (
|
||||
!function_exists('random_bytes')
|
||||
&&
|
||||
$RandomCompatUrandom
|
||||
&&
|
||||
@is_readable('/dev/urandom')
|
||||
) {
|
||||
// Error suppression on is_readable() in case of an open_basedir
|
||||
// or safe_mode failure. All we care about is whether or not we
|
||||
// can read it at this point. If the PHP environment is going to
|
||||
// panic over trying to see if the file can be read in the first
|
||||
// place, that is not helpful to us here.
|
||||
|
||||
// See random_bytes_dev_urandom.php
|
||||
require_once $RandomCompatDIR.'/random_bytes_dev_urandom.php';
|
||||
}
|
||||
// Unset variables after use
|
||||
$RandomCompat_basedir = null;
|
||||
} else {
|
||||
$RandomCompatUrandom = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* mcrypt_create_iv()
|
||||
*/
|
||||
if (
|
||||
!function_exists('random_bytes')
|
||||
&&
|
||||
PHP_VERSION_ID >= 50307
|
||||
&&
|
||||
extension_loaded('mcrypt')
|
||||
&&
|
||||
(DIRECTORY_SEPARATOR !== '/' || $RandomCompatUrandom)
|
||||
) {
|
||||
// Prevent this code from hanging indefinitely on non-Windows;
|
||||
// see https://bugs.php.net/bug.php?id=69833
|
||||
if (
|
||||
DIRECTORY_SEPARATOR !== '/' ||
|
||||
(PHP_VERSION_ID <= 50609 || PHP_VERSION_ID >= 50613)
|
||||
) {
|
||||
// See random_bytes_mcrypt.php
|
||||
require_once $RandomCompatDIR.'/random_bytes_mcrypt.php';
|
||||
}
|
||||
}
|
||||
$RandomCompatUrandom = null;
|
||||
|
||||
if (
|
||||
!function_exists('random_bytes')
|
||||
&&
|
||||
extension_loaded('com_dotnet')
|
||||
&&
|
||||
class_exists('COM')
|
||||
) {
|
||||
$RandomCompat_disabled_classes = preg_split(
|
||||
'#\s*,\s*#',
|
||||
strtolower(ini_get('disable_classes'))
|
||||
);
|
||||
|
||||
if (!in_array('com', $RandomCompat_disabled_classes)) {
|
||||
try {
|
||||
$RandomCompatCOMtest = new COM('CAPICOM.Utilities.1');
|
||||
if (method_exists($RandomCompatCOMtest, 'GetRandom')) {
|
||||
// See random_bytes_com_dotnet.php
|
||||
require_once $RandomCompatDIR.'/random_bytes_com_dotnet.php';
|
||||
}
|
||||
} catch (com_exception $e) {
|
||||
// Don't try to use it.
|
||||
}
|
||||
}
|
||||
$RandomCompat_disabled_classes = null;
|
||||
$RandomCompatCOMtest = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* throw new Exception
|
||||
*/
|
||||
if (!function_exists('random_bytes')) {
|
||||
/**
|
||||
* We don't have any more options, so let's throw an exception right now
|
||||
* and hope the developer won't let it fail silently.
|
||||
*/
|
||||
function random_bytes($length)
|
||||
{
|
||||
throw new Exception(
|
||||
'There is no suitable CSPRNG installed on your system'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('random_int')) {
|
||||
require_once $RandomCompatDIR.'/random_int.php';
|
||||
}
|
||||
|
||||
$RandomCompatDIR = null;
|
||||
/**
|
||||
* PHP 7.0.0 and newer have these functions natively.
|
||||
*/
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
|
||||
define('RANDOM_COMPAT_READ_BUFFER', 8);
|
||||
}
|
||||
|
||||
$RandomCompatDIR = dirname(__FILE__);
|
||||
|
||||
require_once $RandomCompatDIR . '/byte_safe_strings.php';
|
||||
require_once $RandomCompatDIR . '/cast_to_int.php';
|
||||
require_once $RandomCompatDIR . '/error_polyfill.php';
|
||||
|
||||
if (!is_callable('random_bytes')) {
|
||||
/**
|
||||
* PHP 5.2.0 - 5.6.x way to implement random_bytes()
|
||||
*
|
||||
* We use conditional statements here to define the function in accordance
|
||||
* to the operating environment. It's a micro-optimization.
|
||||
*
|
||||
* In order of preference:
|
||||
* 1. Use libsodium if available.
|
||||
* 2. fread() /dev/urandom if available (never on Windows)
|
||||
* 3. mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM)
|
||||
* 4. COM('CAPICOM.Utilities.1')->GetRandom()
|
||||
*
|
||||
* See RATIONALE.md for our reasoning behind this particular order
|
||||
*/
|
||||
if (extension_loaded('libsodium')) {
|
||||
// See random_bytes_libsodium.php
|
||||
if (PHP_VERSION_ID >= 50300 && is_callable('\\Sodium\\randombytes_buf')) {
|
||||
require_once $RandomCompatDIR . '/random_bytes_libsodium.php';
|
||||
} elseif (method_exists('Sodium', 'randombytes_buf')) {
|
||||
require_once $RandomCompatDIR . '/random_bytes_libsodium_legacy.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reading directly from /dev/urandom:
|
||||
*/
|
||||
if (DIRECTORY_SEPARATOR === '/') {
|
||||
// DIRECTORY_SEPARATOR === '/' on Unix-like OSes -- this is a fast
|
||||
// way to exclude Windows.
|
||||
$RandomCompatUrandom = true;
|
||||
$RandomCompat_basedir = ini_get('open_basedir');
|
||||
|
||||
if (!empty($RandomCompat_basedir)) {
|
||||
$RandomCompat_open_basedir = explode(
|
||||
PATH_SEPARATOR,
|
||||
strtolower($RandomCompat_basedir)
|
||||
);
|
||||
$RandomCompatUrandom = (array() !== array_intersect(
|
||||
array('/dev', '/dev/', '/dev/urandom'),
|
||||
$RandomCompat_open_basedir
|
||||
));
|
||||
$RandomCompat_open_basedir = null;
|
||||
}
|
||||
|
||||
if (
|
||||
!is_callable('random_bytes')
|
||||
&&
|
||||
$RandomCompatUrandom
|
||||
&&
|
||||
@is_readable('/dev/urandom')
|
||||
) {
|
||||
// Error suppression on is_readable() in case of an open_basedir
|
||||
// or safe_mode failure. All we care about is whether or not we
|
||||
// can read it at this point. If the PHP environment is going to
|
||||
// panic over trying to see if the file can be read in the first
|
||||
// place, that is not helpful to us here.
|
||||
|
||||
// See random_bytes_dev_urandom.php
|
||||
require_once $RandomCompatDIR . '/random_bytes_dev_urandom.php';
|
||||
}
|
||||
// Unset variables after use
|
||||
$RandomCompat_basedir = null;
|
||||
} else {
|
||||
$RandomCompatUrandom = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* mcrypt_create_iv()
|
||||
*
|
||||
* We only want to use mcypt_create_iv() if:
|
||||
*
|
||||
* - random_bytes() hasn't already been defined
|
||||
* - the mcrypt extensions is loaded
|
||||
* - One of these two conditions is true:
|
||||
* - We're on Windows (DIRECTORY_SEPARATOR !== '/')
|
||||
* - We're not on Windows and /dev/urandom is readabale
|
||||
* (i.e. we're not in a chroot jail)
|
||||
* - Special case:
|
||||
* - If we're not on Windows, but the PHP version is between
|
||||
* 5.6.10 and 5.6.12, we don't want to use mcrypt. It will
|
||||
* hang indefinitely. This is bad.
|
||||
* - If we're on Windows, we want to use PHP >= 5.3.7 or else
|
||||
* we get insufficient entropy errors.
|
||||
*/
|
||||
if (
|
||||
!is_callable('random_bytes')
|
||||
&&
|
||||
// Windows on PHP < 5.3.7 is broken, but non-Windows is not known to be.
|
||||
(DIRECTORY_SEPARATOR === '/' || PHP_VERSION_ID >= 50307)
|
||||
&&
|
||||
// Prevent this code from hanging indefinitely on non-Windows;
|
||||
// see https://bugs.php.net/bug.php?id=69833
|
||||
(
|
||||
DIRECTORY_SEPARATOR !== '/' ||
|
||||
(PHP_VERSION_ID <= 50609 || PHP_VERSION_ID >= 50613)
|
||||
)
|
||||
&&
|
||||
extension_loaded('mcrypt')
|
||||
) {
|
||||
// See random_bytes_mcrypt.php
|
||||
require_once $RandomCompatDIR . '/random_bytes_mcrypt.php';
|
||||
}
|
||||
$RandomCompatUrandom = null;
|
||||
|
||||
/**
|
||||
* This is a Windows-specific fallback, for when the mcrypt extension
|
||||
* isn't loaded.
|
||||
*/
|
||||
if (
|
||||
!is_callable('random_bytes')
|
||||
&&
|
||||
extension_loaded('com_dotnet')
|
||||
&&
|
||||
class_exists('COM')
|
||||
) {
|
||||
$RandomCompat_disabled_classes = preg_split(
|
||||
'#\s*,\s*#',
|
||||
strtolower(ini_get('disable_classes'))
|
||||
);
|
||||
|
||||
if (!in_array('com', $RandomCompat_disabled_classes)) {
|
||||
try {
|
||||
$RandomCompatCOMtest = new COM('CAPICOM.Utilities.1');
|
||||
if (method_exists($RandomCompatCOMtest, 'GetRandom')) {
|
||||
// See random_bytes_com_dotnet.php
|
||||
require_once $RandomCompatDIR . '/random_bytes_com_dotnet.php';
|
||||
}
|
||||
} catch (com_exception $e) {
|
||||
// Don't try to use it.
|
||||
}
|
||||
}
|
||||
$RandomCompat_disabled_classes = null;
|
||||
$RandomCompatCOMtest = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* throw new Exception
|
||||
*/
|
||||
if (!is_callable('random_bytes')) {
|
||||
/**
|
||||
* We don't have any more options, so let's throw an exception right now
|
||||
* and hope the developer won't let it fail silently.
|
||||
*
|
||||
* @param mixed $length
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
function random_bytes($length)
|
||||
{
|
||||
unset($length); // Suppress "variable not used" warnings.
|
||||
throw new Exception(
|
||||
'There is no suitable CSPRNG installed on your system'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_callable('random_int')) {
|
||||
require_once $RandomCompatDIR . '/random_int.php';
|
||||
}
|
||||
|
||||
$RandomCompatDIR = null;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Paragon Initiative Enterprises
|
||||
* Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
@ -26,56 +26,63 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Windows with PHP < 5.3.0 will not have the function
|
||||
* openssl_random_pseudo_bytes() available, so let's use
|
||||
* CAPICOM to work around this deficiency.
|
||||
*
|
||||
* @param int $bytes
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function random_bytes($bytes)
|
||||
{
|
||||
try {
|
||||
$bytes = RandomCompat_intval($bytes);
|
||||
} catch (TypeError $ex) {
|
||||
throw new TypeError(
|
||||
'random_bytes(): $bytes must be an integer'
|
||||
);
|
||||
}
|
||||
|
||||
if ($bytes < 1) {
|
||||
throw new Error(
|
||||
'Length must be greater than 0'
|
||||
);
|
||||
}
|
||||
|
||||
$buf = '';
|
||||
$util = new COM('CAPICOM.Utilities.1');
|
||||
$execCount = 0;
|
||||
|
||||
if (!is_callable('random_bytes')) {
|
||||
/**
|
||||
* Let's not let it loop forever. If we run N times and fail to
|
||||
* get N bytes of random data, then CAPICOM has failed us.
|
||||
* Windows with PHP < 5.3.0 will not have the function
|
||||
* openssl_random_pseudo_bytes() available, so let's use
|
||||
* CAPICOM to work around this deficiency.
|
||||
*
|
||||
* @param int $bytes
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
do {
|
||||
$buf .= base64_decode($util->GetRandom($bytes, 0));
|
||||
if (RandomCompat_strlen($buf) >= $bytes) {
|
||||
/**
|
||||
* Return our random entropy buffer here:
|
||||
*/
|
||||
return RandomCompat_substr($buf, 0, $bytes);
|
||||
function random_bytes($bytes)
|
||||
{
|
||||
try {
|
||||
$bytes = RandomCompat_intval($bytes);
|
||||
} catch (TypeError $ex) {
|
||||
throw new TypeError(
|
||||
'random_bytes(): $bytes must be an integer'
|
||||
);
|
||||
}
|
||||
++$execCount;
|
||||
} while ($execCount < $bytes);
|
||||
|
||||
/**
|
||||
* If we reach here, PHP has failed us.
|
||||
*/
|
||||
throw new Exception(
|
||||
'Could not gather sufficient random data'
|
||||
);
|
||||
if ($bytes < 1) {
|
||||
throw new Error(
|
||||
'Length must be greater than 0'
|
||||
);
|
||||
}
|
||||
|
||||
$buf = '';
|
||||
if (!class_exists('COM')) {
|
||||
throw new Error(
|
||||
'COM does not exist'
|
||||
);
|
||||
}
|
||||
$util = new COM('CAPICOM.Utilities.1');
|
||||
$execCount = 0;
|
||||
|
||||
/**
|
||||
* Let's not let it loop forever. If we run N times and fail to
|
||||
* get N bytes of random data, then CAPICOM has failed us.
|
||||
*/
|
||||
do {
|
||||
$buf .= base64_decode($util->GetRandom($bytes, 0));
|
||||
if (RandomCompat_strlen($buf) >= $bytes) {
|
||||
/**
|
||||
* Return our random entropy buffer here:
|
||||
*/
|
||||
return RandomCompat_substr($buf, 0, $bytes);
|
||||
}
|
||||
++$execCount;
|
||||
} while ($execCount < $bytes);
|
||||
|
||||
/**
|
||||
* If we reach here, PHP has failed us.
|
||||
*/
|
||||
throw new Exception(
|
||||
'Could not gather sufficient random data'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Paragon Initiative Enterprises
|
||||
* Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
@ -30,119 +30,138 @@ if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
|
|||
define('RANDOM_COMPAT_READ_BUFFER', 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unless open_basedir is enabled, use /dev/urandom for
|
||||
* random numbers in accordance with best practices
|
||||
*
|
||||
* Why we use /dev/urandom and not /dev/random
|
||||
* @ref http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers
|
||||
*
|
||||
* @param int $bytes
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function random_bytes($bytes)
|
||||
{
|
||||
static $fp = null;
|
||||
if (!is_callable('random_bytes')) {
|
||||
/**
|
||||
* This block should only be run once
|
||||
*/
|
||||
if (empty($fp)) {
|
||||
/**
|
||||
* We use /dev/urandom if it is a char device.
|
||||
* We never fall back to /dev/random
|
||||
*/
|
||||
$fp = fopen('/dev/urandom', 'rb');
|
||||
if (!empty($fp)) {
|
||||
$st = fstat($fp);
|
||||
if (($st['mode'] & 0170000) !== 020000) {
|
||||
fclose($fp);
|
||||
$fp = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($fp)) {
|
||||
/**
|
||||
* stream_set_read_buffer() does not exist in HHVM
|
||||
*
|
||||
* If we don't set the stream's read buffer to 0, PHP will
|
||||
* internally buffer 8192 bytes, which can waste entropy
|
||||
*
|
||||
* stream_set_read_buffer returns 0 on success
|
||||
*/
|
||||
if (function_exists('stream_set_read_buffer')) {
|
||||
stream_set_read_buffer($fp, RANDOM_COMPAT_READ_BUFFER);
|
||||
}
|
||||
if (function_exists('stream_set_chunk_size')) {
|
||||
stream_set_chunk_size($fp, RANDOM_COMPAT_READ_BUFFER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$bytes = RandomCompat_intval($bytes);
|
||||
} catch (TypeError $ex) {
|
||||
throw new TypeError(
|
||||
'random_bytes(): $bytes must be an integer'
|
||||
);
|
||||
}
|
||||
|
||||
if ($bytes < 1) {
|
||||
throw new Error(
|
||||
'Length must be greater than 0'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This if() block only runs if we managed to open a file handle
|
||||
* Unless open_basedir is enabled, use /dev/urandom for
|
||||
* random numbers in accordance with best practices
|
||||
*
|
||||
* It does not belong in an else {} block, because the above
|
||||
* if (empty($fp)) line is logic that should only be run once per
|
||||
* page load.
|
||||
* Why we use /dev/urandom and not /dev/random
|
||||
* @ref http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers
|
||||
*
|
||||
* @param int $bytes
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
if (!empty($fp)) {
|
||||
$remaining = $bytes;
|
||||
$buf = '';
|
||||
|
||||
function random_bytes($bytes)
|
||||
{
|
||||
static $fp = null;
|
||||
/**
|
||||
* We use fread() in a loop to protect against partial reads
|
||||
* This block should only be run once
|
||||
*/
|
||||
do {
|
||||
$read = fread($fp, $remaining);
|
||||
if ($read === false) {
|
||||
/**
|
||||
* We cannot safely read from the file. Exit the
|
||||
* do-while loop and trigger the exception condition
|
||||
*/
|
||||
$buf = false;
|
||||
break;
|
||||
}
|
||||
if (empty($fp)) {
|
||||
/**
|
||||
* Decrease the number of bytes returned from remaining
|
||||
* We use /dev/urandom if it is a char device.
|
||||
* We never fall back to /dev/random
|
||||
*/
|
||||
$remaining -= RandomCompat_strlen($read);
|
||||
$buf .= $read;
|
||||
} while ($remaining > 0);
|
||||
$fp = fopen('/dev/urandom', 'rb');
|
||||
if (!empty($fp)) {
|
||||
$st = fstat($fp);
|
||||
if (($st['mode'] & 0170000) !== 020000) {
|
||||
fclose($fp);
|
||||
$fp = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is our result valid?
|
||||
*/
|
||||
if ($buf !== false) {
|
||||
if (RandomCompat_strlen($buf) === $bytes) {
|
||||
if (!empty($fp)) {
|
||||
/**
|
||||
* Return our random entropy buffer here:
|
||||
* stream_set_read_buffer() does not exist in HHVM
|
||||
*
|
||||
* If we don't set the stream's read buffer to 0, PHP will
|
||||
* internally buffer 8192 bytes, which can waste entropy
|
||||
*
|
||||
* stream_set_read_buffer returns 0 on success
|
||||
*/
|
||||
return $buf;
|
||||
if (is_callable('stream_set_read_buffer')) {
|
||||
stream_set_read_buffer($fp, RANDOM_COMPAT_READ_BUFFER);
|
||||
}
|
||||
if (is_callable('stream_set_chunk_size')) {
|
||||
stream_set_chunk_size($fp, RANDOM_COMPAT_READ_BUFFER);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If we reach here, PHP has failed us.
|
||||
*/
|
||||
throw new Exception(
|
||||
'Error reading from source device'
|
||||
);
|
||||
try {
|
||||
$bytes = RandomCompat_intval($bytes);
|
||||
} catch (TypeError $ex) {
|
||||
throw new TypeError(
|
||||
'random_bytes(): $bytes must be an integer'
|
||||
);
|
||||
}
|
||||
|
||||
if ($bytes < 1) {
|
||||
throw new Error(
|
||||
'Length must be greater than 0'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This if() block only runs if we managed to open a file handle
|
||||
*
|
||||
* It does not belong in an else {} block, because the above
|
||||
* if (empty($fp)) line is logic that should only be run once per
|
||||
* page load.
|
||||
*/
|
||||
if (!empty($fp)) {
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
$remaining = $bytes;
|
||||
|
||||
/**
|
||||
* @var string|bool
|
||||
*/
|
||||
$buf = '';
|
||||
|
||||
/**
|
||||
* We use fread() in a loop to protect against partial reads
|
||||
*/
|
||||
do {
|
||||
/**
|
||||
* @var string|bool
|
||||
*/
|
||||
$read = fread($fp, $remaining);
|
||||
if (!is_string($read)) {
|
||||
if ($read === false) {
|
||||
/**
|
||||
* We cannot safely read from the file. Exit the
|
||||
* do-while loop and trigger the exception condition
|
||||
*
|
||||
* @var string|bool
|
||||
*/
|
||||
$buf = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Decrease the number of bytes returned from remaining
|
||||
*/
|
||||
$remaining -= RandomCompat_strlen($read);
|
||||
/**
|
||||
* @var string|bool
|
||||
*/
|
||||
$buf = $buf . $read;
|
||||
} while ($remaining > 0);
|
||||
|
||||
/**
|
||||
* Is our result valid?
|
||||
*/
|
||||
if (is_string($buf)) {
|
||||
if (RandomCompat_strlen($buf) === $bytes) {
|
||||
/**
|
||||
* Return our random entropy buffer here:
|
||||
*/
|
||||
return $buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If we reach here, PHP has failed us.
|
||||
*/
|
||||
throw new Exception(
|
||||
'Error reading from source device'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Paragon Initiative Enterprises
|
||||
* Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
@ -26,61 +26,63 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* If the libsodium PHP extension is loaded, we'll use it above any other
|
||||
* solution.
|
||||
*
|
||||
* libsodium-php project:
|
||||
* @ref https://github.com/jedisct1/libsodium-php
|
||||
*
|
||||
* @param int $bytes
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function random_bytes($bytes)
|
||||
{
|
||||
try {
|
||||
$bytes = RandomCompat_intval($bytes);
|
||||
} catch (TypeError $ex) {
|
||||
throw new TypeError(
|
||||
'random_bytes(): $bytes must be an integer'
|
||||
if (!is_callable('random_bytes')) {
|
||||
/**
|
||||
* If the libsodium PHP extension is loaded, we'll use it above any other
|
||||
* solution.
|
||||
*
|
||||
* libsodium-php project:
|
||||
* @ref https://github.com/jedisct1/libsodium-php
|
||||
*
|
||||
* @param int $bytes
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function random_bytes($bytes)
|
||||
{
|
||||
try {
|
||||
$bytes = RandomCompat_intval($bytes);
|
||||
} catch (TypeError $ex) {
|
||||
throw new TypeError(
|
||||
'random_bytes(): $bytes must be an integer'
|
||||
);
|
||||
}
|
||||
|
||||
if ($bytes < 1) {
|
||||
throw new Error(
|
||||
'Length must be greater than 0'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* \Sodium\randombytes_buf() doesn't allow more than 2147483647 bytes to be
|
||||
* generated in one invocation.
|
||||
*/
|
||||
if ($bytes > 2147483647) {
|
||||
$buf = '';
|
||||
for ($i = 0; $i < $bytes; $i += 1073741824) {
|
||||
$n = ($bytes - $i) > 1073741824
|
||||
? 1073741824
|
||||
: $bytes - $i;
|
||||
$buf .= \Sodium\randombytes_buf($n);
|
||||
}
|
||||
} else {
|
||||
$buf = \Sodium\randombytes_buf($bytes);
|
||||
}
|
||||
|
||||
if ($buf !== false) {
|
||||
if (RandomCompat_strlen($buf) === $bytes) {
|
||||
return $buf;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If we reach here, PHP has failed us.
|
||||
*/
|
||||
throw new Exception(
|
||||
'Could not gather sufficient random data'
|
||||
);
|
||||
}
|
||||
|
||||
if ($bytes < 1) {
|
||||
throw new Error(
|
||||
'Length must be greater than 0'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* \Sodium\randombytes_buf() doesn't allow more than 2147483647 bytes to be
|
||||
* generated in one invocation.
|
||||
*/
|
||||
if ($bytes > 2147483647) {
|
||||
$buf = '';
|
||||
for ($i = 0; $i < $bytes; $i += 1073741824) {
|
||||
$n = ($bytes - $i) > 1073741824
|
||||
? 1073741824
|
||||
: $bytes - $i;
|
||||
$buf .= \Sodium\randombytes_buf($n);
|
||||
}
|
||||
} else {
|
||||
$buf = \Sodium\randombytes_buf($bytes);
|
||||
}
|
||||
|
||||
if ($buf !== false) {
|
||||
if (RandomCompat_strlen($buf) === $bytes) {
|
||||
return $buf;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If we reach here, PHP has failed us.
|
||||
*/
|
||||
throw new Exception(
|
||||
'Could not gather sufficient random data'
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Paragon Initiative Enterprises
|
||||
* Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
@ -26,61 +26,67 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* If the libsodium PHP extension is loaded, we'll use it above any other
|
||||
* solution.
|
||||
*
|
||||
* libsodium-php project:
|
||||
* @ref https://github.com/jedisct1/libsodium-php
|
||||
*
|
||||
* @param int $bytes
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function random_bytes($bytes)
|
||||
{
|
||||
try {
|
||||
$bytes = RandomCompat_intval($bytes);
|
||||
} catch (TypeError $ex) {
|
||||
throw new TypeError(
|
||||
'random_bytes(): $bytes must be an integer'
|
||||
);
|
||||
}
|
||||
|
||||
if ($bytes < 1) {
|
||||
throw new Error(
|
||||
'Length must be greater than 0'
|
||||
);
|
||||
}
|
||||
|
||||
if (!is_callable('random_bytes')) {
|
||||
/**
|
||||
* \Sodium\randombytes_buf() doesn't allow more than 2147483647 bytes to be
|
||||
* generated in one invocation.
|
||||
* If the libsodium PHP extension is loaded, we'll use it above any other
|
||||
* solution.
|
||||
*
|
||||
* libsodium-php project:
|
||||
* @ref https://github.com/jedisct1/libsodium-php
|
||||
*
|
||||
* @param int $bytes
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
if ($bytes > 2147483647) {
|
||||
function random_bytes($bytes)
|
||||
{
|
||||
try {
|
||||
$bytes = RandomCompat_intval($bytes);
|
||||
} catch (TypeError $ex) {
|
||||
throw new TypeError(
|
||||
'random_bytes(): $bytes must be an integer'
|
||||
);
|
||||
}
|
||||
|
||||
if ($bytes < 1) {
|
||||
throw new Error(
|
||||
'Length must be greater than 0'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
$buf = '';
|
||||
for ($i = 0; $i < $bytes; $i += 1073741824) {
|
||||
$n = ($bytes - $i) > 1073741824
|
||||
? 1073741824
|
||||
: $bytes - $i;
|
||||
$buf .= Sodium::randombytes_buf($n);
|
||||
}
|
||||
} else {
|
||||
$buf = Sodium::randombytes_buf($bytes);
|
||||
}
|
||||
|
||||
if ($buf !== false) {
|
||||
if (RandomCompat_strlen($buf) === $bytes) {
|
||||
return $buf;
|
||||
/**
|
||||
* \Sodium\randombytes_buf() doesn't allow more than 2147483647 bytes to be
|
||||
* generated in one invocation.
|
||||
*/
|
||||
if ($bytes > 2147483647) {
|
||||
for ($i = 0; $i < $bytes; $i += 1073741824) {
|
||||
$n = ($bytes - $i) > 1073741824
|
||||
? 1073741824
|
||||
: $bytes - $i;
|
||||
$buf .= Sodium::randombytes_buf((int) $n);
|
||||
}
|
||||
} else {
|
||||
$buf .= Sodium::randombytes_buf((int) $bytes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If we reach here, PHP has failed us.
|
||||
*/
|
||||
throw new Exception(
|
||||
'Could not gather sufficient random data'
|
||||
);
|
||||
if (is_string($buf)) {
|
||||
if (RandomCompat_strlen($buf) === $bytes) {
|
||||
return $buf;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If we reach here, PHP has failed us.
|
||||
*/
|
||||
throw new Exception(
|
||||
'Could not gather sufficient random data'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Paragon Initiative Enterprises
|
||||
* Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
@ -26,51 +26,52 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Powered by ext/mcrypt (and thankfully NOT libmcrypt)
|
||||
*
|
||||
* @ref https://bugs.php.net/bug.php?id=55169
|
||||
* @ref https://github.com/php/php-src/blob/c568ffe5171d942161fc8dda066bce844bdef676/ext/mcrypt/mcrypt.c#L1321-L1386
|
||||
*
|
||||
* @param int $bytes
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function random_bytes($bytes)
|
||||
{
|
||||
try {
|
||||
$bytes = RandomCompat_intval($bytes);
|
||||
} catch (TypeError $ex) {
|
||||
throw new TypeError(
|
||||
'random_bytes(): $bytes must be an integer'
|
||||
);
|
||||
}
|
||||
|
||||
if ($bytes < 1) {
|
||||
throw new Error(
|
||||
'Length must be greater than 0'
|
||||
);
|
||||
}
|
||||
|
||||
$buf = @mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM);
|
||||
if (
|
||||
$buf !== false
|
||||
&&
|
||||
RandomCompat_strlen($buf) === $bytes
|
||||
) {
|
||||
/**
|
||||
* Return our random entropy buffer here:
|
||||
*/
|
||||
return $buf;
|
||||
}
|
||||
|
||||
if (!is_callable('random_bytes')) {
|
||||
/**
|
||||
* If we reach here, PHP has failed us.
|
||||
* Powered by ext/mcrypt (and thankfully NOT libmcrypt)
|
||||
*
|
||||
* @ref https://bugs.php.net/bug.php?id=55169
|
||||
* @ref https://github.com/php/php-src/blob/c568ffe5171d942161fc8dda066bce844bdef676/ext/mcrypt/mcrypt.c#L1321-L1386
|
||||
*
|
||||
* @param int $bytes
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
throw new Exception(
|
||||
'Could not gather sufficient random data'
|
||||
);
|
||||
function random_bytes($bytes)
|
||||
{
|
||||
try {
|
||||
$bytes = RandomCompat_intval($bytes);
|
||||
} catch (TypeError $ex) {
|
||||
throw new TypeError(
|
||||
'random_bytes(): $bytes must be an integer'
|
||||
);
|
||||
}
|
||||
|
||||
if ($bytes < 1) {
|
||||
throw new Error(
|
||||
'Length must be greater than 0'
|
||||
);
|
||||
}
|
||||
|
||||
$buf = @mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM);
|
||||
if (
|
||||
$buf !== false
|
||||
&&
|
||||
RandomCompat_strlen($buf) === $bytes
|
||||
) {
|
||||
/**
|
||||
* Return our random entropy buffer here:
|
||||
*/
|
||||
return $buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* If we reach here, PHP has failed us.
|
||||
*/
|
||||
throw new Exception(
|
||||
'Could not gather sufficient random data'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,191 +1,190 @@
|
|||
<?php
|
||||
/**
|
||||
* Random_* Compatibility Library
|
||||
* for using the new PHP 7 random_* API in PHP 5 projects
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Paragon Initiative Enterprises
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fetch a random integer between $min and $max inclusive
|
||||
*
|
||||
* @param int $min
|
||||
* @param int $max
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
function random_int($min, $max)
|
||||
{
|
||||
if (!is_callable('random_int')) {
|
||||
/**
|
||||
* Type and input logic checks
|
||||
* Random_* Compatibility Library
|
||||
* for using the new PHP 7 random_* API in PHP 5 projects
|
||||
*
|
||||
* If you pass it a float in the range (~PHP_INT_MAX, PHP_INT_MAX)
|
||||
* (non-inclusive), it will sanely cast it to an int. If you it's equal to
|
||||
* ~PHP_INT_MAX or PHP_INT_MAX, we let it fail as not an integer. Floats
|
||||
* lose precision, so the <= and => operators might accidentally let a float
|
||||
* through.
|
||||
*/
|
||||
|
||||
try {
|
||||
$min = RandomCompat_intval($min);
|
||||
} catch (TypeError $ex) {
|
||||
throw new TypeError(
|
||||
'random_int(): $min must be an integer'
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
$max = RandomCompat_intval($max);
|
||||
} catch (TypeError $ex) {
|
||||
throw new TypeError(
|
||||
'random_int(): $max must be an integer'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Now that we've verified our weak typing system has given us an integer,
|
||||
* let's validate the logic then we can move forward with generating random
|
||||
* integers along a given range.
|
||||
*/
|
||||
if ($min > $max) {
|
||||
throw new Error(
|
||||
'Minimum value must be less than or equal to the maximum value'
|
||||
);
|
||||
}
|
||||
|
||||
if ($max === $min) {
|
||||
return $min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize variables to 0
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* We want to store:
|
||||
* $bytes => the number of random bytes we need
|
||||
* $mask => an integer bitmask (for use with the &) operator
|
||||
* so we can minimize the number of discards
|
||||
* Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
$attempts = $bits = $bytes = $mask = $valueShift = 0;
|
||||
|
||||
/**
|
||||
* At this point, $range is a positive number greater than 0. It might
|
||||
* overflow, however, if $max - $min > PHP_INT_MAX. PHP will cast it to
|
||||
* a float and we will lose some precision.
|
||||
* Fetch a random integer between $min and $max inclusive
|
||||
*
|
||||
* @param int $min
|
||||
* @param int $max
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
$range = $max - $min;
|
||||
function random_int($min, $max)
|
||||
{
|
||||
/**
|
||||
* Type and input logic checks
|
||||
*
|
||||
* If you pass it a float in the range (~PHP_INT_MAX, PHP_INT_MAX)
|
||||
* (non-inclusive), it will sanely cast it to an int. If you it's equal to
|
||||
* ~PHP_INT_MAX or PHP_INT_MAX, we let it fail as not an integer. Floats
|
||||
* lose precision, so the <= and => operators might accidentally let a float
|
||||
* through.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test for integer overflow:
|
||||
*/
|
||||
if (!is_int($range)) {
|
||||
try {
|
||||
$min = RandomCompat_intval($min);
|
||||
} catch (TypeError $ex) {
|
||||
throw new TypeError(
|
||||
'random_int(): $min must be an integer'
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
$max = RandomCompat_intval($max);
|
||||
} catch (TypeError $ex) {
|
||||
throw new TypeError(
|
||||
'random_int(): $max must be an integer'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Still safely calculate wider ranges.
|
||||
* Provided by @CodesInChaos, @oittaa
|
||||
*
|
||||
* @ref https://gist.github.com/CodesInChaos/03f9ea0b58e8b2b8d435
|
||||
*
|
||||
* We use ~0 as a mask in this case because it generates all 1s
|
||||
*
|
||||
* @ref https://eval.in/400356 (32-bit)
|
||||
* @ref http://3v4l.org/XX9r5 (64-bit)
|
||||
* Now that we've verified our weak typing system has given us an integer,
|
||||
* let's validate the logic then we can move forward with generating random
|
||||
* integers along a given range.
|
||||
*/
|
||||
$bytes = PHP_INT_SIZE;
|
||||
$mask = ~0;
|
||||
if ($min > $max) {
|
||||
throw new Error(
|
||||
'Minimum value must be less than or equal to the maximum value'
|
||||
);
|
||||
}
|
||||
|
||||
} else {
|
||||
if ($max === $min) {
|
||||
return (int) $min;
|
||||
}
|
||||
|
||||
/**
|
||||
* $bits is effectively ceil(log($range, 2)) without dealing with
|
||||
* type juggling
|
||||
* Initialize variables to 0
|
||||
*
|
||||
* We want to store:
|
||||
* $bytes => the number of random bytes we need
|
||||
* $mask => an integer bitmask (for use with the &) operator
|
||||
* so we can minimize the number of discards
|
||||
*/
|
||||
while ($range > 0) {
|
||||
if ($bits % 8 === 0) {
|
||||
++$bytes;
|
||||
$attempts = $bits = $bytes = $mask = $valueShift = 0;
|
||||
|
||||
/**
|
||||
* At this point, $range is a positive number greater than 0. It might
|
||||
* overflow, however, if $max - $min > PHP_INT_MAX. PHP will cast it to
|
||||
* a float and we will lose some precision.
|
||||
*/
|
||||
$range = $max - $min;
|
||||
|
||||
/**
|
||||
* Test for integer overflow:
|
||||
*/
|
||||
if (!is_int($range)) {
|
||||
|
||||
/**
|
||||
* Still safely calculate wider ranges.
|
||||
* Provided by @CodesInChaos, @oittaa
|
||||
*
|
||||
* @ref https://gist.github.com/CodesInChaos/03f9ea0b58e8b2b8d435
|
||||
*
|
||||
* We use ~0 as a mask in this case because it generates all 1s
|
||||
*
|
||||
* @ref https://eval.in/400356 (32-bit)
|
||||
* @ref http://3v4l.org/XX9r5 (64-bit)
|
||||
*/
|
||||
$bytes = PHP_INT_SIZE;
|
||||
$mask = ~0;
|
||||
|
||||
} else {
|
||||
|
||||
/**
|
||||
* $bits is effectively ceil(log($range, 2)) without dealing with
|
||||
* type juggling
|
||||
*/
|
||||
while ($range > 0) {
|
||||
if ($bits % 8 === 0) {
|
||||
++$bytes;
|
||||
}
|
||||
++$bits;
|
||||
$range >>= 1;
|
||||
$mask = $mask << 1 | 1;
|
||||
}
|
||||
++$bits;
|
||||
$range >>= 1;
|
||||
$mask = $mask << 1 | 1;
|
||||
}
|
||||
$valueShift = $min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Now that we have our parameters set up, let's begin generating
|
||||
* random integers until one falls between $min and $max
|
||||
*/
|
||||
do {
|
||||
/**
|
||||
* The rejection probability is at most 0.5, so this corresponds
|
||||
* to a failure probability of 2^-128 for a working RNG
|
||||
*/
|
||||
if ($attempts > 128) {
|
||||
throw new Exception(
|
||||
'random_int: RNG is broken - too many rejections'
|
||||
);
|
||||
$valueShift = $min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Let's grab the necessary number of random bytes
|
||||
*/
|
||||
$randomByteString = random_bytes($bytes);
|
||||
if ($randomByteString === false) {
|
||||
throw new Exception(
|
||||
'Random number generator failure'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Let's turn $randomByteString into an integer
|
||||
*
|
||||
* This uses bitwise operators (<< and |) to build an integer
|
||||
* out of the values extracted from ord()
|
||||
*
|
||||
* Example: [9F] | [6D] | [32] | [0C] =>
|
||||
* 159 + 27904 + 3276800 + 201326592 =>
|
||||
* 204631455
|
||||
*/
|
||||
$val = 0;
|
||||
for ($i = 0; $i < $bytes; ++$i) {
|
||||
$val |= ord($randomByteString[$i]) << ($i * 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply mask
|
||||
* Now that we have our parameters set up, let's begin generating
|
||||
* random integers until one falls between $min and $max
|
||||
*/
|
||||
$val &= $mask;
|
||||
$val += $valueShift;
|
||||
do {
|
||||
/**
|
||||
* The rejection probability is at most 0.5, so this corresponds
|
||||
* to a failure probability of 2^-128 for a working RNG
|
||||
*/
|
||||
if ($attempts > 128) {
|
||||
throw new Exception(
|
||||
'random_int: RNG is broken - too many rejections'
|
||||
);
|
||||
}
|
||||
|
||||
++$attempts;
|
||||
/**
|
||||
* If $val overflows to a floating point number,
|
||||
* ... or is larger than $max,
|
||||
* ... or smaller than $min,
|
||||
* then try again.
|
||||
*/
|
||||
} while (!is_int($val) || $val > $max || $val < $min);
|
||||
/**
|
||||
* Let's grab the necessary number of random bytes
|
||||
*/
|
||||
$randomByteString = random_bytes($bytes);
|
||||
|
||||
return (int) $val;
|
||||
/**
|
||||
* Let's turn $randomByteString into an integer
|
||||
*
|
||||
* This uses bitwise operators (<< and |) to build an integer
|
||||
* out of the values extracted from ord()
|
||||
*
|
||||
* Example: [9F] | [6D] | [32] | [0C] =>
|
||||
* 159 + 27904 + 3276800 + 201326592 =>
|
||||
* 204631455
|
||||
*/
|
||||
$val &= 0;
|
||||
for ($i = 0; $i < $bytes; ++$i) {
|
||||
$val |= ord($randomByteString[$i]) << ($i * 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply mask
|
||||
*/
|
||||
$val &= $mask;
|
||||
$val += $valueShift;
|
||||
|
||||
++$attempts;
|
||||
/**
|
||||
* If $val overflows to a floating point number,
|
||||
* ... or is larger than $max,
|
||||
* ... or smaller than $min,
|
||||
* then try again.
|
||||
*/
|
||||
} while (!is_int($val) || $val > $max || $val < $min);
|
||||
|
||||
return (int) $val;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
require_once 'lib/byte_safe_strings.php';
|
||||
require_once 'lib/cast_to_int.php';
|
||||
require_once 'lib/error_polyfill.php';
|
||||
require_once 'other/ide_stubs/libsodium.php';
|
||||
require_once 'lib/random.php';
|
||||
|
||||
$int = random_int(0, 65536);
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0"?>
|
||||
<psalm
|
||||
autoloader="psalm-autoload.php"
|
||||
stopOnFirstError="false"
|
||||
useDocblockTypes="true"
|
||||
>
|
||||
<projectFiles>
|
||||
<directory name="lib" />
|
||||
</projectFiles>
|
||||
<issueHandlers>
|
||||
<DuplicateClass errorLevel="info" />
|
||||
<InvalidOperand errorLevel="info" />
|
||||
<UndefinedConstant errorLevel="info" />
|
||||
<MissingReturnType errorLevel="info" />
|
||||
</issueHandlers>
|
||||
</psalm>
|
||||
|
|
@ -12,21 +12,29 @@ php:
|
|||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- hhvm
|
||||
- 7.0
|
||||
- 7.1
|
||||
|
||||
before_script:
|
||||
- composer self-update
|
||||
- COMPOSER_ROOT_VERSION=dev-master composer dump-autoload
|
||||
- COMPOSER_ROOT_VERSION=dev-master composer install
|
||||
- if [ "$PIMPLE_EXT" == "yes" ]; then sh -c "cd ext/pimple && phpize && ./configure && make && sudo make install"; fi
|
||||
- if [ "$PIMPLE_EXT" == "yes" ]; then echo "extension=pimple.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`; fi
|
||||
|
||||
script:
|
||||
- cd ext/pimple
|
||||
- if [ "$PIMPLE_EXT" == "yes" ]; then yes n | make test | tee output ; grep -E 'Tests failed +. +0' output; fi
|
||||
- if [ "$PIMPLE_EXT" == "yes" ]; then export SYMFONY_DEPRECATIONS_HELPER=weak; fi
|
||||
- cd ../..
|
||||
- phpunit
|
||||
- ./vendor/bin/simple-phpunit
|
||||
|
||||
matrix:
|
||||
exclude:
|
||||
include:
|
||||
- php: hhvm
|
||||
dist: trusty
|
||||
env: PIMPLE_EXT=no
|
||||
exclude:
|
||||
- php: 7.0
|
||||
env: PIMPLE_EXT=yes
|
||||
- php: 7.1
|
||||
env: PIMPLE_EXT=yes
|
||||
|
|
|
|||
|
|
@ -1,3 +1,23 @@
|
|||
* 3.2.2 (2017-07-23)
|
||||
|
||||
* reverted extending a protected closure throws an exception (deprecated it instead)
|
||||
|
||||
* 3.2.1 (2017-07-17)
|
||||
|
||||
* fixed PHP error
|
||||
|
||||
* 3.2.0 (2017-07-17)
|
||||
|
||||
* added a PSR-11 service locator
|
||||
* added a PSR-11 wrapper
|
||||
* added ServiceIterator
|
||||
* fixed extending a protected closure (now throws InvalidServiceIdentifierException)
|
||||
|
||||
* 3.1.0 (2017-07-03)
|
||||
|
||||
* deprecated the C extension
|
||||
* added support for PSR-11 exceptions
|
||||
|
||||
* 3.0.2 (2015-09-11)
|
||||
|
||||
* refactored the C extension
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2009-2015 Fabien Potencier
|
||||
Copyright (c) 2009-2017 Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
|||
|
|
@ -17,18 +17,7 @@ Before using Pimple in your project, add it to your ``composer.json`` file:
|
|||
|
||||
.. code-block:: bash
|
||||
|
||||
$ ./composer.phar require pimple/pimple ~3.0
|
||||
|
||||
Alternatively, Pimple is also available as a PHP C extension:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ git clone https://github.com/silexphp/Pimple
|
||||
$ cd Pimple/ext/pimple
|
||||
$ phpize
|
||||
$ ./configure
|
||||
$ make
|
||||
$ make install
|
||||
$ ./composer.phar require pimple/pimple "^3.0"
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
|
@ -198,4 +187,140 @@ raw access to this function, you can use the ``raw()`` method:
|
|||
|
||||
$sessionFunction = $container->raw('session');
|
||||
|
||||
PSR-11 compatibility
|
||||
--------------------
|
||||
|
||||
For historical reasons, the ``Container`` class does not implement the PSR-11
|
||||
``ContainerInterface``. However, Pimple provides a helper class that will let
|
||||
you decouple your code from the Pimple container class.
|
||||
|
||||
The PSR-11 container class
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``Pimple\Psr11\Container`` class lets you access the content of an
|
||||
underlying Pimple container using ``Psr\Container\ContainerInterface``
|
||||
methods:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
use Pimple\Container;
|
||||
use Pimple\Psr11\Container as PsrContainer;
|
||||
|
||||
$container = new Container();
|
||||
$container['service'] = function ($c) {
|
||||
return new Service();
|
||||
};
|
||||
$psr11 = new PsrContainer($container);
|
||||
|
||||
$controller = function (PsrContainer $container) {
|
||||
$service = $container->get('service');
|
||||
};
|
||||
$controller($psr11);
|
||||
|
||||
Using the PSR-11 ServiceLocator
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Sometimes, a service needs access to several other services without being sure
|
||||
that all of them will actually be used. In those cases, you may want the
|
||||
instantiation of the services to be lazy.
|
||||
|
||||
The traditional solution is to inject the entire service container to get only
|
||||
the services really needed. However, this is not recommended because it gives
|
||||
services a too broad access to the rest of the application and it hides their
|
||||
actual dependencies.
|
||||
|
||||
The ``ServiceLocator`` is intended to solve this problem by giving access to a
|
||||
set of predefined services while instantiating them only when actually needed.
|
||||
|
||||
It also allows you to make your services available under a different name than
|
||||
the one used to register them. For instance, you may want to use an object
|
||||
that expects an instance of ``EventDispatcherInterface`` to be available under
|
||||
the name ``event_dispatcher`` while your event dispatcher has been
|
||||
registered under the name ``dispatcher``:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
use Monolog\Logger;
|
||||
use Pimple\Psr11\ServiceLocator;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
|
||||
class MyService
|
||||
{
|
||||
/**
|
||||
* "logger" must be an instance of Psr\Log\LoggerInterface
|
||||
* "event_dispatcher" must be an instance of Symfony\Component\EventDispatcher\EventDispatcherInterface
|
||||
*/
|
||||
private $services;
|
||||
|
||||
public function __construct(ContainerInterface $services)
|
||||
{
|
||||
$this->services = $services;
|
||||
}
|
||||
}
|
||||
|
||||
$container['logger'] = function ($c) {
|
||||
return new Monolog\Logger();
|
||||
};
|
||||
$container['dispatcher'] = function () {
|
||||
return new EventDispatcher();
|
||||
};
|
||||
|
||||
$container['service'] = function ($c) {
|
||||
$locator = new ServiceLocator($c, array('logger', 'event_dispatcher' => 'dispatcher'));
|
||||
|
||||
return new MyService($locator);
|
||||
};
|
||||
|
||||
Referencing a Collection of Services Lazily
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Passing a collection of services instances in an array may prove inefficient
|
||||
if the class that consumes the collection only needs to iterate over it at a
|
||||
later stage, when one of its method is called. It can also lead to problems
|
||||
if there is a circular dependency between one of the services stored in the
|
||||
collection and the class that consumes it.
|
||||
|
||||
The ``ServiceIterator`` class helps you solve these issues. It receives a
|
||||
list of service names during instantiation and will retrieve the services
|
||||
when iterated over:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
use Pimple\Container;
|
||||
use Pimple\ServiceIterator;
|
||||
|
||||
class AuthorizationService
|
||||
{
|
||||
private $voters;
|
||||
|
||||
public function __construct($voters)
|
||||
{
|
||||
$this->voters = $voters;
|
||||
}
|
||||
|
||||
public function canAccess($resource)
|
||||
{
|
||||
foreach ($this->voters as $voter) {
|
||||
if (true === $voter->canAccess($resource) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$container = new Container();
|
||||
|
||||
$container['voter1'] = function ($c) {
|
||||
return new SomeVoter();
|
||||
}
|
||||
$container['voter2'] = function ($c) {
|
||||
return new SomeOtherVoter($c['auth']);
|
||||
}
|
||||
$container['auth'] = function ($c) {
|
||||
return new AuthorizationService(new ServiceIterator($c, array('voter1', 'voter2'));
|
||||
}
|
||||
|
||||
.. _Pimple 1.x documentation: https://github.com/silexphp/Pimple/tree/1.1
|
||||
|
|
|
|||
|
|
@ -12,14 +12,18 @@
|
|||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
"php": ">=5.3.0",
|
||||
"psr/container": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "^3.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": { "Pimple": "src/" }
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.0.x-dev"
|
||||
"dev-master": "3.2.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,17 +41,31 @@ extern zend_module_entry pimple_module_entry;
|
|||
#include "TSRM.h"
|
||||
#endif
|
||||
|
||||
#define PIMPLE_VERSION "3.0.2"
|
||||
#define PIMPLE_VERSION "3.2.2-DEV"
|
||||
|
||||
#define PIMPLE_NS "Pimple"
|
||||
#define PSR_CONTAINER_NS "Psr\\Container"
|
||||
#define PIMPLE_EXCEPTION_NS "Pimple\\Exception"
|
||||
|
||||
#define PIMPLE_DEFAULT_ZVAL_CACHE_NUM 5
|
||||
#define PIMPLE_DEFAULT_ZVAL_VALUES_NUM 10
|
||||
|
||||
#define PIMPLE_DEPRECATE do { \
|
||||
int er = EG(error_reporting); \
|
||||
EG(error_reporting) = 0;\
|
||||
php_error(E_DEPRECATED, "The Pimple C extension is deprecated since version 3.1 and will be removed in 4.0."); \
|
||||
EG(error_reporting) = er; \
|
||||
} while (0);
|
||||
|
||||
zend_module_entry *get_module(void);
|
||||
|
||||
PHP_MINIT_FUNCTION(pimple);
|
||||
PHP_MINFO_FUNCTION(pimple);
|
||||
|
||||
PHP_METHOD(FrozenServiceException, __construct);
|
||||
PHP_METHOD(InvalidServiceIdentifierException, __construct);
|
||||
PHP_METHOD(UnknownIdentifierException, __construct);
|
||||
|
||||
PHP_METHOD(Pimple, __construct);
|
||||
PHP_METHOD(Pimple, factory);
|
||||
PHP_METHOD(Pimple, protect);
|
||||
|
|
@ -93,6 +107,8 @@ typedef struct _pimple_closure_object {
|
|||
|
||||
static const char sensiolabs_logo[] = "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHYAAAAUCAMAAABvRTlyAAAAz1BMVEUAAAAAAAAAAAAsThWB5j4AAACD6T8AAACC6D+C6D6C6D+C6D4AAAAAAACC6D4AAAAAAACC6D8AAAAAAAAAAAAAAAAAAAAAAACC6D4AAAAAAAAAAACC6D4AAAAAAAAAAAAAAAAAAAAAAACC6D8AAACC6D4AAAAAAAAAAAAAAAAAAACC6D8AAACC6D6C6D+B6D+C6D+C6D+C6D8AAACC6D6C6D4AAACC6D/K/2KC6D+B6D6C6D6C6D+C6D8sTxUyWRhEeiEAAACC6D+C5z6B6D7drnEVAAAAQXRSTlMAE3oCNSUuDHFHzxaF9UFsu+irX+zlKzYimaJXktyOSFD6BolxqT7QGMMdarMIpuO28r9EolXKgR16OphfXYd4V14GtB4AAAMpSURBVEjHvVSJctowEF1jjME2RziMwUCoMfd9heZqG4n//6buLpJjkmYm03byZmxJa2nf6u2uQcG2bfhqRN4LoTKBzyGDm68M7mAwcOEdjo4zhA/Rf9Go/CVtTgiRhXfIC3EDH8F/eUX1/9KexRo+QgOdtHDsEe/sM7QT32/+K61Z1LFXcXJxN4pTbu1aTQUzuy2PIA0rDo0/0Aa5XFaJvKaVTrubywXvaa1Wq4Vu/Snr3Y7Aojh4VccwykW2N2oQ8wmjyut6+Q1t5ywIG5Npj1sh5E0B7YOzFDjfuRfaOh3O+MbbVNfTWS9COZk3Obd2su5d0a6IU9KLREbw8gEehWSr1r2sPWciXLG38r5NdW0xu9eioU87omjC9yNaMi5GNf6WppVSOqXCFkmCvMB3p9SROLoYQn5pDgQOujA1xjYvqH+plUdkwnmII8VxR/PKYkrfLLomhVlE3b/LhNbNr7hp0H2JaOc4v8dFB58HSsFTSafaqtY1sT3GO8wsy5rhokYPlRJdjPMajyYqTt1EHF/2uqSWQWmAjCUSmQ1MS3g8Btf1XOsy7YIC0CB1b5Xw1Vhba0zbxiCAQLH9TNPmHJXQUtJAN0KcDsoqLxsNvJrJExa7mKIdp2lRE2WexiS4pqWk/0jROlw6K6bV9YOBDGAuqMJ0bnuUKGB0L27bxgRhGEbzihbhxxXaQC88Vkwq8ldCi86RApWUb0Q+4VDosBCc+1s81lUdnBavH4Zp2mm3O44USwOfvSo9oBiwpFg71lMS1VKJLKljS3j9p+fOTvXXlsSNuEv6YPaZda9uRope0VJfKdo7fPiYfSmvFjXQbkhY0d9hCbBWIktRgEDieDhf1N3wbbkmNNgRy8hyl620yGQat/grV3HMpc2HDKTVmOPFz6ylPCKt/nXcAyV260jaAowwIW0YuBzrOgb/KrddZS9OmJaLgpWK4JX2DDuklcLZSDGcn8Vmx9YDNvT6UsjyBApRyFQVX7Vxm9TGxE16nmfRd8/zQoDmggQOTRh5Hv8pMt9Q/L2JmSwkMCE7dA4BuDjHJwfu0Om4QAhOjrN5XkIatglfiN/bUPdCQFjTYgAAAABJRU5ErkJggg==\">";
|
||||
|
||||
static void pimple_exception_call_parent_constructor(zval *this_ptr, const char *format, const char *arg1 TSRMLS_DC);
|
||||
|
||||
static int pimple_zval_to_pimpleval(zval *_zval, pimple_bucket_value *_pimple_bucket_value TSRMLS_DC);
|
||||
static int pimple_zval_is_valid_callback(zval *_zval, pimple_bucket_value *_pimple_bucket_value TSRMLS_DC);
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,15 @@
|
|||
#include "main/php_output.h"
|
||||
#include "SAPI.h"
|
||||
|
||||
static zend_class_entry *pimple_ce_PsrContainerInterface;
|
||||
static zend_class_entry *pimple_ce_PsrContainerExceptionInterface;
|
||||
static zend_class_entry *pimple_ce_PsrNotFoundExceptionInterface;
|
||||
|
||||
static zend_class_entry *pimple_ce_ExpectedInvokableException;
|
||||
static zend_class_entry *pimple_ce_FrozenServiceException;
|
||||
static zend_class_entry *pimple_ce_InvalidServiceIdentifierException;
|
||||
static zend_class_entry *pimple_ce_UnknownIdentifierException;
|
||||
|
||||
static zend_class_entry *pimple_ce;
|
||||
static zend_object_handlers pimple_object_handlers;
|
||||
static zend_class_entry *pimple_closure_ce;
|
||||
|
|
@ -92,6 +101,63 @@ static zend_internal_function pimple_closure_invoker_function;
|
|||
} \
|
||||
} while(0);
|
||||
|
||||
|
||||
/* Psr\Container\ContainerInterface */
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_pimple_PsrContainerInterface_get, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, id)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_pimple_PsrContainerInterface_has, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, id)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
static const zend_function_entry pimple_ce_PsrContainerInterface_functions[] = {
|
||||
PHP_ABSTRACT_ME(ContainerInterface, get, arginfo_pimple_PsrContainerInterface_get)
|
||||
PHP_ABSTRACT_ME(ContainerInterface, has, arginfo_pimple_PsrContainerInterface_has)
|
||||
PHP_FE_END
|
||||
};
|
||||
|
||||
/* Psr\Container\ContainerExceptionInterface */
|
||||
static const zend_function_entry pimple_ce_PsrContainerExceptionInterface_functions[] = {
|
||||
PHP_FE_END
|
||||
};
|
||||
|
||||
/* Psr\Container\NotFoundExceptionInterface */
|
||||
static const zend_function_entry pimple_ce_PsrNotFoundExceptionInterface_functions[] = {
|
||||
PHP_FE_END
|
||||
};
|
||||
|
||||
/* Pimple\Exception\FrozenServiceException */
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_FrozenServiceException___construct, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, id)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
static const zend_function_entry pimple_ce_FrozenServiceException_functions[] = {
|
||||
PHP_ME(FrozenServiceException, __construct, arginfo_FrozenServiceException___construct, ZEND_ACC_PUBLIC)
|
||||
PHP_FE_END
|
||||
};
|
||||
|
||||
/* Pimple\Exception\InvalidServiceIdentifierException */
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_InvalidServiceIdentifierException___construct, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, id)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
static const zend_function_entry pimple_ce_InvalidServiceIdentifierException_functions[] = {
|
||||
PHP_ME(InvalidServiceIdentifierException, __construct, arginfo_InvalidServiceIdentifierException___construct, ZEND_ACC_PUBLIC)
|
||||
PHP_FE_END
|
||||
};
|
||||
|
||||
/* Pimple\Exception\UnknownIdentifierException */
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_UnknownIdentifierException___construct, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, id)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
static const zend_function_entry pimple_ce_UnknownIdentifierException_functions[] = {
|
||||
PHP_ME(UnknownIdentifierException, __construct, arginfo_UnknownIdentifierException___construct, ZEND_ACC_PUBLIC)
|
||||
PHP_FE_END
|
||||
};
|
||||
|
||||
/* Pimple\Container */
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo___construct, 0, 0, 0)
|
||||
ZEND_ARG_ARRAY_INFO(0, value, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
|
@ -138,10 +204,6 @@ ZEND_ARG_OBJ_INFO(0, provider, Pimple\\ServiceProviderInterface, 0)
|
|||
ZEND_ARG_ARRAY_INFO(0, values, 1)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_serviceprovider_register, 0, 0, 1)
|
||||
ZEND_ARG_OBJ_INFO(0, pimple, Pimple\\Container, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
static const zend_function_entry pimple_ce_functions[] = {
|
||||
PHP_ME(Pimple, __construct, arginfo___construct, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(Pimple, factory, arginfo_factory, ZEND_ACC_PUBLIC)
|
||||
|
|
@ -158,11 +220,54 @@ static const zend_function_entry pimple_ce_functions[] = {
|
|||
PHP_FE_END
|
||||
};
|
||||
|
||||
/* Pimple\ServiceProviderInterface */
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_serviceprovider_register, 0, 0, 1)
|
||||
ZEND_ARG_OBJ_INFO(0, pimple, Pimple\\Container, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
static const zend_function_entry pimple_serviceprovider_iface_ce_functions[] = {
|
||||
PHP_ABSTRACT_ME(ServiceProviderInterface, register, arginfo_serviceprovider_register)
|
||||
PHP_FE_END
|
||||
};
|
||||
|
||||
/* parent::__construct(sprintf("Something with %s", $arg1)) */
|
||||
static void pimple_exception_call_parent_constructor(zval *this_ptr, const char *format, const char *arg1 TSRMLS_DC)
|
||||
{
|
||||
zend_class_entry *ce = Z_OBJCE_P(this_ptr);
|
||||
char *message = NULL;
|
||||
int message_len;
|
||||
zval *constructor_arg;
|
||||
|
||||
message_len = spprintf(&message, 0, format, arg1);
|
||||
ALLOC_INIT_ZVAL(constructor_arg);
|
||||
ZVAL_STRINGL(constructor_arg, message, message_len, 1);
|
||||
|
||||
zend_call_method_with_1_params(&this_ptr, ce, &ce->parent->constructor, "__construct", NULL, constructor_arg);
|
||||
|
||||
efree(message);
|
||||
zval_ptr_dtor(&constructor_arg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass a single string parameter to exception constructor and throw
|
||||
*/
|
||||
static void pimple_throw_exception_string(zend_class_entry *ce, const char *message, zend_uint message_len TSRMLS_DC)
|
||||
{
|
||||
zval *exception, *param;
|
||||
|
||||
ALLOC_INIT_ZVAL(exception);
|
||||
object_init_ex(exception, ce);
|
||||
|
||||
ALLOC_INIT_ZVAL(param);
|
||||
ZVAL_STRINGL(param, message, message_len, 1);
|
||||
|
||||
zend_call_method_with_1_params(&exception, ce, &ce->constructor, "__construct", NULL, param);
|
||||
|
||||
zend_throw_exception_object(exception TSRMLS_CC);
|
||||
|
||||
zval_ptr_dtor(¶m);
|
||||
}
|
||||
|
||||
static void pimple_closure_free_object_storage(pimple_closure_object *obj TSRMLS_DC)
|
||||
{
|
||||
zend_object_std_dtor(&obj->zobj TSRMLS_CC);
|
||||
|
|
@ -264,7 +369,7 @@ static void pimple_object_write_dimension(zval *object, zval *offset, zval *valu
|
|||
zend_hash_quick_find(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hash, (void **)&found_value);
|
||||
if (found_value && found_value->type == PIMPLE_IS_SERVICE && found_value->initialized == 1) {
|
||||
pimple_free_bucket(&pimple_value);
|
||||
zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot override frozen service \"%s\".", Z_STRVAL_P(offset));
|
||||
pimple_throw_exception_string(pimple_ce_FrozenServiceException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC);
|
||||
return;
|
||||
}
|
||||
if (zend_hash_quick_update(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hash, (void *)&pimple_value, sizeof(pimple_bucket_value), NULL) == FAILURE) {
|
||||
|
|
@ -284,7 +389,8 @@ static void pimple_object_write_dimension(zval *object, zval *offset, zval *valu
|
|||
zend_hash_index_find(&pimple_obj->values, index, (void **)&found_value);
|
||||
if (found_value && found_value->type == PIMPLE_IS_SERVICE && found_value->initialized == 1) {
|
||||
pimple_free_bucket(&pimple_value);
|
||||
zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot override frozen service \"%ld\".", index);
|
||||
convert_to_string(offset);
|
||||
pimple_throw_exception_string(pimple_ce_FrozenServiceException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC);
|
||||
return;
|
||||
}
|
||||
if (zend_hash_index_update(&pimple_obj->values, index, (void *)&pimple_value, sizeof(pimple_bucket_value), NULL) == FAILURE) {
|
||||
|
|
@ -385,7 +491,8 @@ static zval *pimple_object_read_dimension(zval *object, zval *offset, int type T
|
|||
switch (Z_TYPE_P(offset)) {
|
||||
case IS_STRING:
|
||||
if (zend_symtable_find(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void **)&retval) == FAILURE) {
|
||||
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%s\" is not defined.", Z_STRVAL_P(offset));
|
||||
pimple_throw_exception_string(pimple_ce_UnknownIdentifierException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC);
|
||||
|
||||
return EG(uninitialized_zval_ptr);
|
||||
}
|
||||
break;
|
||||
|
|
@ -419,7 +526,7 @@ static zval *pimple_object_read_dimension(zval *object, zval *offset, int type T
|
|||
}
|
||||
|
||||
if (zend_hash_index_exists(&pimple_obj->factories, retval->handle_num)) {
|
||||
/* Service is a factory, call it everytime and never cache its result */
|
||||
/* Service is a factory, call it every time and never cache its result */
|
||||
PIMPLE_CALL_CB
|
||||
Z_DELREF_P(retval_ptr_ptr); /* fetch dim addr will increment refcount */
|
||||
return retval_ptr_ptr;
|
||||
|
|
@ -482,6 +589,39 @@ static void pimple_bucket_dtor(pimple_bucket_value *bucket)
|
|||
pimple_free_bucket(bucket);
|
||||
}
|
||||
|
||||
PHP_METHOD(FrozenServiceException, __construct)
|
||||
{
|
||||
char *id = NULL;
|
||||
int id_len;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &id, &id_len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
pimple_exception_call_parent_constructor(getThis(), "Cannot override frozen service \"%s\".", id TSRMLS_CC);
|
||||
}
|
||||
|
||||
PHP_METHOD(InvalidServiceIdentifierException, __construct)
|
||||
{
|
||||
char *id = NULL;
|
||||
int id_len;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &id, &id_len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
pimple_exception_call_parent_constructor(getThis(), "Identifier \"%s\" does not contain an object definition.", id TSRMLS_CC);
|
||||
}
|
||||
|
||||
PHP_METHOD(UnknownIdentifierException, __construct)
|
||||
{
|
||||
char *id = NULL;
|
||||
int id_len;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &id, &id_len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
pimple_exception_call_parent_constructor(getThis(), "Identifier \"%s\" is not defined.", id TSRMLS_CC);
|
||||
}
|
||||
|
||||
PHP_METHOD(Pimple, protect)
|
||||
{
|
||||
zval *protected = NULL;
|
||||
|
|
@ -494,7 +634,7 @@ PHP_METHOD(Pimple, protect)
|
|||
|
||||
if (pimple_zval_is_valid_callback(protected, &bucket TSRMLS_CC) == FAILURE) {
|
||||
pimple_free_bucket(&bucket);
|
||||
zend_throw_exception(spl_ce_InvalidArgumentException, "Callable is not a Closure or invokable object.", 0 TSRMLS_CC);
|
||||
zend_throw_exception(pimple_ce_ExpectedInvokableException, "Callable is not a Closure or invokable object.", 0 TSRMLS_CC);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -526,7 +666,7 @@ PHP_METHOD(Pimple, raw)
|
|||
switch (Z_TYPE_P(offset)) {
|
||||
case IS_STRING:
|
||||
if (zend_symtable_find(&pobj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void *)&value) == FAILURE) {
|
||||
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%s\" is not defined.", Z_STRVAL_P(offset));
|
||||
pimple_throw_exception_string(pimple_ce_UnknownIdentifierException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC);
|
||||
RETURN_NULL();
|
||||
}
|
||||
break;
|
||||
|
|
@ -571,13 +711,20 @@ PHP_METHOD(Pimple, extend)
|
|||
switch (Z_TYPE_P(offset)) {
|
||||
case IS_STRING:
|
||||
if (zend_symtable_find(&pobj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void *)&value) == FAILURE) {
|
||||
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%s\" is not defined.", Z_STRVAL_P(offset));
|
||||
pimple_throw_exception_string(pimple_ce_UnknownIdentifierException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC);
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
if (value->type != PIMPLE_IS_SERVICE) {
|
||||
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%s\" does not contain an object definition.", Z_STRVAL_P(offset));
|
||||
pimple_throw_exception_string(pimple_ce_InvalidServiceIdentifierException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC);
|
||||
RETURN_NULL();
|
||||
}
|
||||
if (zend_hash_index_exists(&pobj->protected, value->handle_num)) {
|
||||
int er = EG(error_reporting);
|
||||
EG(error_reporting) = 0;
|
||||
php_error(E_DEPRECATED, "How Pimple behaves when extending protected closures will be fixed in Pimple 4. Are you sure \"%s\" should be protected?", Z_STRVAL_P(offset));
|
||||
EG(error_reporting) = er;
|
||||
}
|
||||
break;
|
||||
case IS_DOUBLE:
|
||||
case IS_BOOL:
|
||||
|
|
@ -588,13 +735,21 @@ PHP_METHOD(Pimple, extend)
|
|||
index = Z_LVAL_P(offset);
|
||||
}
|
||||
if (zend_hash_index_find(&pobj->values, index, (void *)&value) == FAILURE) {
|
||||
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%ld\" is not defined.", index);
|
||||
convert_to_string(offset);
|
||||
pimple_throw_exception_string(pimple_ce_UnknownIdentifierException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC);
|
||||
RETURN_NULL();
|
||||
}
|
||||
if (value->type != PIMPLE_IS_SERVICE) {
|
||||
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%ld\" does not contain an object definition.", index);
|
||||
convert_to_string(offset);
|
||||
pimple_throw_exception_string(pimple_ce_InvalidServiceIdentifierException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC);
|
||||
RETURN_NULL();
|
||||
}
|
||||
if (zend_hash_index_exists(&pobj->protected, value->handle_num)) {
|
||||
int er = EG(error_reporting);
|
||||
EG(error_reporting) = 0;
|
||||
php_error(E_DEPRECATED, "How Pimple behaves when extending protected closures will be fixed in Pimple 4. Are you sure \"%ld\" should be protected?", index);
|
||||
EG(error_reporting) = er;
|
||||
}
|
||||
break;
|
||||
case IS_NULL:
|
||||
default:
|
||||
|
|
@ -603,7 +758,7 @@ PHP_METHOD(Pimple, extend)
|
|||
|
||||
if (pimple_zval_is_valid_callback(callable, &bucket TSRMLS_CC) == FAILURE) {
|
||||
pimple_free_bucket(&bucket);
|
||||
zend_throw_exception(spl_ce_InvalidArgumentException, "Extension service definition is not a Closure or invokable object.", 0 TSRMLS_CC);
|
||||
zend_throw_exception(pimple_ce_ExpectedInvokableException, "Extension service definition is not a Closure or invokable object.", 0 TSRMLS_CC);
|
||||
RETURN_NULL();
|
||||
}
|
||||
pimple_free_bucket(&bucket);
|
||||
|
|
@ -676,7 +831,7 @@ PHP_METHOD(Pimple, factory)
|
|||
|
||||
if (pimple_zval_is_valid_callback(factory, &bucket TSRMLS_CC) == FAILURE) {
|
||||
pimple_free_bucket(&bucket);
|
||||
zend_throw_exception(spl_ce_InvalidArgumentException, "Service definition is not a Closure or invokable object.", 0 TSRMLS_CC);
|
||||
zend_throw_exception(pimple_ce_ExpectedInvokableException, "Service definition is not a Closure or invokable object.", 0 TSRMLS_CC);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -782,7 +937,13 @@ PHP_METHOD(Pimple, __construct)
|
|||
zend_uint str_length;
|
||||
ulong num_index;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!", &values) == FAILURE || !values) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!", &values) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
PIMPLE_DEPRECATE
|
||||
|
||||
if (!values) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -857,7 +1018,38 @@ PHP_METHOD(PimpleClosure, invoker)
|
|||
|
||||
PHP_MINIT_FUNCTION(pimple)
|
||||
{
|
||||
zend_class_entry tmp_ce_PsrContainerInterface, tmp_ce_PsrContainerExceptionInterface, tmp_ce_PsrNotFoundExceptionInterface;
|
||||
zend_class_entry tmp_ce_ExpectedInvokableException, tmp_ce_FrozenServiceException, tmp_ce_InvalidServiceIdentifierException, tmp_ce_UnknownIdentifierException;
|
||||
zend_class_entry tmp_pimple_ce, tmp_pimple_closure_ce, tmp_pimple_serviceprovider_iface_ce;
|
||||
|
||||
/* Psr\Container namespace */
|
||||
INIT_NS_CLASS_ENTRY(tmp_ce_PsrContainerInterface, PSR_CONTAINER_NS, "ContainerInterface", pimple_ce_PsrContainerInterface_functions);
|
||||
INIT_NS_CLASS_ENTRY(tmp_ce_PsrContainerExceptionInterface, PSR_CONTAINER_NS, "ContainerExceptionInterface", pimple_ce_PsrContainerExceptionInterface_functions);
|
||||
INIT_NS_CLASS_ENTRY(tmp_ce_PsrNotFoundExceptionInterface, PSR_CONTAINER_NS, "NotFoundExceptionInterface", pimple_ce_PsrNotFoundExceptionInterface_functions);
|
||||
|
||||
pimple_ce_PsrContainerInterface = zend_register_internal_interface(&tmp_ce_PsrContainerInterface TSRMLS_CC);
|
||||
pimple_ce_PsrContainerExceptionInterface = zend_register_internal_interface(&tmp_ce_PsrContainerExceptionInterface TSRMLS_CC);
|
||||
pimple_ce_PsrNotFoundExceptionInterface = zend_register_internal_interface(&tmp_ce_PsrNotFoundExceptionInterface TSRMLS_CC);
|
||||
|
||||
zend_class_implements(pimple_ce_PsrNotFoundExceptionInterface TSRMLS_CC, 1, pimple_ce_PsrContainerExceptionInterface);
|
||||
|
||||
/* Pimple\Exception namespace */
|
||||
INIT_NS_CLASS_ENTRY(tmp_ce_ExpectedInvokableException, PIMPLE_EXCEPTION_NS, "ExpectedInvokableException", NULL);
|
||||
INIT_NS_CLASS_ENTRY(tmp_ce_FrozenServiceException, PIMPLE_EXCEPTION_NS, "FrozenServiceException", pimple_ce_FrozenServiceException_functions);
|
||||
INIT_NS_CLASS_ENTRY(tmp_ce_InvalidServiceIdentifierException, PIMPLE_EXCEPTION_NS, "InvalidServiceIdentifierException", pimple_ce_InvalidServiceIdentifierException_functions);
|
||||
INIT_NS_CLASS_ENTRY(tmp_ce_UnknownIdentifierException, PIMPLE_EXCEPTION_NS, "UnknownIdentifierException", pimple_ce_UnknownIdentifierException_functions);
|
||||
|
||||
pimple_ce_ExpectedInvokableException = zend_register_internal_class_ex(&tmp_ce_ExpectedInvokableException, spl_ce_InvalidArgumentException, NULL TSRMLS_CC);
|
||||
pimple_ce_FrozenServiceException = zend_register_internal_class_ex(&tmp_ce_FrozenServiceException, spl_ce_RuntimeException, NULL TSRMLS_CC);
|
||||
pimple_ce_InvalidServiceIdentifierException = zend_register_internal_class_ex(&tmp_ce_InvalidServiceIdentifierException, spl_ce_InvalidArgumentException, NULL TSRMLS_CC);
|
||||
pimple_ce_UnknownIdentifierException = zend_register_internal_class_ex(&tmp_ce_UnknownIdentifierException, spl_ce_InvalidArgumentException, NULL TSRMLS_CC);
|
||||
|
||||
zend_class_implements(pimple_ce_ExpectedInvokableException TSRMLS_CC, 1, pimple_ce_PsrContainerExceptionInterface);
|
||||
zend_class_implements(pimple_ce_FrozenServiceException TSRMLS_CC, 1, pimple_ce_PsrContainerExceptionInterface);
|
||||
zend_class_implements(pimple_ce_InvalidServiceIdentifierException TSRMLS_CC, 1, pimple_ce_PsrContainerExceptionInterface);
|
||||
zend_class_implements(pimple_ce_UnknownIdentifierException TSRMLS_CC, 1, pimple_ce_PsrNotFoundExceptionInterface);
|
||||
|
||||
/* Pimple namespace */
|
||||
INIT_NS_CLASS_ENTRY(tmp_pimple_ce, PIMPLE_NS, "Container", pimple_ce_functions);
|
||||
INIT_NS_CLASS_ENTRY(tmp_pimple_closure_ce, PIMPLE_NS, "ContainerClosure", NULL);
|
||||
INIT_NS_CLASS_ENTRY(tmp_pimple_serviceprovider_iface_ce, PIMPLE_NS, "ServiceProviderInterface", pimple_serviceprovider_iface_ce_functions);
|
||||
|
|
|
|||
|
|
@ -26,10 +26,15 @@
|
|||
|
||||
namespace Pimple;
|
||||
|
||||
use Pimple\Exception\ExpectedInvokableException;
|
||||
use Pimple\Exception\FrozenServiceException;
|
||||
use Pimple\Exception\InvalidServiceIdentifierException;
|
||||
use Pimple\Exception\UnknownIdentifierException;
|
||||
|
||||
/**
|
||||
* Container main class.
|
||||
*
|
||||
* @author Fabien Potencier
|
||||
* @author Fabien Potencier
|
||||
*/
|
||||
class Container implements \ArrayAccess
|
||||
{
|
||||
|
|
@ -41,11 +46,11 @@ class Container implements \ArrayAccess
|
|||
private $keys = array();
|
||||
|
||||
/**
|
||||
* Instantiate the container.
|
||||
* Instantiates the container.
|
||||
*
|
||||
* Objects and parameters can be passed as argument to the constructor.
|
||||
*
|
||||
* @param array $values The parameters or objects.
|
||||
* @param array $values The parameters or objects
|
||||
*/
|
||||
public function __construct(array $values = array())
|
||||
{
|
||||
|
|
@ -69,12 +74,12 @@ class Container implements \ArrayAccess
|
|||
* @param string $id The unique identifier for the parameter or object
|
||||
* @param mixed $value The value of the parameter or a closure to define an object
|
||||
*
|
||||
* @throws \RuntimeException Prevent override of a frozen service
|
||||
* @throws FrozenServiceException Prevent override of a frozen service
|
||||
*/
|
||||
public function offsetSet($id, $value)
|
||||
{
|
||||
if (isset($this->frozen[$id])) {
|
||||
throw new \RuntimeException(sprintf('Cannot override frozen service "%s".', $id));
|
||||
throw new FrozenServiceException($id);
|
||||
}
|
||||
|
||||
$this->values[$id] = $value;
|
||||
|
|
@ -88,12 +93,12 @@ class Container implements \ArrayAccess
|
|||
*
|
||||
* @return mixed The value of the parameter or an object
|
||||
*
|
||||
* @throws \InvalidArgumentException if the identifier is not defined
|
||||
* @throws UnknownIdentifierException If the identifier is not defined
|
||||
*/
|
||||
public function offsetGet($id)
|
||||
{
|
||||
if (!isset($this->keys[$id])) {
|
||||
throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
|
||||
throw new UnknownIdentifierException($id);
|
||||
}
|
||||
|
||||
if (
|
||||
|
|
@ -153,12 +158,12 @@ class Container implements \ArrayAccess
|
|||
*
|
||||
* @return callable The passed callable
|
||||
*
|
||||
* @throws \InvalidArgumentException Service definition has to be a closure of an invokable object
|
||||
* @throws ExpectedInvokableException Service definition has to be a closure or an invokable object
|
||||
*/
|
||||
public function factory($callable)
|
||||
{
|
||||
if (!method_exists($callable, '__invoke')) {
|
||||
throw new \InvalidArgumentException('Service definition is not a Closure or invokable object.');
|
||||
throw new ExpectedInvokableException('Service definition is not a Closure or invokable object.');
|
||||
}
|
||||
|
||||
$this->factories->attach($callable);
|
||||
|
|
@ -175,12 +180,12 @@ class Container implements \ArrayAccess
|
|||
*
|
||||
* @return callable The passed callable
|
||||
*
|
||||
* @throws \InvalidArgumentException Service definition has to be a closure of an invokable object
|
||||
* @throws ExpectedInvokableException Service definition has to be a closure or an invokable object
|
||||
*/
|
||||
public function protect($callable)
|
||||
{
|
||||
if (!method_exists($callable, '__invoke')) {
|
||||
throw new \InvalidArgumentException('Callable is not a Closure or invokable object.');
|
||||
throw new ExpectedInvokableException('Callable is not a Closure or invokable object.');
|
||||
}
|
||||
|
||||
$this->protected->attach($callable);
|
||||
|
|
@ -195,12 +200,12 @@ class Container implements \ArrayAccess
|
|||
*
|
||||
* @return mixed The value of the parameter or the closure defining an object
|
||||
*
|
||||
* @throws \InvalidArgumentException if the identifier is not defined
|
||||
* @throws UnknownIdentifierException If the identifier is not defined
|
||||
*/
|
||||
public function raw($id)
|
||||
{
|
||||
if (!isset($this->keys[$id])) {
|
||||
throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
|
||||
throw new UnknownIdentifierException($id);
|
||||
}
|
||||
|
||||
if (isset($this->raw[$id])) {
|
||||
|
|
@ -221,20 +226,31 @@ class Container implements \ArrayAccess
|
|||
*
|
||||
* @return callable The wrapped callable
|
||||
*
|
||||
* @throws \InvalidArgumentException if the identifier is not defined or not a service definition
|
||||
* @throws UnknownIdentifierException If the identifier is not defined
|
||||
* @throws FrozenServiceException If the service is frozen
|
||||
* @throws InvalidServiceIdentifierException If the identifier belongs to a parameter
|
||||
* @throws ExpectedInvokableException If the extension callable is not a closure or an invokable object
|
||||
*/
|
||||
public function extend($id, $callable)
|
||||
{
|
||||
if (!isset($this->keys[$id])) {
|
||||
throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
|
||||
throw new UnknownIdentifierException($id);
|
||||
}
|
||||
|
||||
if (isset($this->frozen[$id])) {
|
||||
throw new FrozenServiceException($id);
|
||||
}
|
||||
|
||||
if (!is_object($this->values[$id]) || !method_exists($this->values[$id], '__invoke')) {
|
||||
throw new \InvalidArgumentException(sprintf('Identifier "%s" does not contain an object definition.', $id));
|
||||
throw new InvalidServiceIdentifierException($id);
|
||||
}
|
||||
|
||||
if (isset($this->protected[$this->values[$id]])) {
|
||||
@trigger_error(sprintf('How Pimple behaves when extending protected closures will be fixed in Pimple 4. Are you sure "%s" should be protected?', $id), E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
if (!is_object($callable) || !method_exists($callable, '__invoke')) {
|
||||
throw new \InvalidArgumentException('Extension service definition is not a Closure or invokable object.');
|
||||
throw new ExpectedInvokableException('Extension service definition is not a Closure or invokable object.');
|
||||
}
|
||||
|
||||
$factory = $this->values[$id];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Pimple.
|
||||
*
|
||||
* Copyright (c) 2009 Fabien Potencier
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is furnished
|
||||
* to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
namespace Pimple\Exception;
|
||||
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
|
||||
/**
|
||||
* A closure or invokable object was expected.
|
||||
*
|
||||
* @author Pascal Luna <skalpa@zetareticuli.org>
|
||||
*/
|
||||
class ExpectedInvokableException extends \InvalidArgumentException implements ContainerExceptionInterface
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Pimple.
|
||||
*
|
||||
* Copyright (c) 2009 Fabien Potencier
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is furnished
|
||||
* to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
namespace Pimple\Exception;
|
||||
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
|
||||
/**
|
||||
* An attempt to modify a frozen service was made.
|
||||
*
|
||||
* @author Pascal Luna <skalpa@zetareticuli.org>
|
||||
*/
|
||||
class FrozenServiceException extends \RuntimeException implements ContainerExceptionInterface
|
||||
{
|
||||
/**
|
||||
* @param string $id Identifier of the frozen service
|
||||
*/
|
||||
public function __construct($id)
|
||||
{
|
||||
parent::__construct(sprintf('Cannot override frozen service "%s".', $id));
|
||||
}
|
||||
}
|
||||
45
vendor/pimple/pimple/src/Pimple/Exception/InvalidServiceIdentifierException.php
vendored
Normal file
45
vendor/pimple/pimple/src/Pimple/Exception/InvalidServiceIdentifierException.php
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Pimple.
|
||||
*
|
||||
* Copyright (c) 2009 Fabien Potencier
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is furnished
|
||||
* to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
namespace Pimple\Exception;
|
||||
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
/**
|
||||
* An attempt to perform an operation that requires a service identifier was made.
|
||||
*
|
||||
* @author Pascal Luna <skalpa@zetareticuli.org>
|
||||
*/
|
||||
class InvalidServiceIdentifierException extends \InvalidArgumentException implements NotFoundExceptionInterface
|
||||
{
|
||||
/**
|
||||
* @param string $id The invalid identifier
|
||||
*/
|
||||
public function __construct($id)
|
||||
{
|
||||
parent::__construct(sprintf('Identifier "%s" does not contain an object definition.', $id));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Pimple.
|
||||
*
|
||||
* Copyright (c) 2009 Fabien Potencier
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is furnished
|
||||
* to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
namespace Pimple\Exception;
|
||||
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
/**
|
||||
* The identifier of a valid service or parameter was expected.
|
||||
*
|
||||
* @author Pascal Luna <skalpa@zetareticuli.org>
|
||||
*/
|
||||
class UnknownIdentifierException extends \InvalidArgumentException implements NotFoundExceptionInterface
|
||||
{
|
||||
/**
|
||||
* @param string $id The unknown identifier
|
||||
*/
|
||||
public function __construct($id)
|
||||
{
|
||||
parent::__construct(sprintf('Identifier "%s" is not defined.', $id));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Pimple.
|
||||
*
|
||||
* Copyright (c) 2009-2017 Fabien Potencier
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is furnished
|
||||
* to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
namespace Pimple\Psr11;
|
||||
|
||||
use Pimple\Container as PimpleContainer;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
* PSR-11 compliant wrapper.
|
||||
*
|
||||
* @author Pascal Luna <skalpa@zetareticuli.org>
|
||||
*/
|
||||
final class Container implements ContainerInterface
|
||||
{
|
||||
private $pimple;
|
||||
|
||||
public function __construct(PimpleContainer $pimple)
|
||||
{
|
||||
$this->pimple = $pimple;
|
||||
}
|
||||
|
||||
public function get($id)
|
||||
{
|
||||
return $this->pimple[$id];
|
||||
}
|
||||
|
||||
public function has($id)
|
||||
{
|
||||
return isset($this->pimple[$id]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Pimple.
|
||||
*
|
||||
* Copyright (c) 2009 Fabien Potencier
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is furnished
|
||||
* to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
namespace Pimple\Psr11;
|
||||
|
||||
use Pimple\Container as PimpleContainer;
|
||||
use Pimple\Exception\UnknownIdentifierException;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Pimple PSR-11 service locator.
|
||||
*
|
||||
* @author Pascal Luna <skalpa@zetareticuli.org>
|
||||
*/
|
||||
class ServiceLocator implements ContainerInterface
|
||||
{
|
||||
private $container;
|
||||
private $aliases = array();
|
||||
|
||||
/**
|
||||
* @param PimpleContainer $container The Container instance used to locate services
|
||||
* @param array $ids Array of service ids that can be located. String keys can be used to define aliases
|
||||
*/
|
||||
public function __construct(PimpleContainer $container, array $ids)
|
||||
{
|
||||
$this->container = $container;
|
||||
|
||||
foreach ($ids as $key => $id) {
|
||||
$this->aliases[is_int($key) ? $id : $key] = $id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($id)
|
||||
{
|
||||
if (!isset($this->aliases[$id])) {
|
||||
throw new UnknownIdentifierException($id);
|
||||
}
|
||||
|
||||
return $this->container[$this->aliases[$id]];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function has($id)
|
||||
{
|
||||
return isset($this->aliases[$id]) && isset($this->container[$this->aliases[$id]]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Pimple.
|
||||
*
|
||||
* Copyright (c) 2009 Fabien Potencier
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is furnished
|
||||
* to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
namespace Pimple;
|
||||
|
||||
/**
|
||||
* Lazy service iterator.
|
||||
*
|
||||
* @author Pascal Luna <skalpa@zetareticuli.org>
|
||||
*/
|
||||
final class ServiceIterator implements \Iterator
|
||||
{
|
||||
private $container;
|
||||
private $ids;
|
||||
|
||||
public function __construct(Container $container, array $ids)
|
||||
{
|
||||
$this->container = $container;
|
||||
$this->ids = $ids;
|
||||
}
|
||||
|
||||
public function rewind()
|
||||
{
|
||||
reset($this->ids);
|
||||
}
|
||||
|
||||
public function current()
|
||||
{
|
||||
return $this->container[current($this->ids)];
|
||||
}
|
||||
|
||||
public function key()
|
||||
{
|
||||
return current($this->ids);
|
||||
}
|
||||
|
||||
public function next()
|
||||
{
|
||||
next($this->ids);
|
||||
}
|
||||
|
||||
public function valid()
|
||||
{
|
||||
return null !== key($this->ids);
|
||||
}
|
||||
}
|
||||
|
|
@ -29,7 +29,7 @@ namespace Pimple\Tests;
|
|||
use Pimple\Container;
|
||||
|
||||
/**
|
||||
* @author Igor Wiedler <igor@wiedler.ch>
|
||||
* @author Igor Wiedler <igor@wiedler.ch>
|
||||
*/
|
||||
class PimpleTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
|
@ -106,7 +106,7 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
|
|||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedException \Pimple\Exception\UnknownIdentifierException
|
||||
* @expectedExceptionMessage Identifier "foo" is not defined.
|
||||
*/
|
||||
public function testOffsetGetValidatesKeyIsPresent()
|
||||
|
|
@ -115,6 +115,17 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
|
|||
echo $pimple['foo'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedExceptionMessage Identifier "foo" is not defined.
|
||||
*/
|
||||
public function testLegacyOffsetGetValidatesKeyIsPresent()
|
||||
{
|
||||
$pimple = new Container();
|
||||
echo $pimple['foo'];
|
||||
}
|
||||
|
||||
public function testOffsetGetHonorsNullValues()
|
||||
{
|
||||
$pimple = new Container();
|
||||
|
|
@ -187,11 +198,11 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
|
|||
public function testFluentRegister()
|
||||
{
|
||||
$pimple = new Container();
|
||||
$this->assertSame($pimple, $pimple->register($this->getMock('Pimple\ServiceProviderInterface')));
|
||||
$this->assertSame($pimple, $pimple->register($this->getMockBuilder('Pimple\ServiceProviderInterface')->getMock()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedException \Pimple\Exception\UnknownIdentifierException
|
||||
* @expectedExceptionMessage Identifier "foo" is not defined.
|
||||
*/
|
||||
public function testRawValidatesKeyIsPresent()
|
||||
|
|
@ -200,6 +211,17 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
|
|||
$pimple->raw('foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedExceptionMessage Identifier "foo" is not defined.
|
||||
*/
|
||||
public function testLegacyRawValidatesKeyIsPresent()
|
||||
{
|
||||
$pimple = new Container();
|
||||
$pimple->raw('foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider serviceDefinitionProvider
|
||||
*/
|
||||
|
|
@ -251,7 +273,7 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
|
|||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedException \Pimple\Exception\UnknownIdentifierException
|
||||
* @expectedExceptionMessage Identifier "foo" is not defined.
|
||||
*/
|
||||
public function testExtendValidatesKeyIsPresent()
|
||||
|
|
@ -260,6 +282,17 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
|
|||
$pimple->extend('foo', function () {});
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedExceptionMessage Identifier "foo" is not defined.
|
||||
*/
|
||||
public function testLegacyExtendValidatesKeyIsPresent()
|
||||
{
|
||||
$pimple = new Container();
|
||||
$pimple->extend('foo', function () {});
|
||||
}
|
||||
|
||||
public function testKeys()
|
||||
{
|
||||
$pimple = new Container();
|
||||
|
|
@ -289,7 +322,7 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
/**
|
||||
* @dataProvider badServiceDefinitionProvider
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedException \Pimple\Exception\ExpectedInvokableException
|
||||
* @expectedExceptionMessage Service definition is not a Closure or invokable object.
|
||||
*/
|
||||
public function testFactoryFailsForInvalidServiceDefinitions($service)
|
||||
|
|
@ -299,8 +332,20 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
|
|||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
* @dataProvider badServiceDefinitionProvider
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedExceptionMessage Service definition is not a Closure or invokable object.
|
||||
*/
|
||||
public function testLegacyFactoryFailsForInvalidServiceDefinitions($service)
|
||||
{
|
||||
$pimple = new Container();
|
||||
$pimple->factory($service);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider badServiceDefinitionProvider
|
||||
* @expectedException \Pimple\Exception\ExpectedInvokableException
|
||||
* @expectedExceptionMessage Callable is not a Closure or invokable object.
|
||||
*/
|
||||
public function testProtectFailsForInvalidServiceDefinitions($service)
|
||||
|
|
@ -310,8 +355,20 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
|
|||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
* @dataProvider badServiceDefinitionProvider
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedExceptionMessage Callable is not a Closure or invokable object.
|
||||
*/
|
||||
public function testLegacyProtectFailsForInvalidServiceDefinitions($service)
|
||||
{
|
||||
$pimple = new Container();
|
||||
$pimple->protect($service);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider badServiceDefinitionProvider
|
||||
* @expectedException \Pimple\Exception\InvalidServiceIdentifierException
|
||||
* @expectedExceptionMessage Identifier "foo" does not contain an object definition.
|
||||
*/
|
||||
public function testExtendFailsForKeysNotContainingServiceDefinitions($service)
|
||||
|
|
@ -322,8 +379,39 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
|
|||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
* @dataProvider badServiceDefinitionProvider
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedExceptionMessage Identifier "foo" does not contain an object definition.
|
||||
*/
|
||||
public function testLegacyExtendFailsForKeysNotContainingServiceDefinitions($service)
|
||||
{
|
||||
$pimple = new Container();
|
||||
$pimple['foo'] = $service;
|
||||
$pimple->extend('foo', function () {});
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
* @expectedDeprecation How Pimple behaves when extending protected closures will be fixed in Pimple 4. Are you sure "foo" should be protected?
|
||||
*/
|
||||
public function testExtendingProtectedClosureDeprecation()
|
||||
{
|
||||
$pimple = new Container();
|
||||
$pimple['foo'] = $pimple->protect(function () {
|
||||
return 'bar';
|
||||
});
|
||||
|
||||
$pimple->extend('foo', function ($value) {
|
||||
return $value.'-baz';
|
||||
});
|
||||
|
||||
$this->assertSame('bar-baz', $pimple['foo']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider badServiceDefinitionProvider
|
||||
* @expectedException \Pimple\Exception\ExpectedInvokableException
|
||||
* @expectedExceptionMessage Extension service definition is not a Closure or invokable object.
|
||||
*/
|
||||
public function testExtendFailsForInvalidServiceDefinitions($service)
|
||||
|
|
@ -333,6 +421,49 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
|
|||
$pimple->extend('foo', $service);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
* @dataProvider badServiceDefinitionProvider
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedExceptionMessage Extension service definition is not a Closure or invokable object.
|
||||
*/
|
||||
public function testLegacyExtendFailsForInvalidServiceDefinitions($service)
|
||||
{
|
||||
$pimple = new Container();
|
||||
$pimple['foo'] = function () {};
|
||||
$pimple->extend('foo', $service);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Pimple\Exception\FrozenServiceException
|
||||
* @expectedExceptionMessage Cannot override frozen service "foo".
|
||||
*/
|
||||
public function testExtendFailsIfFrozenServiceIsNonInvokable()
|
||||
{
|
||||
$pimple = new Container();
|
||||
$pimple['foo'] = function () {
|
||||
return new Fixtures\NonInvokable();
|
||||
};
|
||||
$foo = $pimple['foo'];
|
||||
|
||||
$pimple->extend('foo', function () {});
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Pimple\Exception\FrozenServiceException
|
||||
* @expectedExceptionMessage Cannot override frozen service "foo".
|
||||
*/
|
||||
public function testExtendFailsIfFrozenServiceIsInvokable()
|
||||
{
|
||||
$pimple = new Container();
|
||||
$pimple['foo'] = function () {
|
||||
return new Fixtures\Invokable();
|
||||
};
|
||||
$foo = $pimple['foo'];
|
||||
|
||||
$pimple->extend('foo', function () {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Provider for invalid service definitions.
|
||||
*/
|
||||
|
|
@ -375,7 +506,7 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
|
|||
}
|
||||
|
||||
/**
|
||||
* @expectedException \RuntimeException
|
||||
* @expectedException \Pimple\Exception\FrozenServiceException
|
||||
* @expectedExceptionMessage Cannot override frozen service "foo".
|
||||
*/
|
||||
public function testOverridingServiceAfterFreeze()
|
||||
|
|
@ -391,6 +522,24 @@ class PimpleTest extends \PHPUnit_Framework_TestCase
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
* @expectedException \RuntimeException
|
||||
* @expectedExceptionMessage Cannot override frozen service "foo".
|
||||
*/
|
||||
public function testLegacyOverridingServiceAfterFreeze()
|
||||
{
|
||||
$pimple = new Container();
|
||||
$pimple['foo'] = function () {
|
||||
return 'foo';
|
||||
};
|
||||
$foo = $pimple['foo'];
|
||||
|
||||
$pimple['foo'] = function () {
|
||||
return 'bar';
|
||||
};
|
||||
}
|
||||
|
||||
public function testRemovingServiceAfterFreeze()
|
||||
{
|
||||
$pimple = new Container();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Pimple.
|
||||
*
|
||||
* Copyright (c) 2009-2017 Fabien Potencier
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is furnished
|
||||
* to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
namespace Pimple\Tests\Psr11;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Pimple\Container;
|
||||
use Pimple\Psr11\Container as PsrContainer;
|
||||
use Pimple\Tests\Fixtures\Service;
|
||||
|
||||
class ContainerTest extends TestCase
|
||||
{
|
||||
public function testGetReturnsExistingService()
|
||||
{
|
||||
$pimple = new Container();
|
||||
$pimple['service'] = function () {
|
||||
return new Service();
|
||||
};
|
||||
$psr = new PsrContainer($pimple);
|
||||
|
||||
$this->assertSame($pimple['service'], $psr->get('service'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Psr\Container\NotFoundExceptionInterface
|
||||
* @expectedExceptionMessage Identifier "service" is not defined.
|
||||
*/
|
||||
public function testGetThrowsExceptionIfServiceIsNotFound()
|
||||
{
|
||||
$pimple = new Container();
|
||||
$psr = new PsrContainer($pimple);
|
||||
|
||||
$psr->get('service');
|
||||
}
|
||||
|
||||
public function testHasReturnsTrueIfServiceExists()
|
||||
{
|
||||
$pimple = new Container();
|
||||
$pimple['service'] = function () {
|
||||
return new Service();
|
||||
};
|
||||
$psr = new PsrContainer($pimple);
|
||||
|
||||
$this->assertTrue($psr->has('service'));
|
||||
}
|
||||
|
||||
public function testHasReturnsFalseIfServiceDoesNotExist()
|
||||
{
|
||||
$pimple = new Container();
|
||||
$psr = new PsrContainer($pimple);
|
||||
|
||||
$this->assertFalse($psr->has('service'));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Pimple.
|
||||
*
|
||||
* Copyright (c) 2009 Fabien Potencier
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is furnished
|
||||
* to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
namespace Pimple\Tests\Psr11;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Pimple\Container;
|
||||
use Pimple\Psr11\ServiceLocator;
|
||||
use Pimple\Tests\Fixtures;
|
||||
|
||||
/**
|
||||
* ServiceLocator test case.
|
||||
*
|
||||
* @author Pascal Luna <skalpa@zetareticuli.org>
|
||||
*/
|
||||
class ServiceLocatorTest extends TestCase
|
||||
{
|
||||
public function testCanAccessServices()
|
||||
{
|
||||
$pimple = new Container();
|
||||
$pimple['service'] = function () {
|
||||
return new Fixtures\Service();
|
||||
};
|
||||
$locator = new ServiceLocator($pimple, array('service'));
|
||||
|
||||
$this->assertSame($pimple['service'], $locator->get('service'));
|
||||
}
|
||||
|
||||
public function testCanAccessAliasedServices()
|
||||
{
|
||||
$pimple = new Container();
|
||||
$pimple['service'] = function () {
|
||||
return new Fixtures\Service();
|
||||
};
|
||||
$locator = new ServiceLocator($pimple, array('alias' => 'service'));
|
||||
|
||||
$this->assertSame($pimple['service'], $locator->get('alias'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Pimple\Exception\UnknownIdentifierException
|
||||
* @expectedExceptionMessage Identifier "service" is not defined.
|
||||
*/
|
||||
public function testCannotAccessAliasedServiceUsingRealIdentifier()
|
||||
{
|
||||
$pimple = new Container();
|
||||
$pimple['service'] = function () {
|
||||
return new Fixtures\Service();
|
||||
};
|
||||
$locator = new ServiceLocator($pimple, array('alias' => 'service'));
|
||||
|
||||
$service = $locator->get('service');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Pimple\Exception\UnknownIdentifierException
|
||||
* @expectedExceptionMessage Identifier "foo" is not defined.
|
||||
*/
|
||||
public function testGetValidatesServiceCanBeLocated()
|
||||
{
|
||||
$pimple = new Container();
|
||||
$pimple['service'] = function () {
|
||||
return new Fixtures\Service();
|
||||
};
|
||||
$locator = new ServiceLocator($pimple, array('alias' => 'service'));
|
||||
|
||||
$service = $locator->get('foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Pimple\Exception\UnknownIdentifierException
|
||||
* @expectedExceptionMessage Identifier "invalid" is not defined.
|
||||
*/
|
||||
public function testGetValidatesTargetServiceExists()
|
||||
{
|
||||
$pimple = new Container();
|
||||
$pimple['service'] = function () {
|
||||
return new Fixtures\Service();
|
||||
};
|
||||
$locator = new ServiceLocator($pimple, array('alias' => 'invalid'));
|
||||
|
||||
$service = $locator->get('alias');
|
||||
}
|
||||
|
||||
public function testHasValidatesServiceCanBeLocated()
|
||||
{
|
||||
$pimple = new Container();
|
||||
$pimple['service1'] = function () {
|
||||
return new Fixtures\Service();
|
||||
};
|
||||
$pimple['service2'] = function () {
|
||||
return new Fixtures\Service();
|
||||
};
|
||||
$locator = new ServiceLocator($pimple, array('service1'));
|
||||
|
||||
$this->assertTrue($locator->has('service1'));
|
||||
$this->assertFalse($locator->has('service2'));
|
||||
}
|
||||
|
||||
public function testHasChecksIfTargetServiceExists()
|
||||
{
|
||||
$pimple = new Container();
|
||||
$pimple['service'] = function () {
|
||||
return new Fixtures\Service();
|
||||
};
|
||||
$locator = new ServiceLocator($pimple, array('foo' => 'service', 'bar' => 'invalid'));
|
||||
|
||||
$this->assertTrue($locator->has('foo'));
|
||||
$this->assertFalse($locator->has('bar'));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Pimple.
|
||||
*
|
||||
* Copyright (c) 2009 Fabien Potencier
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is furnished
|
||||
* to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
namespace Pimple\Tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Pimple\Container;
|
||||
use Pimple\ServiceIterator;
|
||||
use Pimple\Tests\Fixtures\Service;
|
||||
|
||||
class ServiceIteratorTest extends TestCase
|
||||
{
|
||||
public function testIsIterable()
|
||||
{
|
||||
$pimple = new Container();
|
||||
$pimple['service1'] = function () {
|
||||
return new Service();
|
||||
};
|
||||
$pimple['service2'] = function () {
|
||||
return new Service();
|
||||
};
|
||||
$pimple['service3'] = function () {
|
||||
return new Service();
|
||||
};
|
||||
$iterator = new ServiceIterator($pimple, array('service1', 'service2'));
|
||||
|
||||
$this->assertSame(array('service1' => $pimple['service1'], 'service2' => $pimple['service2']), iterator_to_array($iterator));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
composer.lock
|
||||
composer.phar
|
||||
/vendor/
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2016 container-interop
|
||||
Copyright (c) 2016 PHP Framework Interoperability Group
|
||||
|
||||
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.
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
# PSR Container
|
||||
|
||||
This repository holds all interfaces/classes/traits related to [PSR-11](https://github.com/container-interop/fig-standards/blob/master/proposed/container.md).
|
||||
|
||||
Note that this is not a container implementation of its own. See the specification for more details.
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"name": "psr/container",
|
||||
"type": "library",
|
||||
"description": "Common Container Interface (PHP FIG PSR-11)",
|
||||
"keywords": ["psr", "psr-11", "container", "container-interop", "container-interface"],
|
||||
"homepage": "https://github.com/php-fig/container",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Container\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
/**
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
|
||||
*/
|
||||
|
||||
namespace Psr\Container;
|
||||
|
||||
/**
|
||||
* Base interface representing a generic exception in a container.
|
||||
*/
|
||||
interface ContainerExceptionInterface
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
/**
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
|
||||
*/
|
||||
|
||||
namespace Psr\Container;
|
||||
|
||||
/**
|
||||
* Describes the interface of a container that exposes methods to read its entries.
|
||||
*/
|
||||
interface ContainerInterface
|
||||
{
|
||||
/**
|
||||
* Finds an entry of the container by its identifier and returns it.
|
||||
*
|
||||
* @param string $id Identifier of the entry to look for.
|
||||
*
|
||||
* @throws NotFoundExceptionInterface No entry was found for **this** identifier.
|
||||
* @throws ContainerExceptionInterface Error while retrieving the entry.
|
||||
*
|
||||
* @return mixed Entry.
|
||||
*/
|
||||
public function get($id);
|
||||
|
||||
/**
|
||||
* Returns true if the container can return an entry for the given identifier.
|
||||
* Returns false otherwise.
|
||||
*
|
||||
* `has($id)` returning true does not mean that `get($id)` will not throw an exception.
|
||||
* It does however mean that `get($id)` will not throw a `NotFoundExceptionInterface`.
|
||||
*
|
||||
* @param string $id Identifier of the entry to look for.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($id);
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
/**
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
|
||||
*/
|
||||
|
||||
namespace Psr\Container;
|
||||
|
||||
/**
|
||||
* No entry was found in the container.
|
||||
*/
|
||||
interface NotFoundExceptionInterface extends ContainerExceptionInterface
|
||||
{
|
||||
}
|
||||
|
|
@ -1,4 +1,8 @@
|
|||
/.php_cs.cache
|
||||
/.phpunit
|
||||
/build/*
|
||||
/composer.lock
|
||||
/phpunit.xml
|
||||
/tests/acceptance.conf.php
|
||||
/tests/smoke.conf.php
|
||||
/build/*
|
||||
/vendor/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
return PhpCsFixer\Config::create()
|
||||
->setRules(array(
|
||||
'@Symfony' => true,
|
||||
'@Symfony:risky' => true,
|
||||
'array_syntax' => array('syntax' => 'long'),
|
||||
'no_unreachable_default_argument_value' => false,
|
||||
'braces' => array('allow_single_line_closure' => true),
|
||||
'heredoc_to_nowdoc' => false,
|
||||
'phpdoc_annotation_without_dot' => false,
|
||||
))
|
||||
->setRiskyAllowed(true)
|
||||
->setFinder(PhpCsFixer\Finder::create()->in(__DIR__))
|
||||
;
|
||||
|
|
@ -11,8 +11,7 @@ before_script:
|
|||
- gem install mailcatcher
|
||||
- mailcatcher --smtp-port 4456
|
||||
|
||||
script:
|
||||
- phpunit --verbose
|
||||
script: ./vendor/bin/simple-phpunit
|
||||
|
||||
matrix:
|
||||
include:
|
||||
|
|
@ -21,7 +20,12 @@ matrix:
|
|||
- php: 5.5
|
||||
- php: 5.6
|
||||
- php: 7.0
|
||||
- php: 7.1
|
||||
- php: hhvm
|
||||
allow_failures:
|
||||
- php: hhvm
|
||||
fast_finish: true
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- .phpunit
|
||||
|
|
|
|||
|
|
@ -1,10 +1,36 @@
|
|||
Changelog
|
||||
=========
|
||||
|
||||
5.4.5 (2016-XX-XX)
|
||||
5.4.8 (2017-05-01)
|
||||
------------------
|
||||
|
||||
* fixed CVE-2016-10033 and CVE-2016-10045
|
||||
* fixed encoding inheritance in addPart()
|
||||
* fixed sorting MIME children when their types are equal
|
||||
|
||||
5.4.7 (2017-04-20)
|
||||
------------------
|
||||
|
||||
* fixed NTLMAuthenticator clobbering bcmath scale
|
||||
|
||||
5.4.6 (2017-02-13)
|
||||
------------------
|
||||
|
||||
* removed exceptions thrown in destructors as they lead to fatal errors
|
||||
* switched to use sha256 by default in DKIM as per the RFC
|
||||
* fixed an 'Undefined variable: pipes' PHP notice
|
||||
* fixed long To headers when using the mail transport
|
||||
* fixed NTLMAuthenticator when no domain is passed with the username
|
||||
* prevented fatal error during unserialization of a message
|
||||
* fixed a PHP warning when sending a message that has a length of a multiple of 8192
|
||||
|
||||
5.4.5 (2016-12-29)
|
||||
------------------
|
||||
|
||||
* SECURITY FIX: fixed CVE-2016-10074 by disallowing potentially unsafe shell characters
|
||||
|
||||
Prior to 5.4.5, the mail transport (Swift_Transport_MailTransport) was vulnerable to passing
|
||||
arbitrary shell arguments if the "From", "ReturnPath" or "Sender" header came
|
||||
from a non-trusted source, potentially allowing Remote Code Execution
|
||||
* deprecated the mail transport
|
||||
|
||||
5.4.4 (2016-11-23)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Swift-5.4.5-DEV
|
||||
Swift-5.4.8
|
||||
|
|
|
|||
|
|
@ -48,8 +48,8 @@ interface Swift_CharacterReader
|
|||
* A value of zero means this is already a valid character.
|
||||
* A value of -1 means this cannot possibly be a valid character.
|
||||
*
|
||||
* @param integer[] $bytes
|
||||
* @param int $size
|
||||
* @param int[] $bytes
|
||||
* @param int $size
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -19,22 +19,22 @@ class Swift_CharacterReader_Utf8Reader implements Swift_CharacterReader
|
|||
/** Pre-computed for optimization */
|
||||
private static $length_map = array(
|
||||
// N=0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x0N
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x1N
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x2N
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x3N
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x4N
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x5N
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x6N
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x7N
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x8N
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x9N
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xAN
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xBN
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xCN
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xDN
|
||||
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 0xEN
|
||||
4,4,4,4,4,4,4,4,5,5,5,5,6,6,0,0, // 0xFN
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x0N
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x1N
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x2N
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x3N
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x4N
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x5N
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x6N
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x7N
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x8N
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x9N
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xAN
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xBN
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xCN
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xDN
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xEN
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 0, 0, // 0xFN
|
||||
);
|
||||
|
||||
private static $s_length_map = array(
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ class Swift_CharacterStream_ArrayCharacterStream implements Swift_CharacterStrea
|
|||
*
|
||||
* @param int $length
|
||||
*
|
||||
* @return integer[]
|
||||
* @return int[]
|
||||
*/
|
||||
public function readBytes($length)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ class Swift_DependencyContainer
|
|||
/**
|
||||
* Returns a singleton of the DependencyContainer.
|
||||
*
|
||||
* @return Swift_DependencyContainer
|
||||
* @return self
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
|
|
@ -143,7 +143,7 @@ class Swift_DependencyContainer
|
|||
*
|
||||
* @param string $itemName
|
||||
*
|
||||
* @return Swift_DependencyContainer
|
||||
* @return $this
|
||||
*/
|
||||
public function register($itemName)
|
||||
{
|
||||
|
|
@ -160,7 +160,7 @@ class Swift_DependencyContainer
|
|||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return Swift_DependencyContainer
|
||||
* @return $this
|
||||
*/
|
||||
public function asValue($value)
|
||||
{
|
||||
|
|
@ -176,7 +176,7 @@ class Swift_DependencyContainer
|
|||
*
|
||||
* @param string $lookup
|
||||
*
|
||||
* @return Swift_DependencyContainer
|
||||
* @return $this
|
||||
*/
|
||||
public function asAliasOf($lookup)
|
||||
{
|
||||
|
|
@ -198,7 +198,7 @@ class Swift_DependencyContainer
|
|||
*
|
||||
* @param string $className
|
||||
*
|
||||
* @return Swift_DependencyContainer
|
||||
* @return $this
|
||||
*/
|
||||
public function asNewInstanceOf($className)
|
||||
{
|
||||
|
|
@ -216,7 +216,7 @@ class Swift_DependencyContainer
|
|||
*
|
||||
* @param string $className
|
||||
*
|
||||
* @return Swift_DependencyContainer
|
||||
* @return $this
|
||||
*/
|
||||
public function asSharedInstanceOf($className)
|
||||
{
|
||||
|
|
@ -236,7 +236,7 @@ class Swift_DependencyContainer
|
|||
*
|
||||
* @param array $lookups
|
||||
*
|
||||
* @return Swift_DependencyContainer
|
||||
* @return $this
|
||||
*/
|
||||
public function withDependencies(array $lookups)
|
||||
{
|
||||
|
|
@ -257,7 +257,7 @@ class Swift_DependencyContainer
|
|||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return Swift_DependencyContainer
|
||||
* @return $this
|
||||
*/
|
||||
public function addConstructorValue($value)
|
||||
{
|
||||
|
|
@ -278,7 +278,7 @@ class Swift_DependencyContainer
|
|||
*
|
||||
* @param string $lookup
|
||||
*
|
||||
* @return Swift_DependencyContainer
|
||||
* @return $this
|
||||
*/
|
||||
public function addConstructorLookup($lookup)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -235,8 +235,8 @@ class Swift_Encoder_QpEncoder implements Swift_Encoder
|
|||
/**
|
||||
* Encode the given byte array into a verbatim QP form.
|
||||
*
|
||||
* @param integer[] $bytes
|
||||
* @param int $size
|
||||
* @param int[] $bytes
|
||||
* @param int $size
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
|
@ -262,7 +262,7 @@ class Swift_Encoder_QpEncoder implements Swift_Encoder
|
|||
*
|
||||
* @param int $size number of bytes to read
|
||||
*
|
||||
* @return integer[]
|
||||
* @return int[]
|
||||
*/
|
||||
protected function _nextSequence($size = 4)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -55,8 +55,6 @@ class Swift_Encoding
|
|||
return self::_lookup('mime.base64contentencoder');
|
||||
}
|
||||
|
||||
// -- Private Static Methods
|
||||
|
||||
private static function _lookup($key)
|
||||
{
|
||||
return Swift_DependencyContainer::getInstance()->lookup($key);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class Swift_Events_CommandEvent extends Swift_Events_EventObject
|
|||
/**
|
||||
* An array of codes which a successful response will contain.
|
||||
*
|
||||
* @var integer[]
|
||||
* @var int[]
|
||||
*/
|
||||
private $_successCodes = array();
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ class Swift_Events_CommandEvent extends Swift_Events_EventObject
|
|||
/**
|
||||
* Get the numeric response codes which indicate success for this command.
|
||||
*
|
||||
* @return integer[]
|
||||
* @return int[]
|
||||
*/
|
||||
public function getSuccessCodes()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class Swift_FailoverTransport extends Swift_Transport_FailoverTransport
|
|||
*
|
||||
* @param Swift_Transport[] $transports
|
||||
*
|
||||
* @return Swift_FailoverTransport
|
||||
* @return self
|
||||
*/
|
||||
public static function newInstance($transports = array())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class Swift_Image extends Swift_EmbeddedFile
|
|||
* @param string $filename
|
||||
* @param string $contentType
|
||||
*
|
||||
* @return Swift_Image
|
||||
* @return self
|
||||
*/
|
||||
public static function newInstance($data = null, $filename = null, $contentType = null)
|
||||
{
|
||||
|
|
@ -48,14 +48,10 @@ class Swift_Image extends Swift_EmbeddedFile
|
|||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return Swift_Image
|
||||
* @return self
|
||||
*/
|
||||
public static function fromPath($path)
|
||||
{
|
||||
$image = self::newInstance()->setFile(
|
||||
new Swift_ByteStream_FileByteStream($path)
|
||||
);
|
||||
|
||||
return $image;
|
||||
return self::newInstance()->setFile(new Swift_ByteStream_FileByteStream($path));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class Swift_LoadBalancedTransport extends Swift_Transport_LoadBalancedTransport
|
|||
*
|
||||
* @param array $transports
|
||||
*
|
||||
* @return Swift_LoadBalancedTransport
|
||||
* @return self
|
||||
*/
|
||||
public static function newInstance($transports = array())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class Swift_MailTransport extends Swift_Transport_MailTransport
|
|||
*
|
||||
* @param string $extraParams To be passed to mail()
|
||||
*
|
||||
* @return Swift_MailTransport
|
||||
* @return self
|
||||
*/
|
||||
public static function newInstance($extraParams = '-f%s')
|
||||
{
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class Swift_Mailer
|
|||
*
|
||||
* @param Swift_Transport $transport
|
||||
*
|
||||
* @return Swift_Mailer
|
||||
* @return self
|
||||
*/
|
||||
public static function newInstance(Swift_Transport $transport)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -86,9 +86,7 @@ class Swift_Message extends Swift_Mime_SimpleMessage
|
|||
*/
|
||||
public function addPart($body, $contentType = null, $charset = null)
|
||||
{
|
||||
return $this->attach(Swift_MimePart::newInstance(
|
||||
$body, $contentType, $charset
|
||||
));
|
||||
return $this->attach(Swift_MimePart::newInstance($body, $contentType, $charset)->setEncoder($this->getEncoder()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ class Swift_Mime_Attachment extends Swift_Mime_SimpleMimeEntity
|
|||
*
|
||||
* @param string $disposition
|
||||
*
|
||||
* @return Swift_Mime_Attachment
|
||||
* @return $this
|
||||
*/
|
||||
public function setDisposition($disposition)
|
||||
{
|
||||
|
|
@ -90,7 +90,7 @@ class Swift_Mime_Attachment extends Swift_Mime_SimpleMimeEntity
|
|||
*
|
||||
* @param string $filename
|
||||
*
|
||||
* @return Swift_Mime_Attachment
|
||||
* @return $this
|
||||
*/
|
||||
public function setFilename($filename)
|
||||
{
|
||||
|
|
@ -115,7 +115,7 @@ class Swift_Mime_Attachment extends Swift_Mime_SimpleMimeEntity
|
|||
*
|
||||
* @param int $size
|
||||
*
|
||||
* @return Swift_Mime_Attachment
|
||||
* @return $this
|
||||
*/
|
||||
public function setSize($size)
|
||||
{
|
||||
|
|
@ -130,7 +130,7 @@ class Swift_Mime_Attachment extends Swift_Mime_SimpleMimeEntity
|
|||
* @param Swift_FileStream $file
|
||||
* @param string $contentType optional
|
||||
*
|
||||
* @return Swift_Mime_Attachment
|
||||
* @return $this
|
||||
*/
|
||||
public function setFile(Swift_FileStream $file, $contentType = null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ interface Swift_Mime_HeaderSet extends Swift_Mime_CharsetObserver
|
|||
/**
|
||||
* Create a new instance of this HeaderSet.
|
||||
*
|
||||
* @return Swift_Mime_HeaderSet
|
||||
* @return self
|
||||
*/
|
||||
public function newInstance();
|
||||
|
||||
|
|
|
|||
|
|
@ -219,8 +219,6 @@ abstract class Swift_Mime_Headers_AbstractHeader implements Swift_Mime_Header
|
|||
return $this->toString();
|
||||
}
|
||||
|
||||
// -- Points of extension
|
||||
|
||||
/**
|
||||
* Set the name of this Header field.
|
||||
*
|
||||
|
|
@ -449,7 +447,7 @@ abstract class Swift_Mime_Headers_AbstractHeader implements Swift_Mime_Header
|
|||
*/
|
||||
protected function toTokens($string = null)
|
||||
{
|
||||
if (is_null($string)) {
|
||||
if (null === $string) {
|
||||
$string = $this->getFieldBody();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ class Swift_Mime_Headers_DateHeader extends Swift_Mime_Headers_AbstractHeader
|
|||
*/
|
||||
public function setTimestamp($timestamp)
|
||||
{
|
||||
if (!is_null($timestamp)) {
|
||||
if (null !== $timestamp) {
|
||||
$timestamp = (int) $timestamp;
|
||||
}
|
||||
$this->clearCachedValueIf($this->_timestamp != $timestamp);
|
||||
|
|
|
|||
|
|
@ -231,15 +231,13 @@ class Swift_Mime_Headers_MailboxHeader extends Swift_Mime_Headers_AbstractHeader
|
|||
public function getFieldBody()
|
||||
{
|
||||
// Compute the string value of the header only if needed
|
||||
if (is_null($this->getCachedValue())) {
|
||||
if (null === $this->getCachedValue()) {
|
||||
$this->setCachedValue($this->createMailboxListString($this->_mailboxes));
|
||||
}
|
||||
|
||||
return $this->getCachedValue();
|
||||
}
|
||||
|
||||
// -- Points of extension
|
||||
|
||||
/**
|
||||
* Normalizes a user-input list of mailboxes into consistent key=>value pairs.
|
||||
*
|
||||
|
|
@ -323,7 +321,7 @@ class Swift_Mime_Headers_MailboxHeader extends Swift_Mime_Headers_AbstractHeader
|
|||
|
||||
foreach ($mailboxes as $email => $name) {
|
||||
$mailboxStr = $email;
|
||||
if (!is_null($name)) {
|
||||
if (null !== $name) {
|
||||
$nameStr = $this->createDisplayNameString($name, empty($strings));
|
||||
$mailboxStr = $nameStr.' <'.$mailboxStr.'>';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ class Swift_Mime_Headers_ParameterizedHeader extends Swift_Mime_Headers_Unstruct
|
|||
{
|
||||
$body = parent::getFieldBody();
|
||||
foreach ($this->_params as $name => $value) {
|
||||
if (!is_null($value)) {
|
||||
if (null !== $value) {
|
||||
// Add the parameter
|
||||
$body .= '; '.$this->_createParameter($name, $value);
|
||||
}
|
||||
|
|
@ -156,7 +156,7 @@ class Swift_Mime_Headers_ParameterizedHeader extends Swift_Mime_Headers_Unstruct
|
|||
|
||||
// Try creating any parameters
|
||||
foreach ($this->_params as $name => $value) {
|
||||
if (!is_null($value)) {
|
||||
if (null !== $value) {
|
||||
// Add the semi-colon separator
|
||||
$tokens[count($tokens) - 1] .= ';';
|
||||
$tokens = array_merge($tokens, $this->generateTokenLines(
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ class Swift_Mime_Headers_PathHeader extends Swift_Mime_Headers_AbstractHeader
|
|||
*/
|
||||
public function setAddress($address)
|
||||
{
|
||||
if (is_null($address)) {
|
||||
if (null === $address) {
|
||||
$this->_address = null;
|
||||
} elseif ('' == $address) {
|
||||
$this->_address = '';
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class Swift_Mime_MimePart extends Swift_Mime_SimpleMimeEntity
|
|||
{
|
||||
parent::__construct($headers, $encoder, $cache, $grammar);
|
||||
$this->setContentType('text/plain');
|
||||
if (!is_null($charset)) {
|
||||
if (null !== $charset) {
|
||||
$this->setCharset($charset);
|
||||
}
|
||||
}
|
||||
|
|
@ -53,7 +53,7 @@ class Swift_Mime_MimePart extends Swift_Mime_SimpleMimeEntity
|
|||
* @param string $contentType optional
|
||||
* @param string $charset optional
|
||||
*
|
||||
* @return Swift_Mime_MimePart
|
||||
* @return $this
|
||||
*/
|
||||
public function setBody($body, $contentType = null, $charset = null)
|
||||
{
|
||||
|
|
@ -82,7 +82,7 @@ class Swift_Mime_MimePart extends Swift_Mime_SimpleMimeEntity
|
|||
*
|
||||
* @param string $charset
|
||||
*
|
||||
* @return Swift_Mime_MimePart
|
||||
* @return $this
|
||||
*/
|
||||
public function setCharset($charset)
|
||||
{
|
||||
|
|
@ -111,7 +111,7 @@ class Swift_Mime_MimePart extends Swift_Mime_SimpleMimeEntity
|
|||
*
|
||||
* @param string $format
|
||||
*
|
||||
* @return Swift_Mime_MimePart
|
||||
* @return $this
|
||||
*/
|
||||
public function setFormat($format)
|
||||
{
|
||||
|
|
@ -136,7 +136,7 @@ class Swift_Mime_MimePart extends Swift_Mime_SimpleMimeEntity
|
|||
*
|
||||
* @param bool $delsp
|
||||
*
|
||||
* @return Swift_Mime_MimePart
|
||||
* @return $this
|
||||
*/
|
||||
public function setDelSp($delsp = true)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ class Swift_Mime_SimpleHeaderSet implements Swift_Mime_HeaderSet
|
|||
/**
|
||||
* Create a new instance of this HeaderSet.
|
||||
*
|
||||
* @return Swift_Mime_HeaderSet
|
||||
* @return self
|
||||
*/
|
||||
public function newInstance()
|
||||
{
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue