From f20164ec533d7ab8f074936c4e0991b91d8e3920 Mon Sep 17 00:00:00 2001 From: Ozan Akman Date: Sun, 10 Nov 2019 11:19:28 +0100 Subject: [PATCH 1/4] Make header splitting more consistent and less buggy --- .gitignore | 1 + composer.lock | 574 +++++++++++++++++++++++++++++--------------- src/Decode.php | 100 +++++--- test/DecodeTest.php | 27 +++ 4 files changed, 475 insertions(+), 227 deletions(-) diff --git a/.gitignore b/.gitignore index 245087a..4611e1e 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ /vendor/ /zf-mkdoc-theme.tgz /zf-mkdoc-theme/ +/.idea diff --git a/composer.lock b/composer.lock index 0f28107..540e8cc 100644 --- a/composer.lock +++ b/composer.lock @@ -1,38 +1,38 @@ { "_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#installing-dependencies", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], "content-hash": "27a40e1f2a7624a8be3444d024f75563", "packages": [ { "name": "zendframework/zend-stdlib", - "version": "3.1.0", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/zendframework/zend-stdlib.git", - "reference": "debedcfc373a293f9250cc9aa03cf121428c8e78" + "reference": "66536006722aff9e62d1b331025089b7ec71c065" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/debedcfc373a293f9250cc9aa03cf121428c8e78", - "reference": "debedcfc373a293f9250cc9aa03cf121428c8e78", + "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/66536006722aff9e62d1b331025089b7ec71c065", + "reference": "66536006722aff9e62d1b331025089b7ec71c065", "shasum": "" }, "require": { "php": "^5.6 || ^7.0" }, "require-dev": { - "athletic/athletic": "~0.1", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "^2.6.2" + "phpbench/phpbench": "^0.13", + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2", + "zendframework/zend-coding-standard": "~1.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev", - "dev-develop": "3.2-dev" + "dev-master": "3.2.x-dev", + "dev-develop": "3.3.x-dev" } }, "autoload": { @@ -44,12 +44,13 @@ "license": [ "BSD-3-Clause" ], - "homepage": "https://github.com/zendframework/zend-stdlib", + "description": "SPL extensions, array utilities, error handlers, and more", "keywords": [ + "ZendFramework", "stdlib", - "zf2" + "zf" ], - "time": "2016-09-13T14:38:50+00:00" + "time": "2018-08-28T21:34:05+00:00" } ], "packages-dev": [ @@ -86,32 +87,34 @@ }, { "name": "doctrine/instantiator", - "version": "1.0.5", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + "reference": "a2c590166b2133a4633738648b6b064edae0814a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a", + "reference": "a2c590166b2133a4633738648b6b064edae0814a", "shasum": "" }, "require": { - "php": ">=5.3,<8.0-DEV" + "php": "^7.1" }, "require-dev": { - "athletic/athletic": "~0.1.8", + "doctrine/coding-standard": "^6.0", "ext-pdo": "*", "ext-phar": "*", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.0" + "phpbench/phpbench": "^0.13", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-shim": "^0.11", + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.2.x-dev" } }, "autoload": { @@ -131,46 +134,52 @@ } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", "keywords": [ "constructor", "instantiate" ], - "time": "2015-06-14T21:17:01+00:00" + "time": "2019-03-17T17:37:11+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.6.1", + "version": "1.9.3", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "8e6e04167378abf1ddb4d3522d8755c5fd90d102" + "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/8e6e04167378abf1ddb4d3522d8755c5fd90d102", - "reference": "8e6e04167378abf1ddb4d3522d8755c5fd90d102", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/007c053ae6f31bba39dfa19a7726f56e9763bbea", + "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea", "shasum": "" }, "require": { - "php": ">=5.4.0" + "php": "^7.1" + }, + "replace": { + "myclabs/deep-copy": "self.version" }, "require-dev": { - "doctrine/collections": "1.*", - "phpunit/phpunit": "~4.1" + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.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", @@ -178,7 +187,7 @@ "object", "object graph" ], - "time": "2017-04-12T18:52:22+00:00" + "time": "2019-08-09T12:45:53+00:00" }, { "name": "phar-io/manifest", @@ -284,35 +293,33 @@ }, { "name": "phpdocumentor/reflection-common", - "version": "1.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c" + "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c", - "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a", + "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a", "shasum": "" }, "require": { - "php": ">=5.5" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^4.6" + "phpunit/phpunit": "~6" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src" - ] + "phpDocumentor\\Reflection\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -334,33 +341,39 @@ "reflection", "static analysis" ], - "time": "2015-12-27T11:43:31+00:00" + "time": "2018-08-07T13:53:10+00:00" }, { "name": "phpdocumentor/reflection-docblock", - "version": "3.2.2", + "version": "4.3.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "4aada1f93c72c35e22fb1383b47fee43b8f1d157" + "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/4aada1f93c72c35e22fb1383b47fee43b8f1d157", - "reference": "4aada1f93c72c35e22fb1383b47fee43b8f1d157", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/b83ff7cfcfee7827e1e78b637a5904fe6a96698e", + "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e", "shasum": "" }, "require": { - "php": ">=5.5", - "phpdocumentor/reflection-common": "^1.0@dev", - "phpdocumentor/type-resolver": "^0.3.0", + "php": "^7.0", + "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0", + "phpdocumentor/type-resolver": "~0.4 || ^1.0.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\\": [ @@ -379,41 +392,40 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2017-08-08T06:39:58+00:00" + "time": "2019-09-12T14:27:41+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "0.3.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "fb3933512008d8162b3cdf9e18dba9309b7c3773" + "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/fb3933512008d8162b3cdf9e18dba9309b7c3773", - "reference": "fb3933512008d8162b3cdf9e18dba9309b7c3773", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", + "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", "shasum": "" }, "require": { - "php": "^5.5 || ^7.0", - "phpdocumentor/reflection-common": "^1.0" + "php": "^7.1", + "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^5.2||^4.8.24" + "ext-tokenizer": "^7.1", + "mockery/mockery": "~1", + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] + "phpDocumentor\\Reflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -426,42 +438,43 @@ "email": "me@mikevanriel.com" } ], - "time": "2017-06-03T08:32:36+00:00" + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "time": "2019-08-22T18:11:29+00:00" }, { "name": "phpspec/prophecy", - "version": "v1.7.0", + "version": "1.9.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "93d39f1f7f9326d746203c7c056f300f7f126073" + "reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073", - "reference": "93d39f1f7f9326d746203c7c056f300f7f126073", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/f6811d96d97bdf400077a0cc100ae56aa32b9203", + "reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", - "sebastian/comparator": "^1.1|^2.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", + "sebastian/comparator": "^1.1|^2.0|^3.0", "sebastian/recursion-context": "^1.0|^2.0|^3.0" }, "require-dev": { "phpspec/phpspec": "^2.5|^3.2", - "phpunit/phpunit": "^4.8 || ^5.6.5" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.6.x-dev" + "dev-master": "1.8.x-dev" } }, "autoload": { - "psr-0": { - "Prophecy\\": "src/" + "psr-4": { + "Prophecy\\": "src/Prophecy" } }, "notification-url": "https://packagist.org/downloads/", @@ -489,20 +502,20 @@ "spy", "stub" ], - "time": "2017-03-02T20:05:34+00:00" + "time": "2019-10-03T11:07:50+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "5.2.2", + "version": "5.3.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "8ed1902a57849e117b5651fc1a5c48110946c06b" + "reference": "c89677919c5dd6d3b3852f230a663118762218ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/8ed1902a57849e117b5651fc1a5c48110946c06b", - "reference": "8ed1902a57849e117b5651fc1a5c48110946c06b", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c89677919c5dd6d3b3852f230a663118762218ac", + "reference": "c89677919c5dd6d3b3852f230a663118762218ac", "shasum": "" }, "require": { @@ -511,14 +524,13 @@ "php": "^7.0", "phpunit/php-file-iterator": "^1.4.2", "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^1.4.11 || ^2.0", + "phpunit/php-token-stream": "^2.0.1", "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.5", "phpunit/phpunit": "^6.0" }, "suggest": { @@ -527,7 +539,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.2.x-dev" + "dev-master": "5.3.x-dev" } }, "autoload": { @@ -542,7 +554,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -553,20 +565,20 @@ "testing", "xunit" ], - "time": "2017-08-03T12:40:43+00:00" + "time": "2018-04-06T15:36:58+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "1.4.2", + "version": "1.4.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5" + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", - "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", "shasum": "" }, "require": { @@ -600,7 +612,7 @@ "filesystem", "iterator" ], - "time": "2016-10-03T07:40:28+00:00" + "time": "2017-11-27T13:52:08+00:00" }, { "name": "phpunit/php-text-template", @@ -694,16 +706,16 @@ }, { "name": "phpunit/php-token-stream", - "version": "2.0.1", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "9a02332089ac48e704c70f6cefed30c224e3c0b0" + "reference": "791198a2c6254db10131eecfe8c06670700904db" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/9a02332089ac48e704c70f6cefed30c224e3c0b0", - "reference": "9a02332089ac48e704c70f6cefed30c224e3c0b0", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", + "reference": "791198a2c6254db10131eecfe8c06670700904db", "shasum": "" }, "require": { @@ -739,20 +751,20 @@ "keywords": [ "tokenizer" ], - "time": "2017-08-20T05:47:52+00:00" + "time": "2017-11-27T05:48:46+00:00" }, { "name": "phpunit/phpunit", - "version": "6.3.0", + "version": "6.5.14", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "9501bab711403a1ab5b8378a8adb4ec3db3debdb" + "reference": "bac23fe7ff13dbdb461481f706f0e9fe746334b7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9501bab711403a1ab5b8378a8adb4ec3db3debdb", - "reference": "9501bab711403a1ab5b8378a8adb4ec3db3debdb", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bac23fe7ff13dbdb461481f706f0e9fe746334b7", + "reference": "bac23fe7ff13dbdb461481f706f0e9fe746334b7", "shasum": "" }, "require": { @@ -766,12 +778,12 @@ "phar-io/version": "^1.0", "php": "^7.0", "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^5.2.2", - "phpunit/php-file-iterator": "^1.4.2", + "phpunit/php-code-coverage": "^5.3", + "phpunit/php-file-iterator": "^1.4.3", "phpunit/php-text-template": "^1.2.1", "phpunit/php-timer": "^1.0.9", - "phpunit/phpunit-mock-objects": "^4.0.3", - "sebastian/comparator": "^2.0.2", + "phpunit/phpunit-mock-objects": "^5.0.9", + "sebastian/comparator": "^2.1", "sebastian/diff": "^2.0", "sebastian/environment": "^3.1", "sebastian/exporter": "^3.1", @@ -797,7 +809,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "6.3.x-dev" + "dev-master": "6.5.x-dev" } }, "autoload": { @@ -823,33 +835,33 @@ "testing", "xunit" ], - "time": "2017-08-04T05:20:39+00:00" + "time": "2019-02-01T05:22:47+00:00" }, { "name": "phpunit/phpunit-mock-objects", - "version": "4.0.4", + "version": "5.0.10", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "2f789b59ab89669015ad984afa350c4ec577ade0" + "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/2f789b59ab89669015ad984afa350c4ec577ade0", - "reference": "2f789b59ab89669015ad984afa350c4ec577ade0", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/cd1cf05c553ecfec36b170070573e540b67d3f1f", + "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.5", "php": "^7.0", "phpunit/php-text-template": "^1.2.1", - "sebastian/exporter": "^3.0" + "sebastian/exporter": "^3.1" }, "conflict": { "phpunit/phpunit": "<6.0" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^6.5.11" }, "suggest": { "ext-soap": "*" @@ -857,7 +869,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0.x-dev" + "dev-master": "5.0.x-dev" } }, "autoload": { @@ -872,7 +884,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -883,7 +895,7 @@ "xunit" ], "abandoned": true, - "time": "2017-08-03T14:08:16+00:00" + "time": "2018-08-09T05:50:03+00:00" }, { "name": "psr/container", @@ -981,30 +993,30 @@ }, { "name": "sebastian/comparator", - "version": "2.0.2", + "version": "2.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "ae068fede81d06e7bb9bb46a367210a3d3e1fe6a" + "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/ae068fede81d06e7bb9bb46a367210a3d3e1fe6a", - "reference": "ae068fede81d06e7bb9bb46a367210a3d3e1fe6a", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/34369daee48eafb2651bea869b4b15d75ccc35f9", + "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9", "shasum": "" }, "require": { "php": "^7.0", - "sebastian/diff": "^2.0", - "sebastian/exporter": "^3.0" + "sebastian/diff": "^2.0 || ^3.0", + "sebastian/exporter": "^3.1" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^6.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "2.1.x-dev" } }, "autoload": { @@ -1035,13 +1047,13 @@ } ], "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": "2017-08-03T07:14:59+00:00" + "time": "2018-02-01T13:46:46+00:00" }, { "name": "sebastian/diff", @@ -1147,16 +1159,16 @@ }, { "name": "sebastian/exporter", - "version": "3.1.0", + "version": "3.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" + "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e", + "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e", "shasum": "" }, "require": { @@ -1183,6 +1195,10 @@ "BSD-3-Clause" ], "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" @@ -1191,17 +1207,13 @@ "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" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" } ], "description": "Provides the functionality to export PHP variables for visualization", @@ -1210,7 +1222,7 @@ "export", "exporter" ], - "time": "2017-04-03T13:19:02+00:00" + "time": "2019-09-14T09:02:43+00:00" }, { "name": "sebastian/global-state", @@ -1495,16 +1507,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "2.9.1", + "version": "2.9.2", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "dcbed1074f8244661eecddfc2a675430d8d33f62" + "reference": "2acf168de78487db620ab4bc524135a13cfe6745" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/dcbed1074f8244661eecddfc2a675430d8d33f62", - "reference": "dcbed1074f8244661eecddfc2a675430d8d33f62", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/2acf168de78487db620ab4bc524135a13cfe6745", + "reference": "2acf168de78487db620ab4bc524135a13cfe6745", "shasum": "" }, "require": { @@ -1569,20 +1581,137 @@ "phpcs", "standards" ], - "time": "2017-05-22T02:43:20+00:00" + "time": "2018-11-07T22:31:41+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.12.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "550ebaac289296ce228a706d0867afc34687e3f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/550ebaac289296ce228a706d0867afc34687e3f4", + "reference": "550ebaac289296ce228a706d0867afc34687e3f4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.12-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "time": "2019-08-06T08:03:45+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.12.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/b42a2f66e8f1b15ccf25652c3424265923eb4f17", + "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.12-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "time": "2019-08-06T08:03:45+00:00" }, { "name": "theseer/tokenizer", - "version": "1.1.0", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" + "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", - "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9", + "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9", "shasum": "" }, "require": { @@ -1609,28 +1738,74 @@ } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "time": "2017-04-07T12:08:54+00:00" + "time": "2019-06-13T22:48:21+00:00" + }, + { + "name": "true/punycode", + "version": "v2.1.1", + "source": { + "type": "git", + "url": "https://github.com/true/php-punycode.git", + "reference": "a4d0c11a36dd7f4e7cd7096076cab6d3378a071e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/true/php-punycode/zipball/a4d0c11a36dd7f4e7cd7096076cab6d3378a071e", + "reference": "a4d0c11a36dd7f4e7cd7096076cab6d3378a071e", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "symfony/polyfill-mbstring": "^1.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.7", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "TrueBV\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Renan Gonçalves", + "email": "renan.saddam@gmail.com" + } + ], + "description": "A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA)", + "homepage": "https://github.com/true/php-punycode", + "keywords": [ + "idna", + "punycode" + ], + "time": "2016-11-16T10:37:54+00:00" }, { "name": "webmozart/assert", - "version": "1.2.0", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", - "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f" + "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f", - "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f", + "url": "https://api.github.com/repos/webmozart/assert/zipball/88e6d84706d09a236046d686bbea96f07b3a34f4", + "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "php": "^5.3.3 || ^7.0", + "symfony/polyfill-ctype": "^1.8" }, "require-dev": { - "phpunit/phpunit": "^4.6", - "sebastian/version": "^1.0.1" + "phpunit/phpunit": "^4.8.36 || ^7.5.13" }, "type": "library", "extra": { @@ -1659,7 +1834,7 @@ "check", "validate" ], - "time": "2016-11-23T20:04:58+00:00" + "time": "2019-08-24T08:43:50+00:00" }, { "name": "zendframework/zend-coding-standard", @@ -1692,30 +1867,30 @@ }, { "name": "zendframework/zend-loader", - "version": "2.5.1", + "version": "2.6.1", "source": { "type": "git", "url": "https://github.com/zendframework/zend-loader.git", - "reference": "c5fd2f071bde071f4363def7dea8dec7393e135c" + "reference": "91da574d29b58547385b2298c020b257310898c6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-loader/zipball/c5fd2f071bde071f4363def7dea8dec7393e135c", - "reference": "c5fd2f071bde071f4363def7dea8dec7393e135c", + "url": "https://api.github.com/repos/zendframework/zend-loader/zipball/91da574d29b58547385b2298c020b257310898c6", + "reference": "91da574d29b58547385b2298c020b257310898c6", "shasum": "" }, "require": { - "php": ">=5.3.23" + "php": "^5.6 || ^7.0" }, "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.4", + "zendframework/zend-coding-standard": "~1.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev", - "dev-develop": "2.6-dev" + "dev-master": "2.6.x-dev", + "dev-develop": "2.7.x-dev" } }, "autoload": { @@ -1727,52 +1902,53 @@ "license": [ "BSD-3-Clause" ], - "homepage": "https://github.com/zendframework/zend-loader", + "description": "Autoloading and plugin loading strategies", "keywords": [ + "ZendFramework", "loader", - "zf2" + "zf" ], - "time": "2015-06-03T14:05:47+00:00" + "time": "2019-09-04T19:38:14+00:00" }, { "name": "zendframework/zend-mail", - "version": "2.8.0", + "version": "2.10.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-mail.git", - "reference": "248230940ab1453b2a532a8fde76c5a6470d7aad" + "reference": "d7beb63d5f7144a21ac100072c453e63860cdab8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-mail/zipball/248230940ab1453b2a532a8fde76c5a6470d7aad", - "reference": "248230940ab1453b2a532a8fde76c5a6470d7aad", + "url": "https://api.github.com/repos/zendframework/zend-mail/zipball/d7beb63d5f7144a21ac100072c453e63860cdab8", + "reference": "d7beb63d5f7144a21ac100072c453e63860cdab8", "shasum": "" }, "require": { "ext-iconv": "*", - "php": "^7.0 || ^5.6", + "php": "^5.6 || ^7.0", + "true/punycode": "^2.1", "zendframework/zend-loader": "^2.5", "zendframework/zend-mime": "^2.5", "zendframework/zend-stdlib": "^2.7 || ^3.0", - "zendframework/zend-validator": "^2.6" + "zendframework/zend-validator": "^2.10.2" }, "require-dev": { - "phpunit/phpunit": "^6.0.8 || ^5.7.15", + "phpunit/phpunit": "^5.7.25 || ^6.4.4 || ^7.1.4", "zendframework/zend-coding-standard": "~1.0.0", "zendframework/zend-config": "^2.6", - "zendframework/zend-crypt": "^2.6", - "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3" + "zendframework/zend-crypt": "^2.6 || ^3.0", + "zendframework/zend-servicemanager": "^2.7.10 || ^3.3.1" }, "suggest": { - "ext-intl": "Handle IDN in AddressList hostnames", "zendframework/zend-crypt": "Crammd5 support in SMTP Auth", - "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3 when using SMTP to deliver messages" + "zendframework/zend-servicemanager": "^2.7.10 || ^3.3.1 when using SMTP to deliver messages" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev", - "dev-develop": "2.9-dev" + "dev-master": "2.10.x-dev", + "dev-develop": "2.11.x-dev" }, "zf": { "component": "Zend\\Mail", @@ -1788,35 +1964,36 @@ "license": [ "BSD-3-Clause" ], - "description": "provides generalized functionality to compose and send both text and MIME-compliant multipart e-mail messages", - "homepage": "https://github.com/zendframework/zend-mail", + "description": "Provides generalized functionality to compose and send both text and MIME-compliant multipart e-mail messages", "keywords": [ + "ZendFramework", "mail", - "zf2" + "zf" ], - "time": "2017-06-08T20:03:58+00:00" + "time": "2018-06-07T13:37:07+00:00" }, { "name": "zendframework/zend-validator", - "version": "2.10.1", + "version": "2.12.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-validator.git", - "reference": "010084ddbd33299bf51ea6f0e07f8f4e8bd832a8" + "reference": "fd24920c2afcf2a70d11f67c3457f8f509453a62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-validator/zipball/010084ddbd33299bf51ea6f0e07f8f4e8bd832a8", - "reference": "010084ddbd33299bf51ea6f0e07f8f4e8bd832a8", + "url": "https://api.github.com/repos/zendframework/zend-validator/zipball/fd24920c2afcf2a70d11f67c3457f8f509453a62", + "reference": "fd24920c2afcf2a70d11f67c3457f8f509453a62", "shasum": "" }, "require": { "container-interop/container-interop": "^1.1", "php": "^5.6 || ^7.0", - "zendframework/zend-stdlib": "^2.7.6 || ^3.1" + "zendframework/zend-stdlib": "^3.2.1" }, "require-dev": { "phpunit/phpunit": "^6.0.8 || ^5.7.15", + "psr/http-message": "^1.0", "zendframework/zend-cache": "^2.6.1", "zendframework/zend-coding-standard": "~1.0.0", "zendframework/zend-config": "^2.6", @@ -1830,6 +2007,7 @@ "zendframework/zend-uri": "^2.5" }, "suggest": { + "psr/http-message": "psr/http-message, required when validating PSR-7 UploadedFileInterface instances via the Upload and UploadFile validators", "zendframework/zend-db": "Zend\\Db component, required by the (No)RecordExists validator", "zendframework/zend-filter": "Zend\\Filter component, required by the Digits validator", "zendframework/zend-i18n": "Zend\\I18n component to allow translation of validation error messages", @@ -1842,8 +2020,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.10-dev", - "dev-develop": "2.11-dev" + "dev-master": "2.12.x-dev", + "dev-develop": "2.13.x-dev" }, "zf": { "component": "Zend\\Validator", @@ -1859,13 +2037,13 @@ "license": [ "BSD-3-Clause" ], - "description": "provides a set of commonly needed validators", - "homepage": "https://github.com/zendframework/zend-validator", + "description": "Validation classes for a wide range of domains, and the ability to chain validators to create complex validation criteria", "keywords": [ + "ZendFramework", "validator", - "zf2" + "zf" ], - "time": "2017-08-22T14:19:23+00:00" + "time": "2019-10-29T08:33:25+00:00" } ], "aliases": [], diff --git a/src/Decode.php b/src/Decode.php index f74ee11..9fee6b3 100644 --- a/src/Decode.php +++ b/src/Decode.php @@ -17,8 +17,8 @@ class Decode * * Parts consist of the header and the body of each MIME part. * - * @param string $body raw body of message - * @param string $boundary boundary as found in content-type + * @param string $body raw body of message + * @param string $boundary boundary as found in content-type * @return array parts with content of each part, empty if no parts found * @throws Exception\RuntimeException */ @@ -61,26 +61,26 @@ public static function splitMime($body, $boundary) * decodes a mime encoded String and returns a * struct of parts with header and body * - * @param string $message raw message content - * @param string $boundary boundary as found in content-type - * @param string $EOL EOL string; defaults to {@link Zend\Mime\Mime::LINEEND} + * @param string $message raw message content + * @param string $boundary boundary as found in content-type + * @param string $EOL EOL string; defaults to {@link Zend\Mime\Mime::LINEEND} * @return array|null parts as array('header' => array(name => value), 'body' => content), null if no parts found * @throws Exception\RuntimeException */ public static function splitMessageStruct($message, $boundary, $EOL = Mime::LINEEND) { $parts = static::splitMime($message, $boundary); - if (! $parts) { + if (!$parts) { return; } $result = []; $headers = null; // "Declare" variable before the first usage "for reading" - $body = null; // "Declare" variable before the first usage "for reading" + $body = null; // "Declare" variable before the first usage "for reading" foreach ($parts as $part) { static::splitMessage($part, $headers, $body, $EOL); $result[] = [ 'header' => $headers, - 'body' => $body, + 'body' => $body, ]; } return $result; @@ -92,11 +92,11 @@ public static function splitMessageStruct($message, $boundary, $EOL = Mime::LINE * * The charset of the returned headers depend on your iconv settings. * - * @param string|Headers $message raw message with header and optional content - * @param Headers $headers output param, headers container - * @param string $body output param, content of message - * @param string $EOL EOL string; defaults to {@link Zend\Mime\Mime::LINEEND} - * @param bool $strict enable strict mode for parsing message + * @param string|Headers $message raw message with header and optional content + * @param Headers $headers output param, headers container + * @param string $body output param, content of message + * @param string $EOL EOL string; defaults to {@link Zend\Mime\Mime::LINEEND} + * @param bool $strict enable strict mode for parsing message * @return null */ public static function splitMessage($message, &$headers, &$body, $EOL = Mime::LINEEND, $strict = false) @@ -107,7 +107,7 @@ public static function splitMessage($message, &$headers, &$body, $EOL = Mime::LI // check for valid header at first line $firstlinePos = strpos($message, "\n"); $firstline = $firstlinePos === false ? $message : substr($message, 0, $firstlinePos); - if (! preg_match('%^[^\s]+[^:]*:%', $firstline)) { + if (!preg_match('%^[^\s]+[^:]*:%', $firstline)) { $headers = new Headers(); // TODO: we're ignoring \r for now - is this function fast enough and is it safe to assume noone needs \r? $body = str_replace(["\r", "\n"], ['', $EOL], $message); @@ -115,7 +115,7 @@ public static function splitMessage($message, &$headers, &$body, $EOL = Mime::LI } // see @ZF2-372, pops the first line off a message if it doesn't contain a header - if (! $strict) { + if (!$strict) { $parts = explode(':', $firstline, 2); if (count($parts) != 2) { $message = substr($message, strpos($message, $EOL) + 1); @@ -131,15 +131,15 @@ public static function splitMessage($message, &$headers, &$body, $EOL = Mime::LI // @todo Maybe this is too much "magic"; we should be more strict here if (strpos($message, $EOL . $EOL)) { list($headers, $body) = explode($EOL . $EOL, $message, 2); - // next is the standard new line + // next is the standard new line } elseif ($EOL != "\r\n" && strpos($message, "\r\n\r\n")) { list($headers, $body) = explode("\r\n\r\n", $message, 2); $headersEOL = "\r\n"; // Headers::fromString will fail with incorrect EOL - // next is the other "standard" new line + // next is the other "standard" new line } elseif ($EOL != "\n" && strpos($message, "\n\n")) { list($headers, $body) = explode("\n\n", $message, 2); $headersEOL = "\n"; - // at last resort find anything that looks like a new line + // at last resort find anything that looks like a new line } else { ErrorHandler::start(E_NOTICE | E_WARNING); list($headers, $body) = preg_split("%([\r\n]+)\\1%U", $message, 2); @@ -152,8 +152,8 @@ public static function splitMessage($message, &$headers, &$body, $EOL = Mime::LI /** * split a content type in its different parts * - * @param string $type content-type - * @param string $wantedPart the wanted part, else an array with all parts is returned + * @param string $type content-type + * @param string $wantedPart the wanted part, else an array with all parts is returned * @return string|array wanted part or all parts as array('type' => content-type, partname => value) */ public static function splitContentType($type, $wantedPart = null) @@ -164,9 +164,9 @@ public static function splitContentType($type, $wantedPart = null) /** * split a header field like content type in its different parts * - * @param string $field header field - * @param string $wantedPart the wanted part, else an array with all parts is returned - * @param string $firstName key name for the first part + * @param string $field header field + * @param string $wantedPart the wanted part, else an array with all parts is returned + * @param string $firstName key name for the first part * @return string|array wanted part or all parts as array($firstName => firstPart, partname => value) * @throws Exception\RuntimeException */ @@ -178,12 +178,19 @@ public static function splitHeaderField($field, $wantedPart = null, $firstName = // special case - a bit optimized if ($firstName === $wantedPart) { $field = strtok($field, ';'); - return $field[0] == '"' ? substr($field, 1, -1) : $field; + + if (self::isQuotedString($field)) { + return substr($field, 1, -1); + } + + return $field; } $field = $firstName . '=' . $field; - if (! preg_match_all('%([^=\s]+)\s*=\s*("[^"]+"|[^;]+)(;\s*|$)%', $field, $matches)) { - throw new Exception\RuntimeException('not a valid header field'); + if (!preg_match_all('%([^=\s]+)\s*=\s*("[^"]+"|[^;]+)(;\s*|$)%', $field, $matches)) { + throw new Exception\InvalidArgumentException( + sprintf('Not a valid header: %s', $field) + ); } if ($wantedPart) { @@ -191,7 +198,7 @@ public static function splitHeaderField($field, $wantedPart = null, $firstName = if (strcasecmp($name, $wantedPart)) { continue; } - if ($matches[2][$key][0] != '"') { + if (!self::isQuotedString($matches[2][$key])) { return $matches[2][$key]; } return substr($matches[2][$key], 1, -1); @@ -202,7 +209,7 @@ public static function splitHeaderField($field, $wantedPart = null, $firstName = $split = []; foreach ($matches[1] as $key => $name) { $name = strtolower($name); - if ($matches[2][$key][0] == '"') { + if (self::isQuotedString($matches[2][$key])) { $split[$name] = substr($matches[2][$key], 1, -1); } else { $split[$name] = $matches[2][$key]; @@ -217,11 +224,46 @@ public static function splitHeaderField($field, $wantedPart = null, $firstName = * * The charset of the returned string depends on your iconv settings. * - * @param string $string encoded string + * @param string $string encoded string * @return string decoded string */ public static function decodeQuotedPrintable($string) { return iconv_mime_decode($string, ICONV_MIME_DECODE_CONTINUE_ON_ERROR, 'UTF-8'); } + + /** + * @param string $str + * @param string $characterToCheck + * @return bool + */ + private static function isQuotedString($str, $characterToCheck = '"') + { + if (empty($str) || !is_string($str)) { + return false; + } + + $matchCount = preg_match('/"/', $str, $matches); + + if (!$matchCount) { + return false; + } + + // The string is containing only one quote, + // which means it's not a valid value and not parsed correctly. + if ($matchCount === 1) { + throw new Exception\InvalidArgumentException( + sprintf('Malformed header value: %s', $str) + ); + } + + $firstCharacter = $str[0]; + $lastCharacter = substr($str, -1); + + if ($firstCharacter === $characterToCheck && $lastCharacter === $characterToCheck) { + return true; + } + + return false; + } } diff --git a/test/DecodeTest.php b/test/DecodeTest.php index ca52f93..74b5127 100644 --- a/test/DecodeTest.php +++ b/test/DecodeTest.php @@ -10,6 +10,8 @@ use PHPUnit\Framework\TestCase; use Zend\Mail\Headers; use Zend\Mime\Decode; +use Zend\Mail\Storage\Message; +use Zend\Mime\Exception\InvalidArgumentException; class DecodeTest extends TestCase { @@ -22,4 +24,29 @@ public function testDecodeMessageWithoutHeaders() self::assertInstanceOf(Headers::class, $headers); self::assertSame($text, $body); } + + public function testSplitHeaderField() + { + $example = << +To: "Mary Smith" +CC: John Doe , +Date: Tue, 1 Jul 2003 10:52:37 +0200 +Message-ID: <5678.21-Nov-1997@example.com> + +Hi everyone, this is a test. +EOD; + $message = new Message(['raw' => $example]); + + // Test single + self::assertEquals('Mary Smith ', $message->getHeaderField('To')); + + // Test multiple + self::assertEquals("John Doe ,\r\n boss@nil.test", $message->getHeaderField('Cc')); + + // Test malformed address + self::expectException(InvalidArgumentException::class); + $message->getHeaderField('From'); + + } } From 047472a8973bc219f8e56af5e6163272c43cc728 Mon Sep 17 00:00:00 2001 From: Ozan Akman Date: Sun, 10 Nov 2019 11:28:13 +0100 Subject: [PATCH 2/4] Revert unnecessary changes back --- src/Decode.php | 49 ++++++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/src/Decode.php b/src/Decode.php index 9fee6b3..e36825a 100644 --- a/src/Decode.php +++ b/src/Decode.php @@ -17,8 +17,8 @@ class Decode * * Parts consist of the header and the body of each MIME part. * - * @param string $body raw body of message - * @param string $boundary boundary as found in content-type + * @param string $body raw body of message + * @param string $boundary boundary as found in content-type * @return array parts with content of each part, empty if no parts found * @throws Exception\RuntimeException */ @@ -61,26 +61,26 @@ public static function splitMime($body, $boundary) * decodes a mime encoded String and returns a * struct of parts with header and body * - * @param string $message raw message content - * @param string $boundary boundary as found in content-type - * @param string $EOL EOL string; defaults to {@link Zend\Mime\Mime::LINEEND} + * @param string $message raw message content + * @param string $boundary boundary as found in content-type + * @param string $EOL EOL string; defaults to {@link Zend\Mime\Mime::LINEEND} * @return array|null parts as array('header' => array(name => value), 'body' => content), null if no parts found * @throws Exception\RuntimeException */ public static function splitMessageStruct($message, $boundary, $EOL = Mime::LINEEND) { $parts = static::splitMime($message, $boundary); - if (!$parts) { + if (! $parts) { return; } $result = []; $headers = null; // "Declare" variable before the first usage "for reading" - $body = null; // "Declare" variable before the first usage "for reading" + $body = null; // "Declare" variable before the first usage "for reading" foreach ($parts as $part) { static::splitMessage($part, $headers, $body, $EOL); $result[] = [ 'header' => $headers, - 'body' => $body, + 'body' => $body, ]; } return $result; @@ -92,11 +92,11 @@ public static function splitMessageStruct($message, $boundary, $EOL = Mime::LINE * * The charset of the returned headers depend on your iconv settings. * - * @param string|Headers $message raw message with header and optional content - * @param Headers $headers output param, headers container - * @param string $body output param, content of message - * @param string $EOL EOL string; defaults to {@link Zend\Mime\Mime::LINEEND} - * @param bool $strict enable strict mode for parsing message + * @param string|Headers $message raw message with header and optional content + * @param Headers $headers output param, headers container + * @param string $body output param, content of message + * @param string $EOL EOL string; defaults to {@link Zend\Mime\Mime::LINEEND} + * @param bool $strict enable strict mode for parsing message * @return null */ public static function splitMessage($message, &$headers, &$body, $EOL = Mime::LINEEND, $strict = false) @@ -107,7 +107,7 @@ public static function splitMessage($message, &$headers, &$body, $EOL = Mime::LI // check for valid header at first line $firstlinePos = strpos($message, "\n"); $firstline = $firstlinePos === false ? $message : substr($message, 0, $firstlinePos); - if (!preg_match('%^[^\s]+[^:]*:%', $firstline)) { + if (! preg_match('%^[^\s]+[^:]*:%', $firstline)) { $headers = new Headers(); // TODO: we're ignoring \r for now - is this function fast enough and is it safe to assume noone needs \r? $body = str_replace(["\r", "\n"], ['', $EOL], $message); @@ -115,7 +115,7 @@ public static function splitMessage($message, &$headers, &$body, $EOL = Mime::LI } // see @ZF2-372, pops the first line off a message if it doesn't contain a header - if (!$strict) { + if (! $strict) { $parts = explode(':', $firstline, 2); if (count($parts) != 2) { $message = substr($message, strpos($message, $EOL) + 1); @@ -152,8 +152,8 @@ public static function splitMessage($message, &$headers, &$body, $EOL = Mime::LI /** * split a content type in its different parts * - * @param string $type content-type - * @param string $wantedPart the wanted part, else an array with all parts is returned + * @param string $type content-type + * @param string $wantedPart the wanted part, else an array with all parts is returned * @return string|array wanted part or all parts as array('type' => content-type, partname => value) */ public static function splitContentType($type, $wantedPart = null) @@ -164,9 +164,9 @@ public static function splitContentType($type, $wantedPart = null) /** * split a header field like content type in its different parts * - * @param string $field header field - * @param string $wantedPart the wanted part, else an array with all parts is returned - * @param string $firstName key name for the first part + * @param string $field header field + * @param string $wantedPart the wanted part, else an array with all parts is returned + * @param string $firstName key name for the first part * @return string|array wanted part or all parts as array($firstName => firstPart, partname => value) * @throws Exception\RuntimeException */ @@ -187,10 +187,8 @@ public static function splitHeaderField($field, $wantedPart = null, $firstName = } $field = $firstName . '=' . $field; - if (!preg_match_all('%([^=\s]+)\s*=\s*("[^"]+"|[^;]+)(;\s*|$)%', $field, $matches)) { - throw new Exception\InvalidArgumentException( - sprintf('Not a valid header: %s', $field) - ); + if (! preg_match_all('%([^=\s]+)\s*=\s*("[^"]+"|[^;]+)(;\s*|$)%', $field, $matches)) { + throw new Exception\RuntimeException('not a valid header field'); } if ($wantedPart) { @@ -224,7 +222,7 @@ public static function splitHeaderField($field, $wantedPart = null, $firstName = * * The charset of the returned string depends on your iconv settings. * - * @param string $string encoded string + * @param string $string encoded string * @return string decoded string */ public static function decodeQuotedPrintable($string) @@ -232,6 +230,7 @@ public static function decodeQuotedPrintable($string) return iconv_mime_decode($string, ICONV_MIME_DECODE_CONTINUE_ON_ERROR, 'UTF-8'); } + /** * @param string $str * @param string $characterToCheck From 3f4051275759dbe2ae95bdfe60190d4bc2da07f4 Mon Sep 17 00:00:00 2001 From: Ozan Akman Date: Sun, 10 Nov 2019 11:30:58 +0100 Subject: [PATCH 3/4] Revert unnecessary changes back --- src/Decode.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Decode.php b/src/Decode.php index e36825a..c2893c1 100644 --- a/src/Decode.php +++ b/src/Decode.php @@ -131,15 +131,15 @@ public static function splitMessage($message, &$headers, &$body, $EOL = Mime::LI // @todo Maybe this is too much "magic"; we should be more strict here if (strpos($message, $EOL . $EOL)) { list($headers, $body) = explode($EOL . $EOL, $message, 2); - // next is the standard new line + // next is the standard new line } elseif ($EOL != "\r\n" && strpos($message, "\r\n\r\n")) { list($headers, $body) = explode("\r\n\r\n", $message, 2); $headersEOL = "\r\n"; // Headers::fromString will fail with incorrect EOL - // next is the other "standard" new line + // next is the other "standard" new line } elseif ($EOL != "\n" && strpos($message, "\n\n")) { list($headers, $body) = explode("\n\n", $message, 2); $headersEOL = "\n"; - // at last resort find anything that looks like a new line + // at last resort find anything that looks like a new line } else { ErrorHandler::start(E_NOTICE | E_WARNING); list($headers, $body) = preg_split("%([\r\n]+)\\1%U", $message, 2); From 99b40cb8abc5c41112d42ab72a74d97a71e5f733 Mon Sep 17 00:00:00 2001 From: Ozan Akman Date: Mon, 11 Nov 2019 19:35:25 +0100 Subject: [PATCH 4/4] Replace regex with substr_count --- src/Decode.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Decode.php b/src/Decode.php index c2893c1..4e104a8 100644 --- a/src/Decode.php +++ b/src/Decode.php @@ -242,7 +242,7 @@ private static function isQuotedString($str, $characterToCheck = '"') return false; } - $matchCount = preg_match('/"/', $str, $matches); + $matchCount = substr_count($str, $characterToCheck); if (!$matchCount) { return false;