diff --git a/.travis.yml b/.travis.yml index 2e69c1b..1614cb5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,20 +1,16 @@ language: php php: + - 7.2 - 7.1 - 7.0 - 5.6 - - 5.5 - - 5.4 - - 5.3 - hhvm matrix: fast_finish: true allow_failures: - - php: 5.5 - - php: 5.4 - - php: 5.3 + - php: 5.6 - php: hhvm before_script: diff --git a/composer.json b/composer.json index f55db82..5be4fa9 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ } ], "require": { - "php": "^5.3 || ^7.0" + "php": "^5.6 || ^7.0" }, "require-dev": { "phpunit/phpunit": "*", diff --git a/composer.lock b/composer.lock index 6bda008..3491f91 100644 --- a/composer.lock +++ b/composer.lock @@ -4,38 +4,37 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "60a0e37a2b61f595676bc1686d94ba4a", "content-hash": "6bd0292f467cd9a167b1eaa4839038e8", "packages": [], "packages-dev": [ { "name": "doctrine/instantiator", - "version": "1.0.5", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", "shasum": "" }, "require": { - "php": ">=5.3,<8.0-DEV" + "php": "^7.1" }, "require-dev": { "athletic/athletic": "~0.1.8", "ext-pdo": "*", "ext-phar": "*", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.0" + "phpunit/phpunit": "^6.2.3", + "squizlabs/php_codesniffer": "^3.0.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.2.x-dev" } }, "autoload": { @@ -60,73 +59,47 @@ "constructor", "instantiate" ], - "time": "2015-06-14 21:17:01" + "time": "2017-07-22T11:58:36+00:00" }, { - "name": "guzzle/guzzle", - "version": "v3.9.3", + "name": "guzzlehttp/guzzle", + "version": "6.3.0", "source": { "type": "git", - "url": "https://github.com/guzzle/guzzle3.git", - "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9" + "url": "https://github.com/guzzle/guzzle.git", + "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/0645b70d953bc1c067bbc8d5bc53194706b628d9", - "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f4db5a78a5ea468d4831de7f0bf9d9415e348699", + "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699", "shasum": "" }, "require": { - "ext-curl": "*", - "php": ">=5.3.3", - "symfony/event-dispatcher": "~2.1" - }, - "replace": { - "guzzle/batch": "self.version", - "guzzle/cache": "self.version", - "guzzle/common": "self.version", - "guzzle/http": "self.version", - "guzzle/inflection": "self.version", - "guzzle/iterator": "self.version", - "guzzle/log": "self.version", - "guzzle/parser": "self.version", - "guzzle/plugin": "self.version", - "guzzle/plugin-async": "self.version", - "guzzle/plugin-backoff": "self.version", - "guzzle/plugin-cache": "self.version", - "guzzle/plugin-cookie": "self.version", - "guzzle/plugin-curlauth": "self.version", - "guzzle/plugin-error-response": "self.version", - "guzzle/plugin-history": "self.version", - "guzzle/plugin-log": "self.version", - "guzzle/plugin-md5": "self.version", - "guzzle/plugin-mock": "self.version", - "guzzle/plugin-oauth": "self.version", - "guzzle/service": "self.version", - "guzzle/stream": "self.version" + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.4", + "php": ">=5.5" }, "require-dev": { - "doctrine/cache": "~1.3", - "monolog/monolog": "~1.0", - "phpunit/phpunit": "3.7.*", - "psr/log": "~1.0", - "symfony/class-loader": "~2.1", - "zendframework/zend-cache": "2.*,<2.3", - "zendframework/zend-log": "2.*,<2.3" + "ext-curl": "*", + "phpunit/phpunit": "^4.0 || ^5.0", + "psr/log": "^1.0" }, "suggest": { - "guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated." + "psr/log": "Required for using the Log middleware" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.9-dev" + "dev-master": "6.2-dev" } }, "autoload": { - "psr-0": { - "Guzzle": "src/", - "Guzzle\\Tests": "tests/" + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -138,13 +111,9 @@ "name": "Michael Dowling", "email": "mtdowling@gmail.com", "homepage": "https://github.com/mtdowling" - }, - { - "name": "Guzzle Community", - "homepage": "https://github.com/guzzle/guzzle/contributors" } ], - "description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle", + "description": "Guzzle is a PHP HTTP client library", "homepage": "http://guzzlephp.org/", "keywords": [ "client", @@ -155,41 +124,160 @@ "rest", "web service" ], - "time": "2015-03-18 18:23:50" + "time": "2017-06-22T18:50:49+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "shasum": "" + }, + "require": { + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "time": "2016-12-20T10:07:11+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c", + "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "request", + "response", + "stream", + "uri", + "url" + ], + "time": "2017-03-20T17:10:46+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.5.1", + "version": "1.7.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "a8773992b362b58498eed24bf85005f363c34771" + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/a8773992b362b58498eed24bf85005f363c34771", - "reference": "a8773992b362b58498eed24bf85005f363c34771", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", "shasum": "" }, "require": { - "php": ">=5.4.0" + "php": "^5.6 || ^7.0" }, "require-dev": { - "doctrine/collections": "1.*", - "phpunit/phpunit": "~4.1" + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^4.1" }, "type": "library", "autoload": { "psr-4": { "DeepCopy\\": "src/DeepCopy/" - } + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "description": "Create deep copies (clones) of your objects", - "homepage": "https://github.com/myclabs/DeepCopy", "keywords": [ "clone", "copy", @@ -197,20 +285,122 @@ "object", "object graph" ], - "time": "2015-11-20 12:04:31" + "time": "2017-10-19T19:58:43+00:00" + }, + { + "name": "phar-io/manifest", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^1.0.1", + "php": "^5.6 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "time": "2017-03-05T18:14:27+00:00" + }, + { + "name": "phar-io/version", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "time": "2017-03-05T17:38:23+00:00" }, { "name": "phpdocumentor/reflection-common", - "version": "1.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c" + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c", - "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", "shasum": "" }, "require": { @@ -251,33 +441,39 @@ "reflection", "static analysis" ], - "time": "2015-12-27 11:43:31" + "time": "2017-09-11T18:02:19+00:00" }, { "name": "phpdocumentor/reflection-docblock", - "version": "3.1.0", + "version": "4.3.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "9270140b940ff02e58ec577c237274e92cd40cdd" + "reference": "94fd0001232e47129dd3504189fa1c7225010d08" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/9270140b940ff02e58ec577c237274e92cd40cdd", - "reference": "9270140b940ff02e58ec577c237274e92cd40cdd", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", + "reference": "94fd0001232e47129dd3504189fa1c7225010d08", "shasum": "" }, "require": { - "php": ">=5.5", - "phpdocumentor/reflection-common": "^1.0@dev", - "phpdocumentor/type-resolver": "^0.2.0", + "php": "^7.0", + "phpdocumentor/reflection-common": "^1.0.0", + "phpdocumentor/type-resolver": "^0.4.0", "webmozart/assert": "^1.0" }, "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^4.4" + "doctrine/instantiator": "~1.0.5", + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^6.4" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, "autoload": { "psr-4": { "phpDocumentor\\Reflection\\": [ @@ -296,24 +492,24 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2016-06-10 09:48:41" + "time": "2017-11-30T07:14:17+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "0.2", + "version": "0.4.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443" + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b39c7a5b194f9ed7bd0dd345c751007a41862443", - "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", "shasum": "" }, "require": { - "php": ">=5.5", + "php": "^5.5 || ^7.0", "phpdocumentor/reflection-common": "^1.0" }, "require-dev": { @@ -343,36 +539,37 @@ "email": "me@mikevanriel.com" } ], - "time": "2016-06-10 07:14:17" + "time": "2017-07-14T14:27:02+00:00" }, { "name": "phpspec/prophecy", - "version": "v1.6.1", + "version": "1.7.5", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "58a8137754bc24b25740d4281399a4a3596058e0" + "reference": "dfd6be44111a7c41c2e884a336cc4f461b3b2401" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/58a8137754bc24b25740d4281399a4a3596058e0", - "reference": "58a8137754bc24b25740d4281399a4a3596058e0", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/dfd6be44111a7c41c2e884a336cc4f461b3b2401", + "reference": "dfd6be44111a7c41c2e884a336cc4f461b3b2401", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", - "sebastian/comparator": "^1.1", - "sebastian/recursion-context": "^1.0" + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", + "sebastian/comparator": "^1.1|^2.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" }, "require-dev": { - "phpspec/phpspec": "^2.0" + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.6.x-dev" + "dev-master": "1.7.x-dev" } }, "autoload": { @@ -405,44 +602,44 @@ "spy", "stub" ], - "time": "2016-06-07 08:13:47" + "time": "2018-02-19T10:16:54+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "4.0.0", + "version": "6.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "900370c81280cc0d942ffbc5912d80464eaee7e9" + "reference": "f8ca4b604baf23dab89d87773c28cc07405189ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/900370c81280cc0d942ffbc5912d80464eaee7e9", - "reference": "900370c81280cc0d942ffbc5912d80464eaee7e9", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f8ca4b604baf23dab89d87773c28cc07405189ba", + "reference": "f8ca4b604baf23dab89d87773c28cc07405189ba", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0", - "phpunit/php-file-iterator": "~1.3", - "phpunit/php-text-template": "~1.2", - "phpunit/php-token-stream": "^1.4.2", - "sebastian/code-unit-reverse-lookup": "~1.0", - "sebastian/environment": "^1.3.2", - "sebastian/version": "~1.0|~2.0" + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^7.1", + "phpunit/php-file-iterator": "^1.4.2", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-token-stream": "^3.0", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^3.0", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1" }, "require-dev": { - "ext-xdebug": ">=2.1.4", - "phpunit/phpunit": "^5.4" + "phpunit/phpunit": "^7.0" }, "suggest": { - "ext-dom": "*", - "ext-xdebug": ">=2.4.0", - "ext-xmlwriter": "*" + "ext-xdebug": "^2.6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0.x-dev" + "dev-master": "6.0-dev" } }, "autoload": { @@ -457,7 +654,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -468,20 +665,20 @@ "testing", "xunit" ], - "time": "2016-06-03 05:03:56" + "time": "2018-02-02T07:01:41+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "1.4.1", + "version": "1.4.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", "shasum": "" }, "require": { @@ -515,7 +712,7 @@ "filesystem", "iterator" ], - "time": "2015-06-21 13:08:43" + "time": "2017-11-27T13:52:08+00:00" }, { "name": "phpunit/php-text-template", @@ -556,29 +753,34 @@ "keywords": [ "template" ], - "time": "2015-06-21 13:50:34" + "time": "2015-06-21T13:50:34+00:00" }, { "name": "phpunit/php-timer", - "version": "1.0.8", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260" + "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260", - "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8b8454ea6958c3dee38453d3bd571e023108c91f", + "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "~4|~5" + "phpunit/phpunit": "^7.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, "autoload": { "classmap": [ "src/" @@ -591,7 +793,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -600,33 +802,33 @@ "keywords": [ "timer" ], - "time": "2016-05-12 18:03:57" + "time": "2018-02-01T13:07:23+00:00" }, { "name": "phpunit/php-token-stream", - "version": "1.4.8", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" + "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", - "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/21ad88bbba7c3d93530d93994e0a33cd45f02ace", + "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": ">=5.3.3" + "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "~4.2" + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -649,51 +851,53 @@ "keywords": [ "tokenizer" ], - "time": "2015-09-15 10:49:45" + "time": "2018-02-01T13:16:43+00:00" }, { "name": "phpunit/phpunit", - "version": "5.4.4", + "version": "7.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "02d5b64aa0837a038a5a4faeeefa5ef44bdcb928" + "reference": "e2f8aa21bc54b6ba218bdd4f9e0dac1e9bc3b4e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/02d5b64aa0837a038a5a4faeeefa5ef44bdcb928", - "reference": "02d5b64aa0837a038a5a4faeeefa5ef44bdcb928", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e2f8aa21bc54b6ba218bdd4f9e0dac1e9bc3b4e9", + "reference": "e2f8aa21bc54b6ba218bdd4f9e0dac1e9bc3b4e9", "shasum": "" }, "require": { "ext-dom": "*", "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "myclabs/deep-copy": "~1.3", - "php": "^5.6 || ^7.0", - "phpspec/prophecy": "^1.3.1", - "phpunit/php-code-coverage": "^4.0", - "phpunit/php-file-iterator": "~1.4", - "phpunit/php-text-template": "~1.2", - "phpunit/php-timer": "^1.0.6", - "phpunit/phpunit-mock-objects": "^3.2", - "sebastian/comparator": "~1.1", - "sebastian/diff": "~1.2", - "sebastian/environment": "~1.3", - "sebastian/exporter": "~1.2", - "sebastian/global-state": "~1.0", - "sebastian/object-enumerator": "~1.0", - "sebastian/resource-operations": "~1.0", - "sebastian/version": "~1.0|~2.0", - "symfony/yaml": "~2.1|~3.0" + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "^1.6.1", + "phar-io/manifest": "^1.0.1", + "phar-io/version": "^1.0", + "php": "^7.1", + "phpspec/prophecy": "^1.7", + "phpunit/php-code-coverage": "^6.0", + "phpunit/php-file-iterator": "^1.4.3", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-timer": "^2.0", + "phpunit/phpunit-mock-objects": "^6.0", + "sebastian/comparator": "^2.1", + "sebastian/diff": "^3.0", + "sebastian/environment": "^3.1", + "sebastian/exporter": "^3.1", + "sebastian/global-state": "^2.0", + "sebastian/object-enumerator": "^3.0.3", + "sebastian/resource-operations": "^1.0", + "sebastian/version": "^2.0.1" }, - "conflict": { - "phpdocumentor/reflection-docblock": "3.0.2" + "require-dev": { + "ext-pdo": "*" }, "suggest": { - "phpunit/php-invoker": "~1.1" + "ext-xdebug": "*", + "phpunit/php-invoker": "^2.0" }, "bin": [ "phpunit" @@ -701,7 +905,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.4.x-dev" + "dev-master": "7.0-dev" } }, "autoload": { @@ -727,33 +931,30 @@ "testing", "xunit" ], - "time": "2016-06-09 09:09:27" + "time": "2018-02-26T07:03:12+00:00" }, { "name": "phpunit/phpunit-mock-objects", - "version": "3.2.3", + "version": "6.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "b13d0d9426ced06958bd32104653526a6c998a52" + "reference": "e3249dedc2d99259ccae6affbc2684eac37c2e53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/b13d0d9426ced06958bd32104653526a6c998a52", - "reference": "b13d0d9426ced06958bd32104653526a6c998a52", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/e3249dedc2d99259ccae6affbc2684eac37c2e53", + "reference": "e3249dedc2d99259ccae6affbc2684eac37c2e53", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.6 || ^7.0", - "phpunit/php-text-template": "^1.2", - "sebastian/exporter": "^1.2" - }, - "conflict": { - "phpunit/phpunit": "<5.4.0" + "doctrine/instantiator": "^1.0.5", + "php": "^7.1", + "phpunit/php-text-template": "^1.2.1", + "sebastian/exporter": "^3.1" }, "require-dev": { - "phpunit/phpunit": "^5.4" + "phpunit/phpunit": "^7.0" }, "suggest": { "ext-soap": "*" @@ -761,7 +962,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.2.x-dev" + "dev-master": "6.0.x-dev" } }, "autoload": { @@ -776,7 +977,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -786,26 +987,84 @@ "mock", "xunit" ], - "time": "2016-06-12 07:37:26" + "time": "2018-02-15T05:27:38+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06T14:39:51+00:00" }, { "name": "psr/log", - "version": "1.0.0", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", "shasum": "" }, + "require": { + "php": ">=5.3.0" + }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, "autoload": { - "psr-0": { - "Psr\\Log\\": "" + "psr-4": { + "Psr\\Log\\": "Psr/Log/" } }, "notification-url": "https://packagist.org/downloads/", @@ -819,48 +1078,57 @@ } ], "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", "keywords": [ "log", "psr", "psr-3" ], - "time": "2012-12-21 11:40:51" + "time": "2016-10-10T12:19:37+00:00" }, { "name": "satooshi/php-coveralls", - "version": "v1.0.1", + "version": "v2.0.0", "source": { "type": "git", - "url": "https://github.com/satooshi/php-coveralls.git", - "reference": "da51d304fe8622bf9a6da39a8446e7afd432115c" + "url": "https://github.com/php-coveralls/php-coveralls.git", + "reference": "3eaf7eb689cdf6b86801a3843940d974dc657068" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/satooshi/php-coveralls/zipball/da51d304fe8622bf9a6da39a8446e7afd432115c", - "reference": "da51d304fe8622bf9a6da39a8446e7afd432115c", + "url": "https://api.github.com/repos/php-coveralls/php-coveralls/zipball/3eaf7eb689cdf6b86801a3843940d974dc657068", + "reference": "3eaf7eb689cdf6b86801a3843940d974dc657068", "shasum": "" }, "require": { "ext-json": "*", "ext-simplexml": "*", - "guzzle/guzzle": "^2.8|^3.0", - "php": ">=5.3.3", + "guzzlehttp/guzzle": "^6.0", + "php": "^5.5 || ^7.0", "psr/log": "^1.0", - "symfony/config": "^2.1|^3.0", - "symfony/console": "^2.1|^3.0", - "symfony/stopwatch": "^2.0|^3.0", - "symfony/yaml": "^2.0|^3.0" + "symfony/config": "^2.1 || ^3.0 || ^4.0", + "symfony/console": "^2.1 || ^3.0 || ^4.0", + "symfony/stopwatch": "^2.0 || ^3.0 || ^4.0", + "symfony/yaml": "^2.0 || ^3.0 || ^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.4.3 || ^6.0" }, "suggest": { "symfony/http-kernel": "Allows Symfony integration" }, "bin": [ - "bin/coveralls" + "bin/php-coveralls" ], "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, "autoload": { "psr-4": { - "Satooshi\\": "src/Satooshi/" + "PhpCoveralls\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -871,38 +1139,55 @@ { "name": "Kitamura Satoshi", "email": "with.no.parachute@gmail.com", - "homepage": "https://www.facebook.com/satooshi.jp" + "homepage": "https://www.facebook.com/satooshi.jp", + "role": "Original creator" + }, + { + "name": "Takashi Matsuo", + "email": "tmatsuo@google.com" + }, + { + "name": "Google Inc" + }, + { + "name": "Dariusz Ruminski", + "email": "dariusz.ruminski@gmail.com", + "homepage": "https://github.com/keradus" + }, + { + "name": "Contributors", + "homepage": "https://github.com/php-coveralls/php-coveralls/graphs/contributors" } ], "description": "PHP client library for Coveralls API", - "homepage": "https://github.com/satooshi/php-coveralls", + "homepage": "https://github.com/php-coveralls/php-coveralls", "keywords": [ "ci", "coverage", "github", "test" ], - "time": "2016-01-20 17:35:46" + "time": "2017-12-08T14:28:16+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe" + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/c36f5e7cfce482fde5bf8d10d41a53591e0198fe", - "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", "shasum": "" }, "require": { - "php": ">=5.6" + "php": "^5.6 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "~5" + "phpunit/phpunit": "^5.7 || ^6.0" }, "type": "library", "extra": { @@ -927,34 +1212,34 @@ ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2016-02-13 06:45:14" + "time": "2017-03-04T06:30:41+00:00" }, { "name": "sebastian/comparator", - "version": "1.2.0", + "version": "2.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" + "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", - "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/34369daee48eafb2651bea869b4b15d75ccc35f9", + "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9", "shasum": "" }, "require": { - "php": ">=5.3.3", - "sebastian/diff": "~1.2", - "sebastian/exporter": "~1.2" + "php": "^7.0", + "sebastian/diff": "^2.0 || ^3.0", + "sebastian/exporter": "^3.1" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^6.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "2.1.x-dev" } }, "autoload": { @@ -985,38 +1270,39 @@ } ], "description": "Provides the functionality to compare PHP values for equality", - "homepage": "http://www.github.com/sebastianbergmann/comparator", + "homepage": "https://github.com/sebastianbergmann/comparator", "keywords": [ "comparator", "compare", "equality" ], - "time": "2015-07-26 15:48:44" + "time": "2018-02-01T13:46:46+00:00" }, { "name": "sebastian/diff", - "version": "1.4.1", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" + "reference": "e09160918c66281713f1c324c1f4c4c3037ba1e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", - "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/e09160918c66281713f1c324c1f4c4c3037ba1e8", + "reference": "e09160918c66281713f1c324c1f4c4c3037ba1e8", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "~4.8" + "phpunit/phpunit": "^7.0", + "symfony/process": "^2 || ^3.3 || ^4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -1041,34 +1327,37 @@ "description": "Diff implementation", "homepage": "https://github.com/sebastianbergmann/diff", "keywords": [ - "diff" + "diff", + "udiff", + "unidiff", + "unified diff" ], - "time": "2015-12-08 07:14:41" + "time": "2018-02-01T13:45:15+00:00" }, { "name": "sebastian/environment", - "version": "1.3.7", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716" + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/4e8f0da10ac5802913afc151413bc8c53b6c2716", - "reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^6.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-master": "3.1.x-dev" } }, "autoload": { @@ -1093,33 +1382,34 @@ "environment", "hhvm" ], - "time": "2016-05-17 03:18:57" + "time": "2017-07-01T08:51:00+00:00" }, { "name": "sebastian/exporter", - "version": "1.2.1", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "7ae5513327cb536431847bcc0c10edba2701064e" + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e", - "reference": "7ae5513327cb536431847bcc0c10edba2701064e", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", "shasum": "" }, "require": { - "php": ">=5.3.3", - "sebastian/recursion-context": "~1.0" + "php": "^7.0", + "sebastian/recursion-context": "^3.0" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "ext-mbstring": "*", + "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "3.1.x-dev" } }, "autoload": { @@ -1159,27 +1449,27 @@ "export", "exporter" ], - "time": "2015-06-21 07:55:53" + "time": "2017-04-03T13:19:02+00:00" }, { "name": "sebastian/global-state", - "version": "1.1.1", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.2" + "phpunit/phpunit": "^6.0" }, "suggest": { "ext-uopz": "*" @@ -1187,7 +1477,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -1210,33 +1500,34 @@ "keywords": [ "global state" ], - "time": "2015-10-12 03:26:01" + "time": "2017-04-27T15:39:26+00:00" }, { "name": "sebastian/object-enumerator", - "version": "1.0.0", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "d4ca2fb70344987502567bc50081c03e6192fb26" + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/d4ca2fb70344987502567bc50081c03e6192fb26", - "reference": "d4ca2fb70344987502567bc50081c03e6192fb26", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", "shasum": "" }, "require": { - "php": ">=5.6", - "sebastian/recursion-context": "~1.0" + "php": "^7.0", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" }, "require-dev": { - "phpunit/phpunit": "~5" + "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "3.0.x-dev" } }, "autoload": { @@ -1256,32 +1547,77 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2016-01-28 13:25:10" + "time": "2017-08-03T12:35:26+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "773f97c67f28de00d397be301821b06708fca0be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", + "reference": "773f97c67f28de00d397be301821b06708fca0be", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "time": "2017-03-29T09:07:27+00:00" }, { "name": "sebastian/recursion-context", - "version": "1.0.2", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "913401df809e99e4f47b27cdd781f4a258d58791" + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791", - "reference": "913401df809e99e4f47b27cdd781f4a258d58791", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "3.0.x-dev" } }, "autoload": { @@ -1309,7 +1645,7 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2015-11-11 19:50:13" + "time": "2017-03-03T06:23:57+00:00" }, { "name": "sebastian/resource-operations", @@ -1351,20 +1687,20 @@ ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2015-07-28 20:34:47" + "time": "2015-07-28T20:34:47+00:00" }, { "name": "sebastian/version", - "version": "2.0.0", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5" + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", - "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", "shasum": "" }, "require": { @@ -1394,25 +1730,34 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-02-04 12:56:52" + "time": "2016-10-03T07:35:21+00:00" }, { "name": "symfony/config", - "version": "v3.1.0", + "version": "v4.0.6", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "048dc47e07f92333203c3b7045868bbc864fc40e" + "reference": "289eadd3771f7682ea2540e4925861c18ec5b4d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/048dc47e07f92333203c3b7045868bbc864fc40e", - "reference": "048dc47e07f92333203c3b7045868bbc864fc40e", + "url": "https://api.github.com/repos/symfony/config/zipball/289eadd3771f7682ea2540e4925861c18ec5b4d0", + "reference": "289eadd3771f7682ea2540e4925861c18ec5b4d0", "shasum": "" }, "require": { - "php": ">=5.5.9", - "symfony/filesystem": "~2.8|~3.0" + "php": "^7.1.3", + "symfony/filesystem": "~3.4|~4.0" + }, + "conflict": { + "symfony/finder": "<3.4" + }, + "require-dev": { + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~3.4|~4.0", + "symfony/finder": "~3.4|~4.0", + "symfony/yaml": "~3.4|~4.0" }, "suggest": { "symfony/yaml": "To use the yaml reference dumper" @@ -1420,7 +1765,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1447,40 +1792,48 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2016-05-20 11:48:17" + "time": "2018-02-04T16:43:51+00:00" }, { "name": "symfony/console", - "version": "v3.1.0", + "version": "v4.0.6", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "f62db5b8afec27073a4609b8c84b1f9936652259" + "reference": "555c8dbe0ae9e561740451eabdbed2cc554b6a51" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/f62db5b8afec27073a4609b8c84b1f9936652259", - "reference": "f62db5b8afec27073a4609b8c84b1f9936652259", + "url": "https://api.github.com/repos/symfony/console/zipball/555c8dbe0ae9e561740451eabdbed2cc554b6a51", + "reference": "555c8dbe0ae9e561740451eabdbed2cc554b6a51", "shasum": "" }, "require": { - "php": ">=5.5.9", + "php": "^7.1.3", "symfony/polyfill-mbstring": "~1.0" }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/process": "<3.3" + }, "require-dev": { "psr/log": "~1.0", - "symfony/event-dispatcher": "~2.8|~3.0", - "symfony/process": "~2.8|~3.0" + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~3.4|~4.0", + "symfony/lock": "~3.4|~4.0", + "symfony/process": "~3.4|~4.0" }, "suggest": { "psr/log": "For using the console logger", "symfony/event-dispatcher": "", + "symfony/lock": "", "symfony/process": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1507,89 +1860,29 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2016-05-30 06:58:39" - }, - { - "name": "symfony/event-dispatcher", - "version": "v2.8.7", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "2a6b8713f8bdb582058cfda463527f195b066110" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/2a6b8713f8bdb582058cfda463527f195b066110", - "reference": "2a6b8713f8bdb582058cfda463527f195b066110", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "~2.0,>=2.0.5|~3.0.0", - "symfony/dependency-injection": "~2.6|~3.0.0", - "symfony/expression-language": "~2.6|~3.0.0", - "symfony/stopwatch": "~2.3|~3.0.0" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.8-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" - }, - "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 EventDispatcher Component", - "homepage": "https://symfony.com", - "time": "2016-06-06 11:11:27" + "time": "2018-02-26T15:55:47+00:00" }, { "name": "symfony/filesystem", - "version": "v3.1.0", + "version": "v4.0.6", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "5751e80d6f94b7c018f338a4a7be0b700d6f3058" + "reference": "5d2d655b2c72fc4d9bf7e9bf14f72a447b940f21" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/5751e80d6f94b7c018f338a4a7be0b700d6f3058", - "reference": "5751e80d6f94b7c018f338a4a7be0b700d6f3058", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/5d2d655b2c72fc4d9bf7e9bf14f72a447b940f21", + "reference": "5d2d655b2c72fc4d9bf7e9bf14f72a447b940f21", "shasum": "" }, "require": { - "php": ">=5.5.9" + "php": "^7.1.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1616,20 +1909,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2016-04-12 18:27:47" + "time": "2018-02-22T10:50:29+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.2.0", + "version": "v1.7.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "dff51f72b0706335131b00a7f49606168c582594" + "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/dff51f72b0706335131b00a7f49606168c582594", - "reference": "dff51f72b0706335131b00a7f49606168c582594", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/78be803ce01e55d3491c1397cf1c64beb9c1b63b", + "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b", "shasum": "" }, "require": { @@ -1641,7 +1934,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2-dev" + "dev-master": "1.7-dev" } }, "autoload": { @@ -1675,29 +1968,29 @@ "portable", "shim" ], - "time": "2016-05-18 14:26:46" + "time": "2018-01-30T19:27:44+00:00" }, { "name": "symfony/stopwatch", - "version": "v3.1.0", + "version": "v4.0.6", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "4670f122fa32a4900003a6802f6b8575f3f0b17e" + "reference": "6795ffa2f8eebedac77f045aa62c0c10b2763042" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/4670f122fa32a4900003a6802f6b8575f3f0b17e", - "reference": "4670f122fa32a4900003a6802f6b8575f3f0b17e", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/6795ffa2f8eebedac77f045aa62c0c10b2763042", + "reference": "6795ffa2f8eebedac77f045aa62c0c10b2763042", "shasum": "" }, "require": { - "php": ">=5.5.9" + "php": "^7.1.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1724,29 +2017,38 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com", - "time": "2016-03-04 07:56:56" + "time": "2018-02-19T16:50:22+00:00" }, { "name": "symfony/yaml", - "version": "v3.1.0", + "version": "v4.0.6", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "eca51b7b65eb9be6af88ad7cc91685f1556f5c9a" + "reference": "de5f125ea39de846b90b313b2cfb031a0152d223" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/eca51b7b65eb9be6af88ad7cc91685f1556f5c9a", - "reference": "eca51b7b65eb9be6af88ad7cc91685f1556f5c9a", + "url": "https://api.github.com/repos/symfony/yaml/zipball/de5f125ea39de846b90b313b2cfb031a0152d223", + "reference": "de5f125ea39de846b90b313b2cfb031a0152d223", "shasum": "" }, "require": { - "php": ">=5.5.9" + "php": "^7.1.3" + }, + "conflict": { + "symfony/console": "<3.4" + }, + "require-dev": { + "symfony/console": "~3.4|~4.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1773,32 +2075,73 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2016-05-26 21:46:24" + "time": "2018-02-19T20:08:53+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "time": "2017-04-07T12:08:54+00:00" }, { "name": "webmozart/assert", - "version": "1.0.2", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", - "reference": "30eed06dd6bc88410a4ff7f77b6d22f3ce13dbde" + "reference": "0df1908962e7a3071564e857d86874dad1ef204a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/30eed06dd6bc88410a4ff7f77b6d22f3ce13dbde", - "reference": "30eed06dd6bc88410a4ff7f77b6d22f3ce13dbde", + "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^5.3.3 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "^4.6" + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "1.3-dev" } }, "autoload": { @@ -1822,7 +2165,7 @@ "check", "validate" ], - "time": "2015-08-24 13:29:44" + "time": "2018-01-29T19:49:41+00:00" } ], "aliases": [], diff --git a/src/Matcher.php b/src/Matcher.php index 3d51af7..c9eff74 100644 --- a/src/Matcher.php +++ b/src/Matcher.php @@ -2,54 +2,48 @@ namespace ZxcvbnPhp; -use ZxcvbnPhp\Matchers\MatchInterface; - class Matcher { - /** * Get matches for a password. * - * @param string $password - * Password string to match. - * @param array $userInputs - * Array of values related to the user (optional). - * @code - * array('Alice Smith') + * @param string $password Password string to match + * @param array $userInputs Array of values related to the user (optional) + * @code array('Alice Smith') * @endcode - * @return array - * Array of Match objects. + * + * @return array Array of Match objects */ - public function getMatches($password, array $userInputs = array()) + public function getMatches($password, array $userInputs = []) { - $matches = array(); + $matches = []; foreach ($this->getMatchers() as $matcher) { $matched = $matcher::match($password, $userInputs); if (is_array($matched) && !empty($matched)) { $matches = array_merge($matches, $matched); } } + return $matches; } /** * Load available Match objects to match against a password. * - * @return array - * Array of classes implementing MatchInterface + * @return array Array of classes implementing MatchInterface */ protected function getMatchers() { // @todo change to dynamic - return array( - 'ZxcvbnPhp\Matchers\DateMatch', - 'ZxcvbnPhp\Matchers\DigitMatch', - 'ZxcvbnPhp\Matchers\L33tMatch', - 'ZxcvbnPhp\Matchers\RepeatMatch', - 'ZxcvbnPhp\Matchers\SequenceMatch', - 'ZxcvbnPhp\Matchers\SpatialMatch', - 'ZxcvbnPhp\Matchers\YearMatch', - 'ZxcvbnPhp\Matchers\DictionaryMatch', - ); + return [ + Matchers\DateMatch::class, + Matchers\DigitMatch::class, + Matchers\L33tMatch::class, + Matchers\RepeatMatch::class, + Matchers\SequenceMatch::class, + Matchers\SpatialMatch::class, + Matchers\YearMatch::class, + Matchers\DictionaryMatch::class, + ]; } -} \ No newline at end of file +} diff --git a/src/Matchers/Bruteforce.php b/src/Matchers/Bruteforce.php index 4b37c4e..9e4cb05 100644 --- a/src/Matchers/Bruteforce.php +++ b/src/Matchers/Bruteforce.php @@ -1,30 +1,12 @@ entropy)) { - $this->entropy = $this->log(pow($this->getCardinality(), strlen($this->token))); + if (null === $this->entropy) { + $this->entropy = $this->log($this->getCardinality() ** strlen($this->token)); } + return $this->entropy; } -} \ No newline at end of file +} diff --git a/src/Matchers/DateMatch.php b/src/Matchers/DateMatch.php index 08613b5..9af8234 100644 --- a/src/Matchers/DateMatch.php +++ b/src/Matchers/DateMatch.php @@ -4,7 +4,6 @@ class DateMatch extends Match { - const NUM_YEARS = 119; // Years match against 1900 - 2019 const NUM_MONTHS = 12; const NUM_DAYS = 31; @@ -32,28 +31,13 @@ class DateMatch extends Match */ public $separator; - /** - * Match occurences of dates in a password - * - * @copydoc Match::match() - */ - public static function match($password, array $userInputs = array()) - { - $matches = array(); - $dates = static::datesWithoutSeparators($password) + static::datesWithSeparators($password); - foreach ($dates as $date) { - $matches[] = new static($password, $date['begin'], $date['end'], $date['token'], $date); - } - return $matches; - } - /** * @param $password * @param $begin * @param $end * @param $token * @param array $params - * Array with keys: day, month, year, separator. + * Array with keys: day, month, year, separator */ public function __construct($password, $begin, $end, $token, $params) { @@ -65,6 +49,27 @@ public function __construct($password, $begin, $end, $token, $params) $this->separator = $params['separator']; } + /** + * Match occurences of dates in a password. + * + * @copydoc Match::match() + * + * @param $password + * @param array $userInputs + * + * @return array + */ + public static function match($password, array $userInputs = []) + { + $matches = []; + $dates = static::datesWithoutSeparators($password) + static::datesWithSeparators($password); + foreach ($dates as $date) { + $matches[] = new static($password, $date['begin'], $date['end'], $date['token'], $date); + } + + return $matches; + } + /** * Get match entropy. * @@ -75,8 +80,7 @@ public function getEntropy() if ($this->year < 100) { // two-digit year $entropy = $this->log(self::NUM_DAYS * self::NUM_MONTHS * 100); - } - else { + } else { // four-digit year $entropy = $this->log(self::NUM_DAYS * self::NUM_MONTHS * self::NUM_YEARS); } @@ -84,6 +88,7 @@ public function getEntropy() if (!empty($this->separator)) { $entropy += 2; } + return $entropy; } @@ -91,44 +96,45 @@ public function getEntropy() * Find dates with separators in a password. * * @param string $password + * * @return array */ protected static function datesWithSeparators($password) { - $dates = array(); + $dates = []; foreach (static::findAll($password, static::DATE_RX_YEAR_SUFFIX) as $captures) { - $date = array( - 'day' => (integer) $captures[1]['token'], - 'month' => (integer) $captures[3]['token'], - 'year' => (integer) $captures[4]['token'], - 'sep' => $captures[2]['token'], + $date = [ + 'day' => (int) $captures[1]['token'], + 'month' => (int) $captures[3]['token'], + 'year' => (int) $captures[4]['token'], + 'sep' => $captures[2]['token'], 'begin' => $captures[0]['begin'], - 'end' => $captures[0]['end'], - ); + 'end' => $captures[0]['end'], + ]; $dates[] = $date; } foreach (static::findAll($password, static::DATE_RX_YEAR_PREFIX) as $captures) { - $date = array( - 'day' => (integer) $captures[4]['token'], - 'month' => (integer) $captures[3]['token'], - 'year' => (integer) $captures[1]['token'], - 'sep' => $captures[2]['token'], + $date = [ + 'day' => (int) $captures[4]['token'], + 'month' => (int) $captures[3]['token'], + 'year' => (int) $captures[1]['token'], + 'sep' => $captures[2]['token'], 'begin' => $captures[0]['begin'], - 'end' => $captures[0]['end'], - ); + 'end' => $captures[0]['end'], + ]; $dates[] = $date; } - $results = array(); + $results = []; foreach ($dates as $candidate) { $date = static::checkDate($candidate['day'], $candidate['month'], $candidate['year']); - if ($date === false) { + if (false === $date) { continue; } list($day, $month, $year) = $date; - $results[] = array( + $results[] = [ 'pattern' => 'date', 'begin' => $candidate['begin'], 'end' => $candidate['end'], @@ -136,8 +142,8 @@ protected static function datesWithSeparators($password) 'separator' => $candidate['sep'], 'day' => $day, 'month' => $month, - 'year' => $year - ); + 'year' => $year, + ]; } return $results; @@ -147,11 +153,12 @@ protected static function datesWithSeparators($password) * Find dates without separators in a password. * * @param string $password + * * @return array */ protected static function datesWithoutSeparators($password) { - $dateMatches = array(); + $dateMatches = []; // 1197 is length-4, 01011997 is length 8 foreach (static::findAll($password, '/(\d{4,8})/') as $captures) { @@ -163,102 +170,106 @@ protected static function datesWithoutSeparators($password) $tokenLen = strlen($token); // Create year candidates. - $candidates1 = array(); + $candidates1 = []; if ($tokenLen <= 6) { // 2 digit year prefix (990112) - $candidates1[] = array( + $candidates1[] = [ 'daymonth' => substr($token, 2), 'year' => substr($token, 0, 2), 'begin' => $begin, - 'end' => $end - ); + 'end' => $end, + ]; // 2 digit year suffix (011299) - $candidates1[] = array( - 'daymonth' => substr($token, 0, ($tokenLen - 2)), + $candidates1[] = [ + 'daymonth' => substr($token, 0, $tokenLen - 2), 'year' => substr($token, -2), 'begin' => $begin, - 'end' => $end - ); + 'end' => $end, + ]; } if ($tokenLen >= 6) { // 4 digit year prefix (199912) - $candidates1[] = array( + $candidates1[] = [ 'daymonth' => substr($token, 4), 'year' => substr($token, 0, 4), 'begin' => $begin, - 'end' => $end - ); + 'end' => $end, + ]; // 4 digit year suffix (121999) - $candidates1[] = array( - 'daymonth' => substr($token, 0, ($tokenLen - 4)), + $candidates1[] = [ + 'daymonth' => substr($token, 0, $tokenLen - 4), 'year' => substr($token, -4), 'begin' => $begin, - 'end' => $end - ); + 'end' => $end, + ]; } // Create day/month candidates from years. - $candidates2 = array(); + $candidates2 = []; foreach ($candidates1 as $candidate) { switch (strlen($candidate['daymonth'])) { case 2: // ex. 1 1 97 - $candidates2[] = array( + $candidates2[] = [ 'day' => $candidate['daymonth'][0], 'month' => $candidate['daymonth'][1], 'year' => $candidate['year'], 'begin' => $candidate['begin'], - 'end' => $candidate['end'] - ); + 'end' => $candidate['end'], + ]; + break; case 3: // ex. 11 1 97 or 1 11 97 - $candidates2[] = array( + $candidates2[] = [ 'day' => substr($candidate['daymonth'], 0, 2), 'month' => substr($candidate['daymonth'], 2), 'year' => $candidate['year'], 'begin' => $candidate['begin'], - 'end' => $candidate['end'] - ); - $candidates2[] = array( + 'end' => $candidate['end'], + ]; + $candidates2[] = [ 'day' => substr($candidate['daymonth'], 0, 1), 'month' => substr($candidate['daymonth'], 1, 3), 'year' => $candidate['year'], 'begin' => $candidate['begin'], - 'end' => $candidate['end'] - ); + 'end' => $candidate['end'], + ]; + break; case 4: // ex. 11 11 97 - $candidates2[] = array( + $candidates2[] = [ 'day' => substr($candidate['daymonth'], 0, 2), 'month' => substr($candidate['daymonth'], 2, 4), 'year' => $candidate['year'], 'begin' => $candidate['begin'], - 'end' => $candidate['end'] - ); + 'end' => $candidate['end'], + ]; + break; } } // Reject invalid candidates foreach ($candidates2 as $candidate) { - $day = (integer) $candidate['day']; - $month = (integer) $candidate['month']; - $year = (integer) $candidate['year']; + $day = (int) $candidate['day']; + $month = (int) $candidate['month']; + $year = (int) $candidate['year']; $date = static::checkDate($day, $month, $year); - if ($date === false) { + if (false === $date) { continue; } list($day, $month, $year) = $date; - $dateMatches[] = array( + $dateMatches[] = [ 'begin' => $candidate['begin'], 'end' => $candidate['end'], 'token' => substr($password, $begin, $begin + $end - 1), 'separator' => '', 'day' => $day, 'month' => $month, - 'year' => $year - ); + 'year' => $year, + ]; } } + return $dateMatches; } @@ -282,9 +293,10 @@ protected static function checkDate($day, $month, $year) if ($day > 31 || $month > 12) { return false; } - if (!((1900 <= $year && $year <= 2019))) { + if (!(1900 <= $year && $year <= 2019)) { return false; } - return array($day, $month, $year); + + return [$day, $month, $year]; } -} \ No newline at end of file +} diff --git a/src/Matchers/DictionaryMatch.php b/src/Matchers/DictionaryMatch.php index 64f897a..c3fc393 100644 --- a/src/Matchers/DictionaryMatch.php +++ b/src/Matchers/DictionaryMatch.php @@ -4,7 +4,6 @@ class DictionaryMatch extends Match { - /** * @var */ @@ -20,17 +19,40 @@ class DictionaryMatch extends Match */ public $matchedWord; + /** + * @param $password + * @param $begin + * @param $end + * @param $token + * @param array $params + */ + public function __construct($password, $begin, $end, $token, $params = []) + { + parent::__construct($password, $begin, $end, $token); + $this->pattern = 'dictionary'; + if (!empty($params)) { + $this->dictionaryName = isset($params['dictionary_name']) ? $params['dictionary_name'] : null; + $this->matchedWord = isset($params['matched_word']) ? $params['matched_word'] : null; + $this->rank = isset($params['rank']) ? $params['rank'] : null; + } + } + /** * Match occurences of dictionary words in password. * * @copydoc Match::match() + * + * @param $password + * @param array $userInputs + * + * @return array */ - public static function match($password, array $userInputs = array()) + public static function match($password, array $userInputs = []) { - $matches = array(); + $matches = []; $dicts = static::getRankedDictionaries(); if (!empty($userInputs)) { - $dicts['user_inputs'] = array(); + $dicts['user_inputs'] = []; foreach ($userInputs as $rank => $input) { $input_lower = strtolower($input); $dicts['user_inputs'][$input_lower] = $rank; @@ -43,25 +65,8 @@ public static function match($password, array $userInputs = array()) $matches[] = new static($password, $result['begin'], $result['end'], $result['token'], $result); } } - return $matches; - } - /** - * @param $password - * @param $begin - * @param $end - * @param $token - * @param array $params - */ - public function __construct($password, $begin, $end, $token, $params = array()) - { - parent::__construct($password, $begin, $end, $token); - $this->pattern = 'dictionary'; - if (!empty($params)) { - $this->dictionaryName = isset($params['dictionary_name']) ? $params['dictionary_name'] : null; - $this->matchedWord = isset($params['matched_word']) ? $params['matched_word'] : null; - $this->rank = isset($params['rank']) ? $params['rank'] : null; - } + return $matches; } /** @@ -79,7 +84,7 @@ protected function uppercaseEntropy() { $token = $this->token; // Return if token is all lowercase. - if ($token === strtolower($token)){ + if ($token === strtolower($token)) { return 0; } @@ -89,7 +94,7 @@ protected function uppercaseEntropy() // a capitalized word is the most common capitalization scheme, so it only doubles the search space // (uncapitalized + capitalized): 1 extra bit of entropy. allcaps and end-capitalized are common enough to // underestimate as 1 extra bit to be safe. - foreach (array($startUpper, $endUpper, $allUpper) as $regex) { + foreach ([$startUpper, $endUpper, $allUpper] as $regex) { if (preg_match($regex, $token)) { return 1; } @@ -105,16 +110,16 @@ protected function uppercaseEntropy() $ord = ord($x); if ($this->isUpper($ord)) { - $uLen += 1; + ++$uLen; } if ($this->isLower($ord)) { - $lLen += 1; + ++$lLen; } } $possibilities = 0; - foreach (range(0, min($uLen, $lLen ) + 1) as $i) { - $possibilities += $this->binom($uLen + $lLen, $i); + foreach (range(0, min($uLen, $lLen) + 1) as $i) { + $possibilities += $this->binom($uLen + $lLen, $i); } return $this->log($possibilities); @@ -124,11 +129,13 @@ protected function uppercaseEntropy() * Match password in a dictionary. * * @param string $password - * @param array $dict + * @param array $dict + * + * @return array */ protected static function dictionaryMatch($password, $dict) { - $result = array(); + $result = []; $length = strlen($password); $pw_lower = strtolower($password); @@ -138,13 +145,13 @@ protected static function dictionaryMatch($password, $dict) $word = substr($pw_lower, $i, $j - $i + 1); if (isset($dict[$word])) { - $result[] = array( + $result[] = [ 'begin' => $i, 'end' => $j, 'token' => substr($password, $i, $j - $i + 1), 'matched_word' => $word, 'rank' => $dict[$word], - ); + ]; } } } @@ -159,7 +166,8 @@ protected static function dictionaryMatch($password, $dict) */ protected static function getRankedDictionaries() { - $data = file_get_contents(dirname(__FILE__) . '/ranked_frequency_lists.json'); + $data = file_get_contents(__DIR__.'/ranked_frequency_lists.json'); + return json_decode($data, true); } -} \ No newline at end of file +} diff --git a/src/Matchers/DigitMatch.php b/src/Matchers/DigitMatch.php index 57a6469..8298664 100644 --- a/src/Matchers/DigitMatch.php +++ b/src/Matchers/DigitMatch.php @@ -4,22 +4,6 @@ class DigitMatch extends Match { - - /** - * Match occurences of 3 or more digits in a password - * - * @copydoc Match::match() - */ - public static function match($password, array $userInputs = array()) - { - $matches = array(); - $groups = static::findAll($password, "/(\d{3,})/"); - foreach ($groups as $captures) { - $matches[] = new static($password, $captures[1]['begin'], $captures[1]['end'], $captures[1]['token']); - } - return $matches; - } - /** * @param $password * @param $begin @@ -32,14 +16,36 @@ public function __construct($password, $begin, $end, $token) $this->pattern = 'digit'; } + /** + * Match occurences of 3 or more digits in a password. + * + * @copydoc Match::match() + * + * @param $password + * @param array $userInputs + * + * @return array + */ + public static function match($password, array $userInputs = []) + { + $matches = []; + $groups = static::findAll($password, '/(\\d{3,})/'); + foreach ($groups as $captures) { + $matches[] = new static($password, $captures[1]['begin'], $captures[1]['end'], $captures[1]['token']); + } + + return $matches; + } + /** * @return float */ public function getEntropy() { - if (is_null($this->entropy)) { - $this->entropy = $this->log(pow(10, strlen($this->token))); + if (null === $this->entropy) { + $this->entropy = $this->log(10 ** strlen($this->token)); } + return $this->entropy; } -} \ No newline at end of file +} diff --git a/src/Matchers/L33tMatch.php b/src/Matchers/L33tMatch.php index 9402680..164917f 100644 --- a/src/Matchers/L33tMatch.php +++ b/src/Matchers/L33tMatch.php @@ -2,15 +2,11 @@ namespace ZxcvbnPhp\Matchers; -use ZxcvbnPhp\Matchers\DictionaryMatch; - /** * Class L33tMatch extends DictionaryMatch to translate l33t into dictionary words for matching. - * @package ZxcvbnPhp\Matchers */ class L33tMatch extends DictionaryMatch { - /** * @var */ @@ -21,38 +17,59 @@ class L33tMatch extends DictionaryMatch */ public $subDisplay; - /** * @var */ public $l33t; + /** + * @param $password + * @param $begin + * @param $end + * @param $token + * @param array $params + */ + public function __construct($password, $begin, $end, $token, $params = []) + { + parent::__construct($password, $begin, $end, $token, $params); + $this->l33t = true; + if (!empty($params)) { + $this->sub = isset($params['sub']) ? $params['sub'] : null; + $this->subDisplay = isset($params['sub_display']) ? $params['sub_display'] : null; + } + } + /** * Match occurences of l33t words in password to dictionary words. * * @copydoc Match::match() + * + * @param $password + * @param array $userInputs + * + * @return array */ - public static function match($password, array $userInputs = array()) + public static function match($password, array $userInputs = []) { // Translate l33t password and dictionary match the translated password. $map = static::getSubstitutions($password); $indexSubs = array_filter($map); if (empty($indexSubs)) { - return array(); + return []; } $translatedWord = static::translate($password, $map); - $matches = array(); + $matches = []; $dicts = static::getRankedDictionaries(); foreach ($dicts as $name => $dict) { $results = static::dictionaryMatch($translatedWord, $dict); foreach ($results as $result) { // Set substituted elements. - $result['sub'] = array(); - $result['sub_display'] = array(); + $result['sub'] = []; + $result['sub_display'] = []; foreach ($indexSubs as $i => $t) { $result['sub'][$password[$i]] = $t; - $result['sub_display'][] = "$password[$i] -> $t"; + $result['sub_display'][] = "{$password[$i]} -> ${t}"; } $result['sub_display'] = implode(', ', $result['sub_display']); $result['dictionary_name'] = $name; @@ -61,24 +78,8 @@ public static function match($password, array $userInputs = array()) $matches[] = new static($password, $result['begin'], $result['end'], $token, $result); } } - return $matches; - } - /** - * @param $password - * @param $begin - * @param $end - * @param $token - * @param array $params - */ - public function __construct($password, $begin, $end, $token, $params = array()) - { - parent::__construct($password, $begin, $end, $token, $params); - $this->l33t = true; - if (!empty($params)) { - $this->sub = isset($params['sub']) ? $params['sub'] : null; - $this->subDisplay = isset($params['sub_display']) ? $params['sub_display'] : null; - } + return $matches; } /** @@ -101,14 +102,14 @@ protected function l33tEntropy() // Count occurences of substituted and unsubstituted characters in the token. foreach (str_split($this->token) as $char) { if ($char === (string) $subbed) { - $sLen++; + ++$sLen; } if ($char === (string) $unsubbed) { - $uLen++; + ++$uLen; } } foreach (range(0, min($uLen, $sLen)) as $i) { - $possibilities += $this->binom($uLen + $sLen, $i); + $possibilities += $this->binom($uLen + $sLen, $i); } } @@ -116,12 +117,14 @@ protected function l33tEntropy() if ($possibilities <= 1) { return 1; } + return $this->log($possibilities); } /** * @param string $string - * @param array $map + * @param array $map + * * @return string */ protected static function translate($string, $map) @@ -130,46 +133,48 @@ protected static function translate($string, $map) foreach (range(0, strlen($string) - 1) as $i) { $out .= !empty($map[$i]) ? $map[$i] : $string[$i]; } + return $out; } /** * @param string $password + * * @return array */ protected static function getSubstitutions($password) { - $map = array(); - - $l33t = array( - 'a' => array('4', '@'), - 'b' => array('8'), - 'c' => array('(', '{', '[', '<'), - 'e' => array('3'), - 'g' => array('6', '9'), - 'i' => array('1', '!', '|'), - 'l' => array('1', '|', '7'), - 'o' => array('0'), - 's' => array('$', '5'), - 't' => array('+', '7'), - 'x' => array('%'), - 'z' => array('2'), - ); + $map = []; + + $l33t = [ + 'a' => ['4', '@'], + 'b' => ['8'], + 'c' => ['(', '{', '[', '<'], + 'e' => ['3'], + 'g' => ['6', '9'], + 'i' => ['1', '!', '|'], + 'l' => ['1', '|', '7'], + 'o' => ['0'], + 's' => ['$', '5'], + 't' => ['+', '7'], + 'x' => ['%'], + 'z' => ['2'], + ]; // Simplified l33t table to reduce duplicates. - $l33t = array( - 'a' => array('4', '@'), - 'b' => array('8'), - 'c' => array('(', '{', '[', '<'), - 'e' => array('3'), - 'g' => array('6', '9'), - 'i' => array('1', '!'), - 'l' => array('|', '7'), - 'o' => array('0'), - 's' => array('$', '5'), - 't' => array('+', '7'), - 'x' => array('%'), - 'z' => array('2'), - ); + $l33t = [ + 'a' => ['4', '@'], + 'b' => ['8'], + 'c' => ['(', '{', '[', '<'], + 'e' => ['3'], + 'g' => ['6', '9'], + 'i' => ['1', '!'], + 'l' => ['|', '7'], + 'o' => ['0'], + 's' => ['$', '5'], + 't' => ['+', '7'], + 'x' => ['%'], + 'z' => ['2'], + ]; /*$chars = array_unique(str_split($password)); foreach ($l33t as $letter => $subs) { @@ -182,7 +187,7 @@ protected static function getSubstitutions($password) foreach (range(0, strlen($password) - 1) as $i) { $map[$i] = null; foreach ($l33t as $char => $subs) { - if (in_array($password[$i], $subs)) { + if (in_array($password[$i], $subs, true)) { $map[$i] = $char; } } diff --git a/src/Matchers/Match.php b/src/Matchers/Match.php index 88ee5a0..4cd3e53 100644 --- a/src/Matchers/Match.php +++ b/src/Matchers/Match.php @@ -4,7 +4,6 @@ abstract class Match implements MatchInterface { - /** * @var */ @@ -59,76 +58,76 @@ public function __construct($password, $begin, $end, $token) /** * Find matches in a password. * - * @param string $password - * Password to check for match. - * @param array $userInputs - * Array of values related to the user (optional). - * @return array - * Array of Match objects + * @param string $password Password to check for match + * @param array $userInputs Array of values related to the user (optional) + * + * @return array Array of Match objects */ - public static function match($password, array $userInputs = array()) {} + public static function match($password, array $userInputs = []) + { + } /** * Calculate entropy for match token of a password. * - * @return float - * Entropy of the matched token in the password. + * @return float Entropy of the matched token in the password */ - public function getEntropy() {} + public function getEntropy() + { + } /** - * Find all occurences of regular expression in a string. - * - * @param string $string - * String to search. - * @param string $regex - * Regular expression with captures. - * @return array - * Array of capture groups. Captures in a group have named indexes: 'begin', 'end', 'token'. - * e.g. fishfish /(fish)/ - * array( - * array( - * array('begin' => 0, 'end' => 3, 'token' => 'fish'), - * array('begin' => 0, 'end' => 3, 'token' => 'fish') - * ), - * array( - * array('begin' => 4, 'end' => 7, 'token' => 'fish'), - * array('begin' => 4, 'end' => 7, 'token' => 'fish') - * ) - * ) - * - */ + * Find all occurences of regular expression in a string. + * + * @param string $string String to search + * @param string $regex Regular expression with captures + * + * @return array + * Array of capture groups. Captures in a group have named indexes: 'begin', 'end', 'token'. + * e.g. fishfish /(fish)/ + * array( + * array( + * array('begin' => 0, 'end' => 3, 'token' => 'fish'), + * array('begin' => 0, 'end' => 3, 'token' => 'fish') + * ), + * array( + * array('begin' => 4, 'end' => 7, 'token' => 'fish'), + * array('begin' => 4, 'end' => 7, 'token' => 'fish') + * ) + * ) + */ public static function findAll($string, $regex) { $count = preg_match_all($regex, $string, $matches, PREG_SET_ORDER); if (!$count) { - return array(); + return []; } $pos = 0; - $groups = array(); + $groups = []; foreach ($matches as $group) { $captureBegin = 0; $match = array_shift($group); $matchBegin = strpos($string, $match, $pos); - $captures = array( - array( + $captures = [ + [ 'begin' => $matchBegin, 'end' => $matchBegin + strlen($match) - 1, 'token' => $match, - ), - ); + ], + ]; foreach ($group as $capture) { - $captureBegin = strpos($match, $capture, $captureBegin); - $captures[] = array( + $captureBegin = strpos($match, $capture, $captureBegin); + $captures[] = [ 'begin' => $matchBegin + $captureBegin, 'end' => $matchBegin + $captureBegin + strlen($capture) - 1, 'token' => $capture, - ); + ]; } $groups[] = $captures; $pos += strlen($match) - 1; } + return $groups; } @@ -139,7 +138,7 @@ public static function findAll($string, $regex) */ public function getCardinality() { - if (!is_null($this->cardinality)) { + if (null !== $this->cardinality) { return $this->cardinality; } $lower = $upper = $digits = $symbols = $unicode = 0; @@ -152,21 +151,18 @@ public function getCardinality() if ($this->isDigit($ord)) { $digits = 10; - } - elseif ($this->isUpper($ord)) { + } elseif ($this->isUpper($ord)) { $upper = 26; - } - elseif ($this->isLower($ord)) { + } elseif ($this->isLower($ord)) { $lower = 26; - } - elseif ($this->isSymbol($ord)) { + } elseif ($this->isSymbol($ord)) { $symbols = 33; - } - else { + } else { $unicode = 100; } } $this->cardinality = $lower + $digits + $upper + $symbols + $unicode; + return $this->cardinality; } @@ -194,6 +190,7 @@ protected function isSymbol($ord) * Calculate entropy. * * @param $number + * * @return float */ protected function log($number) @@ -208,22 +205,24 @@ protected function log($number) * * @param $n * @param $k + * * @return int */ - protected function binom($n, $k) { + protected function binom($n, $k) + { $j = $res = 1; - if($k < 0 || $k > $n) { + if ($k < 0 || $k > $n) { return 0; } - if(($n - $k) < $k) { + if (($n - $k) < $k) { $k = $n - $k; } - while($j <= $k) { + while ($j <= $k) { $res *= $n--; $res /= $j++; } return $res; } -} \ No newline at end of file +} diff --git a/src/Matchers/MatchInterface.php b/src/Matchers/MatchInterface.php index add2d74..6805e92 100644 --- a/src/Matchers/MatchInterface.php +++ b/src/Matchers/MatchInterface.php @@ -4,27 +4,23 @@ interface MatchInterface { - /** * Match this password. * - * @param string $password - * Password to check for match. - * @param array $userInputs - * Array of values related to the user (optional). - * @code - * array('Alice Smith') + * @param string $password Password to check for match + * @param array $userInputs Array of values related to the user (optional) + * @code array('Alice Smith') * @endcode - * @return array - * Array of Match objects + * + * @return array Array of Match objects */ - public static function match($password, array $userInputs = array()); + public static function match($password, array $userInputs = []); /** * Get entropy for this match's token. * * @return float - * Entropy of the matched token in the password. + * Entropy of the matched token in the password */ public function getEntropy(); -} \ No newline at end of file +} diff --git a/src/Matchers/RepeatMatch.php b/src/Matchers/RepeatMatch.php index 7cb9f4d..5857bbc 100644 --- a/src/Matchers/RepeatMatch.php +++ b/src/Matchers/RepeatMatch.php @@ -4,21 +4,39 @@ class RepeatMatch extends Match { - /** * @var */ public $repeatedChar; + /** + * @param $password + * @param $begin + * @param $end + * @param $token + * @param mixed $char + */ + public function __construct($password, $begin, $end, $token, $char) + { + parent::__construct($password, $begin, $end, $token); + $this->pattern = 'repeat'; + $this->repeatedChar = $char; + } + /** * Match 3 or more repeated characters. * * @copydoc Match::match() + * + * @param $password + * @param array $userInputs + * + * @return array */ - public static function match($password, array $userInputs = array()) + public static function match($password, array $userInputs = []) { $groups = static::group($password); - $matches = array(); + $matches = []; $k = 0; foreach ($groups as $group) { @@ -32,20 +50,8 @@ public static function match($password, array $userInputs = array()) } $k += $length; } - return $matches; - } - /** - * @param $password - * @param $begin - * @param $end - * @param $token - */ - public function __construct($password, $begin, $end, $token, $char) - { - parent::__construct($password, $begin, $end, $token); - $this->pattern = 'repeat'; - $this->repeatedChar = $char; + return $matches; } /** @@ -53,9 +59,10 @@ public function __construct($password, $begin, $end, $token, $char) */ public function getEntropy() { - if (is_null($this->entropy)) { - $this->entropy = $this->log($this->getCardinality() * strlen($this->token)); + if (null === $this->entropy) { + $this->entropy = $this->log($this->getCardinality() * strlen($this->token)); } + return $this->entropy; } @@ -63,11 +70,12 @@ public function getEntropy() * Group input by repeated characters. * * @param string $string + * * @return array */ protected static function group($string) { - $grouped = array(); + $grouped = []; $chars = str_split($string); $prevChar = null; @@ -75,13 +83,13 @@ protected static function group($string) foreach ($chars as $char) { if ($prevChar === $char) { $grouped[$i - 1] .= $char; - } - else { + } else { $grouped[$i] = $char; - $i++; + ++$i; $prevChar = $char; } } + return $grouped; } -} \ No newline at end of file +} diff --git a/src/Matchers/SequenceMatch.php b/src/Matchers/SequenceMatch.php index 6c26eb4..c842cff 100644 --- a/src/Matchers/SequenceMatch.php +++ b/src/Matchers/SequenceMatch.php @@ -4,7 +4,6 @@ class SequenceMatch extends Match { - const LOWER = 'abcdefghijklmnopqrstuvwxyz'; const UPPER = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; const DIGITS = '0123456789'; @@ -24,20 +23,43 @@ class SequenceMatch extends Match */ public $ascending; + /** + * @param $password + * @param $begin + * @param $end + * @param $token + * @param array $params + */ + public function __construct($password, $begin, $end, $token, $params = []) + { + parent::__construct($password, $begin, $end, $token); + $this->pattern = 'sequence'; + if (!empty($params)) { + $this->sequenceName = isset($params['sequenceName']) ? $params['sequenceName'] : null; + $this->sequenceSpace = isset($params['sequenceSpace']) ? $params['sequenceSpace'] : null; + $this->ascending = isset($params['ascending']) ? $params['ascending'] : null; + } + } + /** * Match sequences of three or more characters. * * @copydoc Match::match() + * + * @param $password + * @param array $userInputs + * + * @return array */ - public static function match($password, array $userInputs = array()) + public static function match($password, array $userInputs = []) { - $matches = array(); + $matches = []; $passwordLength = strlen($password); - $sequences = self::LOWER . self::UPPER . self::DIGITS; + $sequences = self::LOWER.self::UPPER.self::DIGITS; $revSequences = strrev($sequences); - for ($i = 0; $i < $passwordLength; $i++) { + for ($i = 0; $i < $passwordLength; ++$i) { $pattern = false; $j = $i + 2; // Check for sequence sizes of 3 or more. @@ -45,51 +67,34 @@ public static function match($password, array $userInputs = array()) $pattern = substr($password, $i, 3); } // Find beginning of pattern and then extract full sequences intersection. - if ($pattern && ($pos = strpos($sequences, $pattern)) !== false) { + if ($pattern && false !== ($pos = strpos($sequences, $pattern))) { // Match only remaining password characters. $remainder = substr($password, $j + 1); $pattern .= static::intersect($sequences, $remainder, $pos + 3); - $params = array( + $params = [ 'ascending' => true, 'sequenceName' => static::getSequenceName($pos), 'sequenceSpace' => static::getSequenceSpace($pos), - ); + ]; $matches[] = new static($password, $i, $i + strlen($pattern) - 1, $pattern, $params); // Skip intersecting characters on next loop. $i += strlen($pattern) - 1; } // Search the reverse sequence for pattern. - elseif ($pattern && ($pos = strpos($revSequences, $pattern)) !== false) { + elseif ($pattern && false !== ($pos = strpos($revSequences, $pattern))) { $remainder = substr($password, $j + 1); $pattern .= static::intersect($revSequences, $remainder, $pos + 3); - $params = array( + $params = [ 'ascending' => false, 'sequenceName' => static::getSequenceName($pos), 'sequenceSpace' => static::getSequenceSpace($pos), - ); + ]; $matches[] = new static($password, $i, $i + strlen($pattern) - 1, $pattern, $params); $i += strlen($pattern) - 1; } } - return $matches; - } - /** - * @param $password - * @param $begin - * @param $end - * @param $token - * @param array $params - */ - public function __construct($password, $begin, $end, $token, $params = array()) - { - parent::__construct($password, $begin, $end, $token); - $this->pattern = 'sequence'; - if (!empty($params)) { - $this->sequenceName = isset($params['sequenceName']) ? $params['sequenceName'] : null; - $this->sequenceSpace = isset($params['sequenceSpace']) ? $params['sequenceSpace'] : null; - $this->ascending = isset($params['ascending']) ? $params['ascending'] : null; - } + return $matches; } /** @@ -98,25 +103,22 @@ public function __construct($password, $begin, $end, $token, $params = array()) public function getEntropy() { $char = $this->token[0]; - if ($char === 'a' || $char === '1') { + if ('a' === $char || '1' === $char) { $entropy = 1; - } - else { + } else { $ord = ord($char); if ($this->isDigit($ord)) { $entropy = $this->log(10); - } - elseif ($this->isLower($ord)) { + } elseif ($this->isLower($ord)) { $entropy = $this->log(26); - } - else { + } else { $entropy = $this->log(26) + 1; // Extra bit for upper. } } if (empty($this->ascending)) { - $entropy += 1; // Extra bit for descending instead of ascending + ++$entropy; // Extra bit for descending instead of ascending } return $entropy + $this->log(strlen($this->token)); @@ -127,30 +129,32 @@ public function getEntropy() * * @param string $string * @param string $subString - * @param int $start + * @param int $start * * @return string */ - protected static function intersect($string, $subString, $start) { + protected static function intersect($string, $subString, $start) + { $cut = str_split(substr($string, $start, strlen($subString))); $comp = str_split($subString); foreach ($cut as $i => $c) { if ($comp[$i] === $c) { $intersect[] = $c; - } - else { + } else { break; // Stop loop since intersection ends. } } if (!empty($intersect)) { return implode('', $intersect); } + return ''; } /** * @param $pos * @param bool $reverse + * * @return int */ protected static function getSequenceSpace($pos, $reverse = false) @@ -169,31 +173,35 @@ protected static function getSequenceSpace($pos, $reverse = false) /** * Name of sequence a sequences position belongs to. * - * @param int $pos + * @param int $pos * @param bool $reverse + * * @return string */ protected static function getSequenceName($pos, $reverse = false) { - $sequences = self::LOWER . self::UPPER . self::DIGITS; + $sequences = self::LOWER.self::UPPER.self::DIGITS; $end = strlen($sequences); if (!$reverse && $pos < strlen(self::LOWER)) { return 'lower'; } - elseif (!$reverse && $pos <= $end - strlen(self::DIGITS)) { + + if (!$reverse && $pos <= $end - strlen(self::DIGITS)) { return 'upper'; } - elseif (!$reverse) { + + if (!$reverse) { return 'digits'; } - elseif ($pos < strlen(self::DIGITS)) { + + if ($pos < strlen(self::DIGITS)) { return 'digits'; } - elseif ($pos <= $end - strlen(self::LOWER)) { + + if ($pos <= $end - strlen(self::LOWER)) { return 'upper'; } - else { - return 'lower'; - } + + return 'lower'; } -} \ No newline at end of file +} diff --git a/src/Matchers/SpatialMatch.php b/src/Matchers/SpatialMatch.php index 6bdc279..7e50e16 100644 --- a/src/Matchers/SpatialMatch.php +++ b/src/Matchers/SpatialMatch.php @@ -4,11 +4,9 @@ /** * Class SpatialMatch. - * @package ZxcvbnPhp\Matchers */ class SpatialMatch extends Match { - /** * @var */ @@ -44,26 +42,6 @@ class SpatialMatch extends Match */ protected $keypadAvgDegree; - /** - * Match spatial patterns based on keyboard layouts (e.g. qwerty, dvorak, keypad). - * - * @copydoc Match::match() - */ - public static function match($password, array $userInputs = array()) - { - - $matches = array(); - $graphs = static::getAdjacencyGraphs(); - foreach ($graphs as $name => $graph) { - $results = static::graphMatch($password, $graph); - foreach ($results as $result) { - $result['graph'] = $name; - $matches[] = new static($password, $result['begin'], $result['end'], $result['token'], $result); - } - } - return $matches; - } - /** * @param $password * @param $begin @@ -71,7 +49,7 @@ public static function match($password, array $userInputs = array()) * @param $token * @param array $params */ - public function __construct($password, $begin, $end, $token, $params = array()) + public function __construct($password, $begin, $end, $token, $params = []) { parent::__construct($password, $begin, $end, $token); $this->pattern = 'spatial'; @@ -87,6 +65,31 @@ public function __construct($password, $begin, $end, $token, $params = array()) $this->keypadAvgDegree = 76 / 15; } + /** + * Match spatial patterns based on keyboard layouts (e.g. qwerty, dvorak, keypad). + * + * @copydoc Match::match() + * + * @param $password + * @param array $userInputs + * + * @return array + */ + public static function match($password, array $userInputs = []) + { + $matches = []; + $graphs = static::getAdjacencyGraphs(); + foreach ($graphs as $name => $graph) { + $results = static::graphMatch($password, $graph); + foreach ($results as $result) { + $result['graph'] = $name; + $matches[] = new static($password, $result['begin'], $result['end'], $result['token'], $result); + } + } + + return $matches; + } + /** * Get entropy. * @@ -94,22 +97,22 @@ public function __construct($password, $begin, $end, $token, $params = array()) */ public function getEntropy() { - if ($this->graph === 'qwerty' || $this->graph === 'dvorak' ) { + if ('qwerty' === $this->graph || 'dvorak' === $this->graph) { $startingPos = $this->keyboardStartingPos; $avgDegree = $this->keyboardAvgDegree; - } - else { + } else { $startingPos = $this->keypadStartingPos; $avgDegree = $this->keypadAvgDegree; } $possibilities = 0; // estimate the number of possible patterns w/ token length or less with match turns or less. - for ($i = 2; $i <= strlen($this->token); $i++) { + $tokenLength = strlen($this->token); + for ($i = 2; $i <= $tokenLength; ++$i) { $possibleTurns = min($this->turns, $i - 1); - for ($j = 1; $j <= $possibleTurns; $j++) { - $possibilities += $this->binom($i - 1, $j - 1) * $startingPos * pow($avgDegree, $j); + for ($j = 1; $j <= $possibleTurns; ++$j) { + $possibilities += $this->binom($i - 1, $j - 1) * $startingPos * ($avgDegree ** $j); } } $entropy = $this->log($possibilities); @@ -120,11 +123,12 @@ public function getEntropy() $unshiftedCount = strlen($this->token) - $this->shiftedCount; $len = min($this->shiftedCount, $unshiftedCount); - for ($i = 0; $i <= $len; $i++) { + for ($i = 0; $i <= $len; ++$i) { $possibilities += $this->binom($this->shiftedCount + $unshiftedCount, $i); } $entropy += $this->log($possibilities); } + return $entropy; } @@ -132,11 +136,13 @@ public function getEntropy() * Match spatial patterns in a adjacency graph. * * @param string $password - * @param array $graph + * @param array $graph + * + * @return array */ protected static function graphMatch($password, $graph) { - $result = array(); + $result = []; $i = 0; $passwordLength = strlen($password); @@ -151,26 +157,26 @@ protected static function graphMatch($password, $graph) $prevChar = $password[$j - 1]; $found = false; $curDirection = -1; - $adjacents = isset($graph[$prevChar]) ? $graph[$prevChar] : array(); + $adjacents = isset($graph[$prevChar]) ? $graph[$prevChar] : []; // Consider growing pattern by one character if j hasn't gone over the edge. if ($j < $passwordLength) { $curChar = $password[$j]; - foreach ($adjacents as $adj ) { - $curDirection += 1; + foreach ($adjacents as $adj) { + ++$curDirection; $curCharPos = static::indexOf($adj, $curChar); if ($adj && $curCharPos !== -1) { $found = true; $foundDirection = $curDirection; - if ($curCharPos === 1) { + if (1 === $curCharPos) { // index 1 in the adjacency means the key is shifted, 0 means unshifted: A vs a, % vs 5, etc. // for example, 'q' is adjacent to the entry '2@'. @ is shifted w/ index 1, 2 is unshifted. - $shiftedCount += 1; + ++$shiftedCount; } if ($lastDirection !== $foundDirection) { // adding a turn is correct even in the initial case when last_direction is null: // every spatial pattern starts with a turn. - $turns += 1; + ++$turns; $lastDirection = $foundDirection; } @@ -181,22 +187,23 @@ protected static function graphMatch($password, $graph) // if the current pattern continued, extend j and try to grow again if ($found) { - $j += 1; + ++$j; } // otherwise push the pattern discovered so far, if any... else { // Ignore length 1 or 2 chains. - if ($j - $i > 2) { - $result[] = array( + if ($j - $i > 2) { + $result[] = [ 'begin' => $i, 'end' => $j - 1, 'token' => substr($password, $i, $j - $i), 'turns' => $turns, - 'shifted_count' => $shiftedCount - ); + 'shifted_count' => $shiftedCount, + ]; } // ...and then start a new search for the rest of the password. $i = $j; + break; } } @@ -206,7 +213,7 @@ protected static function graphMatch($password, $graph) } /** - * Get the index of a string a character first + * Get the index of a string a character first. * * @param string $string * @param string $char @@ -216,7 +223,8 @@ protected static function graphMatch($password, $graph) protected static function indexOf($string, $char) { $pos = @strpos($string, $char); - return ($pos === false ? -1 : $pos); + + return false === $pos ? -1 : $pos; } /** @@ -232,11 +240,12 @@ protected static function calcAverageDegree($graph) foreach ($graph as $neighbors) { foreach ($neighbors as $neighbor) { // Ignore empty neighbors. - if (!is_null($neighbor)) { - $sum++; + if (null !== $neighbor) { + ++$sum; } } } + return $sum / count(array_keys($graph)); } @@ -247,7 +256,8 @@ protected static function calcAverageDegree($graph) */ protected static function getAdjacencyGraphs() { - $data = file_get_contents(dirname(__FILE__) . '/adjacency_graphs.json'); + $data = file_get_contents(__DIR__.'/adjacency_graphs.json'); + return json_decode($data, true); } -} \ No newline at end of file +} diff --git a/src/Matchers/YearMatch.php b/src/Matchers/YearMatch.php index 8ff4dc1..5fa1666 100644 --- a/src/Matchers/YearMatch.php +++ b/src/Matchers/YearMatch.php @@ -4,24 +4,8 @@ class YearMatch extends Match { - const NUM_YEARS = 119; - /** - * Match occurences of years in a password - * - * @copydoc Match::match() - */ - public static function match($password, array $userInputs = array()) - { - $matches = array(); - $groups = static::findAll($password, "/(19\d\d|200\d|201\d)/"); - foreach ($groups as $captures) { - $matches[] = new static($password, $captures[1]['begin'], $captures[1]['end'], $captures[1]['token']); - } - return $matches; - } - /** * @param $password * @param $begin @@ -34,14 +18,36 @@ public function __construct($password, $begin, $end, $token) $this->pattern = 'year'; } + /** + * Match occurences of years in a password. + * + * @copydoc Match::match() + * + * @param $password + * @param array $userInputs + * + * @return array + */ + public static function match($password, array $userInputs = []) + { + $matches = []; + $groups = static::findAll($password, '/(19\\d\\d|200\\d|201\\d)/'); + foreach ($groups as $captures) { + $matches[] = new static($password, $captures[1]['begin'], $captures[1]['end'], $captures[1]['token']); + } + + return $matches; + } + /** * @return float */ public function getEntropy() { - if (is_null($this->entropy)) { + if (null === $this->entropy) { $this->entropy = $this->log(self::NUM_YEARS); } + return $this->entropy; } -} \ No newline at end of file +} diff --git a/src/Scorer.php b/src/Scorer.php index 897b04b..12dc42b 100644 --- a/src/Scorer.php +++ b/src/Scorer.php @@ -4,55 +4,49 @@ class Scorer implements ScorerInterface { - const SINGLE_GUESS = 0.010; // Lower bound assumption of time to hash based on bcrypt/scrypt/PBKDF2. const NUM_ATTACKERS = 100; // Assumed number of cores guessing in parallel. protected $crackTime; - /** - * - */ public function score($entropy) { $seconds = $this->calcCrackTime($entropy); - if ($seconds < pow(10, 2)) { + if ($seconds < (10 ** 2)) { return 0; } - if ($seconds < pow(10, 4)) { + if ($seconds < (10 ** 4)) { return 1; } - if ($seconds < pow(10, 6)) { + if ($seconds < (10 ** 6)) { return 2; } - if ($seconds < pow(10, 8)) { + if ($seconds < (10 ** 8)) { return 3; } + return 4; } - /** - * - */ public function getMetrics() { - return array( - 'crack_time' => $this->crackTime - ); + return [ + 'crack_time' => $this->crackTime, + ]; } /** * Get average time to crack based on entropy. * * @param $entropy + * * @return float */ protected function calcCrackTime($entropy) { - $this->crackTime = (0.5 * pow(2, $entropy)) * (Scorer::SINGLE_GUESS / Scorer::NUM_ATTACKERS); + $this->crackTime = (0.5 * (2 ** $entropy)) * (self::SINGLE_GUESS / self::NUM_ATTACKERS); + return $this->crackTime; } - - -} \ No newline at end of file +} diff --git a/src/ScorerInterface.php b/src/ScorerInterface.php index 1b3b9b6..ab75c8e 100644 --- a/src/ScorerInterface.php +++ b/src/ScorerInterface.php @@ -4,22 +4,19 @@ interface ScorerInterface { - /** * Score for a password's bits of entropy. * - * @param float $entropy - * Entropy to score. - * @return float - * Score. + * @param float $entropy Entropy to score + * + * @return float Score */ public function score($entropy); /** * Get metrics used to determine score. * - * @return array - * Key value array of metrics. + * @return array Key value array of metrics */ public function getMetrics(); -} \ No newline at end of file +} diff --git a/src/Searcher.php b/src/Searcher.php index c12c382..d5c4a23 100644 --- a/src/Searcher.php +++ b/src/Searcher.php @@ -6,7 +6,6 @@ class Searcher { - /** * @var */ @@ -15,21 +14,18 @@ class Searcher /** * Calculate the minimum entropy for a password and its matches. * - * @param string $password - * Password. - * @param array $matches - * Array of Match objects on the password. + * @param string $password Password + * @param array $matches Array of Match objects on the password * - * @return float - * Minimum entropy for non-overlapping best matches of a password. + * @return float Minimum entropy for non-overlapping best matches of a password */ public function getMinimumEntropy($password, $matches) { $passwordLength = strlen($password); - $entropyStack = array(); + $entropyStack = []; // for the optimal sequence of matches up to k, holds the final match (match.end == k). // null means the sequence ends without a brute-force character. - $backpointers = array(); + $backpointers = []; $bruteforceMatch = new Bruteforce($password, 0, $passwordLength - 1, $password); $charEntropy = log($bruteforceMatch->getCardinality(), 2); @@ -38,7 +34,7 @@ public function getMinimumEntropy($password, $matches) $entropyStack[$k] = $this->prevValue($entropyStack, $k) + $charEntropy; $backpointers[$k] = null; foreach ($matches as $match) { - if (!isset($match->begin) || $match->end != $k ) { + if (!isset($match->begin) || $match->end !== $k) { continue; } @@ -53,7 +49,7 @@ public function getMinimumEntropy($password, $matches) } // Walk backwards and decode the best sequence - $matchSequence = array(); + $matchSequence = []; $k = $passwordLength - 1; while ($k >= 0) { $match = $backpointers[$k]; @@ -62,20 +58,19 @@ public function getMinimumEntropy($password, $matches) $matchSequence[] = $match; $k = $match->begin - 1; - } - else { - $k -= 1; + } else { + --$k; } } $matchSequence = array_reverse($matchSequence); $s = 0; - $matchSequenceCopy = array(); + $matchSequenceCopy = []; // Handle subtrings that weren't matched as bruteforce match. foreach ($matchSequence as $match) { if ($match->begin - $s > 0) { $matchSequenceCopy[] = $this->makeBruteforceMatch($password, $s, $match->begin - 1, $bruteforceMatch->getCardinality()); - }; + } $s = $match->end + 1; $matchSequenceCopy[] = $match; @@ -86,24 +81,22 @@ public function getMinimumEntropy($password, $matches) } $this->matchSequence = $matchSequenceCopy; - $minEntropy = $entropyStack[$passwordLength - 1]; - return $minEntropy; + return $entropyStack[$passwordLength - 1]; } /** * Get previous value in an array if set otherwise 0. * - * @param array $array - * Array to search. - * @param $index - * Index to get previous value from. + * @param array $array Array to search + * @param $index Index to get previous value from * * @return mixed */ protected function prevValue($array, $index) { - $index = $index - 1; + --$index; + return ($index < 0 || $index >= count($array)) ? 0 : $array[$index]; } @@ -111,9 +104,9 @@ protected function prevValue($array, $index) * Make a bruteforce match object for substring of password. * * @param string $password - * @param int $begin - * @param int $end - * @param int $cardinality optional + * @param int $begin + * @param int $end + * @param int $cardinality optional * * @return Bruteforce match */ @@ -122,6 +115,7 @@ protected function makeBruteforceMatch($password, $begin, $end, $cardinality = n $match = new Bruteforce($password, $begin, $end, substr($password, $begin, $end + 1), $cardinality); // Set entropy in match. $match->getEntropy(); + return $match; } -} \ No newline at end of file +} diff --git a/src/Zxcvbn.php b/src/Zxcvbn.php index d25b3f0..e388b3c 100644 --- a/src/Zxcvbn.php +++ b/src/Zxcvbn.php @@ -21,32 +21,30 @@ class Zxcvbn public function __construct() { - $this->scorer = new \ZxcvbnPhp\Scorer(); - $this->searcher = new \ZxcvbnPhp\Searcher(); - $this->matcher = new \ZxcvbnPhp\Matcher(); + $this->scorer = new Scorer(); + $this->searcher = new Searcher(); + $this->matcher = new Matcher(); } /** * Calculate password strength via non-overlapping minimum entropy patterns. * - * @param string $password - * Password to measure. - * @param array $userInputs - * Optional user inputs. + * @param string $password Password to measure + * @param array $userInputs Optional user inputs * - * @return array - * Strength result array with keys: - * password - * entropy - * match_sequence - * score + * @return array Strength result array with keys: + * password + * entropy + * match_sequence + * score */ - public function passwordStrength($password, array $userInputs = array()) + public function passwordStrength($password, array $userInputs = []) { $timeStart = microtime(true); - if (strlen($password) === 0) { + if ('' === $password) { $timeStop = microtime(true) - $timeStart; - return $this->result($password, 0, array(), 0, array('calc_time' => $timeStop)); + + return $this->result($password, 0, [], 0, ['calc_time' => $timeStop]); } // Get matches for $password. @@ -62,7 +60,8 @@ public function passwordStrength($password, array $userInputs = array()) $timeStop = microtime(true) - $timeStart; // Include metrics and calculation time. - $params = array_merge($metrics, array('calc_time' => $timeStop)); + $params = array_merge($metrics, ['calc_time' => $timeStop]); + return $this->result($password, $entropy, $bestMatches, $score, $params); } @@ -70,21 +69,22 @@ public function passwordStrength($password, array $userInputs = array()) * Result array. * * @param string $password - * @param float $entropy - * @param array $matches - * @param int $score - * @param array $params + * @param float $entropy + * @param array $matches + * @param int $score + * @param array $params * * @return array */ - protected function result($password, $entropy, $matches, $score, $params = array()) { - $r = array( - 'password' => $password, - 'entropy' => $entropy, + protected function result($password, $entropy, $matches, $score, $params = []) + { + $r = [ + 'password' => $password, + 'entropy' => $entropy, 'match_sequence' => $matches, - 'score' => $score - ); + 'score' => $score, + ]; + return array_merge($params, $r); } - -} \ No newline at end of file +} diff --git a/test/MatcherTest.php b/test/MatcherTest.php index 682cca9..1d48be9 100644 --- a/test/MatcherTest.php +++ b/test/MatcherTest.php @@ -2,19 +2,22 @@ namespace ZxcvbnPhp\Test; +use PHPUnit\Framework\TestCase; use ZxcvbnPhp\Matcher; -class MatcherTest extends \PHPUnit_Framework_TestCase +/** + * @covers \ZxcvbnPhp\Matcher + */ +class MatcherTest extends TestCase { - public function testGetMatches() { $matcher = new Matcher(); - $matches = $matcher->getMatches("jjj"); - $this->assertSame('repeat', $matches[0]->pattern, "Pattern incorrect"); + $matches = $matcher->getMatches('jjj'); + $this->assertSame('repeat', $matches[0]->pattern, 'Pattern incorrect'); $this->assertCount(1, $matches); - $matches = $matcher->getMatches("jjjjj"); - $this->assertSame('repeat', $matches[0]->pattern, "Pattern incorrect"); + $matches = $matcher->getMatches('jjjjj'); + $this->assertSame('repeat', $matches[0]->pattern, 'Pattern incorrect'); } -} \ No newline at end of file +} diff --git a/test/Matchers/BruteforceTest.php b/test/Matchers/BruteforceTest.php index ee5f0eb..1bd394a 100644 --- a/test/Matchers/BruteforceTest.php +++ b/test/Matchers/BruteforceTest.php @@ -2,9 +2,13 @@ namespace ZxcvbnPhp\Test\Matchers; +use PHPUnit\Framework\TestCase; use ZxcvbnPhp\Matchers\Bruteforce; -class BruteforceTest extends \PHPUnit_Framework_TestCase +/** + * @covers \ZxcvbnPhp\Matchers\Bruteforce + */ +class BruteforceTest extends TestCase { public function testCardinality() { @@ -24,11 +28,11 @@ public function testCardinality() public function testEntropy() { $match = new Bruteforce('99', 0, 1, '99'); - $this->assertSame(log(pow(10, 2), 2), $match->getEntropy()); + $this->assertSame(log(10 ** 2, 2), $match->getEntropy()); $password = 'aB1*'; $match = new Bruteforce($password, 0, 3, $password); $this->assertSame(95, $match->getCardinality()); - $this->assertSame(log(pow(95, 4), 2), $match->getEntropy()); + $this->assertSame(log(95 ** 4, 2), $match->getEntropy()); } -} \ No newline at end of file +} diff --git a/test/Matchers/DateTest.php b/test/Matchers/DateTest.php index 33a9027..aa32782 100644 --- a/test/Matchers/DateTest.php +++ b/test/Matchers/DateTest.php @@ -2,9 +2,13 @@ namespace ZxcvbnPhp\Test\Matchers; +use PHPUnit\Framework\TestCase; use ZxcvbnPhp\Matchers\DateMatch; -class DateTest extends \PHPUnit_Framework_TestCase +/** + * @covers \ZxcvbnPhp\Matchers\DateMatch + */ +class DateTest extends TestCase { public function testMatch() { @@ -28,41 +32,41 @@ public function testMatch() $password = '15111997'; $matches = DateMatch::match($password); $this->assertCount(1, $matches); - $this->assertSame(15, $matches[0]->day, "Incorrect day"); - $this->assertSame(11, $matches[0]->month, "Incorrect month"); - $this->assertSame(1997, $matches[0]->year, "Incorrect year"); + $this->assertSame(15, $matches[0]->day, 'Incorrect day'); + $this->assertSame(11, $matches[0]->month, 'Incorrect month'); + $this->assertSame(1997, $matches[0]->year, 'Incorrect year'); $password = '19970404'; $matches = DateMatch::match($password); $this->assertCount(1, $matches); - $this->assertSame(04, $matches[0]->day, "Incorrect day"); - $this->assertSame(04, $matches[0]->month, "Incorrect month"); - $this->assertSame(1997, $matches[0]->year, "Incorrect year"); + $this->assertSame(04, $matches[0]->day, 'Incorrect day'); + $this->assertSame(04, $matches[0]->month, 'Incorrect month'); + $this->assertSame(1997, $matches[0]->year, 'Incorrect year'); // Test separators. $password = '04/04/1997'; $matches = DateMatch::match($password); $this->assertCount(1, $matches); - $this->assertSame(04, $matches[0]->day, "Incorrect day"); - $this->assertSame(04, $matches[0]->month, "Incorrect month"); - $this->assertSame(1997, $matches[0]->year, "Incorrect year"); - $this->assertSame('/', $matches[0]->separator, "Incorrect separator"); + $this->assertSame(04, $matches[0]->day, 'Incorrect day'); + $this->assertSame(04, $matches[0]->month, 'Incorrect month'); + $this->assertSame(1997, $matches[0]->year, 'Incorrect year'); + $this->assertSame('/', $matches[0]->separator, 'Incorrect separator'); $password = 'password1997-04-04'; $matches = DateMatch::match($password); $this->assertCount(1, $matches); - $this->assertSame(04, $matches[0]->day, "Incorrect day"); - $this->assertSame(04, $matches[0]->month, "Incorrect month"); - $this->assertSame(1997, $matches[0]->year, "Incorrect year"); - $this->assertSame('-', $matches[0]->separator, "Incorrect separator"); + $this->assertSame(04, $matches[0]->day, 'Incorrect day'); + $this->assertSame(04, $matches[0]->month, 'Incorrect month'); + $this->assertSame(1997, $matches[0]->year, 'Incorrect year'); + $this->assertSame('-', $matches[0]->separator, 'Incorrect separator'); $password = 'date11/11/2000-2001-04-04'; $matches = DateMatch::match($password); $this->assertCount(2, $matches); - $this->assertSame(11, $matches[0]->day, "Incorrect day"); - $this->assertSame(11, $matches[0]->month, "Incorrect month"); - $this->assertSame(2000, $matches[0]->year, "Incorrect year"); - $this->assertSame('-', $matches[1]->separator, "Incorrect separator"); + $this->assertSame(11, $matches[0]->day, 'Incorrect day'); + $this->assertSame(11, $matches[0]->month, 'Incorrect month'); + $this->assertSame(2000, $matches[0]->year, 'Incorrect year'); + $this->assertSame('-', $matches[1]->separator, 'Incorrect separator'); } public function testEntropy() @@ -71,4 +75,4 @@ public function testEntropy() $matches = DateMatch::match($password); $this->assertSame(log(119 * 12 * 31, 2), $matches[0]->getEntropy()); } -} \ No newline at end of file +} diff --git a/test/Matchers/DictionaryTest.php b/test/Matchers/DictionaryTest.php index f4b70ef..fc5f54b 100644 --- a/test/Matchers/DictionaryTest.php +++ b/test/Matchers/DictionaryTest.php @@ -2,9 +2,13 @@ namespace ZxcvbnPhp\Test\Matchers; +use PHPUnit\Framework\TestCase; use ZxcvbnPhp\Matchers\DictionaryMatch; -class DictionaryTest extends \PHPUnit_Framework_TestCase +/** + * @covers \ZxcvbnPhp\Matchers\DictionaryMatch + */ +class DictionaryTest extends TestCase { public function testMatch() { @@ -20,24 +24,24 @@ public function testMatch() $matches = DictionaryMatch::match($password); // 11 matches for "password" in english and password dictionaries. $this->assertCount(11, $matches); - $this->assertSame('pass', $matches[0]->token, "Token incorrect"); - $this->assertSame('passwords', $matches[0]->dictionaryName, "Dictionary name incorrect"); + $this->assertSame('pass', $matches[0]->token, 'Token incorrect'); + $this->assertSame('passwords', $matches[0]->dictionaryName, 'Dictionary name incorrect'); $password = '8dll20BEN3lld0'; $matches = DictionaryMatch::match($password); $this->assertCount(2, $matches); $password = '39Kx9.1x0!3n6'; - $matches = DictionaryMatch::match($password, array($password)); + $matches = DictionaryMatch::match($password, [$password]); $this->assertCount(1, $matches); - $this->assertSame('user_inputs', $matches[0]->dictionaryName, "Dictionary name incorrect"); - } + $this->assertSame('user_inputs', $matches[0]->dictionaryName, 'Dictionary name incorrect'); + } public function testEntropy() { $password = 'password'; $matches = DictionaryMatch::match($password); // Match 0 is "pass" with rank 35. - $this->assertEquals(log(35, 2), $matches[0]->getEntropy()); + $this->assertSame(log(35, 2), $matches[0]->getEntropy()); } -} \ No newline at end of file +} diff --git a/test/Matchers/DigitTest.php b/test/Matchers/DigitTest.php index 4d39303..f5af132 100644 --- a/test/Matchers/DigitTest.php +++ b/test/Matchers/DigitTest.php @@ -2,9 +2,13 @@ namespace ZxcvbnPhp\Test\Matchers; +use PHPUnit\Framework\TestCase; use ZxcvbnPhp\Matchers\DigitMatch; -class DigitTest extends \PHPUnit_Framework_TestCase +/** + * @covers \ZxcvbnPhp\Matchers\DigitMatch + */ +class DigitTest extends TestCase { public function testMatch() { @@ -15,25 +19,25 @@ public function testMatch() $password = '123'; $matches = DigitMatch::match($password); $this->assertCount(1, $matches); - $this->assertSame($password, $matches[0]->token, "Token incorrect"); - $this->assertSame($password, $matches[0]->password, "Password incorrect"); + $this->assertSame($password, $matches[0]->token, 'Token incorrect'); + $this->assertSame($password, $matches[0]->password, 'Password incorrect'); $password = 'password123'; $matches = DigitMatch::match($password); $this->assertCount(1, $matches); - $this->assertEquals(strpos($password, '1'), $matches[0]->begin, "Match begin character incorrect"); - $this->assertEquals(strlen($password) - 1, $matches[0]->end, "Match end character incorrect"); - $this->assertEquals(3, strlen($matches[0]->token), "Token length incorrect"); + $this->assertSame(strpos($password, '1'), $matches[0]->begin, 'Match begin character incorrect'); + $this->assertSame(strlen($password) - 1, $matches[0]->end, 'Match end character incorrect'); + $this->assertSame(3, strlen($matches[0]->token), 'Token length incorrect'); $password = '123 456546'; $matches = DigitMatch::match($password); $this->assertCount(2, $matches); - } + } public function testEntropy() { $password = '123'; $matches = DigitMatch::match($password); - $this->assertEquals(log(pow(10, 3), 2), $matches[0]->getEntropy()); + $this->assertSame(log(10 ** 3, 2), $matches[0]->getEntropy()); } -} \ No newline at end of file +} diff --git a/test/Matchers/L33tTest.php b/test/Matchers/L33tTest.php index 09f6e4b..5847f23 100644 --- a/test/Matchers/L33tTest.php +++ b/test/Matchers/L33tTest.php @@ -2,9 +2,13 @@ namespace ZxcvbnPhp\Test\Matchers; +use PHPUnit\Framework\TestCase; use ZxcvbnPhp\Matchers\L33tMatch; -class L33tTest extends \PHPUnit_Framework_TestCase +/** + * @covers \ZxcvbnPhp\Matchers\L33tMatch + */ +class L33tTest extends TestCase { public function testMatch() { @@ -32,10 +36,10 @@ public function testEntropy() $password = 'p4ss'; $matches = L33tMatch::match($password); // 'pass' has a rank of 35 and l33t entropy of 1. - $this->assertEquals(log(35, 2) + 1, $matches[0]->getEntropy()); + $this->assertSame(log(35, 2) + 1, $matches[0]->getEntropy()); $password = 'p45s'; $matches = L33tMatch::match($password); - $this->assertEquals(log(35, 2) + 2, $matches[0]->getEntropy()); + $this->assertSame(log(35, 2) + 2, $matches[0]->getEntropy()); } -} \ No newline at end of file +} diff --git a/test/Matchers/RepeatTest.php b/test/Matchers/RepeatTest.php index f2d6b8f..11631cc 100644 --- a/test/Matchers/RepeatTest.php +++ b/test/Matchers/RepeatTest.php @@ -2,9 +2,13 @@ namespace ZxcvbnPhp\Test\Matchers; +use PHPUnit\Framework\TestCase; use ZxcvbnPhp\Matchers\RepeatMatch; -class RepeatTest extends \PHPUnit_Framework_TestCase +/** + * @covers \ZxcvbnPhp\Matchers\RepeatMatch + */ +class RepeatTest extends TestCase { public function testMatch() { @@ -19,31 +23,30 @@ public function testMatch() $password = 'aaa'; $matches = RepeatMatch::match($password); $this->assertCount(1, $matches); - $this->assertEquals('aaa', $matches[0]->token, "Token incorrect"); - $this->assertEquals('a', $matches[0]->repeatedChar, "Repeated character incorrect"); + $this->assertSame('aaa', $matches[0]->token, 'Token incorrect'); + $this->assertSame('a', $matches[0]->repeatedChar, 'Repeated character incorrect'); $password = 'aaa1bbb'; $matches = RepeatMatch::match($password); $this->assertCount(2, $matches); - $this->assertEquals('bbb', $matches[1]->token, "Token incorrect"); - $this->assertEquals('b', $matches[1]->repeatedChar, "Repeated character incorrect"); + $this->assertSame('bbb', $matches[1]->token, 'Token incorrect'); + $this->assertSame('b', $matches[1]->repeatedChar, 'Repeated character incorrect'); $password = 'taaaaaa'; $matches = RepeatMatch::match($password); $this->assertCount(1, $matches); - $this->assertSame('aaaaaa', $matches[0]->token, "Token incorrect"); - $this->assertSame('a', $matches[0]->repeatedChar, "Repeated character incorrect"); + $this->assertSame('aaaaaa', $matches[0]->token, 'Token incorrect'); + $this->assertSame('a', $matches[0]->repeatedChar, 'Repeated character incorrect'); } public function testEntropy() { $password = 'aaa'; $matches = RepeatMatch::match($password); - $this->assertEquals(log(26 * 3, 2), $matches[0]->getEntropy()); + $this->assertSame(log(26 * 3, 2), $matches[0]->getEntropy()); $password = '..................'; $matches = RepeatMatch::match($password); - $this->assertEquals(log(33 * strlen($password), 2), $matches[0]->getEntropy()); + $this->assertSame(log(33 * strlen($password), 2), $matches[0]->getEntropy()); } - -} \ No newline at end of file +} diff --git a/test/Matchers/SequenceTest.php b/test/Matchers/SequenceTest.php index 7aafdd7..6b5be5a 100644 --- a/test/Matchers/SequenceTest.php +++ b/test/Matchers/SequenceTest.php @@ -2,9 +2,13 @@ namespace ZxcvbnPhp\Test\Matchers; +use PHPUnit\Framework\TestCase; use ZxcvbnPhp\Matchers\SequenceMatch; -class SequenceTest extends \PHPUnit_Framework_TestCase +/** + * @covers \ZxcvbnPhp\Matchers\SequenceMatch + */ +class SequenceTest extends TestCase { public function testMatch() { @@ -19,40 +23,40 @@ public function testMatch() $password = '12345'; $matches = SequenceMatch::match($password); $this->assertCount(1, $matches); - $this->assertSame($password, $matches[0]->token, "Token incorrect"); - $this->assertSame($password, $matches[0]->password, "Password incorrect"); + $this->assertSame($password, $matches[0]->token, 'Token incorrect'); + $this->assertSame($password, $matches[0]->password, 'Password incorrect'); $password = 'ZYX'; $matches = SequenceMatch::match($password); $this->assertCount(1, $matches); - $this->assertSame($password, $matches[0]->token, "Token incorrect"); - $this->assertSame($password, $matches[0]->password, "Password incorrect"); + $this->assertSame($password, $matches[0]->token, 'Token incorrect'); + $this->assertSame($password, $matches[0]->password, 'Password incorrect'); $password = 'pass123wordZYX'; $matches = SequenceMatch::match($password); $this->assertCount(2, $matches); - $this->assertSame('123', $matches[0]->token, "First match token incorrect"); - $this->assertSame('ZYX', $matches[1]->token, "Second match token incorrect"); + $this->assertSame('123', $matches[0]->token, 'First match token incorrect'); + $this->assertSame('ZYX', $matches[1]->token, 'Second match token incorrect'); $password = 'wordZYX '; $matches = SequenceMatch::match($password); - $this->assertEquals('ZYX', $matches[0]->token, "First match token incorrect"); + $this->assertSame('ZYX', $matches[0]->token, 'First match token incorrect'); $password = 'XYZ123 '; $matches = SequenceMatch::match($password); - $this->assertEquals('XYZ', $matches[0]->token, "First match token incorrect"); - $this->assertEquals('123', $matches[1]->token, "Second match token incorrect"); + $this->assertSame('XYZ', $matches[0]->token, 'First match token incorrect'); + $this->assertSame('123', $matches[1]->token, 'Second match token incorrect'); $password = 'abc213456de'; $matches = SequenceMatch::match($password); - $this->assertEquals('abc', $matches[0]->token, "First match token incorrect"); - $this->assertEquals('3456', $matches[1]->token, "Second match token incorrect"); + $this->assertSame('abc', $matches[0]->token, 'First match token incorrect'); + $this->assertSame('3456', $matches[1]->token, 'Second match token incorrect'); } public function testEntropy() { $password = '12345'; $matches = SequenceMatch::match($password); - $this->assertEquals(log(5, 2) + 1, $matches[0]->getEntropy()); + $this->assertSame(log(5, 2) + 1, $matches[0]->getEntropy()); } -} \ No newline at end of file +} diff --git a/test/Matchers/SpatialTest.php b/test/Matchers/SpatialTest.php index 0c47807..9033223 100644 --- a/test/Matchers/SpatialTest.php +++ b/test/Matchers/SpatialTest.php @@ -2,9 +2,13 @@ namespace ZxcvbnPhp\Test\Matchers; +use PHPUnit\Framework\TestCase; use ZxcvbnPhp\Matchers\SpatialMatch; -class SpatialTest extends \PHPUnit_Framework_TestCase +/** + * @covers \ZxcvbnPhp\Matchers\SpatialMatch + */ +class SpatialTest extends TestCase { public function testMatch() { @@ -19,17 +23,17 @@ public function testMatch() $password = 'qwerty'; $matches = SpatialMatch::match($password); $this->assertCount(1, $matches); - $this->assertSame(1, $matches[0]->turns, "Turns incorrect"); + $this->assertSame(1, $matches[0]->turns, 'Turns incorrect'); $password = '8qwerty_'; $matches = SpatialMatch::match($password); $this->assertCount(1, $matches); - $this->assertSame('qwerty', $matches[0]->token, "Token incorrect"); + $this->assertSame('qwerty', $matches[0]->token, 'Token incorrect'); $password = 'qwER43@!'; $matches = SpatialMatch::match($password); $this->assertCount(2, $matches); - $this->assertSame('dvorak', $matches[1]->graph, "Graph incorrect"); + $this->assertSame('dvorak', $matches[1]->graph, 'Graph incorrect'); $password = 'AOEUIDHG&*()LS_'; $matches = SpatialMatch::match($password); @@ -40,11 +44,11 @@ public function testEntropy() { $password = 'reds'; $matches = SpatialMatch::match($password); - $this->assertEquals(15.23614334369886, $matches[0]->getEntropy()); + $this->assertSame(15.23614334369886, $matches[0]->getEntropy()); // Test shifted character. $password = 'rEds'; $matches = SpatialMatch::match($password); - $this->assertEquals(17.55807143858622, $matches[0]->getEntropy()); + $this->assertSame(17.55807143858622, $matches[0]->getEntropy()); } -} \ No newline at end of file +} diff --git a/test/Matchers/YearTest.php b/test/Matchers/YearTest.php index 861b39f..049c8d6 100644 --- a/test/Matchers/YearTest.php +++ b/test/Matchers/YearTest.php @@ -2,9 +2,13 @@ namespace ZxcvbnPhp\Test\Matchers; +use PHPUnit\Framework\TestCase; use ZxcvbnPhp\Matchers\YearMatch; -class YearTest extends \PHPUnit_Framework_TestCase +/** + * @covers \ZxcvbnPhp\Matchers\YearMatch + */ +class YearTest extends TestCase { public function testMatch() { @@ -15,19 +19,19 @@ public function testMatch() $password = '1900'; $matches = YearMatch::match($password); $this->assertCount(1, $matches); - $this->assertSame($password, $matches[0]->token, "Token incorrect"); - $this->assertSame($password, $matches[0]->password, "Password incorrect"); + $this->assertSame($password, $matches[0]->token, 'Token incorrect'); + $this->assertSame($password, $matches[0]->password, 'Password incorrect'); $password = 'password1900'; $matches = YearMatch::match($password); $this->assertCount(1, $matches); - $this->assertSame("1900", $matches[0]->token, "Token incorrect"); + $this->assertSame('1900', $matches[0]->token, 'Token incorrect'); } public function testEntropy() { $password = '1900'; $matches = YearMatch::match($password); - $this->assertEquals(log(119, 2), $matches[0]->getEntropy()); + $this->assertSame(log(119, 2), $matches[0]->getEntropy()); } -} \ No newline at end of file +} diff --git a/test/ScorerTest.php b/test/ScorerTest.php index 98aca4e..4b96107 100644 --- a/test/ScorerTest.php +++ b/test/ScorerTest.php @@ -2,15 +2,18 @@ namespace ZxcvbnPhp\Test; +use PHPUnit\Framework\TestCase; use ZxcvbnPhp\Scorer; -class ScorerTest extends \PHPUnit_Framework_TestCase +/** + * @covers \ZxcvbnPhp\Scorer + */ +class ScorerTest extends TestCase { - public function testScore() { $scorer = new Scorer(); - $this->assertEquals(0, $scorer->score(0), 'Score incorrect'); + $this->assertSame(0, $scorer->score(0), 'Score incorrect'); } public function testCrackTime() @@ -18,6 +21,6 @@ public function testCrackTime() $scorer = new Scorer(); $scorer->score(8); $metrics = $scorer->getMetrics(); - $this->assertEquals(0.0128, $metrics['crack_time'], 'Crack time incorrect'); + $this->assertSame(0.0128, $metrics['crack_time'], 'Crack time incorrect'); } -} \ No newline at end of file +} diff --git a/test/SearcherTest.php b/test/SearcherTest.php index ce610f1..53ddbe2 100644 --- a/test/SearcherTest.php +++ b/test/SearcherTest.php @@ -2,27 +2,29 @@ namespace ZxcvbnPhp\Test; +use PHPUnit\Framework\TestCase; use ZxcvbnPhp\Matchers\RepeatMatch; use ZxcvbnPhp\Searcher; -use ZxcvbnPhp\Matchers\Repeat; -class SearcherTest extends \PHPUnit_Framework_TestCase +/** + * @covers \ZxcvbnPhp\Searcher + */ +class SearcherTest extends TestCase { - public function testMinimumEntropyMatchSequence() { $searcher = new Searcher(); // Test simple password with no matches. $password = 'a'; - $entropy = $searcher->getMinimumEntropy($password, array()); - $this->assertEquals(log(26, 2), $entropy, 'Entropy incorrect for single character lowercase password'); + $entropy = $searcher->getMinimumEntropy($password, []); + $this->assertSame(log(26, 2), $entropy, 'Entropy incorrect for single character lowercase password'); // Test password with repeat pattern. $password = 'aaa'; $match = new RepeatMatch($password, 0, 2, 'aaa', 'a'); - $entropy = $searcher->getMinimumEntropy($password, array($match)); - $this->assertEquals(log(26 * 3, 2), $entropy, "Entropy incorrect for '$password'"); + $entropy = $searcher->getMinimumEntropy($password, [$match]); + $this->assertSame(log(26 * 3, 2), $entropy, "Entropy incorrect for '${password}'"); $sequence = $searcher->matchSequence; - $this->assertSame($match, $sequence[0], "Best match incorrect"); + $this->assertSame($match, $sequence[0], 'Best match incorrect'); } -} \ No newline at end of file +} diff --git a/test/ZxcvbnTest.php b/test/ZxcvbnTest.php index e14c68f..8c7bcf9 100644 --- a/test/ZxcvbnTest.php +++ b/test/ZxcvbnTest.php @@ -2,35 +2,38 @@ namespace ZxcvbnPhp\Test; +use PHPUnit\Framework\TestCase; use ZxcvbnPhp\Zxcvbn; -class ZxcvbnTest extends \PHPUnit_Framework_TestCase +/** + * @covers \ZxcvbnPhp\Zxcvbn + */ +class ZxcvbnTest extends TestCase { - public function testZxcvbn() { $zxcvbn = new Zxcvbn(); - $result = $zxcvbn->passwordStrength(""); - $this->assertEquals(0, $result['entropy'], "Entropy incorrect"); - $this->assertEquals(0, $result['score'], "Score incorrect"); + $result = $zxcvbn->passwordStrength(''); + $this->assertSame(0, $result['entropy'], 'Entropy incorrect'); + $this->assertSame(0, $result['score'], 'Score incorrect'); - $result = $zxcvbn->passwordStrength("password"); - $this->assertEquals(0, $result['entropy'], "Entropy incorrect"); - $this->assertEquals(0, $result['score'], "Score incorrect"); + $result = $zxcvbn->passwordStrength('password'); + $this->assertSame(0.0, $result['entropy'], 'Entropy incorrect'); + $this->assertSame(0, $result['score'], 'Score incorrect'); - $result = $zxcvbn->passwordStrength("jjjjj"); - $this->assertSame('repeat', $result['match_sequence'][0]->pattern, "Pattern incorrect"); + $result = $zxcvbn->passwordStrength('jjjjj'); + $this->assertSame('repeat', $result['match_sequence'][0]->pattern, 'Pattern incorrect'); $password = 'abc213456de'; $result = $zxcvbn->passwordStrength($password); - $this->assertEquals(1, $result['score'], "Score incorrect"); + $this->assertSame(1, $result['score'], 'Score incorrect'); $password = '123abcdefgh334123abcdefgh334123abcdefgh334'; $result = $zxcvbn->passwordStrength($password); - $this->assertEquals(4, $result['score'], "Score incorrect"); + $this->assertSame(4, $result['score'], 'Score incorrect'); $password = '3m8dlD.3Y@example.c0m'; - $result = $zxcvbn->passwordStrength($password, array($password)); - $this->assertEquals(0, $result['score'], "Score incorrect"); + $result = $zxcvbn->passwordStrength($password, [$password]); + $this->assertSame(0, $result['score'], 'Score incorrect'); } } diff --git a/test/config/bootstrap.php b/test/config/bootstrap.php index f408832..ce25f65 100644 --- a/test/config/bootstrap.php +++ b/test/config/bootstrap.php @@ -1,6 +1,6 @@