From c35d52bd53fafd4a92c72c8e0b8489ebfc1a4306 Mon Sep 17 00:00:00 2001 From: Rob DiMarco Date: Wed, 18 Nov 2015 22:05:17 -0800 Subject: [PATCH 01/37] Addresses issue #72 - update link to current spec --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 7f1b026b..5d53658d 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,7 @@ PHP-JWT ======= -A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should -conform to the [current spec](http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-06) +A simple library to encode and decode JSON Web Tokens (JWT) in PHP, conforming to [RFC 7519](https://tools.ietf.org/html/rfc7519). Installation ------------ From d99ab404a14a6169d0e3961a941e67e0bc3f3cea Mon Sep 17 00:00:00 2001 From: Arjan Keeman Date: Wed, 30 Dec 2015 22:08:26 +0100 Subject: [PATCH 02/37] Remove null as possible key value in docblock The docblock states that null is a possible value for $key, however, it clearly results in an exception. --- src/JWT.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/JWT.php b/src/JWT.php index b3532df7..955351b5 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -39,11 +39,11 @@ class JWT /** * Decodes a JWT string into a PHP object. * - * @param string $jwt The JWT - * @param string|array|null $key The key, or map of keys. - * If the algorithm used is asymmetric, this is the public key - * @param array $allowed_algs List of supported verification algorithms - * Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256' + * @param string $jwt The JWT + * @param string|array $key The key, or map of keys. + * If the algorithm used is asymmetric, this is the public key + * @param array $allowed_algs List of supported verification algorithms + * Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256' * * @return object The JWT's payload as a PHP object * From f2758c8ebdc88b48dbcdc91aed8b2ad873df688f Mon Sep 17 00:00:00 2001 From: Lars Moelleken Date: Mon, 1 Feb 2016 13:26:42 +0100 Subject: [PATCH 03/37] [+]: ".gitattributes" <- prevent installing special files via composer [*]: add missing phpdoc --- .gitattributes | 8 ++++++++ src/JWT.php | 1 + 2 files changed, 9 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..c682f861 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,8 @@ +* text=auto + +/tests export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore +/.travis.yml export-ignore +/phpunit.xml.dist export-ignore +/run-tests.sh export-ignore diff --git a/src/JWT.php b/src/JWT.php index b3532df7..78512a19 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -130,6 +130,7 @@ public static function decode($jwt, $key, $allowed_algs = array()) * If the algorithm used is asymmetric, this is the private key * @param string $alg The signing algorithm. * Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256' + * @param mixed $keyId * @param array $head An array with header elements to attach * * @return string A signed JWT From bb6d53b94367d4e32bbcc0f7e90b658b37fdbdfd Mon Sep 17 00:00:00 2001 From: Joseph McDermott Date: Fri, 29 Apr 2016 15:18:23 +0100 Subject: [PATCH 04/37] Allow timestamp to be specified rather than relying on PHP time() function --- src/JWT.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/JWT.php b/src/JWT.php index b3532df7..6a120631 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -29,6 +29,13 @@ class JWT */ public static $leeway = 0; + /** + * Allow the current timestamp to be specified. + * Useful for fixing a value within unit testing. + * Will default to PHP time() value if null. + */ + public static $timestamp = null; + public static $supported_algs = array( 'HS256' => array('hash_hmac', 'SHA256'), 'HS512' => array('hash_hmac', 'SHA512'), @@ -59,6 +66,8 @@ class JWT */ public static function decode($jwt, $key, $allowed_algs = array()) { + $timestamp = is_null(self::$timestamp) ? time() : self::$timestamp; + if (empty($key)) { throw new InvalidArgumentException('Key may not be empty'); } @@ -99,7 +108,7 @@ public static function decode($jwt, $key, $allowed_algs = array()) // Check if the nbf if it is defined. This is the time that the // token can actually be used. If it's not yet that time, abort. - if (isset($payload->nbf) && $payload->nbf > (time() + self::$leeway)) { + if (isset($payload->nbf) && $payload->nbf > ($timestamp + self::$leeway)) { throw new BeforeValidException( 'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->nbf) ); @@ -108,14 +117,14 @@ public static function decode($jwt, $key, $allowed_algs = array()) // Check that this token has been created before 'now'. This prevents // using tokens that have been created for later use (and haven't // correctly used the nbf claim). - if (isset($payload->iat) && $payload->iat > (time() + self::$leeway)) { + if (isset($payload->iat) && $payload->iat > ($timestamp + self::$leeway)) { throw new BeforeValidException( 'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->iat) ); } // Check if this token has expired. - if (isset($payload->exp) && (time() - self::$leeway) >= $payload->exp) { + if (isset($payload->exp) && ($timestamp - self::$leeway) >= $payload->exp) { throw new ExpiredException('Expired token'); } From d6e222c1406367e879668d24968e087de1241c0f Mon Sep 17 00:00:00 2001 From: Joseph McDermott Date: Tue, 3 May 2016 09:43:19 +0100 Subject: [PATCH 05/37] Commit with Google email address for CLA --- src/JWT.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/JWT.php b/src/JWT.php index 6a120631..5b430404 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -32,6 +32,7 @@ class JWT /** * Allow the current timestamp to be specified. * Useful for fixing a value within unit testing. + * * Will default to PHP time() value if null. */ public static $timestamp = null; From 1db579cabf402d6b34ce9d909ef96784b7f3f04a Mon Sep 17 00:00:00 2001 From: Kunal Mehta Date: Thu, 9 Jun 2016 16:34:13 -0700 Subject: [PATCH 06/37] Remove newline at beginning of run-tests.sh The extra newline trips a warning in lintian when packaging for Debian, so just remove it. --- run-tests.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/run-tests.sh b/run-tests.sh index d37c30fd..c4bb9348 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -1,4 +1,3 @@ - #!/usr/bin/env bash gpg --fingerprint D8406D0D82947747293778314AA394086372C20A if [ $? -ne 0 ]; then From d6186e0519e606af8f4dcf561b073066ba8035d1 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Thu, 16 Jun 2016 22:01:28 +0200 Subject: [PATCH 07/37] Fix exceptions classes (#81) * Use InvalidArgumentException when $allowed_algs is not array > Exception thrown if an argument is not of the expected type. http://php.net/manual/en/class.invalidargumentexception.php * Use RuntimeExceptions for exceptions related with unencoded data. RuntimeExceptions is the correct exception error source is the decoded data. Note LogicExceptions as defined in PHP documentation implies a modification in the code by the developer. > Exception that represents error in the program logic. This kind of exception should lead directly to a fix in your code. http://php.net/manual/en/class.logicexception.php But the token is a data provided by an external source which is out side of the control of the developer so there is no way of prevent malformed tokens. --- src/JWT.php | 14 ++++++++------ tests/JWTTest.php | 6 +++--- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/JWT.php b/src/JWT.php index 7228e96a..0e613688 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -55,7 +55,6 @@ class JWT * * @return object The JWT's payload as a PHP object * - * @throws DomainException Algorithm was not provided * @throws UnexpectedValueException Provided JWT was invalid * @throws SignatureInvalidException Provided JWT was invalid because the signature verification failed * @throws BeforeValidException Provided JWT is trying to be used before it's eligible as defined by 'nbf' @@ -72,6 +71,9 @@ public static function decode($jwt, $key, $allowed_algs = array()) if (empty($key)) { throw new InvalidArgumentException('Key may not be empty'); } + if (!is_array($allowed_algs)) { + throw new InvalidArgumentException('Algorithm not allowed'); + } $tks = explode('.', $jwt); if (count($tks) != 3) { throw new UnexpectedValueException('Wrong number of segments'); @@ -86,19 +88,19 @@ public static function decode($jwt, $key, $allowed_algs = array()) $sig = JWT::urlsafeB64Decode($cryptob64); if (empty($header->alg)) { - throw new DomainException('Empty algorithm'); + throw new UnexpectedValueException('Empty algorithm'); } if (empty(self::$supported_algs[$header->alg])) { - throw new DomainException('Algorithm not supported'); + throw new UnexpectedValueException('Algorithm not supported'); } - if (!is_array($allowed_algs) || !in_array($header->alg, $allowed_algs)) { - throw new DomainException('Algorithm not allowed'); + if (!in_array($header->alg, $allowed_algs)) { + throw new UnexpectedValueException('Algorithm not allowed'); } if (is_array($key) || $key instanceof \ArrayAccess) { if (isset($header->kid)) { $key = $key[$header->kid]; } else { - throw new DomainException('"kid" empty, unable to lookup correct key'); + throw new UnexpectedValueException('"kid" empty, unable to lookup correct key'); } } diff --git a/tests/JWTTest.php b/tests/JWTTest.php index 89de8d28..e99ea03a 100644 --- a/tests/JWTTest.php +++ b/tests/JWTTest.php @@ -232,21 +232,21 @@ public function testArrayAccessKIDChooser() public function testNoneAlgorithm() { $msg = JWT::encode('abc', 'my_key'); - $this->setExpectedException('DomainException'); + $this->setExpectedException('UnexpectedValueException'); JWT::decode($msg, 'my_key', array('none')); } public function testIncorrectAlgorithm() { $msg = JWT::encode('abc', 'my_key'); - $this->setExpectedException('DomainException'); + $this->setExpectedException('UnexpectedValueException'); JWT::decode($msg, 'my_key', array('RS256')); } public function testMissingAlgorithm() { $msg = JWT::encode('abc', 'my_key'); - $this->setExpectedException('DomainException'); + $this->setExpectedException('UnexpectedValueException'); JWT::decode($msg, 'my_key'); } From d42564707c695e96f1208d9af52d8f599db044c6 Mon Sep 17 00:00:00 2001 From: Tom Chapman Date: Tue, 28 Jun 2016 17:57:35 +0100 Subject: [PATCH 08/37] Add in support for late static binding, so that developers can extend and override variables / methods if they so require (#88) --- src/JWT.php | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/JWT.php b/src/JWT.php index 0e613688..6d30e941 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -66,7 +66,7 @@ class JWT */ public static function decode($jwt, $key, $allowed_algs = array()) { - $timestamp = is_null(self::$timestamp) ? time() : self::$timestamp; + $timestamp = is_null(static::$timestamp) ? time() : static::$timestamp; if (empty($key)) { throw new InvalidArgumentException('Key may not be empty'); @@ -79,18 +79,18 @@ public static function decode($jwt, $key, $allowed_algs = array()) throw new UnexpectedValueException('Wrong number of segments'); } list($headb64, $bodyb64, $cryptob64) = $tks; - if (null === ($header = JWT::jsonDecode(JWT::urlsafeB64Decode($headb64)))) { + if (null === ($header = static::jsonDecode(static::urlsafeB64Decode($headb64)))) { throw new UnexpectedValueException('Invalid header encoding'); } - if (null === $payload = JWT::jsonDecode(JWT::urlsafeB64Decode($bodyb64))) { + if (null === $payload = static::jsonDecode(static::urlsafeB64Decode($bodyb64))) { throw new UnexpectedValueException('Invalid claims encoding'); } - $sig = JWT::urlsafeB64Decode($cryptob64); + $sig = static::urlsafeB64Decode($cryptob64); if (empty($header->alg)) { throw new UnexpectedValueException('Empty algorithm'); } - if (empty(self::$supported_algs[$header->alg])) { + if (empty(static::$supported_algs[$header->alg])) { throw new UnexpectedValueException('Algorithm not supported'); } if (!in_array($header->alg, $allowed_algs)) { @@ -105,13 +105,13 @@ public static function decode($jwt, $key, $allowed_algs = array()) } // Check the signature - if (!JWT::verify("$headb64.$bodyb64", $sig, $key, $header->alg)) { + if (!static::verify("$headb64.$bodyb64", $sig, $key, $header->alg)) { throw new SignatureInvalidException('Signature verification failed'); } // Check if the nbf if it is defined. This is the time that the // token can actually be used. If it's not yet that time, abort. - if (isset($payload->nbf) && $payload->nbf > ($timestamp + self::$leeway)) { + if (isset($payload->nbf) && $payload->nbf > ($timestamp + static::$leeway)) { throw new BeforeValidException( 'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->nbf) ); @@ -120,14 +120,14 @@ public static function decode($jwt, $key, $allowed_algs = array()) // Check that this token has been created before 'now'. This prevents // using tokens that have been created for later use (and haven't // correctly used the nbf claim). - if (isset($payload->iat) && $payload->iat > ($timestamp + self::$leeway)) { + if (isset($payload->iat) && $payload->iat > ($timestamp + static::$leeway)) { throw new BeforeValidException( 'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->iat) ); } // Check if this token has expired. - if (isset($payload->exp) && ($timestamp - self::$leeway) >= $payload->exp) { + if (isset($payload->exp) && ($timestamp - static::$leeway) >= $payload->exp) { throw new ExpiredException('Expired token'); } @@ -160,12 +160,12 @@ public static function encode($payload, $key, $alg = 'HS256', $keyId = null, $he $header = array_merge($head, $header); } $segments = array(); - $segments[] = JWT::urlsafeB64Encode(JWT::jsonEncode($header)); - $segments[] = JWT::urlsafeB64Encode(JWT::jsonEncode($payload)); + $segments[] = static::urlsafeB64Encode(static::jsonEncode($header)); + $segments[] = static::urlsafeB64Encode(static::jsonEncode($payload)); $signing_input = implode('.', $segments); - $signature = JWT::sign($signing_input, $key, $alg); - $segments[] = JWT::urlsafeB64Encode($signature); + $signature = static::sign($signing_input, $key, $alg); + $segments[] = static::urlsafeB64Encode($signature); return implode('.', $segments); } @@ -184,10 +184,10 @@ public static function encode($payload, $key, $alg = 'HS256', $keyId = null, $he */ public static function sign($msg, $key, $alg = 'HS256') { - if (empty(self::$supported_algs[$alg])) { + if (empty(static::$supported_algs[$alg])) { throw new DomainException('Algorithm not supported'); } - list($function, $algorithm) = self::$supported_algs[$alg]; + list($function, $algorithm) = static::$supported_algs[$alg]; switch($function) { case 'hash_hmac': return hash_hmac($algorithm, $msg, $key, true); @@ -217,11 +217,11 @@ public static function sign($msg, $key, $alg = 'HS256') */ private static function verify($msg, $signature, $key, $alg) { - if (empty(self::$supported_algs[$alg])) { + if (empty(static::$supported_algs[$alg])) { throw new DomainException('Algorithm not supported'); } - list($function, $algorithm) = self::$supported_algs[$alg]; + list($function, $algorithm) = static::$supported_algs[$alg]; switch($function) { case 'openssl': $success = openssl_verify($msg, $signature, $key, $algorithm); @@ -236,13 +236,13 @@ private static function verify($msg, $signature, $key, $alg) if (function_exists('hash_equals')) { return hash_equals($signature, $hash); } - $len = min(self::safeStrlen($signature), self::safeStrlen($hash)); + $len = min(static::safeStrlen($signature), static::safeStrlen($hash)); $status = 0; for ($i = 0; $i < $len; $i++) { $status |= (ord($signature[$i]) ^ ord($hash[$i])); } - $status |= (self::safeStrlen($signature) ^ self::safeStrlen($hash)); + $status |= (static::safeStrlen($signature) ^ static::safeStrlen($hash)); return ($status === 0); } @@ -276,7 +276,7 @@ public static function jsonDecode($input) } if (function_exists('json_last_error') && $errno = json_last_error()) { - JWT::handleJsonError($errno); + static::handleJsonError($errno); } elseif ($obj === null && $input !== 'null') { throw new DomainException('Null result with non-null input'); } @@ -296,7 +296,7 @@ public static function jsonEncode($input) { $json = json_encode($input); if (function_exists('json_last_error') && $errno = json_last_error()) { - JWT::handleJsonError($errno); + static::handleJsonError($errno); } elseif ($json === 'null' && $input !== null) { throw new DomainException('Null result with non-null input'); } From dccf163dc8ed7ed6a00afc06c51ee5186a428d35 Mon Sep 17 00:00:00 2001 From: Rob DiMarco Date: Sun, 17 Jul 2016 21:51:16 -0700 Subject: [PATCH 09/37] Update README for v4.0.0 --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 5d53658d..d4589b1c 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,12 @@ $decoded = JWT::decode($jwt, $key, array('HS256')); Changelog --------- +#### 4.0.0 / 2016-07-17 +- Add support for late static binding. See [#88](https://github.com/firebase/php-jwt/pull/88) for details. Thanks to [@chappy84](https://github.com/chappy84)! +- Use static `$timestamp` instead of `time()` to improve unit testing. See [#93](https://github.com/firebase/php-jwt/pull/93) for details. Thanks to [@josephmcdermott](https://github.com/josephmcdermott)! +- Fixes to exceptions classes. See [#81](https://github.com/firebase/php-jwt/pull/81) for details. Thanks to [@Maks3w](https://github.com/Maks3w)! +- Fixes to PHPDoc. See [#76](https://github.com/firebase/php-jwt/pull/76) for details. Thanks to [@akeeman](https://github.com/akeeman)! + #### 3.0.0 / 2015-07-22 - Minimum PHP version updated from `5.2.0` to `5.3.0`. - Add `\Firebase\JWT` namespace. See From 0ac88049d2b75ceb23c266702be0117cfd9ea5a8 Mon Sep 17 00:00:00 2001 From: thanhpv Date: Wed, 10 Aug 2016 11:01:19 +0700 Subject: [PATCH 10/37] Update readme :computer: --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 55e8e02f..d6a89c3a 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,13 @@ $decoded = JWT::decode($jwt, $key, array('HS256')); Changelog --------- +#### 4.0.0 / 2016-08-10 +- Update to 4.0.0 from upstream +- Add support for late static binding. See [#88](https://github.com/firebase/php-jwt/pull/88) for details. Thanks to [@chappy84](https://github.com/chappy84)! +- Use static `$timestamp` instead of `time()` to improve unit testing. See [#93](https://github.com/firebase/php-jwt/pull/93) for details. Thanks to [@josephmcdermott](https://github.com/josephmcdermott)! +- Fixes to exceptions classes. See [#81](https://github.com/firebase/php-jwt/pull/81) for details. Thanks to [@Maks3w](https://github.com/Maks3w)! +- Fixes to PHPDoc. See [#76](https://github.com/firebase/php-jwt/pull/76) for details. Thanks to [@akeeman](https://github.com/akeeman)! + #### 3.0.3 / 2015-11-05 - Minimum PHP version updated from `5.3.0` to `5.4.0`. - Add JWK support From 3aa3d978973f080746b2f2f75b10d3f38cbb0557 Mon Sep 17 00:00:00 2001 From: Petr Kotek Date: Thu, 1 Sep 2016 01:16:29 +0200 Subject: [PATCH 11/37] Travis: run tests also under PHP 5.6 and PHP 7.0 (#108) --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index b1135a16..96a0f19c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,8 @@ php: - 5.3 - 5.4 - 5.5 + - 5.6 + - 7.0 - hhvm sudo: false From 491ab3a80566cd1427549994ee7a07d9154311c4 Mon Sep 17 00:00:00 2001 From: Tim Stamp Date: Mon, 12 Dec 2016 12:14:10 +0000 Subject: [PATCH 12/37] bugfix: 'kid' not in given key list if 'kid' value is not found in the given key map, should throw an exception. Instead, it was outputting a php warning for using an undefined index, resulting in a null key. --- src/JWT.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/JWT.php b/src/JWT.php index 6d30e941..8170dba2 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -98,6 +98,9 @@ public static function decode($jwt, $key, $allowed_algs = array()) } if (is_array($key) || $key instanceof \ArrayAccess) { if (isset($header->kid)) { + if(!isset($key[$header->kid])) { + throw new UnexpectedValueException('"kid" not found in key map, unable to lookup correct key'); + } $key = $key[$header->kid]; } else { throw new UnexpectedValueException('"kid" empty, unable to lookup correct key'); From 64d7eb06134058728fae1c8027c8ebe4e61bdfc6 Mon Sep 17 00:00:00 2001 From: Tim Stamp Date: Tue, 24 Jan 2017 10:56:53 +0000 Subject: [PATCH 13/37] cosmetic updates --- src/JWT.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/JWT.php b/src/JWT.php index 8170dba2..d45052cf 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -98,8 +98,8 @@ public static function decode($jwt, $key, $allowed_algs = array()) } if (is_array($key) || $key instanceof \ArrayAccess) { if (isset($header->kid)) { - if(!isset($key[$header->kid])) { - throw new UnexpectedValueException('"kid" not found in key map, unable to lookup correct key'); + if (!isset($key[$header->kid])) { + throw new UnexpectedValueException('"kid" invalid, unable to lookup correct key'); } $key = $key[$header->kid]; } else { From c8c727c0492eb09ac43e3083ae1ab71daab805e9 Mon Sep 17 00:00:00 2001 From: Phan Van Thanh Date: Wed, 5 Apr 2017 11:45:02 +0700 Subject: [PATCH 14/37] Update parse key set for multi keys --- src/JWK.php | 47 ++++++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/src/JWK.php b/src/JWK.php index cf3cc930..8eecb73f 100644 --- a/src/JWK.php +++ b/src/JWK.php @@ -1,6 +1,7 @@ $v) - { - if(!is_string($k)) - { - if(is_array($v) && isset($v['kid'])) + foreach ($source as $k => $v) { + if (!is_string($k)) { + if (is_array($v) && isset($v['kid'])) $k = $v['kid']; - elseif(is_object($v) && property_exists($v,'kid')) + elseif (is_object($v) && property_exists($v, 'kid')) $k = $v->{'kid'}; } - $v = self::parseKey($v); - $keys[$k] = $v; + try { + $v = self::parseKey($v); + $keys[$k] = $v; + } catch (UnexpectedValueException $e) { + //Do nothing + } } - + } + if (0 < count($keys)) { return $keys; } - throw new UnexpectedValueException('Failed to parse JWK'); } @@ -67,19 +66,17 @@ public static function parseKeySet($source) */ public static function parseKey($source) { - if(!is_array($source)) + if (!is_array($source)) $source = (array)$source; - if(!empty($source) && isset($source['kty']) && isset($source['n']) && isset($source['e'])) - { - switch ($source['kty']) - { + if (!empty($source) && isset($source['kty']) && isset($source['n']) && isset($source['e'])) { + switch ($source['kty']) { case 'RSA': if (array_key_exists('d', $source)) throw new UnexpectedValueException('Failed to parse JWK: RSA private key is not supported'); $pem = self::createPemFromModulusAndExponent($source['n'], $source['e']); $pKey = openssl_pkey_get_public($pem); - if($pKey !== false) + if ($pKey !== false) return $pKey; break; default: From 59f4a8420461970c5e559464843df3ce696d2340 Mon Sep 17 00:00:00 2001 From: Phan Van Thanh Date: Wed, 5 Apr 2017 11:45:46 +0700 Subject: [PATCH 15/37] Add test function for parse key set multi keys --- tests/JWTTest.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/JWTTest.php b/tests/JWTTest.php index c97784c9..60dcabcb 100644 --- a/tests/JWTTest.php +++ b/tests/JWTTest.php @@ -42,6 +42,17 @@ public function testDecodeByJWKKeySet() $this->assertEquals(1476248233,$payload->exp); } + public function testDecodeByMultiJWKKeySet() + { + $jsKey = '{"keys":[{"kty":"RSA","e":"AQAB","use":"sig","kid":"CXup","n":"hrwD-lc-IwzwidCANmy4qsiZk11yp9kHykOuP0yOnwi36VomYTQVEzZXgh2sDJpGgAutdQudgwLoV8tVSsTG9SQHgJjH9Pd_9V4Ab6PANyZNG6DSeiq1QfiFlEP6Obt0JbRB3W7X2vkxOVaNoWrYskZodxU2V0ogeVL_LkcCGAyNu2jdx3j0DjJatNVk7ystNxb9RfHhJGgpiIkO5S3QiSIVhbBKaJHcZHPF1vq9g0JMGuUCI-OTSVg6XBkTLEGw1C_R73WD_oVEBfdXbXnLukoLHBS11p3OxU7f4rfxA_f_72_UwmWGJnsqS3iahbms3FkvqoL9x_Vj3GhuJSf97Q"},{"kty":"EC","use":"sig","crv":"P-256","kid":"yGvt","x":"pvgdqM3RCshljmuCF1D2Ez1w5ei5k7-bpimWLPNeEHI","y":"JSmUhbUTqiFclVLEdw6dz038F7Whw4URobjXbAReDuM"},{"kty":"EC","use":"sig","crv":"P-384","kid":"9nHY","x":"JPKhjhE0Bj579Mgj3Cn3ERGA8fKVYoGOaV9BPKhtnEobphf8w4GSeigMesL-038W","y":"UbJa1QRX7fo9LxSlh7FOH5ABT5lEtiQeQUcX9BW0bpJFlEVGqwec80tYLdOIl59M"},{"kty":"EC","use":"sig","crv":"P-521","kid":"tVzS","x":"AZgkRHlIyNQJlPIwTWdHqouw41k9dS3GJO04BDEnJnd_Dd1owlCn9SMXA-JuXINn4slwbG4wcECbctXb2cvdGtmn","y":"AdBC6N9lpupzfzcIY3JLIuc8y8MnzV-ItmzHQcC5lYWMTbuM9NU_FlvINeVo8g6i4YZms2xFB-B0VVdaoF9kUswC"}]}'; + $key = JWK::parseKeySet($jsKey); + + $msg = 'eyJraWQiOiJDWHVwIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJmOGI2N2NjNDYwMzA3NzdlZmQ4YmNlNmMxYmZlMjljNmMwZjgxOGVjIiwic2NwIjpbIm9wZW5pZCIsIm5hbWUiLCJwcm9maWxlIiwicGljdHVyZSIsImVtYWlsIiwicnMtcGstbWFpbiIsInJzLXBrLXNvIiwicnMtcGstaXNzdWUiLCJycy1way13ZWIiXSwiY2xtIjpbIiE1djhIIl0sImlzcyI6Imh0dHBzOlwvXC9pZC5wcm9qZWN0a2l0Lm5ldFwvYXV0aGVudGljYXRlIiwiZXhwIjoxNDkyMjI4MzM2LCJpYXQiOjE0OTEzNjQzMzYsImNpZCI6ImNpZC1way13ZWIifQ.KW1K-72bMtiNwvyYBgffG6VaG6I59cELGYQR8M2q7HA8dmzliu6QREJrqyPtwW_rDJZbsD3eylvkRinK9tlsMXCOfEJbxLdAC9b4LKOsnsbuXXwsJHWkFG0a7osdW0ZpXJDoMFlO1aosxRGMkaqhf1wIkvQ5PM_EB08LJv7oz64Antn5bYaoajwgvJRl7ChatRDn9Sx5UIElKD1BK4Uw5WdrZwBlWdWZVNCSFhy4F6SdZvi3OBlXzluDwq61RC-pl2iivilJNljYWVrthHDS1xdtaVz4oteHW13-IS7NNEz6PVnzo5nyoPWMAB4JlRnxcfOFTTUqOA2mX5Csg0UpdQ'; + $payload = JWT::decode($msg, $key, array('RS256')); + $this->assertEquals("f8b67cc46030777efd8bce6c1bfe29c6c0f818ec",$payload->sub); + $this->assertEquals(1492228336,$payload->exp); + } + public function testUrlSafeCharacters() { $encoded = JWT::encode('f?', 'a'); From 7f72b48d1fc07525b277ee83533b5e2305e3de14 Mon Sep 17 00:00:00 2001 From: Joost Faassen Date: Mon, 19 Jun 2017 18:29:59 +0200 Subject: [PATCH 16/37] Support RS384 and RS512 (#117) --- src/JWT.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/JWT.php b/src/JWT.php index 6d30e941..ea3cc7d1 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -42,6 +42,8 @@ class JWT 'HS512' => array('hash_hmac', 'SHA512'), 'HS384' => array('hash_hmac', 'SHA384'), 'RS256' => array('openssl', 'SHA256'), + 'RS384' => array('openssl', 'SHA384'), + 'RS512' => array('openssl', 'SHA512'), ); /** From 407a78d1de53feb44050e315562e988336d8d284 Mon Sep 17 00:00:00 2001 From: Arjan Keeman Date: Mon, 19 Jun 2017 18:34:20 +0200 Subject: [PATCH 17/37] draft-ietf-oauth-json-web-token-06 --> rfc7519 (#107) The README says this package is conform rfc7519 (May 2015) rather than just the 6th draft (valid until June 2013). The implementation seems indeed to be compatible with the rfc. --- src/JWT.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/JWT.php b/src/JWT.php index ea3cc7d1..607710d1 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -8,7 +8,7 @@ /** * JSON Web Token implementation, based on this spec: - * http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-06 + * https://tools.ietf.org/html/rfc7519 * * PHP version 5 * From d6b3174112411dd2c3b1642e00987ecefdb4f1bb Mon Sep 17 00:00:00 2001 From: Henry N Date: Mon, 19 Jun 2017 18:40:24 +0200 Subject: [PATCH 18/37] example for RS256 openssl (#125) --- README.md | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/README.md b/README.md index d4589b1c..5c3261a2 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,60 @@ $decoded_array = (array) $decoded; JWT::$leeway = 60; // $leeway in seconds $decoded = JWT::decode($jwt, $key, array('HS256')); +?> +``` +Example with RS256 (openssl) +---------------------------- +```php + "example.org", + "aud" => "example.com", + "iat" => 1356999524, + "nbf" => 1357000000 +); + +$jwt = JWT::encode($token, $privateKey, 'RS256'); +echo "Encode:\n" . print_r($jwt, true) . "\n"; + +$decoded = JWT::decode($jwt, $publicKey, array('RS256')); + +/* + NOTE: This will now be an object instead of an associative array. To get + an associative array, you will need to cast it as such: +*/ + +$decoded_array = (array) $decoded; +echo "Decode:\n" . print_r($decoded_array, true) . "\n"; ?> ``` From 0f8f85aa4396de6a18791a561e2a626fb782399a Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Wed, 21 Jun 2017 11:26:30 -0700 Subject: [PATCH 19/37] Fixes travis, adds PHP 7.1, and removes HHVM (#160) --- .gitignore | 1 + .travis.yml | 9 +++------ composer.json | 5 ++++- composer.lock | 19 ------------------- 4 files changed, 8 insertions(+), 26 deletions(-) delete mode 100644 composer.lock diff --git a/.gitignore b/.gitignore index 7c29c87b..080f19aa 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ vendor phpunit.phar phpunit.phar.asc composer.phar +composer.lock diff --git a/.travis.yml b/.travis.yml index 96a0f19c..89131cc1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,12 +6,9 @@ php: - 5.5 - 5.6 - 7.0 - - hhvm + - 7.1 sudo: false -before_script: - - wget -nc http://getcomposer.org/composer.phar - - php composer.phar install - -script: phpunit --configuration phpunit.xml.dist +before_script: composer install +script: phpunit diff --git a/composer.json b/composer.json index 1a5e93b5..4244f133 100644 --- a/composer.json +++ b/composer.json @@ -23,5 +23,8 @@ "Firebase\\JWT\\": "src" } }, - "minimum-stability": "dev" + "minimum-stability": "dev", + "require-dev": { + "phpunit/phpunit": " 4.8.35" + } } diff --git a/composer.lock b/composer.lock deleted file mode 100644 index 5518ae41..00000000 --- a/composer.lock +++ /dev/null @@ -1,19 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", - "This file is @generated automatically" - ], - "hash": "60a5df5d283a7ae9000173248eba8909", - "packages": [], - "packages-dev": [], - "aliases": [], - "minimum-stability": "dev", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": ">=5.2.0" - }, - "platform-dev": [] -} From aa6419a5e92869c0c463361848788ec4f1e8728e Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Wed, 21 Jun 2017 11:38:45 -0700 Subject: [PATCH 20/37] Updates JWT::verify to handle openssl errors (#159) --- src/JWT.php | 14 +++++++++----- tests/JWTTest.php | 29 +++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/JWT.php b/src/JWT.php index 2e5758ea..7729143e 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -88,7 +88,7 @@ public static function decode($jwt, $key, $allowed_algs = array()) throw new UnexpectedValueException('Invalid claims encoding'); } $sig = static::urlsafeB64Decode($cryptob64); - + if (empty($header->alg)) { throw new UnexpectedValueException('Empty algorithm'); } @@ -230,11 +230,15 @@ private static function verify($msg, $signature, $key, $alg) switch($function) { case 'openssl': $success = openssl_verify($msg, $signature, $key, $algorithm); - if (!$success) { - throw new DomainException("OpenSSL unable to verify data: " . openssl_error_string()); - } else { - return $signature; + if ($success === 1) { + return true; + } elseif ($success === 0) { + return false; } + // returns 1 on success, 0 on failure, -1 on error. + throw new DomainException( + 'OpenSSL error: ' . openssl_error_string() + ); case 'hash_hmac': default: $hash = hash_hmac($algorithm, $msg, $key, true); diff --git a/tests/JWTTest.php b/tests/JWTTest.php index e99ea03a..99ae9c38 100644 --- a/tests/JWTTest.php +++ b/tests/JWTTest.php @@ -1,8 +1,13 @@ 'test-eit;v=1')); - $this->assertEquals(JWT::decode($msg, 'my_key', array('HS256')), 'abc'); + $this->assertEquals(JWT::decode($msg, 'my_key', array('HS256')), 'abc'); } public function testInvalidSegmentCount() @@ -261,4 +266,24 @@ public function testInvalidSegmentCount() $this->setExpectedException('UnexpectedValueException'); JWT::decode('brokenheader.brokenbody', 'my_key', array('HS256')); } + + public function testVerifyError() + { + $this->setExpectedException('DomainException'); + $pkey = openssl_pkey_new(); + $msg = JWT::encode('abc', $pkey, 'RS256'); + self::$opensslVerifyReturnValue = -1; + JWT::decode($msg, $pkey, array('RS256')); + } +} + +/* + * Allows the testing of openssl_verify with an error return value + */ +function openssl_verify($msg, $signature, $key, $algorithm) +{ + if (null !== JWTTest::$opensslVerifyReturnValue) { + return JWTTest::$opensslVerifyReturnValue; + } + return \openssl_verify($msg, $signature, $key, $algorithm); } From d2c50fdaedaa64f91229c30fa4190b0113847b45 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Wed, 21 Jun 2017 13:50:08 -0700 Subject: [PATCH 21/37] removes minimum-stabity from composer.json (#161) --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index 4244f133..b76ffd19 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,6 @@ "Firebase\\JWT\\": "src" } }, - "minimum-stability": "dev", "require-dev": { "phpunit/phpunit": " 4.8.35" } From b2a53166f9e2d8958be837e1b368c0897fc52a77 Mon Sep 17 00:00:00 2001 From: Giorgio Balduzzi Date: Wed, 21 Jun 2017 22:57:21 +0200 Subject: [PATCH 22/37] Add the proper Exception message for all JSON error types by PHP (#110) --- src/JWT.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/JWT.php b/src/JWT.php index 7729143e..814afc0a 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -352,8 +352,10 @@ private static function handleJsonError($errno) { $messages = array( JSON_ERROR_DEPTH => 'Maximum stack depth exceeded', + JSON_ERROR_STATE_MISMATCH => 'Invalid or malformed JSON', JSON_ERROR_CTRL_CHAR => 'Unexpected control character found', - JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON' + JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON', + JSON_ERROR_UTF8 => 'Malformed UTF-8 characters' //PHP >= 5.3.3 ); throw new DomainException( isset($messages[$errno]) From d67523fd6a2da172a196fe41a73ba5d4b563619f Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Wed, 21 Jun 2017 14:51:26 -0700 Subject: [PATCH 23/37] Detect invalid Base64 encoding in signature (#162) --- src/JWT.php | 5 +++-- tests/JWTTest.php | 7 +++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/JWT.php b/src/JWT.php index 814afc0a..cb1ca7d1 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -87,8 +87,9 @@ public static function decode($jwt, $key, $allowed_algs = array()) if (null === $payload = static::jsonDecode(static::urlsafeB64Decode($bodyb64))) { throw new UnexpectedValueException('Invalid claims encoding'); } - $sig = static::urlsafeB64Decode($cryptob64); - + if (false === ($sig = static::urlsafeB64Decode($cryptob64))) { + throw new UnexpectedValueException('Invalid signature encoding'); + } if (empty($header->alg)) { throw new UnexpectedValueException('Empty algorithm'); } diff --git a/tests/JWTTest.php b/tests/JWTTest.php index 99ae9c38..804a3769 100644 --- a/tests/JWTTest.php +++ b/tests/JWTTest.php @@ -267,6 +267,13 @@ public function testInvalidSegmentCount() JWT::decode('brokenheader.brokenbody', 'my_key', array('HS256')); } + public function testInvalidSignatureEncoding() + { + $msg = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwibmFtZSI6ImZvbyJ9.Q4Kee9E8o0Xfo4ADXvYA8t7dN_X_bU9K5w6tXuiSjlUxx"; + $this->setExpectedException('UnexpectedValueException'); + JWT::decode($msg, 'secret', array('HS256')); + } + public function testVerifyError() { $this->setExpectedException('DomainException'); From 8becb3b775a2288bda7259f6d13fce89999a4a14 Mon Sep 17 00:00:00 2001 From: Chinedu Francis Nwafili Date: Thu, 22 Jun 2017 09:51:13 +0700 Subject: [PATCH 24/37] Add new line warning to README (#115) --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 5c3261a2..294234b8 100644 --- a/README.md +++ b/README.md @@ -168,6 +168,12 @@ Time: 0 seconds, Memory: 2.50Mb OK (5 tests, 5 assertions) ``` +New Lines in private keys +----- + +If your private key contains `\n` characters, be sure to wrap it in double quotes `""` +and not single quotes `''` in order to properly interpret the escaped characters. + License ------- [3-Clause BSD](http://opensource.org/licenses/BSD-3-Clause). From 4db1e95de5e6fd56af1a6f3ea4cdc6ccd65393d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Mon, 26 Jun 2017 18:56:41 +0200 Subject: [PATCH 25/37] added `array` type hinting to `decode` method (#101) --- src/JWT.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/JWT.php b/src/JWT.php index cb1ca7d1..22a67e32 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -66,16 +66,13 @@ class JWT * @uses jsonDecode * @uses urlsafeB64Decode */ - public static function decode($jwt, $key, $allowed_algs = array()) + public static function decode($jwt, $key, array $allowed_algs = array()) { $timestamp = is_null(static::$timestamp) ? time() : static::$timestamp; if (empty($key)) { throw new InvalidArgumentException('Key may not be empty'); } - if (!is_array($allowed_algs)) { - throw new InvalidArgumentException('Algorithm not allowed'); - } $tks = explode('.', $jwt); if (count($tks) != 3) { throw new UnexpectedValueException('Wrong number of segments'); From f97b3e35c8f0b2c9bb4c27a0eb9bf735c25713ef Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Mon, 26 Jun 2017 10:28:13 -0700 Subject: [PATCH 26/37] Remove outdated package.xml (#165) --- package.xml | 77 ----------------------------------------------------- 1 file changed, 77 deletions(-) delete mode 100644 package.xml diff --git a/package.xml b/package.xml deleted file mode 100644 index a95b056f..00000000 --- a/package.xml +++ /dev/null @@ -1,77 +0,0 @@ - - - JWT - pear.php.net - A JWT encoder/decoder. - A JWT encoder/decoder library for PHP. - - Neuman Vong - lcfrs - neuman+pear@twilio.com - yes - - - Firebase Operations - firebase - operations@firebase.com - yes - - 2015-07-22 - - 3.0.0 - 3.0.0 - - - beta - beta - - BSD 3-Clause License - -Initial release with basic support for JWT encoding, decoding and signature verification. - - - - - - - - - - - - - 5.1 - - - 1.7.0 - - - json - - - hash - - - - - - - - 0.1.0 - 0.1.0 - - - beta - beta - - 2015-04-01 - BSD 3-Clause License - -Initial release with basic support for JWT encoding, decoding and signature verification. - - - - From 9984a4d3a32ae7673d6971ea00bae9d0a1abba0e Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Tue, 27 Jun 2017 15:17:23 -0700 Subject: [PATCH 27/37] updates README changelog for v5.0.0 (#166) --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index 294234b8..b1a7a3a2 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,27 @@ echo "Decode:\n" . print_r($decoded_array, true) . "\n"; Changelog --------- +#### 5.0.0 / 2017-06-26 +- Support RS384 and RS512. + See [#117](https://github.com/firebase/php-jwt/pull/117). Thanks [@joostfaassen](https://github.com/joostfaassen)! +- Add an example for RS256 openssl. + See [#125](https://github.com/firebase/php-jwt/pull/125). Thanks [@akeeman](https://github.com/akeeman)! +- Detect invalid Base64 encoding in signature. + See [#162](https://github.com/firebase/php-jwt/pull/162). Thanks [@psignoret](https://github.com/psignoret)! +- Update `JWT::verify` to handle OpenSSL errors. + See [#159](https://github.com/firebase/php-jwt/pull/159). Thanks [@bshaffer](https://github.com/bshaffer)! +- Add `array` type hinting to `decode` method + See [#101](https://github.com/firebase/php-jwt/pull/101). Thanks [@hywak](https://github.com/hywak)! +- Add all JSON error types. + See [#110](https://github.com/firebase/php-jwt/pull/110). Thanks [@gbalduzzi](https://github.com/gbalduzzi)! +- Bugfix 'kid' not in given key list. + See [#129](https://github.com/firebase/php-jwt/pull/129). Thanks [@stampycode](https://github.com/stampycode)! +- Miscellaneous cleanup, documentation and test fixes. + See [#107](https://github.com/firebase/php-jwt/pull/107), [#115](https://github.com/firebase/php-jwt/pull/115), + [#160](https://github.com/firebase/php-jwt/pull/160), [#161](https://github.com/firebase/php-jwt/pull/161), and + [#165](https://github.com/firebase/php-jwt/pull/165). Thanks [@akeeman](https://github.com/akeeman), + [@chinedufn](https://github.com/chinedufn), and [@bshaffer](https://github.com/bshaffer)! + #### 4.0.0 / 2016-07-17 - Add support for late static binding. See [#88](https://github.com/firebase/php-jwt/pull/88) for details. Thanks to [@chappy84](https://github.com/chappy84)! - Use static `$timestamp` instead of `time()` to improve unit testing. See [#93](https://github.com/firebase/php-jwt/pull/93) for details. Thanks to [@josephmcdermott](https://github.com/josephmcdermott)! From 1ccf497b40552e7a5f9663aa09bc80dd6f0b4f4e Mon Sep 17 00:00:00 2001 From: ThanhPV Date: Thu, 28 Sep 2017 00:35:11 +0700 Subject: [PATCH 28/37] Remove composer.lock --- .gitignore | 1 + composer.lock | 1058 ------------------------------------------------- 2 files changed, 1 insertion(+), 1058 deletions(-) delete mode 100644 composer.lock diff --git a/.gitignore b/.gitignore index b1a05b0b..cc979c1b 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ phpunit.phar phpunit.phar.asc composer.phar .idea +composer.lock \ No newline at end of file diff --git a/composer.lock b/composer.lock deleted file mode 100644 index 7ad0cb8e..00000000 --- a/composer.lock +++ /dev/null @@ -1,1058 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", - "This file is @generated automatically" - ], - "hash": "18867f3a3b90fcdf289d47ec125a6b94", - "packages": [], - "packages-dev": [ - { - "name": "doctrine/instantiator", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", - "shasum": "" - }, - "require": { - "php": ">=5.3,<8.0-DEV" - }, - "require-dev": { - "athletic/athletic": "~0.1.8", - "ext-pdo": "*", - "ext-phar": "*", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", - "keywords": [ - "constructor", - "instantiate" - ], - "time": "2015-06-14 21:17:01" - }, - { - "name": "myclabs/deep-copy", - "version": "1.3.1", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "95d662954e06000cdf63ec9c9f0a6c598d9c5eb9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/95d662954e06000cdf63ec9c9f0a6c598d9c5eb9", - "reference": "95d662954e06000cdf63ec9c9f0a6c598d9c5eb9", - "shasum": "" - }, - "require": { - "php": ">=5.4.0" - }, - "require-dev": { - "doctrine/collections": "1.*", - "phpunit/phpunit": "~4.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - } - }, - "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", - "duplicate", - "object", - "object graph" - ], - "time": "2015-07-19 19:57:13" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", - "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "suggest": { - "dflydev/markdown": "~1.0", - "erusev/parsedown": "~1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "phpDocumentor": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "mike.vanriel@naenius.com" - } - ], - "time": "2015-02-03 12:10:50" - }, - { - "name": "phpspec/prophecy", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "4f9b1eaf0a7da77c362f8d91cbc68ab1f4718d62" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4f9b1eaf0a7da77c362f8d91cbc68ab1f4718d62", - "reference": "4f9b1eaf0a7da77c362f8d91cbc68ab1f4718d62", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "phpdocumentor/reflection-docblock": "~2.0", - "sebastian/comparator": "~1.1" - }, - "require-dev": { - "phpspec/phpspec": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.5.x-dev" - } - }, - "autoload": { - "psr-0": { - "Prophecy\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com/" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "time": "2015-09-22 14:49:23" - }, - { - "name": "phpunit/php-code-coverage", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "12259bb1352612df9ec24048714a3bedafe79674" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/12259bb1352612df9ec24048714a3bedafe79674", - "reference": "12259bb1352612df9ec24048714a3bedafe79674", - "shasum": "" - }, - "require": { - "php": ">=5.6", - "phpunit/php-file-iterator": "~1.3", - "phpunit/php-text-template": "~1.2", - "phpunit/php-token-stream": "~1.3", - "sebastian/environment": "^1.3.2", - "sebastian/version": "~1.0" - }, - "require-dev": { - "ext-xdebug": ">=2.1.4", - "phpunit/phpunit": "~5" - }, - "suggest": { - "ext-dom": "*", - "ext-xdebug": ">=2.2.1", - "ext-xmlwriter": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "time": "2015-09-24 07:56:07" - }, - { - "name": "phpunit/php-file-iterator", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "time": "2015-06-21 13:08:43" - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "time": "2015-06-21 13:50:34" - }, - { - "name": "phpunit/php-timer", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b", - "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "time": "2015-06-21 08:01:12" - }, - { - "name": "phpunit/php-token-stream", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "cab6c6fefee93d7b7c3a01292a0fe0884ea66644" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/cab6c6fefee93d7b7c3a01292a0fe0884ea66644", - "reference": "cab6c6fefee93d7b7c3a01292a0fe0884ea66644", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "time": "2015-09-23 14:46:55" - }, - { - "name": "phpunit/phpunit", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "b3db8bc29009cbd788cd827d7376a5e8018243ce" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b3db8bc29009cbd788cd827d7376a5e8018243ce", - "reference": "b3db8bc29009cbd788cd827d7376a5e8018243ce", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "myclabs/deep-copy": "~1.3", - "php": ">=7.0", - "phpspec/prophecy": "^1.3.1", - "phpunit/php-code-coverage": "~3.0", - "phpunit/php-file-iterator": "~1.4", - "phpunit/php-text-template": "~1.2", - "phpunit/php-timer": ">=1.0.6", - "phpunit/phpunit-mock-objects": ">=3.0", - "sebastian/comparator": "~1.1", - "sebastian/diff": "~1.2", - "sebastian/environment": "~1.3", - "sebastian/exporter": "~1.2", - "sebastian/global-state": "~1.0", - "sebastian/resource-operations": "~1.0", - "sebastian/version": "~1.0", - "symfony/yaml": "~2.1|~3.0" - }, - "suggest": { - "phpunit/php-invoker": "~1.1" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "time": "2015-09-27 08:37:11" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "4f526b7e2c42cacf32c86e1e0c9ab9d3b24273cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/4f526b7e2c42cacf32c86e1e0c9ab9d3b24273cf", - "reference": "4f526b7e2c42cacf32c86e1e0c9ab9d3b24273cf", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "php": ">=5.6", - "phpunit/php-text-template": "~1.2", - "sebastian/exporter": "~1.2" - }, - "require-dev": { - "phpunit/phpunit": "~5" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "time": "2015-09-02 07:30:58" - }, - { - "name": "sebastian/comparator", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", - "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "sebastian/diff": "~1.2", - "sebastian/exporter": "~1.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "http://www.github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "time": "2015-07-26 15:48:44" - }, - { - "name": "sebastian/diff", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "6899b3e33bfbd386d88b5eea5f65f563e8793051" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/6899b3e33bfbd386d88b5eea5f65f563e8793051", - "reference": "6899b3e33bfbd386d88b5eea5f65f563e8793051", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Diff implementation", - "homepage": "http://www.github.com/sebastianbergmann/diff", - "keywords": [ - "diff" - ], - "time": "2015-06-22 14:15:55" - }, - { - "name": "sebastian/environment", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6324c907ce7a52478eeeaede764f48733ef5ae44", - "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "time": "2015-08-03 06:14:51" - }, - { - "name": "sebastian/exporter", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "f88f8936517d54ae6d589166810877fb2015d0a2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/f88f8936517d54ae6d589166810877fb2015d0a2", - "reference": "f88f8936517d54ae6d589166810877fb2015d0a2", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "sebastian/recursion-context": "~1.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "time": "2015-08-09 04:23:41" - }, - { - "name": "sebastian/global-state", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "23af31f402993cfd94e99cbc4b782e9a78eb0e97" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/23af31f402993cfd94e99cbc4b782e9a78eb0e97", - "reference": "23af31f402993cfd94e99cbc4b782e9a78eb0e97", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.2" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "time": "2015-06-21 15:11:22" - }, - { - "name": "sebastian/recursion-context", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "994d4a811bafe801fb06dccbee797863ba2792ba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/994d4a811bafe801fb06dccbee797863ba2792ba", - "reference": "994d4a811bafe801fb06dccbee797863ba2792ba", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "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": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2015-06-21 08:04:50" - }, - { - "name": "sebastian/resource-operations", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "shasum": "" - }, - "require": { - "php": ">=5.6.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": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "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" - }, - { - "name": "sebastian/version", - "version": "1.0.6", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", - "shasum": "" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "time": "2015-06-21 13:59:46" - }, - { - "name": "symfony/yaml", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/symfony/Yaml.git", - "reference": "b68154f3ee23d8294936433fd31725a83bd02f71" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/b68154f3ee23d8294936433fd31725a83bd02f71", - "reference": "b68154f3ee23d8294936433fd31725a83bd02f71", - "shasum": "" - }, - "require": { - "php": ">=5.5.9" - }, - "require-dev": { - "symfony/phpunit-bridge": "~2.8|~3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - } - }, - "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 Yaml Component", - "homepage": "https://symfony.com/", - "time": "2015-09-14 14:15:24" - } - ], - "aliases": [], - "minimum-stability": "dev", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": ">=5.3.0" - }, - "platform-dev": [] -} From 9c2857091f13ab367385bf00efeadf41a86aeb88 Mon Sep 17 00:00:00 2001 From: ThanhPV Date: Thu, 28 Sep 2017 00:39:37 +0700 Subject: [PATCH 29/37] Fix test failed by using phpunit ^6.0 --- composer.json | 6 ++-- tests/JWTTest.php | 84 ++++++++++++++++++++++++----------------------- 2 files changed, 47 insertions(+), 43 deletions(-) diff --git a/composer.json b/composer.json index 5b52468a..5e3344c9 100644 --- a/composer.json +++ b/composer.json @@ -21,12 +21,14 @@ ], "license": "BSD-3-Clause", "require": { - "php": ">=5.4.0" + "php": ">=5.4.0", + "phpunit/phpunit": "^6.0" }, "autoload": { "psr-4": { "Firebase\\JWT\\": "src" } }, - "minimum-stability": "dev" + "minimum-stability": "dev", + "prefer-stable": true } diff --git a/tests/JWTTest.php b/tests/JWTTest.php index 60dcabcb..55b44cb5 100644 --- a/tests/JWTTest.php +++ b/tests/JWTTest.php @@ -2,12 +2,12 @@ use Firebase\JWT\JWT; use Firebase\JWT\JWK; -class JWTTest extends PHPUnit_Framework_TestCase +class JWTTest extends \PHPUnit\Framework\TestCase { public function testEncodeDecode() { - $msg = JWT::encode('abc', 'my_key'); - $this->assertEquals(JWT::decode($msg, 'my_key', array('HS256')), 'abc'); + $msg = JWT::encode(['abc'], 'my_key'); + $this->assertEquals(JWT::decode($msg, 'my_key', array('HS256')), ['abc']); } public function testDecodeFromPython() @@ -36,10 +36,11 @@ public function testDecodeByJWKKeySet() $jsKey = '{"keys":[{"kty":"RSA","e":"AQAB","use":"sig","kid":"s1","n":"kWp2zRA23Z3vTL4uoe8kTFptxBVFunIoP4t_8TDYJrOb7D1iZNDXVeEsYKp6ppmrTZDAgd-cNOTKLd4M39WJc5FN0maTAVKJc7NxklDeKc4dMe1BGvTZNG4MpWBo-taKULlYUu0ltYJuLzOjIrTHfarucrGoRWqM0sl3z2-fv9k"}]}'; $key = JWK::parseKeySet($jsKey); - $msg = 'eyJraWQiOiJzMSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiJYcEFCeEpnVXhLN2JKdnVnRGFXaXlYLWF6aDliSlJ4OGU1dGJzdjVZblpRIiwic2NwIjpbIm9wZW5pZCIsImVtYWlsIiwicHJvZmlsZSIsInJzLXBrLW1haW4iLCJycy1way1zbyIsInJzLXBrLWlzc3VlIiwicnMtcGstd2ViIl0sImNsbSI6WyJwcm9qZWN0R3JvdXBzIiwiITV2OEgiXSwiaXNzIjoiaHR0cDpcL1wvaWQucHJvamVjdGtpdC5uZXQiLCJleHAiOjE0NzYyNDgyMzMsImNpZCI6ImNpZC1way13ZWIifQ.cxkukSfQ9YrvLr8X-0RV_00FRoSvnA1er-6qvfpgIKjShjUfjga4T-wCv-KrVpYqQAxTdDZZJNwiDo3oLuqSwsvBmwT1Wyt1wce9GLAd3MSW9KtHnygGwqtdbP3taWieQrpgNNlQTJHex-XqlkVR722pxgPjtj-96IV8WPC0vek'; + $msg = 'eyJraWQiOiJzMSIsImFsZyI6IlJTMjU2In0.eyJzY3AiOlsib3BlbmlkIiwiZW1haWwiLCJwcm9maWxlIiwiYWFzIl0sInN1YiI6InRVQ1l0bmZJQlBXY3JTSmY0eUJmdk4xa3d3NEtHY3kzTElQazFHVnpzRTAiLCJjbG0iOlsiITV2OEgiXSwiaXNzIjoiaHR0cDpcL1wvMTMwLjIxMS4yNDMuMTE0OjgwODBcL2MyaWQiLCJleHAiOjE0NDExMjY1MzksInVpcCI6eyJncm91cHMiOlsiYWRtaW4iLCJhdWRpdCJdfSwiY2lkIjoicGstb2lkYy0wMSJ9.PvYrnf3k1Z0wgRwCgq0WXKaoIv1hHtzBFO5cGfCs6bl4suc6ilwCWmJqRxGYkU2fNTGyMOt3OUnnBEwl6v5qN6jv7zbkVAVKVvbQLxhHC2nXe3izvoCiVaMEH6hE7VTWwnPbX_qO72mCwTizHTJTZGLOsyXLYM6ctdOMf7sFPTI'; + $this->expectException('Firebase\JWT\ExpiredException'); $payload = JWT::decode($msg, $key, array('RS256')); - $this->assertEquals("XpABxJgUxK7bJvugDaWiyX-azh9bJRx8e5tbsv5YnZQ",$payload->sub); - $this->assertEquals(1476248233,$payload->exp); + $this->assertEquals("tUCYtnfIBPWcrSJf4yBfvN1kww4KGcy3LIPk1GVzsE0",$payload->sub); + $this->assertEquals(1441126539,$payload->exp); } public function testDecodeByMultiJWKKeySet() @@ -48,6 +49,7 @@ public function testDecodeByMultiJWKKeySet() $key = JWK::parseKeySet($jsKey); $msg = 'eyJraWQiOiJDWHVwIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJmOGI2N2NjNDYwMzA3NzdlZmQ4YmNlNmMxYmZlMjljNmMwZjgxOGVjIiwic2NwIjpbIm9wZW5pZCIsIm5hbWUiLCJwcm9maWxlIiwicGljdHVyZSIsImVtYWlsIiwicnMtcGstbWFpbiIsInJzLXBrLXNvIiwicnMtcGstaXNzdWUiLCJycy1way13ZWIiXSwiY2xtIjpbIiE1djhIIl0sImlzcyI6Imh0dHBzOlwvXC9pZC5wcm9qZWN0a2l0Lm5ldFwvYXV0aGVudGljYXRlIiwiZXhwIjoxNDkyMjI4MzM2LCJpYXQiOjE0OTEzNjQzMzYsImNpZCI6ImNpZC1way13ZWIifQ.KW1K-72bMtiNwvyYBgffG6VaG6I59cELGYQR8M2q7HA8dmzliu6QREJrqyPtwW_rDJZbsD3eylvkRinK9tlsMXCOfEJbxLdAC9b4LKOsnsbuXXwsJHWkFG0a7osdW0ZpXJDoMFlO1aosxRGMkaqhf1wIkvQ5PM_EB08LJv7oz64Antn5bYaoajwgvJRl7ChatRDn9Sx5UIElKD1BK4Uw5WdrZwBlWdWZVNCSFhy4F6SdZvi3OBlXzluDwq61RC-pl2iivilJNljYWVrthHDS1xdtaVz4oteHW13-IS7NNEz6PVnzo5nyoPWMAB4JlRnxcfOFTTUqOA2mX5Csg0UpdQ'; + $this->expectException('Firebase\JWT\ExpiredException'); $payload = JWT::decode($msg, $key, array('RS256')); $this->assertEquals("f8b67cc46030777efd8bce6c1bfe29c6c0f818ec",$payload->sub); $this->assertEquals(1492228336,$payload->exp); @@ -55,25 +57,25 @@ public function testDecodeByMultiJWKKeySet() public function testUrlSafeCharacters() { - $encoded = JWT::encode('f?', 'a'); - $this->assertEquals('f?', JWT::decode($encoded, 'a', array('HS256'))); + $encoded = JWT::encode(['f?'], 'a'); + $this->assertEquals(['f?'], JWT::decode($encoded, 'a', array('HS256'))); } public function testMalformedUtf8StringsFail() { - $this->setExpectedException('DomainException'); - JWT::encode(pack('c', 128), 'a'); + $this->expectException('DomainException'); + JWT::encode(array('c', 128), 'a', 'RSA'); } public function testMalformedJsonThrowsException() { - $this->setExpectedException('DomainException'); + $this->expectException('DomainException'); JWT::jsonDecode('this is not valid JSON string'); } public function testExpiredToken() { - $this->setExpectedException('Firebase\JWT\ExpiredException'); + $this->expectException('Firebase\JWT\ExpiredException'); $payload = array( "message" => "abc", "exp" => time() - 20); // time in the past @@ -83,7 +85,7 @@ public function testExpiredToken() public function testBeforeValidTokenWithNbf() { - $this->setExpectedException('Firebase\JWT\BeforeValidException'); + $this->expectException('Firebase\JWT\BeforeValidException'); $payload = array( "message" => "abc", "nbf" => time() + 20); // time in the future @@ -93,7 +95,7 @@ public function testBeforeValidTokenWithNbf() public function testBeforeValidTokenWithIat() { - $this->setExpectedException('Firebase\JWT\BeforeValidException'); + $this->expectException('Firebase\JWT\BeforeValidException'); $payload = array( "message" => "abc", "iat" => time() + 20); // time in the future @@ -129,7 +131,7 @@ public function testExpiredTokenWithLeeway() $payload = array( "message" => "abc", "exp" => time() - 70); // time far in the past - $this->setExpectedException('Firebase\JWT\ExpiredException'); + $this->expectException('Firebase\JWT\ExpiredException'); $encoded = JWT::encode($payload, 'my_key'); $decoded = JWT::decode($encoded, 'my_key', array('HS256')); $this->assertEquals($decoded->message, 'abc'); @@ -177,8 +179,8 @@ public function testInvalidTokenWithNbfLeeway() "message" => "abc", "nbf" => time() + 65); // not before too far in future $encoded = JWT::encode($payload, 'my_key'); - $this->setExpectedException('Firebase\JWT\BeforeValidException'); - $decoded = JWT::decode($encoded, 'my_key', array('HS256')); + $this->expectException('Firebase\JWT\BeforeValidException'); + JWT::decode($encoded, 'my_key', array('HS256')); JWT::$leeway = 0; } @@ -201,8 +203,8 @@ public function testInvalidTokenWithIatLeeway() "message" => "abc", "iat" => time() + 65); // issued too far in future $encoded = JWT::encode($payload, 'my_key'); - $this->setExpectedException('Firebase\JWT\BeforeValidException'); - $decoded = JWT::decode($encoded, 'my_key', array('HS256')); + $this->expectException('Firebase\JWT\BeforeValidException'); + JWT::decode($encoded, 'my_key', array('HS256')); JWT::$leeway = 0; } @@ -212,8 +214,8 @@ public function testInvalidToken() "message" => "abc", "exp" => time() + 20); // time in the future $encoded = JWT::encode($payload, 'my_key'); - $this->setExpectedException('Firebase\JWT\SignatureInvalidException'); - $decoded = JWT::decode($encoded, 'my_key2', array('HS256')); + $this->expectException('Firebase\JWT\SignatureInvalidException'); + JWT::decode($encoded, 'my_key2', array('HS256')); } public function testNullKeyFails() @@ -222,8 +224,8 @@ public function testNullKeyFails() "message" => "abc", "exp" => time() + JWT::$leeway + 20); // time in the future $encoded = JWT::encode($payload, 'my_key'); - $this->setExpectedException('InvalidArgumentException'); - $decoded = JWT::decode($encoded, null, array('HS256')); + $this->expectException('InvalidArgumentException'); + JWT::decode($encoded, null, array('HS256')); } public function testEmptyKeyFails() @@ -232,14 +234,14 @@ public function testEmptyKeyFails() "message" => "abc", "exp" => time() + JWT::$leeway + 20); // time in the future $encoded = JWT::encode($payload, 'my_key'); - $this->setExpectedException('InvalidArgumentException'); - $decoded = JWT::decode($encoded, '', array('HS256')); + $this->expectException('InvalidArgumentException'); + JWT::decode($encoded, '', array('HS256')); } public function testRSEncodeDecode() { $privKey = openssl_pkey_new(array( - //'config'=>'C:/wamp/bin/apache/Apache2.4.4/conf/openssl.cnf',//Remove this line when test on travis-ci.org + 'config'=>'C:/wamp64/bin/apache/apache2.4.27/conf/openssl.cnf',//Remove this line when test on travis-ci.org 'digest_alg' => 'sha512', 'private_key_bits' => 4096, 'private_key_type' => OPENSSL_KEYTYPE_RSA)); @@ -250,60 +252,60 @@ public function testRSEncodeDecode() } else { - $msg = JWT::encode('abc', $privKey, 'RS256'); + $msg = JWT::encode(['abc'], $privKey, 'RS256'); $pubKey = openssl_pkey_get_details($privKey); $pubKey = $pubKey['key']; $decoded = JWT::decode($msg, $pubKey, array('RS256')); - $this->assertEquals($decoded, 'abc'); + $this->assertEquals($decoded, ['abc']); } } public function testKIDChooser() { $keys = array('1' => 'my_key', '2' => 'my_key2'); - $msg = JWT::encode('abc', $keys['1'], 'HS256', '1'); + $msg = JWT::encode(['abc'], $keys['1'], 'HS256', '1'); $decoded = JWT::decode($msg, $keys, array('HS256')); - $this->assertEquals($decoded, 'abc'); + $this->assertEquals($decoded, ['abc']); } public function testArrayAccessKIDChooser() { $keys = new ArrayObject(array('1' => 'my_key', '2' => 'my_key2')); - $msg = JWT::encode('abc', $keys['1'], 'HS256', '1'); + $msg = JWT::encode(['abc'], $keys['1'], 'HS256', '1'); $decoded = JWT::decode($msg, $keys, array('HS256')); - $this->assertEquals($decoded, 'abc'); + $this->assertEquals($decoded, ['abc']); } public function testNoneAlgorithm() { - $msg = JWT::encode('abc', 'my_key'); - $this->setExpectedException('UnexpectedValueException'); + $msg = JWT::encode(['abc'], 'my_key'); + $this->expectException('UnexpectedValueException'); JWT::decode($msg, 'my_key', array('none')); } public function testIncorrectAlgorithm() { - $msg = JWT::encode('abc', 'my_key'); - $this->setExpectedException('UnexpectedValueException'); + $msg = JWT::encode(['abc'], 'my_key'); + $this->expectException('UnexpectedValueException'); JWT::decode($msg, 'my_key', array('RS256')); } public function testMissingAlgorithm() { - $msg = JWT::encode('abc', 'my_key'); - $this->setExpectedException('UnexpectedValueException'); + $msg = JWT::encode(['abc'], 'my_key'); + $this->expectException('UnexpectedValueException'); JWT::decode($msg, 'my_key'); } public function testAdditionalHeaders() { - $msg = JWT::encode('abc', 'my_key', 'HS256', null, array('cty' => 'test-eit;v=1')); - $this->assertEquals(JWT::decode($msg, 'my_key', array('HS256')), 'abc'); + $msg = JWT::encode(['abc'], 'my_key', 'HS256', null, array('cty' => 'test-eit;v=1')); + $this->assertEquals(JWT::decode($msg, 'my_key', array('HS256')), ['abc']); } public function testInvalidSegmentCount() { - $this->setExpectedException('UnexpectedValueException'); + $this->expectException('UnexpectedValueException'); JWT::decode('brokenheader.brokenbody', 'my_key', array('HS256')); } } From 63b161e13a210fd7e50930d545107b73b05155f4 Mon Sep 17 00:00:00 2001 From: ThanhPV Date: Thu, 28 Sep 2017 00:45:28 +0700 Subject: [PATCH 30/37] Fix config openssl for travis-ci --- .travis.yml | 8 ++++---- tests/JWTTest.php | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index f4543497..b081d546 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,11 @@ language: php php: - - 5.4 - - 5.5 - - 5.6 +# - 5.4 +# - 5.5 +# - 5.6 - 7 - - hhvm +# - hhvm sudo: false diff --git a/tests/JWTTest.php b/tests/JWTTest.php index 55b44cb5..07d06331 100644 --- a/tests/JWTTest.php +++ b/tests/JWTTest.php @@ -241,7 +241,7 @@ public function testEmptyKeyFails() public function testRSEncodeDecode() { $privKey = openssl_pkey_new(array( - 'config'=>'C:/wamp64/bin/apache/apache2.4.27/conf/openssl.cnf',//Remove this line when test on travis-ci.org + //'config'=>'C:/wamp64/bin/apache/apache2.4.27/conf/openssl.cnf',//Remove this line when test on travis-ci.org 'digest_alg' => 'sha512', 'private_key_bits' => 4096, 'private_key_type' => OPENSSL_KEYTYPE_RSA)); From bac0422822b92fe7a0ed1fc7b1b633d9efa37bae Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Fri, 26 Jan 2018 11:13:29 -0800 Subject: [PATCH 31/37] Adds PHP 7.2 to Travis (#186) --- .travis.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 89131cc1..26f0ff0f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,17 @@ language: php php: - - 5.3 - 5.4 - 5.5 - 5.6 - 7.0 - 7.1 + - 7.2 + +matrix: + include: + - php: 5.3 + dist: precise sudo: false From 51668dc736ff19339c082ba7df5c8f80f98d1abd Mon Sep 17 00:00:00 2001 From: Or Rosenblatt Date: Thu, 22 Mar 2018 11:49:39 +0200 Subject: [PATCH 32/37] Fix Travis CI for PHP5.3 build --- src/JWK.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/JWK.php b/src/JWK.php index 8eecb73f..618761ea 100644 --- a/src/JWK.php +++ b/src/JWK.php @@ -24,7 +24,7 @@ class JWK */ public static function parseKeySet($source) { - $keys = []; + $keys = array(); if (is_string($source)) { $source = json_decode($source, true); } else if (is_object($source)) { @@ -155,4 +155,4 @@ private static function encodeLength($length) return pack('Ca*', 0x80 | strlen($temp), $temp); } -} \ No newline at end of file +} From e68cc4fb9a3d77571f339e10dc8aa8d9817f9bb9 Mon Sep 17 00:00:00 2001 From: Or Rosenblatt Date: Thu, 22 Mar 2018 13:43:32 +0200 Subject: [PATCH 33/37] Revert "Fix Travis CI for PHP5.3 build" This reverts commit 51668dc736ff19339c082ba7df5c8f80f98d1abd. --- src/JWK.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/JWK.php b/src/JWK.php index 618761ea..8eecb73f 100644 --- a/src/JWK.php +++ b/src/JWK.php @@ -24,7 +24,7 @@ class JWK */ public static function parseKeySet($source) { - $keys = array(); + $keys = []; if (is_string($source)) { $source = json_decode($source, true); } else if (is_object($source)) { @@ -155,4 +155,4 @@ private static function encodeLength($length) return pack('Ca*', 0x80 | strlen($temp), $temp); } -} +} \ No newline at end of file From fd0289fc39a887d397dcf9779315c8820e9e67ab Mon Sep 17 00:00:00 2001 From: Or Rosenblatt Date: Thu, 22 Mar 2018 13:49:25 +0200 Subject: [PATCH 34/37] Remove support for PHP5.3 build on Travis CI (deprecated at 2014) --- .travis.yml | 5 ----- README.md | 1 - composer.json | 2 +- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 26f0ff0f..245579d6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,11 +8,6 @@ php: - 7.1 - 7.2 -matrix: - include: - - php: 5.3 - dist: precise - sudo: false before_script: composer install diff --git a/README.md b/README.md index 594c6cc8..4d18cb7f 100644 --- a/README.md +++ b/README.md @@ -120,7 +120,6 @@ Changelog #### 5.0.0 / 2018-03-21 - Update to 5.0.0 from upstream - - Minimum PHP version downgraded from `5.4.0` to `5.3.0`. #### 4.0.0 / 2016-08-10 - Update to 4.0.0 from upstream diff --git a/composer.json b/composer.json index b403dc7c..ba3b10b4 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ ], "license": "BSD-3-Clause", "require": { - "php": ">=5.3.0" + "php": ">=5.4.0" }, "autoload": { "psr-4": { From 187a29eef5a4d2528bb1a9c7a334a11ce3fee38b Mon Sep 17 00:00:00 2001 From: Bui Sy Nguyen Date: Mon, 2 Apr 2018 16:15:30 +0700 Subject: [PATCH 35/37] Add HHVM to php target --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 245579d6..04999816 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ php: - 7.0 - 7.1 - 7.2 + - hhvm sudo: false From 4d122587247012550605c5bd1be6f6453b00ff35 Mon Sep 17 00:00:00 2001 From: Bui Sy Nguyen Date: Mon, 2 Apr 2018 17:22:47 +0700 Subject: [PATCH 36/37] Allow failures on HHVM --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 04999816..71c1227c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,9 @@ php: - 7.1 - 7.2 - hhvm +matrix: + allow_failures: + - php: hhvm sudo: false From 91047b202bbe7d966e8fce67ab16ebca8bdcb6b7 Mon Sep 17 00:00:00 2001 From: Bui Sy Nguyen Date: Mon, 2 Apr 2018 17:36:30 +0700 Subject: [PATCH 37/37] Allow failures on HHVM --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index ba3b10b4..e25cb490 100644 --- a/composer.json +++ b/composer.json @@ -29,6 +29,6 @@ } }, "require-dev": { - "phpunit/phpunit": " 4.8.35" + "phpunit/phpunit": "4.8.36" } }