J. King
4 years ago
commit
76f5abedcd
23 changed files with 9282 additions and 0 deletions
@ -0,0 +1,7 @@ |
|||||
|
* text=auto encoding=utf-8 |
||||
|
|
||||
|
*.html diff=html |
||||
|
*.php diff=php |
||||
|
*.bat eol=crlf |
||||
|
*.cmd eol=crlf |
||||
|
.gitignore -eol |
@ -0,0 +1,5 @@ |
|||||
|
/vendor |
||||
|
/vendor-bin/*/vendor |
||||
|
/tests/coverage |
||||
|
/tests/.phpunit.result.cache |
||||
|
/.php_cs.cache |
@ -0,0 +1,79 @@ |
|||||
|
<?php |
||||
|
declare(strict_types=1); |
||||
|
|
||||
|
const BASE = __DIR__.DIRECTORY_SEPARATOR; |
||||
|
|
||||
|
$paths = [ |
||||
|
__FILE__, |
||||
|
BASE."RoboFile.php", |
||||
|
BASE."lib", |
||||
|
BASE."tests", |
||||
|
]; |
||||
|
$rules = [ |
||||
|
// house rules where PSR series is silent |
||||
|
'align_multiline_comment' => ['comment_type' => "phpdocs_only"], |
||||
|
'array_syntax' => ['syntax' => "short"], |
||||
|
'binary_operator_spaces' => [ |
||||
|
'default' => "single_space", |
||||
|
'operators' => ['=>' => "align_single_space"], |
||||
|
], |
||||
|
'cast_spaces' => ['space' => "single"], |
||||
|
'concat_space' => ['spacing' => "none"], |
||||
|
'list_syntax' => ['syntax' => "short"], |
||||
|
'magic_constant_casing' => true, |
||||
|
'magic_method_casing' => true, |
||||
|
'modernize_types_casting' => true, |
||||
|
'native_function_casing' => true, |
||||
|
'native_function_type_declaration_casing' => true, |
||||
|
'no_binary_string' => true, |
||||
|
'no_blank_lines_after_phpdoc' => true, |
||||
|
'no_empty_comment' => true, |
||||
|
'no_empty_phpdoc' => true, |
||||
|
'no_extra_blank_lines' => true, // this could probably use more configuration |
||||
|
'no_mixed_echo_print' => ['use' => "echo"], |
||||
|
'no_short_bool_cast' => true, |
||||
|
'no_trailing_comma_in_singleline_array' => true, |
||||
|
'no_unneeded_control_parentheses' => true, |
||||
|
'no_unneeded_curly_braces' => true, |
||||
|
'no_unused_imports' => true, |
||||
|
'no_whitespace_before_comma_in_array' => true, |
||||
|
'normalize_index_brace' => true, |
||||
|
'object_operator_without_whitespace' => true, |
||||
|
'pow_to_exponentiation' => true, |
||||
|
'set_type_to_cast' => true, |
||||
|
'standardize_not_equals' => true, |
||||
|
'trailing_comma_in_multiline_array' => true, |
||||
|
'unary_operator_spaces' => true, |
||||
|
'yoda_style' => false, |
||||
|
// PSR standard to apply |
||||
|
'@PSR2' => true, |
||||
|
// PSR-12 rules; php-cs-fixer does not yet support PSR-12 natively |
||||
|
'compact_nullable_typehint' => true, |
||||
|
'declare_equal_normalize' => ['space' => "none"], |
||||
|
'function_typehint_space' => true, |
||||
|
'lowercase_cast' => true, |
||||
|
'lowercase_static_reference' => true, |
||||
|
'no_alternative_syntax' => true, |
||||
|
'no_empty_statement' => true, |
||||
|
'no_leading_import_slash' => true, |
||||
|
'no_leading_namespace_whitespace' => true, |
||||
|
'no_whitespace_in_blank_line' => true, |
||||
|
'return_type_declaration' => ['space_before' => "none"], |
||||
|
'single_trait_insert_per_statement' => true, |
||||
|
'short_scalar_cast' => true, |
||||
|
'visibility_required' => ['elements' => ["const", "property", "method"]], |
||||
|
// house exceptions to PSR rules |
||||
|
'braces' => ['position_after_functions_and_oop_constructs' => "same"], |
||||
|
'function_declaration' => ['closure_function_spacing' => "none"], |
||||
|
'new_with_braces' => false, // no option to specify absence of braces |
||||
|
]; |
||||
|
|
||||
|
$finder = \PhpCsFixer\Finder::create(); |
||||
|
foreach ($paths as $path) { |
||||
|
if (is_file($path)) { |
||||
|
$finder = $finder->append([$path]); |
||||
|
} else { |
||||
|
$finder = $finder->in($path); |
||||
|
} |
||||
|
} |
||||
|
return \PhpCsFixer\Config::create()->setRiskyAllowed(true)->setRules($rules)->setFinder($finder); |
@ -0,0 +1,3 @@ |
|||||
|
Prohect lead |
||||
|
------------- |
||||
|
J. King https://jkingweb.ca/ |
@ -0,0 +1,22 @@ |
|||||
|
Copyright (c) 2018 J. King |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person |
||||
|
obtaining a copy of this software and associated documentation |
||||
|
files (the "Software"), to deal in the Software without |
||||
|
restriction, including without limitation the rights to use, |
||||
|
copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the |
||||
|
Software is furnished to do so, subject to the following |
||||
|
conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be |
||||
|
included in all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
||||
|
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
||||
|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
||||
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
||||
|
OTHER DEALINGS IN THE SOFTWARE. |
@ -0,0 +1,146 @@ |
|||||
|
<?php |
||||
|
|
||||
|
use Robo\Result; |
||||
|
|
||||
|
const BASE = __DIR__.\DIRECTORY_SEPARATOR; |
||||
|
const BASE_TEST = BASE."tests".\DIRECTORY_SEPARATOR; |
||||
|
define("IS_WIN", defined("PHP_WINDOWS_VERSION_MAJOR")); |
||||
|
define("IS_MAC", php_uname("s") === "Darwin"); |
||||
|
|
||||
|
function norm(string $path): string { |
||||
|
$out = realpath($path); |
||||
|
if (!$out) { |
||||
|
$out = str_replace(["/", "\\"], \DIRECTORY_SEPARATOR, $path); |
||||
|
} |
||||
|
return $out; |
||||
|
} |
||||
|
|
||||
|
class RoboFile extends \Robo\Tasks { |
||||
|
/** Runs the typical test suite |
||||
|
* |
||||
|
* Arguments passed to the task are passed on to PHPUnit. Thus one may, for |
||||
|
* example, run the following command and get the expected results: |
||||
|
* |
||||
|
* ./robo test --testsuite TTRSS --exclude-group slow --testdox |
||||
|
* |
||||
|
* Please see the PHPUnit documentation for available options. |
||||
|
*/ |
||||
|
public function test(array $args): Result { |
||||
|
return $this->runTests(escapeshellarg(\PHP_BINARY), "typical", $args); |
||||
|
} |
||||
|
|
||||
|
/** Runs the full test suite |
||||
|
* |
||||
|
* This includes pedantic tests which may help to identify problems. |
||||
|
* See help for the "test" task for more details. |
||||
|
*/ |
||||
|
public function testFull(array $args): Result { |
||||
|
return $this->runTests(escapeshellarg(\PHP_BINARY), "full", $args); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Runs a quick subset of the test suite |
||||
|
* |
||||
|
* See help for the "test" task for more details. |
||||
|
*/ |
||||
|
public function testQuick(array $args): Result { |
||||
|
return $this->runTests(escapeshellarg(\PHP_BINARY), "quick", $args); |
||||
|
} |
||||
|
|
||||
|
/** Produces a code coverage report |
||||
|
* |
||||
|
* By default this task produces an HTML-format coverage report in |
||||
|
* tests/coverage/. Additional reports may be produced by passing |
||||
|
* arguments to this task as one would to PHPUnit. |
||||
|
* |
||||
|
* Robo first tries to use pcov and will fall back first to xdebug then |
||||
|
* phpdbg. Neither pcov nor xdebug need to be enabled to be used; they |
||||
|
* only need to be present in the extension load path to be used. |
||||
|
*/ |
||||
|
public function coverage(array $args): Result { |
||||
|
// run tests with code coverage reporting enabled |
||||
|
$exec = $this->findCoverageEngine(); |
||||
|
return $this->runTests($exec, "coverage", array_merge(["--coverage-html", BASE_TEST."coverage"], $args)); |
||||
|
} |
||||
|
|
||||
|
/** Produces a code coverage report, with redundant tests |
||||
|
* |
||||
|
* Depending on the environment, some tests that normally provide |
||||
|
* coverage may be skipped, while working alternatives are normally |
||||
|
* suppressed for reasons of time. This coverage report will try to |
||||
|
* run all tests which may cover code. |
||||
|
* |
||||
|
* See also help for the "coverage" task for more details. |
||||
|
*/ |
||||
|
public function coverageFull(array $args): Result { |
||||
|
// run tests with code coverage reporting enabled |
||||
|
$exec = $this->findCoverageEngine(); |
||||
|
return $this->runTests($exec, "typical", array_merge(["--coverage-html", BASE_TEST."coverage"], $args)); |
||||
|
} |
||||
|
|
||||
|
/** Runs the coding standards fixer */ |
||||
|
public function clean($opts = ['demo|d' => false]): Result { |
||||
|
$t = $this->taskExec(norm(BASE."vendor/bin/php-cs-fixer")); |
||||
|
$t->arg("fix"); |
||||
|
if ($opts['demo']) { |
||||
|
$t->args("--dry-run", "--diff")->option("--diff-format", "udiff"); |
||||
|
} |
||||
|
return $t->run(); |
||||
|
} |
||||
|
|
||||
|
protected function findCoverageEngine(): string { |
||||
|
$dir = rtrim(ini_get("extension_dir"), "/").\DIRECTORY_SEPARATOR; |
||||
|
$ext = IS_WIN ? "dll" : (IS_MAC ? "dylib" : "so"); |
||||
|
$php = escapeshellarg(\PHP_BINARY); |
||||
|
$code = escapeshellarg(BASE."lib"); |
||||
|
if (extension_loaded("pcov")) { |
||||
|
return "$php -d pcov.enabled=1 -d pcov.directory=$code"; |
||||
|
} elseif (extension_loaded("xdebug")) { |
||||
|
return $php; |
||||
|
} elseif (file_exists($dir."pcov.$ext")) { |
||||
|
return "$php -d extension=pcov.$ext -d pcov.enabled=1 -d pcov.directory=$code"; |
||||
|
} elseif (file_exists($dir."pcov.$ext")) { |
||||
|
return "$php -d zend_extension=xdebug.$ext"; |
||||
|
} else { |
||||
|
if (IS_WIN) { |
||||
|
$dbg = dirname(\PHP_BINARY)."\\phpdbg.exe"; |
||||
|
$dbg = file_exists($dbg) ? $dbg : ""; |
||||
|
} else { |
||||
|
$dbg = trim(`which phpdbg 2>/dev/null`); |
||||
|
} |
||||
|
if ($dbg) { |
||||
|
return escapeshellarg($dbg)." -qrr"; |
||||
|
} else { |
||||
|
return $php; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected function blackhole(bool $all = false): string { |
||||
|
$hole = IS_WIN ? "nul" : "/dev/null"; |
||||
|
return $all ? ">$hole 2>&1" : "2>$hole"; |
||||
|
} |
||||
|
|
||||
|
protected function runTests(string $executor, string $set, array $args): Result { |
||||
|
switch ($set) { |
||||
|
case "typical": |
||||
|
$set = ["--exclude-group", "optional"]; |
||||
|
break; |
||||
|
case "quick": |
||||
|
$set = ["--exclude-group", "optional,slow"]; |
||||
|
break; |
||||
|
case "coverage": |
||||
|
$set = ["--exclude-group", "optional,coverageOptional"]; |
||||
|
break; |
||||
|
case "full": |
||||
|
$set = []; |
||||
|
break; |
||||
|
default: |
||||
|
throw new \Exception; |
||||
|
} |
||||
|
$execpath = norm(BASE."vendor-bin/phpunit/vendor/phpunit/phpunit/phpunit"); |
||||
|
$confpath = realpath(BASE_TEST."phpunit.dist.xml") ?: norm(BASE_TEST."phpunit.xml"); |
||||
|
//$this->taskServer(8000)->host("localhost")->dir(BASE_TEST."docroot")->rawArg("-n")->arg(BASE_TEST."server.php")->rawArg($this->blackhole())->background()->run(); |
||||
|
return $this->taskExec($executor)->option("-d", "zend.assertions=1")->arg($execpath)->option("-c", $confpath)->args(array_merge($set, $args))->run(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,39 @@ |
|||||
|
{ |
||||
|
"name": "mensbeam/mimesniff", |
||||
|
"type": "library", |
||||
|
"description": "An implementation of the WHATWG Mimesniff specification", |
||||
|
"keywords": ["whatwg", "mime", "mimesniff"], |
||||
|
"license": "MIT", |
||||
|
"authors": [ |
||||
|
{ |
||||
|
"name": "J. King", |
||||
|
"email": "jking@jkingweb.ca", |
||||
|
"homepage": "https://jkingweb.ca/" |
||||
|
} |
||||
|
], |
||||
|
"require": { |
||||
|
"php": "^7.1" |
||||
|
}, |
||||
|
"require-dev": { |
||||
|
"bamarni/composer-bin-plugin": "^1.3" |
||||
|
}, |
||||
|
"config": { |
||||
|
"platform": { |
||||
|
"php": "7.1.33" |
||||
|
} |
||||
|
}, |
||||
|
"scripts": { |
||||
|
"post-install-cmd": ["@composer bin all install"], |
||||
|
"post-update-cmd": ["@composer bin all update"] |
||||
|
}, |
||||
|
"autoload": { |
||||
|
"psr-4": { |
||||
|
"MensBeam\\Mime\\": "lib/" |
||||
|
} |
||||
|
}, |
||||
|
"autoload-dev": { |
||||
|
"psr-4": { |
||||
|
"MensBeam\\Mime\\TestCase\\": "tests/cases/" |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,63 @@ |
|||||
|
{ |
||||
|
"_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", |
||||
|
"This file is @generated automatically" |
||||
|
], |
||||
|
"content-hash": "8ccabde36f4d647880e48bda8d68b1bc", |
||||
|
"packages": [], |
||||
|
"packages-dev": [ |
||||
|
{ |
||||
|
"name": "bamarni/composer-bin-plugin", |
||||
|
"version": "v1.3.0", |
||||
|
"source": { |
||||
|
"type": "git", |
||||
|
"url": "https://github.com/bamarni/composer-bin-plugin.git", |
||||
|
"reference": "67f9d314dc7ecf7245b8637906e151ccc62b8d24" |
||||
|
}, |
||||
|
"dist": { |
||||
|
"type": "zip", |
||||
|
"url": "https://api.github.com/repos/bamarni/composer-bin-plugin/zipball/67f9d314dc7ecf7245b8637906e151ccc62b8d24", |
||||
|
"reference": "67f9d314dc7ecf7245b8637906e151ccc62b8d24", |
||||
|
"shasum": "" |
||||
|
}, |
||||
|
"require": { |
||||
|
"composer-plugin-api": "^1.0" |
||||
|
}, |
||||
|
"require-dev": { |
||||
|
"composer/composer": "dev-master", |
||||
|
"symfony/console": "^2.5 || ^3.0 || ^4.0" |
||||
|
}, |
||||
|
"type": "composer-plugin", |
||||
|
"extra": { |
||||
|
"class": "Bamarni\\Composer\\Bin\\Plugin", |
||||
|
"branch-alias": { |
||||
|
"dev-master": "1.1-dev" |
||||
|
} |
||||
|
}, |
||||
|
"autoload": { |
||||
|
"psr-4": { |
||||
|
"Bamarni\\Composer\\Bin\\": "src" |
||||
|
} |
||||
|
}, |
||||
|
"notification-url": "https://packagist.org/downloads/", |
||||
|
"license": [ |
||||
|
"MIT" |
||||
|
], |
||||
|
"time": "2019-03-17T12:38:04+00:00" |
||||
|
} |
||||
|
], |
||||
|
"aliases": [], |
||||
|
"minimum-stability": "stable", |
||||
|
"stability-flags": [], |
||||
|
"prefer-stable": false, |
||||
|
"prefer-lowest": false, |
||||
|
"platform": { |
||||
|
"php": "^7.1" |
||||
|
}, |
||||
|
"platform-dev": [], |
||||
|
"platform-overrides": { |
||||
|
"php": "7.1.33" |
||||
|
}, |
||||
|
"plugin-api-version": "1.1.0" |
||||
|
} |
@ -0,0 +1,158 @@ |
|||||
|
<?php |
||||
|
/** @license MIT |
||||
|
* Copyright 2020 J. King et al. |
||||
|
* See LICENSE and AUTHORS files for details */ |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
namespace MensBeam\Mime; |
||||
|
|
||||
|
/** @property-read string $type |
||||
|
* @property-read string $subtype |
||||
|
* @property-read string $essence |
||||
|
* @property-read array $params |
||||
|
*/ |
||||
|
class MimeType { |
||||
|
protected const TYPE_PATTERN = <<<'PATTERN' |
||||
|
<^ |
||||
|
[\t\r\n ]* # optional leading whitespace |
||||
|
([^/]+) # type |
||||
|
/ # type/subtype delimiter |
||||
|
([^;]+) # subtype (possibly with trailing whitespace) |
||||
|
(;.*)? # optional parameters, to be parsed separately |
||||
|
[\t\r\n ]* # optional trailing whitespace |
||||
|
$>sx |
||||
|
PATTERN; |
||||
|
protected const PARAM_PATTERN = <<<'PATTERN' |
||||
|
< |
||||
|
[;\t\r\n ]* # parameter delimiter and leading whitespace, all optional |
||||
|
([^=;]*) # parameter name; may be empty |
||||
|
(?:= # parameter name/value delimiter |
||||
|
( |
||||
|
"(?:\\"|[^"])*(?:"|$)[^;]* # quoted parameter value and optional garbage |
||||
|
|[^;]* # unquoted parameter value (possibly with trailing whitespace) |
||||
|
) |
||||
|
)? |
||||
|
;? # optional trailing parameter delimiter |
||||
|
[\t\r\n ]* # optional trailing whitespace |
||||
|
>sx |
||||
|
PATTERN; |
||||
|
protected const TOKEN_PATTERN = '<^[A-Za-z0-9!#$%&\'*+\-\.\^_`|~]+$>s'; |
||||
|
protected const BARE_VALUE_PATTERN = '<^[\t\x{20}-\x{7E}\x{80}-\x{FF}]+$>su'; |
||||
|
protected const QUOTED_VALUE_PATTERN = '<^"((?:\\\"|[\t !\x{23}-\x{7E}\x{80}-\x{FF}])*)(?:"|$)>su'; |
||||
|
protected const ESCAPE_PATTERN = '<\\\(.)>s'; |
||||
|
protected const CHAR_MAP = [0x80 => "\u{80}","\u{81}","\u{82}","\u{83}","\u{84}","\u{85}","\u{86}","\u{87}","\u{88}","\u{89}","\u{8a}","\u{8b}","\u{8c}","\u{8d}","\u{8e}","\u{8f}","\u{90}","\u{91}","\u{92}","\u{93}","\u{94}","\u{95}","\u{96}","\u{97}","\u{98}","\u{99}","\u{9a}","\u{9b}","\u{9c}","\u{9d}","\u{9e}","\u{9f}","\u{a0}","\u{a1}","\u{a2}","\u{a3}","\u{a4}","\u{a5}","\u{a6}","\u{a7}","\u{a8}","\u{a9}","\u{aa}","\u{ab}","\u{ac}","\u{ad}","\u{ae}","\u{af}","\u{b0}","\u{b1}","\u{b2}","\u{b3}","\u{b4}","\u{b5}","\u{b6}","\u{b7}","\u{b8}","\u{b9}","\u{ba}","\u{bb}","\u{bc}","\u{bd}","\u{be}","\u{bf}","\u{c0}","\u{c1}","\u{c2}","\u{c3}","\u{c4}","\u{c5}","\u{c6}","\u{c7}","\u{c8}","\u{c9}","\u{ca}","\u{cb}","\u{cc}","\u{cd}","\u{ce}","\u{cf}","\u{d0}","\u{d1}","\u{d2}","\u{d3}","\u{d4}","\u{d5}","\u{d6}","\u{d7}","\u{d8}","\u{d9}","\u{da}","\u{db}","\u{dc}","\u{dd}","\u{de}","\u{df}","\u{e0}","\u{e1}","\u{e2}","\u{e3}","\u{e4}","\u{e5}","\u{e6}","\u{e7}","\u{e8}","\u{e9}","\u{ea}","\u{eb}","\u{ec}","\u{ed}","\u{ee}","\u{ef}","\u{f0}","\u{f1}","\u{f2}","\u{f3}","\u{f4}","\u{f5}","\u{f6}","\u{f7}","\u{f8}","\u{f9}","\u{fa}","\u{fb}","\u{fc}","\u{fd}","\u{fe}","\u{ff}"]; |
||||
|
|
||||
|
private $type = ""; |
||||
|
private $subtype = ""; |
||||
|
private $params = []; |
||||
|
private $essence; |
||||
|
|
||||
|
private function __construct(string $type = "", string $subtype = "", array $params = []) { |
||||
|
$this->type = $type; |
||||
|
$this->subtype = $subtype; |
||||
|
$this->params = $params; |
||||
|
} |
||||
|
|
||||
|
public function __get(string $name) { |
||||
|
if ($name === "essence") { |
||||
|
return $this->type."/".$this->subtype; |
||||
|
} |
||||
|
return $this->$name ?? null; |
||||
|
} |
||||
|
|
||||
|
public function __toString(): string { |
||||
|
$out = $this->__get("essence"); |
||||
|
if (is_array($this->params) && sizeof($this->params)) { |
||||
|
foreach ($this->params as $name => $value) { |
||||
|
$out .= ";$name=".(preg_match(self::TOKEN_PATTERN, $value) ? $value : '"'.str_replace(["\\", '"'], ["\\\\", "\\\""], $value).'"'); |
||||
|
} |
||||
|
} |
||||
|
return $out; |
||||
|
} |
||||
|
|
||||
|
public static function parse(string $mimeType): ?self { |
||||
|
if (preg_match(self::TYPE_PATTERN, $mimeType, $match)) { |
||||
|
[$mimeType, $type, $subtype, $params] = array_pad($match, 4, ""); |
||||
|
if (strlen($type = static::parseHttpToken($type)) && strlen($subtype = static::parseHttpToken(rtrim($subtype, "\t\r\n ")))) { |
||||
|
return new static(strtolower($type), strtolower($subtype), static::parseParams($params)); |
||||
|
} |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
public static function parseBytes(string $mimeType): ?self { |
||||
|
return static::parse(static::decode($mimeType)); |
||||
|
} |
||||
|
|
||||
|
public static function decode(string $bytes): string { |
||||
|
$out = ""; |
||||
|
for ($a = 0; $a < strlen($bytes); $a++) { |
||||
|
$c = $bytes[$a]; |
||||
|
$p = ord($c); |
||||
|
$out .= $p < 0x80 ? $c : self::CHAR_MAP[$a]; |
||||
|
} |
||||
|
return $out; |
||||
|
} |
||||
|
|
||||
|
public static function encode(string $chars): ?string { |
||||
|
$map = array_combine(array_values(self::CHAR_MAP), range(chr(0x80), chr(0xFF))); |
||||
|
$out = ""; |
||||
|
foreach (preg_split("<>u", $chars) as $c) { |
||||
|
if (strlen($c) === 1) { |
||||
|
$out .= $c; |
||||
|
} elseif (isset($map[$c])) { |
||||
|
$out .= $map[$c]; |
||||
|
} else { |
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
|
return $out; |
||||
|
} |
||||
|
|
||||
|
protected static function parseParams(string $params): array { |
||||
|
$out = []; |
||||
|
if (preg_match_all(self::PARAM_PATTERN, $params, $matches, \PREG_SET_ORDER)) { |
||||
|
foreach ($matches as $match) { |
||||
|
[$param, $name, $value] = array_pad($match, 3, ""); |
||||
|
$name = strtolower(static::parseHttpToken($name)); |
||||
|
if (!strlen($name) || isset($out[$name])) { |
||||
|
continue; |
||||
|
} elseif (strlen($value) && $value[0] === '"') { |
||||
|
$value = static::parseHttpQuotedValue($value); |
||||
|
if (is_null($value)) { |
||||
|
continue; |
||||
|
} |
||||
|
} else { |
||||
|
$value = static::parseHttpBareValue($value); |
||||
|
if (!strlen($value)) { |
||||
|
continue; |
||||
|
} |
||||
|
} |
||||
|
$out[$name] = $value; |
||||
|
} |
||||
|
} |
||||
|
return $out; |
||||
|
} |
||||
|
|
||||
|
protected static function parseHttpToken(string $token): string { |
||||
|
if (preg_match(self::TOKEN_PATTERN, $token, $match)) { |
||||
|
return $token; |
||||
|
} |
||||
|
return ""; |
||||
|
} |
||||
|
|
||||
|
protected static function parseHttpBareValue(string $value): string { |
||||
|
$value = rtrim($value, "\t\r\n "); |
||||
|
if (preg_match(self::BARE_VALUE_PATTERN, $value, $match)) { |
||||
|
return $value; |
||||
|
} |
||||
|
return ""; |
||||
|
} |
||||
|
|
||||
|
protected static function parseHttpQuotedValue(string $value): ?string { |
||||
|
if (preg_match(self::QUOTED_VALUE_PATTERN, $value, $match)) { |
||||
|
return preg_replace(self::ESCAPE_PATTERN, '$1', $match[1]); |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
} |
@ -0,0 +1,14 @@ |
|||||
|
#! /bin/sh |
||||
|
base=`dirname "$0"` |
||||
|
roboCommand="$1" |
||||
|
if [ $# -eq 0 ]; then |
||||
|
"$base/vendor/bin/robo" |
||||
|
else |
||||
|
shift |
||||
|
ulimit -n 2048 |
||||
|
if [ "$1" = "clean" ]; then |
||||
|
"$base/vendor/bin/robo" "$roboCommand" "$@" |
||||
|
else |
||||
|
"$base/vendor/bin/robo" "$roboCommand" -- "$@" |
||||
|
fi |
||||
|
fi |
@ -0,0 +1,21 @@ |
|||||
|
@echo off |
||||
|
setlocal |
||||
|
set base=%~dp0 |
||||
|
set roboCommand=%1 |
||||
|
|
||||
|
rem get all arguments except the first |
||||
|
shift |
||||
|
set "args=" |
||||
|
:parse |
||||
|
if "%~1" neq "" ( |
||||
|
set args=%args% %1 |
||||
|
shift |
||||
|
goto :parse |
||||
|
) |
||||
|
if defined args set args=%args:~1% |
||||
|
|
||||
|
if "%1"=="clean" ( |
||||
|
call "%base%vendor\bin\robo" "%roboCommand%" %args% |
||||
|
) else ( |
||||
|
call "%base%vendor\bin\robo" "%roboCommand%" -- %args% |
||||
|
) |
@ -0,0 +1,20 @@ |
|||||
|
<?php |
||||
|
/** @license MIT |
||||
|
* Copyright 2020 J. King |
||||
|
* See LICENSE and AUTHORS files for details */ |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
namespace MensBeam\Mime; |
||||
|
|
||||
|
const NS_BASE = __NAMESPACE__."\\"; |
||||
|
define(NS_BASE."BASE", dirname(__DIR__).DIRECTORY_SEPARATOR); |
||||
|
const DOCROOT = BASE."tests".DIRECTORY_SEPARATOR."docroot".DIRECTORY_SEPARATOR; |
||||
|
ini_set("memory_limit", "-1"); |
||||
|
ini_set("zend.assertions", "1"); |
||||
|
ini_set("assert.exception", "true"); |
||||
|
error_reporting(\E_ALL); |
||||
|
require_once BASE."vendor".DIRECTORY_SEPARATOR."autoload.php"; |
||||
|
|
||||
|
if (function_exists("xdebug_set_filter")) { |
||||
|
xdebug_set_filter(\XDEBUG_FILTER_CODE_COVERAGE, \XDEBUG_PATH_WHITELIST, [BASE."lib/"]); |
||||
|
} |
@ -0,0 +1,42 @@ |
|||||
|
<?php |
||||
|
/** @license MIT |
||||
|
* Copyright 2020 J. King |
||||
|
* See LICENSE and AUTHORS files for details */ |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
namespace MensBeam\Mime\TestCase; |
||||
|
|
||||
|
use MensBeam\Mime\MimeType as Mime; |
||||
|
|
||||
|
/** @covers \MensBeam\Mime\MimeType */ |
||||
|
class MimeTypeTest extends \PHPUnit\Framework\TestCase { |
||||
|
/** @dataProvider provideStandardTests */ |
||||
|
public function testStandardTestSuite(string $input, ?string $exp): void { |
||||
|
if (is_null($exp)) { |
||||
|
$this->assertNull(Mime::parse($input)); |
||||
|
} else { |
||||
|
$this->assertSame($exp, (string) Mime::parse($input)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public function provideStandardTests(): iterable { |
||||
|
foreach (new \GlobIterator(__DIR__."/*.json", \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::KEY_AS_FILENAME) as $file => $path) { |
||||
|
$indexOffset = 0; |
||||
|
$description = ""; |
||||
|
foreach (json_decode(file_get_contents($path)) as $index => $test) { |
||||
|
if (is_string($test)) { |
||||
|
// the array member is a description of the next member |
||||
|
// the index offset should be decremented, the description stored, and this entry skipped |
||||
|
$indexOffset--; |
||||
|
$description = $test; |
||||
|
continue; |
||||
|
} else { |
||||
|
$index += $indexOffset; |
||||
|
$description = $description ? ": $description" : ""; |
||||
|
yield "$file #$index$description" => [$test->input, $test->output]; |
||||
|
$description = null; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,20 @@ |
|||||
|
The MimeType class is an original work, but its test suite is derived |
||||
|
in part from an existing test corpus from the following source: |
||||
|
|
||||
|
The Web Platform Test suite |
||||
|
<https://github.com/web-platform-tests/wpt/tree/62317fb983ca5687e4133d89f5523839fdab7f69/mimesniff/mime-types> |
||||
|
|
||||
|
The license text is reproduced below, but please note that the license text |
||||
|
has changed since the last time the mimesniff portion of the test suite was |
||||
|
modified; the text included here is current as of 2019-04-25. |
||||
|
|
||||
|
|
||||
|
Copyright 2019 web-platform-tests contributors |
||||
|
|
||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: |
||||
|
|
||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. |
||||
|
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. |
||||
|
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. |
||||
|
|
||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
File diff suppressed because it is too large
@ -0,0 +1,383 @@ |
|||||
|
[ |
||||
|
"Basics", |
||||
|
{ |
||||
|
"input": "text/html;charset=gbk", |
||||
|
"output": "text/html;charset=gbk", |
||||
|
"navigable": true, |
||||
|
"encoding": "GBK" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "TEXT/HTML;CHARSET=GBK", |
||||
|
"output": "text/html;charset=GBK", |
||||
|
"navigable": true, |
||||
|
"encoding": "GBK" |
||||
|
}, |
||||
|
"Legacy comment syntax", |
||||
|
{ |
||||
|
"input": "text/html;charset=gbk(", |
||||
|
"output": "text/html;charset=\"gbk(\"", |
||||
|
"navigable": true, |
||||
|
"encoding": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;x=(;charset=gbk", |
||||
|
"output": "text/html;x=\"(\";charset=gbk", |
||||
|
"navigable": true, |
||||
|
"encoding": "GBK" |
||||
|
}, |
||||
|
"Duplicate parameter", |
||||
|
{ |
||||
|
"input": "text/html;charset=gbk;charset=windows-1255", |
||||
|
"output": "text/html;charset=gbk", |
||||
|
"navigable": true, |
||||
|
"encoding": "GBK" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;charset=();charset=GBK", |
||||
|
"output": "text/html;charset=\"()\"", |
||||
|
"navigable": true, |
||||
|
"encoding": null |
||||
|
}, |
||||
|
"Spaces", |
||||
|
{ |
||||
|
"input": "text/html;charset =gbk", |
||||
|
"output": "text/html", |
||||
|
"navigable": true, |
||||
|
"encoding": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html ;charset=gbk", |
||||
|
"output": "text/html;charset=gbk", |
||||
|
"navigable": true, |
||||
|
"encoding": "GBK" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html; charset=gbk", |
||||
|
"output": "text/html;charset=gbk", |
||||
|
"navigable": true, |
||||
|
"encoding": "GBK" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;charset= gbk", |
||||
|
"output": "text/html;charset=\" gbk\"", |
||||
|
"navigable": true, |
||||
|
"encoding": "GBK" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;charset= \"gbk\"", |
||||
|
"output": "text/html;charset=\" \\\"gbk\\\"\"", |
||||
|
"navigable": true, |
||||
|
"encoding": null |
||||
|
}, |
||||
|
"0x0B and 0x0C", |
||||
|
{ |
||||
|
"input": "text/html;charset=\u000Bgbk", |
||||
|
"output": "text/html", |
||||
|
"navigable": true, |
||||
|
"encoding": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;charset=\u000Cgbk", |
||||
|
"output": "text/html", |
||||
|
"navigable": true, |
||||
|
"encoding": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;\u000Bcharset=gbk", |
||||
|
"output": "text/html", |
||||
|
"navigable": true, |
||||
|
"encoding": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;\u000Ccharset=gbk", |
||||
|
"output": "text/html", |
||||
|
"navigable": true, |
||||
|
"encoding": null |
||||
|
}, |
||||
|
"Single quotes are a token, not a delimiter", |
||||
|
{ |
||||
|
"input": "text/html;charset='gbk'", |
||||
|
"output": "text/html;charset='gbk'", |
||||
|
"navigable": true, |
||||
|
"encoding": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;charset='gbk", |
||||
|
"output": "text/html;charset='gbk", |
||||
|
"navigable": true, |
||||
|
"encoding": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;charset=gbk'", |
||||
|
"output": "text/html;charset=gbk'", |
||||
|
"navigable": true, |
||||
|
"encoding": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;charset=';charset=GBK", |
||||
|
"output": "text/html;charset='", |
||||
|
"navigable": true, |
||||
|
"encoding": null |
||||
|
}, |
||||
|
"Invalid parameters", |
||||
|
{ |
||||
|
"input": "text/html;test;charset=gbk", |
||||
|
"output": "text/html;charset=gbk", |
||||
|
"navigable": true, |
||||
|
"encoding": "GBK" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;test=;charset=gbk", |
||||
|
"output": "text/html;charset=gbk", |
||||
|
"navigable": true, |
||||
|
"encoding": "GBK" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;';charset=gbk", |
||||
|
"output": "text/html;charset=gbk", |
||||
|
"navigable": true, |
||||
|
"encoding": "GBK" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;\";charset=gbk", |
||||
|
"output": "text/html;charset=gbk", |
||||
|
"navigable": true, |
||||
|
"encoding": "GBK" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html ; ; charset=gbk", |
||||
|
"output": "text/html;charset=gbk", |
||||
|
"navigable": true, |
||||
|
"encoding": "GBK" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;;;;charset=gbk", |
||||
|
"output": "text/html;charset=gbk", |
||||
|
"navigable": true, |
||||
|
"encoding": "GBK" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;charset= \"\u007F;charset=GBK", |
||||
|
"output": "text/html;charset=GBK", |
||||
|
"navigable": true, |
||||
|
"encoding": "GBK" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;charset=\"\u007F;charset=foo\";charset=GBK", |
||||
|
"output": "text/html;charset=GBK", |
||||
|
"navigable": true, |
||||
|
"encoding": "GBK" |
||||
|
}, |
||||
|
"Double quotes", |
||||
|
{ |
||||
|
"input": "text/html;charset=\"gbk\"", |
||||
|
"output": "text/html;charset=gbk", |
||||
|
"navigable": true, |
||||
|
"encoding": "GBK" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;charset=\"gbk", |
||||
|
"output": "text/html;charset=gbk", |
||||
|
"navigable": true, |
||||
|
"encoding": "GBK" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;charset=gbk\"", |
||||
|
"output": "text/html;charset=\"gbk\\\"\"", |
||||
|
"navigable": true, |
||||
|
"encoding": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;charset=\" gbk\"", |
||||
|
"output": "text/html;charset=\" gbk\"", |
||||
|
"navigable": true, |
||||
|
"encoding": "GBK" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;charset=\"gbk \"", |
||||
|
"output": "text/html;charset=\"gbk \"", |
||||
|
"navigable": true, |
||||
|
"encoding": "GBK" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;charset=\"\\ gbk\"", |
||||
|
"output": "text/html;charset=\" gbk\"", |
||||
|
"navigable": true, |
||||
|
"encoding": "GBK" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;charset=\"\\g\\b\\k\"", |
||||
|
"output": "text/html;charset=gbk", |
||||
|
"navigable": true, |
||||
|
"encoding": "GBK" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;charset=\"gbk\"x", |
||||
|
"output": "text/html;charset=gbk", |
||||
|
"navigable": true, |
||||
|
"encoding": "GBK" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;charset=\"\";charset=GBK", |
||||
|
"output": "text/html;charset=\"\"", |
||||
|
"navigable": true, |
||||
|
"encoding": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html;charset=\";charset=GBK", |
||||
|
"output": "text/html;charset=\";charset=GBK\"", |
||||
|
"navigable": true, |
||||
|
"encoding": null |
||||
|
}, |
||||
|
"Unexpected code points", |
||||
|
{ |
||||
|
"input": "text/html;charset={gbk}", |
||||
|
"output": "text/html;charset=\"{gbk}\"", |
||||
|
"navigable": true, |
||||
|
"encoding": null |
||||
|
}, |
||||
|
"Parameter name longer than 127", |
||||
|
{ |
||||
|
"input": "text/html;0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789=x;charset=gbk", |
||||
|
"output": "text/html;0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789=x;charset=gbk", |
||||
|
"navigable": true, |
||||
|
"encoding": "GBK" |
||||
|
}, |
||||
|
"type/subtype longer than 127", |
||||
|
{ |
||||
|
"input": "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789/0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", |
||||
|
"output": "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789/0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" |
||||
|
}, |
||||
|
"Valid", |
||||
|
{ |
||||
|
"input": "!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", |
||||
|
"output": "!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "x/x;x=\"\t !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008A\u008B\u008C\u008D\u008E\u008F\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009A\u009B\u009C\u009D\u009E\u009F\u00A0\u00A1\u00A2\u00A3\u00A4\u00A5\u00A6\u00A7\u00A8\u00A9\u00AA\u00AB\u00AC\u00AD\u00AE\u00AF\u00B0\u00B1\u00B2\u00B3\u00B4\u00B5\u00B6\u00B7\u00B8\u00B9\u00BA\u00BB\u00BC\u00BD\u00BE\u00BF\u00C0\u00C1\u00C2\u00C3\u00C4\u00C5\u00C6\u00C7\u00C8\u00C9\u00CA\u00CB\u00CC\u00CD\u00CE\u00CF\u00D0\u00D1\u00D2\u00D3\u00D4\u00D5\u00D6\u00D7\u00D8\u00D9\u00DA\u00DB\u00DC\u00DD\u00DE\u00DF\u00E0\u00E1\u00E2\u00E3\u00E4\u00E5\u00E6\u00E7\u00E8\u00E9\u00EA\u00EB\u00EC\u00ED\u00EE\u00EF\u00F0\u00F1\u00F2\u00F3\u00F4\u00F5\u00F6\u00F7\u00F8\u00F9\u00FA\u00FB\u00FC\u00FD\u00FE\u00FF\"", |
||||
|
"output": "x/x;x=\"\t !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008A\u008B\u008C\u008D\u008E\u008F\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009A\u009B\u009C\u009D\u009E\u009F\u00A0\u00A1\u00A2\u00A3\u00A4\u00A5\u00A6\u00A7\u00A8\u00A9\u00AA\u00AB\u00AC\u00AD\u00AE\u00AF\u00B0\u00B1\u00B2\u00B3\u00B4\u00B5\u00B6\u00B7\u00B8\u00B9\u00BA\u00BB\u00BC\u00BD\u00BE\u00BF\u00C0\u00C1\u00C2\u00C3\u00C4\u00C5\u00C6\u00C7\u00C8\u00C9\u00CA\u00CB\u00CC\u00CD\u00CE\u00CF\u00D0\u00D1\u00D2\u00D3\u00D4\u00D5\u00D6\u00D7\u00D8\u00D9\u00DA\u00DB\u00DC\u00DD\u00DE\u00DF\u00E0\u00E1\u00E2\u00E3\u00E4\u00E5\u00E6\u00E7\u00E8\u00E9\u00EA\u00EB\u00EC\u00ED\u00EE\u00EF\u00F0\u00F1\u00F2\u00F3\u00F4\u00F5\u00F6\u00F7\u00F8\u00F9\u00FA\u00FB\u00FC\u00FD\u00FE\u00FF\"" |
||||
|
}, |
||||
|
"End-of-file handling", |
||||
|
{ |
||||
|
"input": "x/x;test", |
||||
|
"output": "x/x" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "x/x;test=\"\\", |
||||
|
"output": "x/x;test=\"\\\\\"" |
||||
|
}, |
||||
|
"Whitespace (not handled by generated-mime-types.json or above)", |
||||
|
{ |
||||
|
"input": "x/x;x= ", |
||||
|
"output": "x/x" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "x/x;x=\t", |
||||
|
"output": "x/x" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "x/x\n\r\t ;x=x", |
||||
|
"output": "x/x;x=x" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "\n\r\t x/x;x=x\n\r\t ", |
||||
|
"output": "x/x;x=x" |
||||
|
}, |
||||
|
{ |
||||
|
"input": "x/x;\n\r\t x=x\n\r\t ;x=y", |
||||
|
"output": "x/x;x=x" |
||||
|
}, |
||||
|
"Latin1", |
||||
|
{ |
||||
|
"input": "text/html;test=\u00FF;charset=gbk", |
||||
|
"output": "text/html;test=\"\u00FF\";charset=gbk", |
||||
|
"navigable": true, |
||||
|
"encoding": "GBK" |
||||
|
}, |
||||
|
">Latin1", |
||||
|
{ |
||||
|
"input": "x/x;test=\uFFFD;x=x", |
||||
|
"output": "x/x;x=x" |
||||
|
}, |
||||
|
"Failure", |
||||
|
{ |
||||
|
"input": "\u000Bx/x", |
||||
|
"output": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "\u000Cx/x", |
||||
|
"output": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "x/x\u000B", |
||||
|
"output": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "x/x\u000C", |
||||
|
"output": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "", |
||||
|
"output": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "\t", |
||||
|
"output": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "/", |
||||
|
"output": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "bogus", |
||||
|
"output": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "bogus/", |
||||
|
"output": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "bogus/ ", |
||||
|
"output": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "bogus/bogus/;", |
||||
|
"output": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "</>", |
||||
|
"output": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "(/)", |
||||
|
"output": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "ÿ/ÿ", |
||||
|
"output": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/html(;doesnot=matter", |
||||
|
"output": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "{/}", |
||||
|
"output": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "\u0100/\u0100", |
||||
|
"output": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text /html", |
||||
|
"output": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "text/ html", |
||||
|
"output": null |
||||
|
}, |
||||
|
{ |
||||
|
"input": "\"text/html\"", |
||||
|
"output": null |
||||
|
} |
||||
|
] |
@ -0,0 +1,26 @@ |
|||||
|
<?xml version="1.0"?> |
||||
|
<phpunit |
||||
|
colors="true" |
||||
|
bootstrap="bootstrap.php" |
||||
|
cacheTokens="true" |
||||
|
convertErrorsToExceptions="false" |
||||
|
convertNoticesToExceptions="false" |
||||
|
convertWarningsToExceptions="false" |
||||
|
beStrictAboutTestsThatDoNotTestAnything="true" |
||||
|
beStrictAboutOutputDuringTests="true" |
||||
|
forceCoversAnnotation="true" |
||||
|
executionOrder="default" |
||||
|
> |
||||
|
|
||||
|
<filter> |
||||
|
<whitelist processUncoveredFilesFromWhitelist="true"> |
||||
|
<directory suffix=".php">../lib</directory> |
||||
|
</whitelist> |
||||
|
</filter> |
||||
|
|
||||
|
<testsuites> |
||||
|
<testsuite name="MIME"> |
||||
|
<directory>cases</directory> |
||||
|
</testsuite> |
||||
|
</testsuites> |
||||
|
</phpunit> |
@ -0,0 +1,5 @@ |
|||||
|
{ |
||||
|
"require-dev": { |
||||
|
"friendsofphp/php-cs-fixer": "^2.16" |
||||
|
} |
||||
|
} |
File diff suppressed because it is too large
@ -0,0 +1,6 @@ |
|||||
|
{ |
||||
|
"require-dev": { |
||||
|
"phpunit/phpunit": "^9.0", |
||||
|
"symfony/yaml": "^5.0" |
||||
|
} |
||||
|
} |
File diff suppressed because it is too large
@ -0,0 +1,5 @@ |
|||||
|
{ |
||||
|
"require-dev": { |
||||
|
"consolidation/robo": "^2.0" |
||||
|
} |
||||
|
} |
File diff suppressed because it is too large
Loading…
Reference in new issue