This commit is contained in:
cutemeli
2025-12-22 10:35:30 +00:00
parent 0bfc6c8425
commit 5ce7ca2c5d
38927 changed files with 0 additions and 4594700 deletions

View File

@@ -1,7 +0,0 @@
#!/bin/bash
# Temporary workaround for cyclic dependencies - can be removed once 3.0 has been released
echo "Branch as 2.99.x in Pre-Install"
git checkout -b 2.99.x

View File

@@ -1 +0,0 @@
Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. (https://getlaminas.org/)

View File

@@ -1,26 +0,0 @@
Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
- 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.
- Neither the name of Laminas Foundation 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 OWNER 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.

View File

@@ -1,42 +0,0 @@
# laminas-validator
[![Build Status](https://github.com/laminas/laminas-validator/actions/workflows/continuous-integration.yml/badge.svg)](https://github.com/laminas/laminas-validator/actions/workflows/continuous-integration.yml)
[![Type Coverage](https://shepherd.dev/github/laminas/laminas-validator/coverage.svg)](https://shepherd.dev/github/laminas/laminas-validator)
> ## 🇷🇺 Русским гражданам
>
> Мы, участники Laminas, родились и живем в разных странах. У многих из нас есть друзья, родственники и коллеги как в России, так и в Украине. Некоторые из нас родились в России. Некоторые из нас живут в России. У некоторых бабушки и дедушки сражались с фашистами во Второй мировой войне. Здесь никто не поддерживает фашизм.
>
> У одного из нас есть украинская родственница, которая спаслась из дома вместе с сыном. Поезд задержался из-за бомбежки на дороге впереди. У нас есть друзья, которые прячутся в бомбоубежищах. Мы с тревогой ждем весточки от них после воздушных налетов, которые беспорядочно наносят удары и попадают по больницам, школам, детским садам и домам. Мы не берем это из каких-либо СМИ. Мы наблюдаем это напрямую.
>
> Вы доверяете нам достаточно, чтоб использовать наши программы, и мы просим вас довериться нам вновь. Мы нуждаемся в помощи. Выходите и протестуйте против этой бесполезной войны. Остановите кровопролитие. Скажите "Нет войне!"
>
> ## 🇺🇸 To Citizens of Russia
>
> We at Laminas come from all over the world. Many of us have friends, family and colleagues in both Russia and Ukraine. Some of us were born in Russia. Some of us currently live in Russia. Some have grandparents who fought Nazis in World War II. Nobody here supports fascism.
>
> One team member has a Ukrainian relative who fled her home with her son. The train was delayed due to bombing on the road ahead. We have friends who are hiding in bomb shelters. We anxiously follow up on them after the air raids, which indiscriminately fire at hospitals, schools, kindergartens and houses. We're not taking this from any media. These are our actual experiences.
>
> You trust us enough to use our software. We ask that you trust us to say the truth on this. We need your help. Go out and protest this unnecessary war. Stop the bloodshed. Say "stop the war!"
laminas-validator provides a set of commonly needed validators. It also provides a
simple validator chaining mechanism by which multiple validators may be applied
to a single datum in a user-defined order.
## Installation
Run the following to install this library:
```bash
$ composer require laminas/laminas-validator
```
## Documentation
Browse the documentation online at https://docs.laminas.dev/laminas-validator/
## Support
* [Issues](https://github.com/laminas/laminas-validator/issues/)
* [Chat](https://laminas.dev/chat/)
* [Forum](https://discourse.laminas.dev/)

View File

@@ -1,158 +0,0 @@
<?php
declare(strict_types=1);
use Laminas\Validator\Hostname;
require __DIR__ . '/../vendor/autoload.php';
const IANA_URL = 'https://data.iana.org/TLD/tlds-alpha-by-domain.txt';
const LAMINAS_HOSTNAME_VALIDATOR_FILE = __DIR__ . '/../src/Hostname.php';
if (! file_exists(LAMINAS_HOSTNAME_VALIDATOR_FILE) || ! is_readable(LAMINAS_HOSTNAME_VALIDATOR_FILE)) {
printf("Error: cannot read file '%s'%s", LAMINAS_HOSTNAME_VALIDATOR_FILE, PHP_EOL);
exit(1);
}
if (! is_writable(LAMINAS_HOSTNAME_VALIDATOR_FILE)) {
printf("Error: cannot update file '%s'%s", LAMINAS_HOSTNAME_VALIDATOR_FILE, PHP_EOL);
exit(1);
}
/** @psalm-var list<string> $newFileContent */
$newFileContent = []; // new file content
$insertDone = false; // becomes 'true' when we find start of $validTlds declaration
$insertFinish = false; // becomes 'true' when we find end of $validTlds declaration
$checkOnly = isset($argv[1]) ? $argv[1] === '--check-only' : false;
$response = getOfficialTLDs();
$currentFileContent = file(LAMINAS_HOSTNAME_VALIDATOR_FILE);
foreach ($currentFileContent as $line) {
if ($insertDone === $insertFinish) {
// Outside of $validTlds definition; keep line as-is
$newFileContent[] = $line;
}
if ($insertFinish) {
continue;
}
if ($insertDone) {
// Detect where the $validTlds declaration ends
if (preg_match('/^\s+\];\s*$/', $line)) {
$newFileContent[] = $line;
$insertFinish = true;
}
continue;
}
// Detect where the $validTlds declaration begins
if (preg_match('/^\s+protected\s+\$validTlds\s+=\s+\[\s*$/', $line)) {
$newFileContent = array_merge($newFileContent, getNewValidTlds($response));
$insertDone = true;
}
}
if (! $insertDone) {
printf('Error: cannot find line with "protected $validTlds"%s', PHP_EOL);
exit(1);
}
if (! $insertFinish) {
printf('Error: cannot find end of $validTlds declaration%s', PHP_EOL);
exit(1);
}
if ($currentFileContent === $newFileContent) {
printf('Nothing to do. Validator has no TLD changes.%s', PHP_EOL);
exit(0);
}
if ($checkOnly) {
printf(
'TLDs must be updated, please run `php bin/update_hostname_validator.php` and push your changes%s',
PHP_EOL
);
exit(1);
}
if (false === @file_put_contents(LAMINAS_HOSTNAME_VALIDATOR_FILE, $newFileContent)) {
printf('Error: cannot write info file "%s"%s', LAMINAS_HOSTNAME_VALIDATOR_FILE, PHP_EOL);
exit(1);
}
printf('Validator TLD file updated.%s', PHP_EOL);
exit(0);
/**
* Get Official TLDs
*/
function getOfficialTLDs(): string
{
try {
return file_get_contents(IANA_URL);
} catch (Throwable $e) {
printf(
'Downloading the IANA TLD list failed: %s',
$e->getMessage(),
);
exit(1);
}
}
/**
* Extract new Valid TLDs from a string containing one per line.
*
* @return list<string>
*/
function getNewValidTlds(string $string): array
{
$decodePunycode = getPunycodeDecoder();
// Get new TLDs from the list previously fetched
$newValidTlds = [];
foreach (preg_grep('/^[^#]/', preg_split("#\r?\n#", $string)) as $line) {
$newValidTlds [] = sprintf(
"%s'%s',\n",
str_repeat(' ', 8),
$decodePunycode(strtolower($line))
);
}
return $newValidTlds;
}
/**
* Retrieve and return a punycode decoder.
*
* TLDs are puny encoded.
*
* We need a decodePunycode function to translate TLDs to UTF-8:
*
* - use idn_to_utf8 if available
* - otherwise, use Hostname::decodePunycode()
*
* @return callable
*/
function getPunycodeDecoder()
{
if (function_exists('idn_to_utf8')) {
return function ($domain) {
return idn_to_utf8($domain, 0, INTL_IDNA_VARIANT_UTS46);
};
}
$hostnameValidator = new Hostname();
$reflection = new ReflectionClass($hostnameValidator::class);
$decodePunyCode = $reflection->getMethod('decodePunycode');
return function ($encode) use ($hostnameValidator, $decodePunyCode) {
if (strpos($encode, 'xn--') === 0) {
return $decodePunyCode->invokeArgs($hostnameValidator, [substr($encode, 4)]);
}
return $encode;
};
}

View File

@@ -1,86 +0,0 @@
{
"name": "laminas/laminas-validator",
"description": "Validation classes for a wide range of domains, and the ability to chain validators to create complex validation criteria",
"license": "BSD-3-Clause",
"keywords": [
"laminas",
"validator"
],
"homepage": "https://laminas.dev",
"support": {
"docs": "https://docs.laminas.dev/laminas-validator/",
"issues": "https://github.com/laminas/laminas-validator/issues",
"source": "https://github.com/laminas/laminas-validator",
"rss": "https://github.com/laminas/laminas-validator/releases.atom",
"chat": "https://laminas.dev/chat",
"forum": "https://discourse.laminas.dev"
},
"config": {
"sort-packages": true,
"platform": {
"php": "8.2.99"
},
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
},
"extra": {
"laminas": {
"component": "Laminas\\Validator",
"config-provider": "Laminas\\Validator\\ConfigProvider"
}
},
"require": {
"php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0",
"laminas/laminas-servicemanager": "^3.21.0",
"laminas/laminas-stdlib": "^3.19",
"psr/http-message": "^1.0.1 || ^2.0.0"
},
"require-dev": {
"laminas/laminas-coding-standard": "^2.5",
"laminas/laminas-db": "^2.20",
"laminas/laminas-filter": "^2.41.0",
"laminas/laminas-i18n": "^2.30.0",
"laminas/laminas-session": "^2.25.1",
"laminas/laminas-uri": "^2.13.0",
"phpunit/phpunit": "^10.5.58",
"psalm/plugin-phpunit": "^0.19.0",
"psr/http-client": "^1.0.3",
"psr/http-factory": "^1.1.0",
"vimeo/psalm": "^5.26.1"
},
"suggest": {
"laminas/laminas-db": "Laminas\\Db component, required by the (No)RecordExists validator",
"laminas/laminas-filter": "Laminas\\Filter component, required by the Digits validator",
"laminas/laminas-i18n": "Laminas\\I18n component to allow translation of validation error messages",
"laminas/laminas-i18n-resources": "Translations of validator messages",
"laminas/laminas-servicemanager": "Laminas\\ServiceManager component to allow using the ValidatorPluginManager and validator chains",
"laminas/laminas-session": "Laminas\\Session component, ^2.8; required by the Csrf validator",
"laminas/laminas-uri": "Laminas\\Uri component, required by the Uri and Sitemap\\Loc validators",
"psr/http-message": "psr/http-message, required when validating PSR-7 UploadedFileInterface instances via the Upload and UploadFile validators"
},
"autoload": {
"psr-4": {
"Laminas\\Validator\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"LaminasTest\\Validator\\": "test/"
}
},
"scripts": {
"check": [
"@cs-check",
"@test"
],
"cs-check": "phpcs",
"cs-fix": "phpcbf",
"test": "phpunit --colors=always",
"test-coverage": "phpunit --colors=always --coverage-clover clover.xml",
"static-analysis": "psalm --shepherd --stats"
},
"conflict": {
"zendframework/zend-validator": "*"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +0,0 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"local>laminas/.github:renovate-config"
]
}

View File

@@ -1,662 +0,0 @@
<?php
namespace Laminas\Validator;
use Laminas\Stdlib\ArrayUtils;
use Traversable;
use function array_key_exists;
use function array_keys;
use function array_unique;
use function current;
use function implode;
use function is_array;
use function is_object;
use function is_string;
use function key;
use function method_exists;
use function str_repeat;
use function str_replace;
use function strlen;
use function substr;
use function ucfirst;
use function var_export;
use const SORT_REGULAR;
/**
* @psalm-type AbstractOptions = array{
* messages: array<string, string>,
* messageTemplates: array<string, string>,
* messageVariables: array<string, mixed>,
* translator: Translator\TranslatorInterface|null,
* translatorTextDomain: string|null,
* translatorEnabled: bool,
* valueObscured: bool,
* }
* @property array<string, mixed> $options
* @property array<string, string> $messageTemplates
* @property array<string, mixed> $messageVariables
*/
abstract class AbstractValidator implements
Translator\TranslatorAwareInterface,
ValidatorInterface
{
/**
* The value to be validated
*
* @var mixed
*/
protected $value;
/**
* Default translation object for all validate objects
*
* @var Translator\TranslatorInterface
*/
protected static $defaultTranslator;
/**
* Default text domain to be used with translator
*
* @var string
*/
protected static $defaultTranslatorTextDomain = 'default';
/**
* Limits the maximum returned length of an error message
*
* @var int
*/
protected static $messageLength = -1;
/**
* @deprecated Since 2.61.0 This property will be removed in 3.0
*
* @var AbstractOptions&array<string, mixed>
*/
protected $abstractOptions = [
'messages' => [], // Array of validation failure messages
'messageTemplates' => [], // Array of validation failure message templates
'messageVariables' => [], // Array of additional variables available for validation failure messages
'translator' => null, // Translation object to used -> Translator\TranslatorInterface
'translatorTextDomain' => null, // Translation text domain
'translatorEnabled' => true, // Is translation enabled?
'valueObscured' => false, // Flag indicating whether value should be obfuscated in error messages
];
/**
* Abstract constructor for all validators
* A validator should accept following parameters:
* - nothing f.e. Validator()
* - one or multiple scalar values f.e. Validator($first, $second, $third)
* - an array f.e. Validator(array($first => 'first', $second => 'second', $third => 'third'))
* - an instance of Traversable f.e. Validator($config_instance)
*
* @param array<string, mixed>|Traversable<string, mixed> $options
*/
public function __construct($options = null)
{
// The abstract constructor allows no scalar values
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
}
/** @psalm-suppress RedundantConditionGivenDocblockType */
if (isset($this->messageTemplates) && is_array($this->messageTemplates)) {
$this->abstractOptions['messageTemplates'] = $this->messageTemplates;
}
/** @psalm-suppress RedundantConditionGivenDocblockType */
if (isset($this->messageVariables) && is_array($this->messageVariables)) {
$this->abstractOptions['messageVariables'] = $this->messageVariables;
}
if (is_array($options)) {
$this->setOptions($options);
}
}
/**
* Returns an option
*
* @deprecated Since 2.61.0 This method will be removed in 3.0
*
* @param string $option Option to be returned
* @return mixed Returned option
* @throws Exception\InvalidArgumentException
*/
public function getOption($option)
{
if (array_key_exists($option, $this->abstractOptions)) {
return $this->abstractOptions[$option];
}
/** @psalm-suppress RedundantConditionGivenDocblockType */
if (isset($this->options) && array_key_exists($option, $this->options)) {
return $this->options[$option];
}
throw new Exception\InvalidArgumentException("Invalid option '$option'");
}
/**
* Returns all available options
*
* @deprecated Since 2.61.0 This method will be removed in 3.0
*
* @return array<string, mixed> Array with all available options
*/
public function getOptions()
{
$result = $this->abstractOptions;
/** @psalm-suppress RedundantConditionGivenDocblockType */
if (isset($this->options) && is_array($this->options)) {
$result += $this->options;
}
return $result;
}
/**
* Sets one or multiple options
*
* @deprecated Since 2.61.0 This method will be removed in 3.0 - Options should be passed to the constructor
*
* @param array<string, mixed>|Traversable<string, mixed> $options Options to set
* @return self Provides fluid interface
* @throws Exception\InvalidArgumentException If $options is not an array or Traversable.
*/
public function setOptions($options = [])
{
/** @psalm-suppress DocblockTypeContradiction */
if (! is_array($options) && ! $options instanceof Traversable) {
throw new Exception\InvalidArgumentException(__METHOD__ . ' expects an array or Traversable');
}
/**
* @psalm-suppress RedundantConditionGivenDocblockType
* @psalm-var mixed $option
*/
foreach ($options as $name => $option) {
$fname = 'set' . ucfirst($name);
$fname2 = 'is' . ucfirst($name);
if (($name !== 'setOptions') && method_exists($this, $name)) {
$this->{$name}($option);
} elseif (($fname !== 'setOptions') && method_exists($this, $fname)) {
$this->{$fname}($option);
} elseif (method_exists($this, $fname2)) {
$this->{$fname2}($option);
} elseif (isset($this->options) && is_array($this->options)) {
$this->options[$name] = $option;
} else {
$this->abstractOptions[$name] = $option;
}
}
return $this;
}
/**
* Returns array of validation failure messages
*
* @return array<string, string>
*/
public function getMessages()
{
return array_unique($this->abstractOptions['messages'], SORT_REGULAR);
}
/**
* Invoke as command
*
* @return bool
*/
public function __invoke(mixed $value)
{
return $this->isValid($value);
}
/**
* Returns an array of the names of variables that are used in constructing validation failure messages
*
* @deprecated Since 2.61.0 This method will be removed in 3.0
*
* @return list<string>
*/
public function getMessageVariables()
{
return array_keys($this->abstractOptions['messageVariables']);
}
/**
* Returns the message templates from the validator
*
* @deprecated Since 2.61.0 This method will be removed in 3.0
*
* @return array<string, string>
*/
public function getMessageTemplates()
{
return $this->abstractOptions['messageTemplates'];
}
/**
* Sets the validation failure message template for a particular key
*
* @param string $messageString
* @param string|null $messageKey OPTIONAL
* @return $this Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function setMessage($messageString, $messageKey = null)
{
if ($messageKey === null) {
$keys = array_keys($this->abstractOptions['messageTemplates']);
foreach ($keys as $key) {
$this->setMessage($messageString, $key);
}
return $this;
}
if (! isset($this->abstractOptions['messageTemplates'][$messageKey])) {
throw new Exception\InvalidArgumentException("No message template exists for key '$messageKey'");
}
$this->abstractOptions['messageTemplates'][$messageKey] = $messageString;
return $this;
}
/**
* Sets validation failure message templates given as an array, where the array keys are the message keys,
* and the array values are the message template strings.
*
* @deprecated Since 2.61.0 This method will be removed in 3.0
* Provide customised messages via the `messages` constructor option
*
* @param array<string, string> $messages
* @return $this
*/
public function setMessages(array $messages)
{
foreach ($messages as $key => $message) {
$this->setMessage($message, $key);
}
return $this;
}
/**
* Magic function returns the value of the requested property, if and only if it is the value or a
* message variable.
*
* @deprecated Since 2.61.0 This method will be removed in 3.0 - It will no longer be possible to fetch any internal
* properties
*
* @param string $property
* @return mixed
* @throws Exception\InvalidArgumentException
*/
public function __get($property)
{
if ($property === 'value') {
return $this->value;
}
if (array_key_exists($property, $this->abstractOptions['messageVariables'])) {
/** @psalm-var mixed $result */
$result = $this->abstractOptions['messageVariables'][$property];
if (is_array($result)) {
return $this->{key($result)}[current($result)];
}
return $this->{$result};
}
/** @psalm-suppress RedundantConditionGivenDocblockType */
if (isset($this->messageVariables) && array_key_exists($property, $this->messageVariables)) {
/** @psalm-var mixed $result */
$result = $this->{$this->messageVariables[$property]};
if (is_array($result)) {
return $this->{key($result)}[current($result)];
}
return $this->{$result};
}
throw new Exception\InvalidArgumentException("No property exists by the name '$property'");
}
/**
* Constructs and returns a validation failure message with the given message key and value.
*
* Returns null if and only if $messageKey does not correspond to an existing template.
*
* If a translator is available and a translation exists for $messageKey,
* the translation will be used.
*
* @param string $messageKey
* @param string|array|object $value
* @return null|string
*/
protected function createMessage($messageKey, $value)
{
if (! isset($this->abstractOptions['messageTemplates'][$messageKey])) {
return null;
}
$message = $this->abstractOptions['messageTemplates'][$messageKey];
$message = $this->translateMessage($messageKey, $message);
if (is_object($value)) {
$value = method_exists($value, '__toString')
? (string) $value
: $value::class . ' object';
} elseif (is_array($value)) {
$value = var_export($value, true);
} else {
/** @psalm-suppress RedundantCastGivenDocblockType $value */
$value = (string) $value;
}
if ($this->isValueObscured()) {
$value = str_repeat('*', strlen($value));
}
$message = str_replace('%value%', $value, $message);
foreach ($this->abstractOptions['messageVariables'] as $ident => $property) {
if (is_array($property)) {
$value = $this->{key($property)}[current($property)];
if (is_array($value)) {
$value = '[' . implode(', ', $value) . ']';
}
} else {
$value = $this->$property;
}
$message = str_replace("%$ident%", (string) $value, $message);
}
$length = self::getMessageLength();
if (($length > -1) && (strlen($message) > $length)) {
$message = substr($message, 0, $length - 3) . '...';
}
return $message;
}
/**
* @param string|null $messageKey
* @param null|string|array|object $value OPTIONAL
* @return void
*/
protected function error($messageKey, $value = null)
{
if ($messageKey === null) {
$keys = array_keys($this->abstractOptions['messageTemplates']);
$messageKey = current($keys);
}
if ($value === null) {
/** @psalm-var string|array|object $value */
$value = $this->value;
}
$message = $this->createMessage($messageKey, $value);
if (! is_string($message)) {
return;
}
$this->abstractOptions['messages'][$messageKey] = $message;
}
/**
* Returns the validation value
*
* @return mixed Value to be validated
*/
protected function getValue()
{
return $this->value;
}
/**
* Sets the value to be validated and clears the messages and errors arrays
*
* @return void
*/
protected function setValue(mixed $value)
{
$this->value = $value;
$this->abstractOptions['messages'] = [];
}
/**
* Set flag indicating whether or not value should be obfuscated in messages
*
* @deprecated Since 2.61.0 This method will be removed in 3.0 - Use the `valueObscured` option via the constructor
*
* @param bool $flag
* @return $this
*/
public function setValueObscured($flag)
{
/** @psalm-suppress RedundantCastGivenDocblockType */
$this->abstractOptions['valueObscured'] = (bool) $flag;
return $this;
}
/**
* Retrieve flag indicating whether or not value should be obfuscated in
* messages
*
* @deprecated Since 2.61.0 This method will be removed in 3.0
*
* @return bool
*/
public function isValueObscured()
{
return $this->abstractOptions['valueObscured'];
}
/**
* Set translation object
*
* @param string $textDomain (optional)
* @return $this
* @throws Exception\InvalidArgumentException
*/
public function setTranslator(?Translator\TranslatorInterface $translator = null, $textDomain = null)
{
$this->abstractOptions['translator'] = $translator;
if (null !== $textDomain) {
$this->setTranslatorTextDomain($textDomain);
}
return $this;
}
/**
* Return translation object
*
* @return Translator\TranslatorInterface|null
*/
public function getTranslator()
{
if (! $this->isTranslatorEnabled()) {
return null;
}
if (null === $this->abstractOptions['translator']) {
$this->abstractOptions['translator'] = self::getDefaultTranslator();
}
return $this->abstractOptions['translator'];
}
/**
* Does this validator have its own specific translator?
*
* @deprecated Since 2.61.0 This method will be removed in 3.0
*
* @return bool
*/
public function hasTranslator()
{
return (bool) $this->abstractOptions['translator'];
}
/**
* Set translation text domain
*
* @deprecated since 2.61.0 This method will be removed in 3.0 Use the `translatorTextDomain` option, or set
* the text domain at the same time as the translator via `setTranslator()`
*
* @param string $textDomain
* @return $this
*/
public function setTranslatorTextDomain($textDomain = 'default')
{
$this->abstractOptions['translatorTextDomain'] = $textDomain;
return $this;
}
/**
* Return the translation text domain
*
* @deprecated Since 2.61.0 This method will be removed in 3.0
*
* @return string
*/
public function getTranslatorTextDomain()
{
if (null === $this->abstractOptions['translatorTextDomain']) {
$this->abstractOptions['translatorTextDomain'] =
self::getDefaultTranslatorTextDomain();
}
return $this->abstractOptions['translatorTextDomain'];
}
/**
* Set default translation object for all validate objects
*
* @param string $textDomain (optional)
* @return void
* @throws Exception\InvalidArgumentException
*/
public static function setDefaultTranslator(?Translator\TranslatorInterface $translator = null, $textDomain = null)
{
static::$defaultTranslator = $translator;
if (null !== $textDomain) {
self::setDefaultTranslatorTextDomain($textDomain);
}
}
/**
* Get default translation object for all validate objects
*
* @deprecated Since 2.61.0 This method will be removed in 3.0
*
* @return Translator\TranslatorInterface|null
*/
public static function getDefaultTranslator()
{
return static::$defaultTranslator;
}
/**
* Is there a default translation object set?
*
* @deprecated Since 2.61.0 This method will be removed in 3.0
*
* @return bool
*/
public static function hasDefaultTranslator()
{
return (bool) static::$defaultTranslator;
}
/**
* Set default translation text domain for all validate objects
*
* @param string $textDomain
* @return void
*/
public static function setDefaultTranslatorTextDomain($textDomain = 'default')
{
static::$defaultTranslatorTextDomain = $textDomain;
}
/**
* Get default translation text domain for all validate objects
*
* @deprecated Since 2.61.0 This method will be removed in 3.0
*
* @return string
*/
public static function getDefaultTranslatorTextDomain()
{
return static::$defaultTranslatorTextDomain;
}
/**
* Indicate whether or not translation should be enabled
*
* @deprecated Since 2.61.0 This method will be removed in 3.0
*
* @param bool $enabled
* @return $this
*/
public function setTranslatorEnabled($enabled = true)
{
/** @psalm-suppress RedundantCastGivenDocblockType */
$this->abstractOptions['translatorEnabled'] = (bool) $enabled;
return $this;
}
/**
* Is translation enabled?
*
* @deprecated Since 2.61.0 This method will be removed in 3.0
*
* @return bool
*/
public function isTranslatorEnabled()
{
return $this->abstractOptions['translatorEnabled'];
}
/**
* Returns the maximum allowed message length
*
* @deprecated Since 2.61.0 This method will be removed in 3.0
*
* @return int
*/
public static function getMessageLength()
{
return static::$messageLength;
}
/**
* Sets the maximum allowed message length
*
* @param int $length
* @return void
*/
public static function setMessageLength($length = -1)
{
static::$messageLength = $length;
}
/**
* Translate a validation message
*
* @param string $messageKey
* @param string $message
* @return string
*/
protected function translateMessage($messageKey, $message)
{
$translator = $this->getTranslator();
if (! $translator) {
return $message;
}
return $translator->translate($message, $this->getTranslatorTextDomain());
}
}

View File

@@ -1,220 +0,0 @@
<?php
namespace Laminas\Validator;
use Laminas\Stdlib\ArrayUtils;
use Laminas\Validator\Barcode\AdapterInterface;
use Laminas\Validator\Exception\InvalidArgumentException;
use Traversable;
use function assert;
use function class_exists;
use function get_debug_type;
use function is_array;
use function is_string;
use function sprintf;
use function strtolower;
use function substr;
use function ucfirst;
/** @final */
class Barcode extends AbstractValidator
{
public const INVALID = 'barcodeInvalid';
public const FAILED = 'barcodeFailed';
public const INVALID_CHARS = 'barcodeInvalidChars';
public const INVALID_LENGTH = 'barcodeInvalidLength';
/** @var array<string, string> */
protected $messageTemplates = [
self::FAILED => 'The input failed checksum validation',
self::INVALID_CHARS => 'The input contains invalid characters',
self::INVALID_LENGTH => 'The input should have a length of %length% characters',
self::INVALID => 'Invalid type given. String expected',
];
/**
* Additional variables available for validation failure messages
*
* @var array<string, array<string, string>>
*/
protected $messageVariables = [
'length' => ['options' => 'length'],
];
/**
* @var array{
* adapter: null|AdapterInterface,
* options: null|array<string, mixed>,
* length: null|int|array,
* useChecksum: null|bool,
* }
*/
protected $options = [
'adapter' => null, // Barcode adapter Laminas\Validator\Barcode\AbstractAdapter
'options' => null, // Options for this adapter
'length' => null,
'useChecksum' => null,
];
/**
* Constructor for barcodes
*
* @param iterable<string, mixed>|null|string|AdapterInterface $options Options to use
*/
public function __construct($options = null)
{
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
}
if ($options === null) {
$options = [];
}
if (is_string($options) || $options instanceof AdapterInterface) {
$options = ['adapter' => $options];
}
if (! is_array($options)) {
throw new InvalidArgumentException(sprintf(
'Options should be an array, a string representing the name of an adapter, or an adapter instance. '
. 'Received "%s"',
get_debug_type($options),
));
}
parent::__construct($options);
}
/**
* Returns the set adapter
*
* @deprecated Since 2.60.0 all option setters and getters are deprecated for removal in 3.0
*
* @return AdapterInterface
*/
public function getAdapter()
{
if (! $this->options['adapter'] instanceof Barcode\AdapterInterface) {
$this->setAdapter('Ean13');
}
assert($this->options['adapter'] instanceof Barcode\AdapterInterface);
return $this->options['adapter'];
}
/**
* Sets a new barcode adapter
*
* @deprecated Since 2.60.0 all option setters and getters are deprecated for removal in 3.0
*
* @param string|AdapterInterface $adapter Barcode adapter to use
* @param array $options Options for this adapter
* @return $this
* @throws InvalidArgumentException
*/
public function setAdapter($adapter, $options = null)
{
if (is_string($adapter)) {
$adapter = ucfirst(strtolower($adapter));
$adapter = 'Laminas\\Validator\\Barcode\\' . $adapter;
if (! class_exists($adapter)) {
throw new InvalidArgumentException('Barcode adapter matching "' . $adapter . '" not found');
}
$adapter = new $adapter($options);
}
if (! $adapter instanceof Barcode\AdapterInterface) {
throw new InvalidArgumentException(
sprintf(
'Adapter %s does not implement Laminas\\Validator\\Barcode\\AdapterInterface',
get_debug_type($adapter)
)
);
}
$this->options['adapter'] = $adapter;
return $this;
}
/**
* Returns the checksum option
*
* @deprecated Since 2.60.0 all option setters and getters are deprecated for removal in 3.0
*
* @return string|null
*/
public function getChecksum()
{
return $this->getAdapter()->getChecksum();
}
/**
* Sets if checksum should be validated, if no value is given the actual setting is returned
*
* @deprecated Since 2.60.0 all option setters and getters are deprecated for removal in 3.0
*
* @param null|bool $checksum
* @return AdapterInterface|bool
*/
public function useChecksum($checksum = null)
{
return $this->getAdapter()->useChecksum($checksum);
}
/**
* Defined by Laminas\Validator\ValidatorInterface
*
* Returns true if and only if $value contains a valid barcode
*
* @param string $value
* @return bool
*/
public function isValid($value)
{
if (! is_string($value)) {
$this->error(self::INVALID);
return false;
}
$this->setValue($value);
$adapter = $this->getAdapter();
$this->options['length'] = $adapter->getLength();
$result = $adapter->hasValidLength($value);
if (! $result) {
if (is_array($this->options['length'])) {
$temp = $this->options['length'];
$this->options['length'] = '';
foreach ($temp as $length) {
$this->options['length'] .= '/';
$this->options['length'] .= $length;
}
$this->options['length'] = substr($this->options['length'], 1);
}
$this->error(self::INVALID_LENGTH);
return false;
}
$result = $adapter->hasValidCharacters($value);
if (! $result) {
$this->error(self::INVALID_CHARS);
return false;
}
if ($this->useChecksum(null)) {
$result = $adapter->hasValidChecksum($value);
if (! $result) {
$this->error(self::FAILED);
return false;
}
}
return true;
}
}

View File

@@ -1,317 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
use function chr;
use function is_array;
use function is_string;
use function method_exists;
use function str_replace;
use function str_split;
use function strlen;
use function substr;
/** @deprecated Since 2.60.0 In v3 adapters should implement AdapterInterface directly */
abstract class AbstractAdapter implements AdapterInterface
{
/**
* Allowed options for this adapter
*
* @var array{
* length: int|array|'even'|'odd'|null,
* characters: int|string|array|null,
* checksum: null|string,
* useChecksum: null|bool,
* }
*/
protected $options = [
'length' => null, // Allowed barcode lengths, integer, array, string
'characters' => null, // Allowed barcode characters
'checksum' => null, // Callback to checksum function
'useChecksum' => true, // Is a checksum value included?, boolean
];
/**
* Checks the length of a barcode
*
* @param string $value The barcode to check for proper length
* @return bool
*/
public function hasValidLength($value)
{
if (! is_string($value)) {
return false;
}
$fixum = strlen($value);
$length = $this->getLength();
if (is_array($length)) {
foreach ($length as $value) {
if ($fixum === $value) {
return true;
}
if ($value === -1) {
return true;
}
}
return false;
}
if ($fixum === $length) {
return true;
}
if ($length === -1) {
return true;
}
if ($length === 'even') {
$count = $fixum % 2;
return 0 === $count;
}
if ($length === 'odd') {
$count = $fixum % 2;
return 1 === $count;
}
return false;
}
/**
* Checks for allowed characters within the barcode
*
* @param string $value The barcode to check for allowed characters
* @return bool
*/
public function hasValidCharacters($value)
{
if (! is_string($value)) {
return false;
}
$characters = $this->getCharacters();
if ($characters === 128) {
for ($x = 0; $x < 128; ++$x) {
$value = str_replace(chr($x), '', $value);
}
} else {
$chars = str_split($characters);
foreach ($chars as $char) {
$value = str_replace($char, '', $value);
}
}
if (strlen($value) > 0) {
return false;
}
return true;
}
/**
* Validates the checksum
*
* @param string $value The barcode to check the checksum for
* @return bool
*/
public function hasValidChecksum($value)
{
$checksum = $this->getChecksum();
if ($checksum !== null) {
if (method_exists($this, $checksum)) {
return $this->$checksum($value);
}
}
return false;
}
/**
* Returns the allowed barcode length
*
* @return int|array|string|null
*/
public function getLength()
{
return $this->options['length'];
}
/**
* Returns the allowed characters
*
* @return int|string|array|null
*/
public function getCharacters()
{
return $this->options['characters'];
}
/**
* Returns the checksum function name
*
* @return string|null
*/
public function getChecksum()
{
return $this->options['checksum'];
}
/**
* Sets the checksum validation method
*
* @param string $checksum Checksum method to call
* @return $this
*/
protected function setChecksum($checksum)
{
$this->options['checksum'] = $checksum;
return $this;
}
/**
* Sets the checksum validation, if no value is given, the actual setting is returned
*
* @inheritDoc
*/
public function useChecksum($check = null)
{
if ($check === null) {
return $this->options['useChecksum'];
}
$this->options['useChecksum'] = (bool) $check;
return $this;
}
/**
* Sets the length of this barcode
*
* @param int|array $length
* @return $this
*/
protected function setLength($length)
{
$this->options['length'] = $length;
return $this;
}
/**
* Sets the allowed characters of this barcode
*
* @param int|string|array $characters
* @return $this
*/
protected function setCharacters($characters)
{
$this->options['characters'] = $characters;
return $this;
}
/**
* Validates the checksum (Modulo 10)
* GTIN implementation factor 3
*
* @param string $value The barcode to validate
* @return bool
*/
protected function gtin($value)
{
$barcode = substr($value, 0, -1);
$sum = 0;
$length = strlen($barcode) - 1;
for ($i = 0; $i <= $length; $i++) {
if (($i % 2) === 0) {
$sum += $barcode[$length - $i] * 3;
} else {
$sum += $barcode[$length - $i];
}
}
$calc = $sum % 10;
$checksum = $calc === 0 ? 0 : 10 - $calc;
return $value[$length + 1] === (string) $checksum;
}
/**
* Validates the checksum (Modulo 10)
* IDENTCODE implementation factors 9 and 4
*
* @param string $value The barcode to validate
* @return bool
*/
protected function identcode($value)
{
$barcode = substr($value, 0, -1);
$sum = 0;
$length = strlen($value) - 2;
for ($i = 0; $i <= $length; $i++) {
if (($i % 2) === 0) {
$sum += $barcode[$length - $i] * 4;
} else {
$sum += $barcode[$length - $i] * 9;
}
}
$calc = $sum % 10;
$checksum = $calc === 0 ? 0 : 10 - $calc;
return $value[$length + 1] === (string) $checksum;
}
/**
* Validates the checksum (Modulo 10)
* CODE25 implementation factor 3
*
* @param string $value The barcode to validate
* @return bool
*/
protected function code25($value)
{
$barcode = substr($value, 0, -1);
$sum = 0;
$length = strlen($barcode) - 1;
for ($i = 0; $i <= $length; $i++) {
if (($i % 2) === 0) {
$sum += $barcode[$i] * 3;
} else {
$sum += $barcode[$i];
}
}
$calc = $sum % 10;
$checksum = $calc === 0 ? 0 : 10 - $calc;
return $value[$length + 1] === (string) $checksum;
}
/**
* Validates the checksum ()
* POSTNET implementation
*
* @param string $value The barcode to validate
* @return bool
*/
protected function postnet($value)
{
$checksum = substr($value, -1, 1);
$values = str_split(substr($value, 0, -1));
$check = 0;
foreach ($values as $row) {
$check += $row;
}
$check %= 10;
$check = 10 - $check;
return (string) $check === $checksum;
}
}

View File

@@ -1,66 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
interface AdapterInterface
{
/**
* Checks the length of a barcode
*
* @param string $value The barcode to check for proper length
* @return bool
*/
public function hasValidLength($value);
/**
* Checks for allowed characters within the barcode
*
* @param string $value The barcode to check for allowed characters
* @return bool
*/
public function hasValidCharacters($value);
/**
* Validates the checksum
*
* @param string $value The barcode to check the checksum for
* @return bool
*/
public function hasValidChecksum($value);
/**
* Returns the allowed barcode length
*
* @return int|string|array|null
*/
public function getLength();
/**
* Returns the allowed characters
*
* @deprecated Since 2.60.0 all option setters and getters are deprecated for removal in 3.0
*
* @return int|string|array|null
*/
public function getCharacters();
/**
* Returns if barcode uses a checksum
*
* @deprecated Since 2.60.0 all option setters and getters are deprecated for removal in 3.0
*
* @return string|null
*/
public function getChecksum();
/**
* Sets the checksum validation, if no value is given, the actual setting is returned
*
* @deprecated Since 2.60.0 all option setters and getters are deprecated for removal in 3.0
*
* @param bool|null $check
* @return $this|bool
* @psalm-return ($check is null ? bool : static)
*/
public function useChecksum($check = null);
}

View File

@@ -1,67 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
use function strpbrk;
use function substr;
/** @final */
class Codabar extends AbstractAdapter
{
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength(-1);
$this->setCharacters('0123456789-$:/.+ABCDTN*E');
$this->useChecksum(false);
}
/**
* Checks for allowed characters
*
* @see Laminas\Validator\Barcode.AbstractAdapter::checkChars()
*
* @param string $value
* @return bool
*/
public function hasValidCharacters($value)
{
if (strpbrk($value, 'ABCD') !== false) {
$first = $value[0];
if (strpbrk($first, 'ABCD') === false) {
// Missing start char
return false;
}
$last = substr($value, -1, 1);
if (strpbrk($last, 'ABCD') === false) {
// Missing stop char
return false;
}
$value = substr($value, 1, -1);
} elseif (strpbrk($value, 'TN*E') !== false) {
$first = $value[0];
if (strpbrk($first, 'TN*E') === false) {
// Missing start char
return false;
}
$last = substr($value, -1, 1);
if (strpbrk($last, 'TN*E') === false) {
// Missing stop char
return false;
}
$value = substr($value, 1, -1);
}
$chars = $this->getCharacters();
$this->setCharacters('0123456789-$:/.+');
$result = parent::hasValidCharacters($value);
$this->setCharacters($chars);
return $result;
}
}

View File

@@ -1,738 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
use Laminas\Stdlib\StringUtils;
use Laminas\Stdlib\StringWrapper\StringWrapperInterface;
use Laminas\Validator\Exception;
use function chr;
use function is_string;
use function ord;
/** @final */
class Code128 extends AbstractAdapter
{
/**
* The used string wrapper used for basic UTF-8 string functions
*
* @var StringWrapperInterface
*/
protected $utf8StringWrapper;
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength(-1);
$this->setCharacters([
'A' => [
0 => ' ',
1 => '!',
2 => '"',
3 => '#',
4 => '$',
5 => '%',
6 => '&',
7 => "'",
8 => '(',
9 => ')',
10 => '*',
11 => '+',
12 => ',',
13 => '-',
14 => '.',
15 => '/',
16 => '0',
17 => '1',
18 => '2',
19 => '3',
20 => '4',
21 => '5',
22 => '6',
23 => '7',
24 => '8',
25 => '9',
26 => ':',
27 => ';',
28 => '<',
29 => '=',
30 => '>',
31 => '?',
32 => '@',
33 => 'A',
34 => 'B',
35 => 'C',
36 => 'D',
37 => 'E',
38 => 'F',
39 => 'G',
40 => 'H',
41 => 'I',
42 => 'J',
43 => 'K',
44 => 'L',
45 => 'M',
46 => 'N',
47 => 'O',
48 => 'P',
49 => 'Q',
50 => 'R',
51 => 'S',
52 => 'T',
53 => 'U',
54 => 'V',
55 => 'W',
56 => 'X',
57 => 'Y',
58 => 'Z',
59 => '[',
60 => '\\',
61 => ']',
62 => '^',
63 => '_',
64 => 0x00,
65 => 0x01,
66 => 0x02,
67 => 0x03,
68 => 0x04,
69 => 0x05,
70 => 0x06,
71 => 0x07,
72 => 0x08,
73 => 0x09,
74 => 0x0A,
75 => 0x0B,
76 => 0x0C,
77 => 0x0D,
78 => 0x0E,
79 => 0x0F,
80 => 0x10,
81 => 0x11,
82 => 0x12,
83 => 0x13,
84 => 0x14,
85 => 0x15,
86 => 0x16,
87 => 0x17,
88 => 0x18,
89 => 0x19,
90 => 0x1A,
91 => 0x1B,
92 => 0x1C,
93 => 0x1D,
94 => 0x1E,
95 => 0x1F,
96 => 'Ç',
97 => 'ü',
98 => 'é',
99 => 'â',
100 => 'ä',
101 => 'à',
102 => 'å',
103 => '‡',
104 => 'ˆ',
105 => '‰',
106 => 'Š',
],
'B' => [
0 => ' ',
1 => '!',
2 => '"',
3 => '#',
4 => '$',
5 => '%',
6 => '&',
7 => "'",
8 => '(',
9 => ')',
10 => '*',
11 => '+',
12 => ',',
13 => '-',
14 => '.',
15 => '/',
16 => '0',
17 => '1',
18 => '2',
19 => '3',
20 => '4',
21 => '5',
22 => '6',
23 => '7',
24 => '8',
25 => '9',
26 => ':',
27 => ';',
28 => '<',
29 => '=',
30 => '>',
31 => '?',
32 => '@',
33 => 'A',
34 => 'B',
35 => 'C',
36 => 'D',
37 => 'E',
38 => 'F',
39 => 'G',
40 => 'H',
41 => 'I',
42 => 'J',
43 => 'K',
44 => 'L',
45 => 'M',
46 => 'N',
47 => 'O',
48 => 'P',
49 => 'Q',
50 => 'R',
51 => 'S',
52 => 'T',
53 => 'U',
54 => 'V',
55 => 'W',
56 => 'X',
57 => 'Y',
58 => 'Z',
59 => '[',
60 => '\\',
61 => ']',
62 => '^',
63 => '_',
64 => '`',
65 => 'a',
66 => 'b',
67 => 'c',
68 => 'd',
69 => 'e',
70 => 'f',
71 => 'g',
72 => 'h',
73 => 'i',
74 => 'j',
75 => 'k',
76 => 'l',
77 => 'm',
78 => 'n',
79 => 'o',
80 => 'p',
81 => 'q',
82 => 'r',
83 => 's',
84 => 't',
85 => 'u',
86 => 'v',
87 => 'w',
88 => 'x',
89 => 'y',
90 => 'z',
91 => '{',
92 => '|',
93 => '}',
94 => '~',
95 => 0x7F,
96 => 'Ç',
97 => 'ü',
98 => 'é',
99 => 'â',
100 => 'ä',
101 => 'à',
102 => 'å',
103 => '‡',
104 => 'ˆ',
105 => '‰',
106 => 'Š',
],
'C' => [
0 => '00',
1 => '01',
2 => '02',
3 => '03',
4 => '04',
5 => '05',
6 => '06',
7 => '07',
8 => '08',
9 => '09',
10 => '10',
11 => '11',
12 => '12',
13 => '13',
14 => '14',
15 => '15',
16 => '16',
17 => '17',
18 => '18',
19 => '19',
20 => '20',
21 => '21',
22 => '22',
23 => '23',
24 => '24',
25 => '25',
26 => '26',
27 => '27',
28 => '28',
29 => '29',
30 => '30',
31 => '31',
32 => '32',
33 => '33',
34 => '34',
35 => '35',
36 => '36',
37 => '37',
38 => '38',
39 => '39',
40 => '40',
41 => '41',
42 => '42',
43 => '43',
44 => '44',
45 => '45',
46 => '46',
47 => '47',
48 => '48',
49 => '49',
50 => '50',
51 => '51',
52 => '52',
53 => '53',
54 => '54',
55 => '55',
56 => '56',
57 => '57',
58 => '58',
59 => '59',
60 => '60',
61 => '61',
62 => '62',
63 => '63',
64 => '64',
65 => '65',
66 => '66',
67 => '67',
68 => '68',
69 => '69',
70 => '70',
71 => '71',
72 => '72',
73 => '73',
74 => '74',
75 => '75',
76 => '76',
77 => '77',
78 => '78',
79 => '79',
80 => '80',
81 => '81',
82 => '82',
83 => '83',
84 => '84',
85 => '85',
86 => '86',
87 => '87',
88 => '88',
89 => '89',
90 => '90',
91 => '91',
92 => '92',
93 => '93',
94 => '94',
95 => '95',
96 => '96',
97 => '97',
98 => '98',
99 => '99',
100 => 'ä',
101 => 'à',
102 => 'å',
103 => '‡',
104 => 'ˆ',
105 => '‰',
106 => 'Š',
],
]);
$this->setChecksum('code128');
}
/**
* @deprecated Since 2.60.0 all option setters and getters are deprecated for removal in 3.0
*
* @return void
*/
public function setUtf8StringWrapper(StringWrapperInterface $utf8StringWrapper)
{
if (! $utf8StringWrapper->isSupported('UTF-8')) {
throw new Exception\InvalidArgumentException(
'The string wrapper needs to support UTF-8 character encoding'
);
}
$this->utf8StringWrapper = $utf8StringWrapper;
}
/**
* Get the string wrapper supporting UTF-8 character encoding
*
* @deprecated Since 2.60.0 all option setters and getters are deprecated for removal in 3.0
*
* @return StringWrapperInterface
*/
public function getUtf8StringWrapper()
{
if (! $this->utf8StringWrapper) {
$this->utf8StringWrapper = StringUtils::getWrapper('UTF-8');
}
return $this->utf8StringWrapper;
}
/**
* Checks for allowed characters within the barcode
*
* @param string $value The barcode to check for allowed characters
* @return bool
*/
public function hasValidCharacters($value)
{
if (! is_string($value)) {
return false;
}
// get used string wrapper for UTF-8 character encoding
$strWrapper = $this->getUtf8StringWrapper();
// detect starting charset
$set = $this->getCodingSet($value);
$read = $set;
if ($set !== '') {
$value = $strWrapper->substr($value, 1, null);
}
// process barcode
while ($value !== '' && $value !== false) {
$char = $strWrapper->substr($value, 0, 1);
switch ($char) {
// Function definition
case 'Ç':
case 'ü':
case 'å':
break;
// Switch 1 char between A and B
case 'é':
if ($set === 'A') {
$read = 'B';
break;
}
if ($set === 'B') {
$read = 'A';
break;
}
break;
// Switch to C
case 'â':
$set = 'C';
$read = 'C';
break;
// Switch to B
case 'ä':
$set = 'B';
$read = 'B';
break;
// Switch to A
case 'à':
$set = 'A';
$read = 'A';
break;
// Doubled start character
case '‡':
case 'ˆ':
case '‰':
return false;
// Chars after the stop character
case 'Š':
break 2;
default:
// Does the char exist within the charset to read?
if ($this->ord128($char, $read) === -1) {
return false;
}
break;
}
$value = $strWrapper->substr($value, 1, null);
$read = $set;
}
if ($value !== '' && is_string($value) && $strWrapper->strlen($value) !== 1) {
return false;
}
return true;
}
/**
* Validates the checksum ()
*
* @param string $value The barcode to validate
* @return bool
*/
protected function code128($value)
{
$sum = 0;
$pos = 1;
$set = $this->getCodingSet($value);
$read = $set;
$usecheck = $this->useChecksum(null);
$strWrapper = $this->getUtf8StringWrapper();
$char = $strWrapper->substr($value, 0, 1);
if ($char === '‡') {
$sum = 103;
} elseif ($char === 'ˆ') {
$sum = 104;
} elseif ($char === '‰') {
$sum = 105;
} elseif ($usecheck === true) {
// no start value, unable to detect a proper checksum
return false;
}
$value = $strWrapper->substr($value, 1, null);
while ($strWrapper->strpos((string) $value, 'Š') !== false || ((string) $value !== '')) {
$char = $strWrapper->substr($value, 0, 1);
if ($read === 'C') {
$char = $strWrapper->substr($value, 0, 2);
}
switch ($char) {
// Function definition
case 'Ç':
case 'ü':
case 'å':
$sum += $pos * $this->ord128($char, $set);
break;
case 'é':
$sum += $pos * $this->ord128($char, $set);
if ($set === 'A') {
$read = 'B';
break;
}
if ($set === 'B') {
$read = 'A';
break;
}
break;
// Switch to C
case 'â':
$sum += $pos * $this->ord128($char, $set);
$set = 'C';
$read = 'C';
break;
// Switch to B
case 'ä':
$sum += $pos * $this->ord128($char, $set);
$set = 'B';
$read = 'B';
break;
// Switch to A
case 'à':
$sum += $pos * $this->ord128($char, $set);
$set = 'A';
$read = 'A';
break;
case '‡':
case 'ˆ':
case '‰':
return false;
default:
// Does the char exist within the charset to read?
if ($this->ord128($char, $read) === -1) {
return false;
}
$sum += $pos * $this->ord128($char, $set);
break;
}
$value = $strWrapper->substr($value, 1);
++$pos;
if (($strWrapper->strpos($value, 'Š') === 1) && ($strWrapper->strlen($value) === 2)) {
// break by stop and checksum char
break;
}
$read = $set;
}
if (($strWrapper->strpos($value, 'Š') !== 1) || ($strWrapper->strlen($value) !== 2)) {
// return false if checksum is not readable and true if no startvalue is detected
return ! $usecheck;
}
$mod = $sum % 103;
if ($strWrapper->substr($value, 0, 1) === $this->chr128($mod, $set)) {
return true;
}
return false;
}
/**
* Returns the coding set for a barcode
*
* @param string $value Barcode
* @return string
*/
protected function getCodingSet($value)
{
$value = $this->getUtf8StringWrapper()->substr($value, 0, 1);
return match ($value) {
'‡' => 'A',
'ˆ' => 'B',
'‰' => 'C',
default => '',
};
}
/**
* Internal method to return the code128 integer from an ascii value
*
* Table A
* ASCII CODE128
* 32 to 95 == 0 to 63
* 0 to 31 == 64 to 95
* 128 to 138 == 96 to 106
*
* Table B
* ASCII CODE128
* 32 to 138 == 0 to 106
*
* Table C
* ASCII CODE128
* "00" to "99" == 0 to 99
* 132 to 138 == 100 to 106
*
* @param string $value
* @param string $set
* @return int
*/
protected function ord128($value, $set)
{
$ord = ord($value[0]);
if ($set === 'A') {
if ($ord < 32) {
return $ord + 64;
} elseif ($ord < 96) {
return $ord - 32;
} elseif ($ord > 138) {
return -1;
} else {
return $ord - 32;
}
} elseif ($set === 'B') {
if ($ord < 32) {
return -1;
} elseif ($ord <= 138) {
return $ord - 32;
} else {
return -1;
}
} elseif ($set === 'C') {
$val = (int) $value;
if (($val >= 0) && ($val <= 99)) {
return $val;
} elseif (($ord >= 132) && ($ord <= 138)) {
return $ord - 32;
} else {
return -1;
}
} else {
if ($ord < 32) {
return $ord + 64;
} elseif ($ord <= 138) {
return $ord - 32;
} else {
return -1;
}
}
}
/**
* Internal Method to return the ascii value from a code128 integer
*
* Table A
* ASCII CODE128
* 32 to 95 == 0 to 63
* 0 to 31 == 64 to 95
* 128 to 138 == 96 to 106
*
* Table B
* ASCII CODE128
* 32 to 138 == 0 to 106
*
* Table C
* ASCII CODE128
* "00" to "99" == 0 to 99
* 132 to 138 == 100 to 106
*
* @param int $value
* @param string $set
* @return int|string
*/
protected function chr128($value, $set)
{
if ($set === 'A') {
if ($value < 64) {
return chr($value + 32);
} elseif ($value < 96) {
return chr($value - 64);
} elseif ($value > 106) {
return -1;
} else {
return chr($value + 32);
}
} elseif ($set === 'B') {
if ($value > 106) {
return -1;
} else {
return chr($value + 32);
}
} elseif ($set === 'C') {
if (($value >= 0) && ($value <= 9)) {
return '0' . (string) $value;
} elseif ($value <= 99) {
return (string) $value;
} elseif ($value <= 106) {
return chr($value + 32);
} else {
return -1;
}
} else {
if ($value <= 106) {
return $value + 32;
} else {
return -1;
}
}
}
}

View File

@@ -1,18 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
/** @final */
class Code25 extends AbstractAdapter
{
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength(-1);
$this->setCharacters('0123456789');
$this->setChecksum('code25');
$this->useChecksum(false);
}
}

View File

@@ -1,20 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
/** @final */
class Code25interleaved extends AbstractAdapter
{
/**
* Constructor
*
* Sets check flag to false.
*/
public function __construct()
{
$this->setLength('even');
$this->setCharacters('0123456789');
$this->setChecksum('code25');
$this->useChecksum(false);
}
}

View File

@@ -1,91 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
use function str_split;
use function substr;
/** @final */
class Code39 extends AbstractAdapter
{
/** @var array */
protected $check = [
'0' => 0,
'1' => 1,
'2' => 2,
'3' => 3,
'4' => 4,
'5' => 5,
'6' => 6,
'7' => 7,
'8' => 8,
'9' => 9,
'A' => 10,
'B' => 11,
'C' => 12,
'D' => 13,
'E' => 14,
'F' => 15,
'G' => 16,
'H' => 17,
'I' => 18,
'J' => 19,
'K' => 20,
'L' => 21,
'M' => 22,
'N' => 23,
'O' => 24,
'P' => 25,
'Q' => 26,
'R' => 27,
'S' => 28,
'T' => 29,
'U' => 30,
'V' => 31,
'W' => 32,
'X' => 33,
'Y' => 34,
'Z' => 35,
'-' => 36,
'.' => 37,
' ' => 38,
'$' => 39,
'/' => 40,
'+' => 41,
'%' => 42,
];
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength(-1);
$this->setCharacters('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ -.$/+%');
$this->setChecksum('code39');
$this->useChecksum(false);
}
/**
* Validates the checksum (Modulo 43)
*
* @param string $value The barcode to validate
* @return bool
*/
protected function code39($value)
{
$checksum = substr($value, -1, 1);
$value = str_split(substr($value, 0, -1));
$count = 0;
foreach ($value as $char) {
$count += $this->check[$char];
}
$mod = $count % 43;
if ($mod === $this->check[$checksum]) {
return true;
}
return false;
}
}

View File

@@ -1,17 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
/** @final */
class Code39ext extends AbstractAdapter
{
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength(-1);
$this->setCharacters(128);
$this->useChecksum(false);
}
}

View File

@@ -1,120 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
use function array_search;
use function count;
use function str_split;
use function substr;
/** @final */
class Code93 extends AbstractAdapter
{
/**
* Note that the characters !"§& are only synonyms
*
* @var array
*/
protected $check = [
'0' => 0,
'1' => 1,
'2' => 2,
'3' => 3,
'4' => 4,
'5' => 5,
'6' => 6,
'7' => 7,
'8' => 8,
'9' => 9,
'A' => 10,
'B' => 11,
'C' => 12,
'D' => 13,
'E' => 14,
'F' => 15,
'G' => 16,
'H' => 17,
'I' => 18,
'J' => 19,
'K' => 20,
'L' => 21,
'M' => 22,
'N' => 23,
'O' => 24,
'P' => 25,
'Q' => 26,
'R' => 27,
'S' => 28,
'T' => 29,
'U' => 30,
'V' => 31,
'W' => 32,
'X' => 33,
'Y' => 34,
'Z' => 35,
'-' => 36,
'.' => 37,
' ' => 38,
'$' => 39,
'/' => 40,
'+' => 41,
'%' => 42,
'!' => 43,
'"' => 44,
'§' => 45,
'&' => 46,
];
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength(-1);
$this->setCharacters('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ -.$/+%');
$this->setChecksum('code93');
$this->useChecksum(false);
}
/**
* Validates the checksum (Modulo CK)
*
* @param string $value The barcode to validate
* @return bool
*/
protected function code93($value)
{
$checksum = substr($value, -2, 2);
$value = str_split(substr($value, 0, -2));
$count = 0;
$length = count($value) % 20;
foreach ($value as $char) {
if ($length === 0) {
$length = 20;
}
$count += $this->check[$char] * $length;
--$length;
}
$check = array_search($count % 47, $this->check);
$value[] = $check;
$count = 0;
$length = count($value) % 15;
foreach ($value as $char) {
if ($length === 0) {
$length = 15;
}
$count += $this->check[$char] * $length;
--$length;
}
$check .= array_search($count % 47, $this->check);
if ($check === $checksum) {
return true;
}
return false;
}
}

View File

@@ -1,17 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
/** @final */
class Code93ext extends AbstractAdapter
{
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength(-1);
$this->setCharacters(128);
$this->useChecksum(false);
}
}

View File

@@ -1,17 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
/** @final */
class Ean12 extends AbstractAdapter
{
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength(12);
$this->setCharacters('0123456789');
$this->setChecksum('gtin');
}
}

View File

@@ -1,17 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
/** @final */
class Ean13 extends AbstractAdapter
{
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength(13);
$this->setCharacters('0123456789');
$this->setChecksum('gtin');
}
}

View File

@@ -1,17 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
/** @final */
class Ean14 extends AbstractAdapter
{
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength(14);
$this->setCharacters('0123456789');
$this->setChecksum('gtin');
}
}

View File

@@ -1,17 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
/** @final */
class Ean18 extends AbstractAdapter
{
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength(18);
$this->setCharacters('0123456789');
$this->setChecksum('gtin');
}
}

View File

@@ -1,17 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
/** @final */
class Ean2 extends AbstractAdapter
{
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength(2);
$this->setCharacters('0123456789');
$this->useChecksum(false);
}
}

View File

@@ -1,19 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
/** @final */
class Ean5 extends AbstractAdapter
{
/**
* Constructor
*
* Sets check flag to false.
*/
public function __construct()
{
$this->setLength(5);
$this->setCharacters('0123456789');
$this->useChecksum(false);
}
}

View File

@@ -1,36 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
use function strlen;
/** @final */
class Ean8 extends AbstractAdapter
{
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength([7, 8]);
$this->setCharacters('0123456789');
$this->setChecksum('gtin');
}
/**
* Overrides parent checkLength
*
* @param string $value Value
* @return bool
*/
public function hasValidLength($value)
{
if (strlen($value) === 7) {
$this->useChecksum(false);
} else {
$this->useChecksum(true);
}
return parent::hasValidLength($value);
}
}

View File

@@ -1,17 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
/** @final */
class Gtin12 extends AbstractAdapter
{
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength(12);
$this->setCharacters('0123456789');
$this->setChecksum('gtin');
}
}

View File

@@ -1,17 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
/** @final */
class Gtin13 extends AbstractAdapter
{
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength(13);
$this->setCharacters('0123456789');
$this->setChecksum('gtin');
}
}

View File

@@ -1,17 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
/** @final */
class Gtin14 extends AbstractAdapter
{
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength(14);
$this->setCharacters('0123456789');
$this->setChecksum('gtin');
}
}

View File

@@ -1,38 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
/** @final */
class Identcode extends AbstractAdapter
{
/**
* Allowed barcode lengths
*
* @var int
*/
protected $length = 12;
/**
* Allowed barcode characters
*
* @var string
*/
protected $characters = '0123456789';
/**
* Checksum function
*
* @var string
*/
protected $checksum = 'identcode';
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength(12);
$this->setCharacters('0123456789');
$this->setChecksum('identcode');
}
}

View File

@@ -1,19 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
/** @final */
class Intelligentmail extends AbstractAdapter
{
/**
* Constructor
*
* Sets check flag to false.
*/
public function __construct()
{
$this->setLength([20, 25, 29, 31]);
$this->setCharacters('0123456789');
$this->useChecksum(false);
}
}

View File

@@ -1,92 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
use function str_contains;
use function str_split;
use function strlen;
use function substr;
/** @final */
class Issn extends AbstractAdapter
{
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength([8, 13]);
$this->setCharacters('0123456789X');
$this->setChecksum('gtin');
}
/**
* Allows X on length of 8 chars
*
* @param string $value The barcode to check for allowed characters
* @return bool
*/
public function hasValidCharacters($value)
{
if (strlen($value) !== 8) {
if (str_contains($value, 'X')) {
return false;
}
}
return parent::hasValidCharacters($value);
}
/**
* Validates the checksum
*
* @param string $value The barcode to check the checksum for
* @return bool
*/
public function hasValidChecksum($value)
{
if (strlen($value) === 8) {
$this->setChecksum('issn');
} else {
$this->setChecksum('gtin');
}
return parent::hasValidChecksum($value);
}
/**
* Validates the checksum ()
* ISSN implementation (reversed mod11)
*
* @param string $value The barcode to validate
* @return bool
*/
protected function issn($value)
{
$checksum = substr($value, -1, 1);
$values = str_split(substr($value, 0, -1));
$check = 0;
$multi = 8;
foreach ($values as $token) {
if ($token === 'X') {
$token = 10;
}
$check += $token * $multi;
--$multi;
}
$check %= 11;
$check = $check === 0 ? 0 : 11 - $check;
if ((string) $check === $checksum) {
return true;
}
if (($check === 10) && ($checksum === 'X')) {
return true;
}
return false;
}
}

View File

@@ -1,17 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
/** @final */
class Itf14 extends AbstractAdapter
{
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength(14);
$this->setCharacters('0123456789');
$this->setChecksum('gtin');
}
}

View File

@@ -1,17 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
/** @final */
class Leitcode extends AbstractAdapter
{
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength(14);
$this->setCharacters('0123456789');
$this->setChecksum('identcode');
}
}

View File

@@ -1,17 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
/** @final */
class Planet extends AbstractAdapter
{
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength([12, 14]);
$this->setCharacters('0123456789');
$this->setChecksum('postnet');
}
}

View File

@@ -1,17 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
/** @final */
class Postnet extends AbstractAdapter
{
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength([6, 7, 10, 12]);
$this->setCharacters('0123456789');
$this->setChecksum('postnet');
}
}

View File

@@ -1,157 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
use function array_intersect;
use function array_keys;
use function current;
use function str_split;
use function strlen;
use function substr;
/** @final */
class Royalmail extends AbstractAdapter
{
/** @var array<array-key, int> */
protected $rows = [
'0' => 1,
'1' => 1,
'2' => 1,
'3' => 1,
'4' => 1,
'5' => 1,
'6' => 2,
'7' => 2,
'8' => 2,
'9' => 2,
'A' => 2,
'B' => 2,
'C' => 3,
'D' => 3,
'E' => 3,
'F' => 3,
'G' => 3,
'H' => 3,
'I' => 4,
'J' => 4,
'K' => 4,
'L' => 4,
'M' => 4,
'N' => 4,
'O' => 5,
'P' => 5,
'Q' => 5,
'R' => 5,
'S' => 5,
'T' => 5,
'U' => 0,
'V' => 0,
'W' => 0,
'X' => 0,
'Y' => 0,
'Z' => 0,
];
/** @var array<array-key, int> */
protected $columns = [
'0' => 1,
'1' => 2,
'2' => 3,
'3' => 4,
'4' => 5,
'5' => 0,
'6' => 1,
'7' => 2,
'8' => 3,
'9' => 4,
'A' => 5,
'B' => 0,
'C' => 1,
'D' => 2,
'E' => 3,
'F' => 4,
'G' => 5,
'H' => 0,
'I' => 1,
'J' => 2,
'K' => 3,
'L' => 4,
'M' => 5,
'N' => 0,
'O' => 1,
'P' => 2,
'Q' => 3,
'R' => 4,
'S' => 5,
'T' => 0,
'U' => 1,
'V' => 2,
'W' => 3,
'X' => 4,
'Y' => 5,
'Z' => 0,
];
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength(-1);
$this->setCharacters('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ');
$this->setChecksum('royalmail');
}
/**
* Validates the checksum ()
*
* @param string $value The barcode to validate
* @return bool
*/
protected function royalmail($value)
{
$checksum = substr($value, -1, 1);
$values = str_split(substr($value, 0, -1));
$rowvalue = 0;
$colvalue = 0;
foreach ($values as $row) {
$rowvalue += $this->rows[$row];
$colvalue += $this->columns[$row];
}
$rowvalue %= 6;
$colvalue %= 6;
$rowchkvalue = array_keys($this->rows, $rowvalue);
$colchkvalue = array_keys($this->columns, $colvalue);
$intersect = array_intersect($rowchkvalue, $colchkvalue);
$chkvalue = (string) current($intersect);
if ($chkvalue === $checksum) {
return true;
}
return false;
}
/**
* Allows start and stop tag within checked chars
*
* @param string $value The barcode to check for allowed characters
* @return bool
*/
public function hasValidCharacters($value)
{
if ($value[0] === '(') {
$value = substr($value, 1);
if ($value[strlen($value) - 1] === ')') {
$value = substr($value, 0, -1);
} else {
return false;
}
}
return parent::hasValidCharacters($value);
}
}

View File

@@ -1,17 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
/** @final */
class Sscc extends AbstractAdapter
{
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength(18);
$this->setCharacters('0123456789');
$this->setChecksum('gtin');
}
}

View File

@@ -1,17 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
/** @final */
class Upca extends AbstractAdapter
{
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength(12);
$this->setCharacters('0123456789');
$this->setChecksum('gtin');
}
}

View File

@@ -1,36 +0,0 @@
<?php
namespace Laminas\Validator\Barcode;
use function strlen;
/** @final */
class Upce extends AbstractAdapter
{
/**
* Constructor for this barcode adapter
*/
public function __construct()
{
$this->setLength([6, 7, 8]);
$this->setCharacters('0123456789');
$this->setChecksum('gtin');
}
/**
* Overrides parent checkLength
*
* @param string $value Value
* @return bool
*/
public function hasValidLength($value)
{
if (strlen($value) !== 8) {
$this->useChecksum(false);
} else {
$this->useChecksum(true);
}
return parent::hasValidLength($value);
}
}

View File

@@ -1,220 +0,0 @@
<?php
namespace Laminas\Validator;
use Laminas\Stdlib\ArrayUtils;
use Traversable;
use function array_key_exists;
use function array_shift;
use function func_get_args;
use function is_array;
use function is_numeric;
use function is_string;
use const PHP_INT_MAX;
/**
* @deprecated Since 2.60.0 - This validator has been superseded by the NumberComparison and DateComparison validators
*
* @final
*/
class Between extends AbstractValidator
{
public const NOT_BETWEEN = 'notBetween';
public const NOT_BETWEEN_STRICT = 'notBetweenStrict';
public const VALUE_NOT_NUMERIC = 'valueNotNumeric';
public const VALUE_NOT_STRING = 'valueNotString';
/**
* Retain if min and max are numeric values. Allow to not compare string and numeric types
*/
private ?bool $numeric = null;
/**
* Validation failure message template definitions
*
* @var array<string, string>
*/
protected $messageTemplates = [
self::NOT_BETWEEN => "The input is not between '%min%' and '%max%', inclusively",
self::NOT_BETWEEN_STRICT => "The input is not strictly between '%min%' and '%max%'",
self::VALUE_NOT_NUMERIC => "The min ('%min%') and max ('%max%') values are numeric, but the input is not",
self::VALUE_NOT_STRING => "The min ('%min%') and max ('%max%') values are non-numeric strings, "
. 'but the input is not a string',
];
/**
* Additional variables available for validation failure messages
*
* @var array
*/
protected $messageVariables = [
'min' => ['options' => 'min'],
'max' => ['options' => 'max'],
];
/**
* Options for the between validator
*
* @var array
*/
protected $options = [
'inclusive' => true, // Whether to do inclusive comparisons, allowing equivalence to min and/or max
'min' => 0,
'max' => PHP_INT_MAX,
];
/**
* Sets validator options
* Accepts the following option keys:
* 'min' => scalar, minimum border
* 'max' => scalar, maximum border
* 'inclusive' => boolean, inclusive border values
*
* @param array<string, mixed>|Traversable<string, mixed> $options
* @throws Exception\InvalidArgumentException
*/
public function __construct($options = null)
{
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
}
if (! is_array($options)) {
$temp = [];
/** @psalm-var array<string, int|string> $options */
$options = func_get_args();
$temp['min'] = array_shift($options);
if (! empty($options)) {
$temp['max'] = array_shift($options);
}
if (! empty($options)) {
$temp['inclusive'] = array_shift($options);
}
$options = $temp;
}
if (! array_key_exists('min', $options) || ! array_key_exists('max', $options)) {
throw new Exception\InvalidArgumentException("Missing option: 'min' and 'max' have to be given");
}
if (
(isset($options['min']) && is_numeric($options['min']))
&& (isset($options['max']) && is_numeric($options['max']))
) {
$this->numeric = true;
} elseif (
(isset($options['min']) && is_string($options['min']))
&& (isset($options['max']) && is_string($options['max']))
) {
$this->numeric = false;
} else {
throw new Exception\InvalidArgumentException(
"Invalid options: 'min' and 'max' should be of the same scalar type"
);
}
parent::__construct($options);
}
/**
* Returns the min option
*
* @return mixed
*/
public function getMin()
{
return $this->options['min'];
}
/**
* Sets the min option
*
* @return $this Provides a fluent interface
*/
public function setMin(mixed $min)
{
$this->options['min'] = $min;
return $this;
}
/**
* Returns the max option
*
* @return mixed
*/
public function getMax()
{
return $this->options['max'];
}
/**
* Sets the max option
*
* @return $this Provides a fluent interface
*/
public function setMax(mixed $max)
{
$this->options['max'] = $max;
return $this;
}
/**
* Returns the inclusive option
*
* @return bool
*/
public function getInclusive()
{
return $this->options['inclusive'];
}
/**
* Sets the inclusive option
*
* @param bool $inclusive
* @return $this Provides a fluent interface
*/
public function setInclusive($inclusive)
{
$this->options['inclusive'] = $inclusive;
return $this;
}
/**
* Returns true if and only if $value is between min and max options, inclusively
* if inclusive option is true.
*
* @param mixed $value
* @return bool
*/
public function isValid($value)
{
$this->setValue($value);
if ($this->numeric && ! is_numeric($value)) {
$this->error(self::VALUE_NOT_NUMERIC);
return false;
}
if (! $this->numeric && ! is_string($value)) {
$this->error(self::VALUE_NOT_STRING);
return false;
}
if ($this->getInclusive()) {
if ($this->getMin() > $value || $value > $this->getMax()) {
$this->error(self::NOT_BETWEEN);
return false;
}
} else {
if ($this->getMin() >= $value || $value >= $this->getMax()) {
$this->error(self::NOT_BETWEEN_STRICT);
return false;
}
}
return true;
}
}

View File

@@ -1,216 +0,0 @@
<?php // phpcs:disable WebimpressCodingStandard.Formatting.Reference.UnexpectedSpace
namespace Laminas\Validator;
use Traversable;
use function array_shift;
use function func_get_args;
use function is_array;
use function iterator_to_array;
/** @final */
class Bitwise extends AbstractValidator
{
public const OP_AND = 'and';
public const OP_XOR = 'xor';
public const NOT_AND = 'notAnd';
public const NOT_AND_STRICT = 'notAndStrict';
public const NOT_XOR = 'notXor';
public const NO_OP = 'noOp';
/** @var int */
protected $control;
/**
* Validation failure message template definitions
*
* @var array<string, string>
*/
protected $messageTemplates = [
self::NOT_AND => "The input has no common bit set with '%control%'",
self::NOT_AND_STRICT => "The input doesn't have the same bits set as '%control%'",
self::NOT_XOR => "The input has common bit set with '%control%'",
self::NO_OP => "No operator was present to compare '%control%' against",
];
/**
* Additional variables available for validation failure messages
*
* @var array<string, string>
*/
protected $messageVariables = [
'control' => 'control',
];
/** @var null|string */
protected $operator;
/** @var bool */
protected $strict = false;
/**
* Sets validator options
* Accepts the following option keys:
* 'control' => int
* 'operator' =>
* 'strict' => bool
*
* @param array|Traversable $options
*/
public function __construct($options = null)
{
if ($options instanceof Traversable) {
$options = iterator_to_array($options);
}
if (! is_array($options)) {
$options = func_get_args();
$temp['control'] = array_shift($options);
if (! empty($options)) {
$temp['operator'] = array_shift($options);
}
if (! empty($options)) {
$temp['strict'] = array_shift($options);
}
$options = $temp;
}
parent::__construct($options);
}
/**
* Returns the control parameter.
*
* @deprecated Since 2.60 All option getters and setters will be removed in 3.0
*
* @return integer
*/
public function getControl()
{
return $this->control;
}
/**
* Returns the operator parameter.
*
* @deprecated Since 2.60 All option getters and setters will be removed in 3.0
*
* @return null|string
*/
public function getOperator()
{
return $this->operator;
}
/**
* Returns the strict parameter.
*
* @deprecated Since 2.60 All option getters and setters will be removed in 3.0
*
* @return boolean
*/
public function getStrict()
{
return $this->strict;
}
/**
* Returns true if and only if $value is between min and max options, inclusively
* if inclusive option is true.
*
* @param mixed $value
* @return bool
*/
public function isValid($value)
{
$this->setValue($value);
if (self::OP_AND === $this->operator) {
if ($this->strict) {
// All the bits set in value must be set in control
$result = ($this->control & $value) === $value;
if (! $result) {
$this->error(self::NOT_AND_STRICT);
}
return $result;
}
// At least one of the bits must be common between value and control
$result = (bool) ($this->control & $value);
if (! $result) {
$this->error(self::NOT_AND);
}
return $result;
}
if (self::OP_XOR === $this->operator) {
// Parentheses are required due to order of operations with bitwise operations
// phpcs:ignore WebimpressCodingStandard.Formatting.RedundantParentheses.SingleEquality
$result = ($this->control ^ $value) === ($this->control | $value);
if (! $result) {
$this->error(self::NOT_XOR);
}
return $result;
}
$this->error(self::NO_OP);
return false;
}
/**
* Sets the control parameter.
*
* @deprecated Since 2.60 All option getters and setters will be removed in 3.0
*
* @param integer $control
* @return $this
*/
public function setControl($control)
{
$this->control = (int) $control;
return $this;
}
/**
* Sets the operator parameter.
*
* @deprecated Since 2.60 All option getters and setters will be removed in 3.0
*
* @param string $operator
* @return $this
*/
public function setOperator($operator)
{
$this->operator = $operator;
return $this;
}
/**
* Sets the strict parameter.
*
* @deprecated Since 2.60 All option getters and setters will be removed in 3.0
*
* @param boolean $strict
* @return $this
*/
public function setStrict($strict)
{
$this->strict = (bool) $strict;
return $this;
}
}

View File

@@ -1,328 +0,0 @@
<?php
namespace Laminas\Validator;
use function in_array;
use function is_string;
use function preg_match;
use function strtoupper;
/** @final */
class BusinessIdentifierCode extends AbstractValidator
{
public const INVALID = 'valueNotBic';
public const NOT_STRING = 'valueNotString';
public const NOT_VALID_COUNTRY = 'valueNotCountry';
/** @var string[] */
protected $messageTemplates = [
self::NOT_STRING => 'Invalid type given; string expected',
self::INVALID => 'Invalid BIC format',
self::NOT_VALID_COUNTRY => 'Invalid country code',
];
/**
* @see https://www.bundesbank.de/resource/blob/749660/d2c6e00664251b4d83483c229e084e44/mL/technische-spezifikationen-scc-anhang-112018-data.pdf (page 39)
*/
private const REGEX_BIC = '/^[a-z]{4}(?<country>[a-z]{2})[a-z2-9][a-np-z0-9]([0-9a-z]{3})?$/i';
/**
* List of all country codes defined by ISO 3166-1 alpha-2
*
* @see https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Current_codes
*
* @var string[]
*/
private const ISO_COUNTRIES = [
'AD',
'AE',
'AF',
'AG',
'AI',
'AL',
'AM',
'AO',
'AQ',
'AR',
'AS',
'AT',
'AU',
'AW',
'AX',
'AZ',
'BA',
'BB',
'BD',
'BE',
'BF',
'BG',
'BH',
'BI',
'BJ',
'BL',
'BM',
'BN',
'BO',
'BQ',
'BQ',
'BR',
'BS',
'BT',
'BV',
'BW',
'BY',
'BZ',
'CA',
'CC',
'CD',
'CF',
'CG',
'CH',
'CI',
'CK',
'CL',
'CM',
'CN',
'CO',
'CR',
'CU',
'CV',
'CW',
'CX',
'CY',
'CZ',
'DE',
'DJ',
'DK',
'DM',
'DO',
'DZ',
'EC',
'EE',
'EG',
'EH',
'ER',
'ES',
'ET',
'FI',
'FJ',
'FK',
'FM',
'FO',
'FR',
'GA',
'GB',
'GD',
'GE',
'GF',
'GG',
'GH',
'GI',
'GL',
'GM',
'GN',
'GP',
'GQ',
'GR',
'GS',
'GT',
'GU',
'GW',
'GY',
'HK',
'HM',
'HN',
'HR',
'HT',
'HU',
'ID',
'IE',
'IL',
'IM',
'IN',
'IO',
'IQ',
'IR',
'IS',
'IT',
'JE',
'JM',
'JO',
'JP',
'KE',
'KG',
'KH',
'KI',
'KM',
'KN',
'KP',
'KR',
'KW',
'KY',
'KZ',
'LA',
'LB',
'LC',
'LI',
'LK',
'LR',
'LS',
'LT',
'LU',
'LV',
'LY',
'MA',
'MC',
'MD',
'ME',
'MF',
'MG',
'MH',
'MK',
'ML',
'MM',
'MN',
'MO',
'MP',
'MQ',
'MR',
'MS',
'MT',
'MU',
'MV',
'MW',
'MX',
'MY',
'MZ',
'NA',
'NC',
'NE',
'NF',
'NG',
'NI',
'NL',
'NO',
'NP',
'NR',
'NU',
'NZ',
'OM',
'PA',
'PE',
'PF',
'PG',
'PH',
'PK',
'PL',
'PM',
'PN',
'PR',
'PS',
'PT',
'PW',
'PY',
'QA',
'RE',
'RO',
'RS',
'RU',
'RW',
'SA',
'SB',
'SC',
'SD',
'SE',
'SG',
'SH',
'SI',
'SJ',
'SK',
'SL',
'SM',
'SN',
'SO',
'SR',
'SS',
'ST',
'SV',
'SX',
'SY',
'SZ',
'TC',
'TD',
'TF',
'TG',
'TH',
'TJ',
'TK',
'TL',
'TM',
'TN',
'TO',
'TR',
'TT',
'TV',
'TW',
'TZ',
'UA',
'UG',
'UM',
'US',
'UY',
'UZ',
'VA',
'VC',
'VE',
'VG',
'VI',
'VN',
'VU',
'WF',
'WS',
'YE',
'YT',
'ZA',
'ZM',
'ZW',
];
/**
* This code is the only one used by SWIFT that is not defined by ISO 3166-1 alpha-2
*
* @see https://en.wikipedia.org/wiki/ISO_9362
*
* @var string
*/
private const KOSOVO_EXCEPTION = 'XK';
/** {@inheritDoc} */
public function isValid($value): bool
{
if (! is_string($value)) {
$this->error(self::NOT_STRING);
return false;
}
if (
empty($value)
|| ! preg_match(self::REGEX_BIC, $value, $matches)
) {
$this->error(self::INVALID);
return false;
}
if (! $this->isSwiftValidCountry($matches['country'])) {
$this->error(self::NOT_VALID_COUNTRY);
return false;
}
return true;
}
private function isSwiftValidCountry(string $countryCode): bool
{
$countryCode = strtoupper($countryCode);
return in_array($countryCode, self::ISO_COUNTRIES, true)
|| $countryCode === self::KOSOVO_EXCEPTION;
}
}

View File

@@ -1,189 +0,0 @@
<?php
namespace Laminas\Validator;
use Exception;
use Laminas\Validator\Exception\InvalidArgumentException;
use function array_merge;
use function assert;
use function call_user_func_array;
use function is_bool;
use function is_callable;
/**
* @psalm-type OptionsProperty = array{
* callback: callable|null,
* callbackOptions: array<array-key, mixed>,
* throwExceptions: bool,
* bind: bool,
* }
* @psalm-type OptionsArgument = array{
* callback: callable,
* callbackOptions?: array<array-key, mixed>,
* throwExceptions?: bool,
* bind?: bool,
* ...<string, mixed>
* }
* @final
*/
class Callback extends AbstractValidator
{
/**
* Invalid callback
*/
public const INVALID_CALLBACK = 'callbackInvalid';
/**
* Invalid value
*/
public const INVALID_VALUE = 'callbackValue';
/**
* Validation failure message template definitions
*
* @var array
*/
protected $messageTemplates = [
self::INVALID_VALUE => 'The input is not valid',
self::INVALID_CALLBACK => 'An exception has been raised within the callback',
];
/**
* Default options to set for the validator
*
* @var OptionsProperty
*/
protected $options = [
'callback' => null, // Callback in a call_user_func format, string || array
'callbackOptions' => [], // Options for the callback
'throwExceptions' => false, // Whether to throw exceptions raised within the callback or not
'bind' => false, // Bind the callback to the validator instance
];
/** @param OptionsArgument|callable $options */
public function __construct($options = null)
{
if (is_callable($options)) {
$options = ['callback' => $options];
}
$bind = $options['bind'] ?? false;
assert(is_bool($bind));
$closure = $options['callback'] ?? null;
if (is_callable($closure) && $bind === true) {
$options['callback'] = $closure(...)->bindTo($this);
}
parent::__construct($options);
}
/**
* Returns the set callback
*
* @deprecated Since 2.60.0 All option setters and getters will be removed in v3.0
*
* @return callable|null
*/
public function getCallback()
{
return $this->options['callback'];
}
/**
* Sets the callback
*
* @deprecated Since 2.60.0 All option setters and getters will be removed in v3.0
*
* @param callable $callback
* @return $this Provides a fluent interface
* @throws InvalidArgumentException
*/
public function setCallback($callback)
{
if (! is_callable($callback)) {
throw new InvalidArgumentException('Invalid callback given');
}
$this->options['callback'] = $callback;
return $this;
}
/**
* Returns the set options for the callback
*
* @deprecated Since 2.60.0 All option setters and getters will be removed in v3.0
*
* @return array<array-key, mixed>
*/
public function getCallbackOptions()
{
return $this->options['callbackOptions'];
}
/**
* Sets options for the callback
*
* @deprecated Since 2.60.0 All option setters and getters will be removed in v3.0
*
* @param array<array-key, mixed> $options
* @return $this Provides a fluent interface
*/
public function setCallbackOptions(mixed $options)
{
$this->options['callbackOptions'] = (array) $options;
return $this;
}
/**
* Returns true if and only if the set callback returns
* for the provided $value
*
* @param mixed $value
* @param mixed $context Additional context to provide to the callback
* @return bool
* @throws InvalidArgumentException
*/
public function isValid($value, $context = null)
{
$this->setValue($value);
$options = $this->getCallbackOptions();
$callback = $this->getCallback();
if (! is_callable($callback)) {
throw new InvalidArgumentException('No callback given');
}
$args = [$value];
if (empty($options) && ! empty($context)) {
$args[] = $context;
}
if (! empty($options) && empty($context)) {
$args = array_merge($args, $options);
}
if (! empty($options) && ! empty($context)) {
$args[] = $context;
$args = array_merge($args, $options);
}
try {
if (! call_user_func_array($callback, $args)) {
$this->error(self::INVALID_VALUE);
return false;
}
} catch (Exception $exception) {
/**
* Intentionally excluding catchable \Error as they are indicative of a bug and should not be suppressed
*/
$this->error(self::INVALID_CALLBACK);
if ($this->options['throwExceptions'] === true) {
throw $exception;
}
return false;
}
return true;
}
}

View File

@@ -1,41 +0,0 @@
<?php
namespace Laminas\Validator;
/** @final */
class ConfigProvider
{
/**
* Return configuration for this component.
*
* @return array
*/
public function __invoke()
{
return [
'dependencies' => $this->getDependencyConfig(),
];
}
/**
* Return dependency mappings for this component.
*
* @return array
*/
public function getDependencyConfig()
{
return [
'aliases' => [
Translator\TranslatorInterface::class => Translator\Translator::class,
'ValidatorManager' => ValidatorPluginManager::class,
// Legacy Zend Framework aliases
'Zend\Validator\ValidatorPluginManager' => ValidatorPluginManager::class,
],
'factories' => [
Translator\Translator::class => Translator\TranslatorFactory::class,
ValidatorPluginManager::class => ValidatorPluginManagerFactory::class,
],
];
}
}

View File

@@ -1,455 +0,0 @@
<?php
namespace Laminas\Validator;
use Exception;
use Laminas\Stdlib\ArrayUtils;
use Laminas\Validator\Exception\InvalidArgumentException;
use SensitiveParameter;
use Traversable;
use function array_key_exists;
use function array_keys;
use function array_shift;
use function constant;
use function ctype_digit;
use function defined;
use function floor;
use function func_get_args;
use function in_array;
use function is_array;
use function is_callable;
use function is_string;
use function str_starts_with;
use function strlen;
use function strtoupper;
/** @final */
class CreditCard extends AbstractValidator
{
/**
* Detected CCI list
*
* @var string
*/
public const ALL = 'All';
public const AMERICAN_EXPRESS = 'American_Express';
public const UNIONPAY = 'Unionpay';
public const DINERS_CLUB = 'Diners_Club';
public const DINERS_CLUB_US = 'Diners_Club_US';
public const DISCOVER = 'Discover';
public const JCB = 'JCB';
public const LASER = 'Laser';
public const MAESTRO = 'Maestro';
public const MASTERCARD = 'Mastercard';
public const SOLO = 'Solo';
public const VISA = 'Visa';
public const MIR = 'Mir';
public const CHECKSUM = 'creditcardChecksum';
public const CONTENT = 'creditcardContent';
public const INVALID = 'creditcardInvalid';
public const LENGTH = 'creditcardLength';
public const PREFIX = 'creditcardPrefix';
public const SERVICE = 'creditcardService';
public const SERVICEFAILURE = 'creditcardServiceFailure';
/**
* Validation failure message template definitions
*
* @var array
*/
protected $messageTemplates = [
self::CHECKSUM => 'The input seems to contain an invalid checksum',
self::CONTENT => 'The input must contain only digits',
self::INVALID => 'Invalid type given. String expected',
self::LENGTH => 'The input contains an invalid amount of digits',
self::PREFIX => 'The input is not from an allowed institute',
self::SERVICE => 'The input seems to be an invalid credit card number',
self::SERVICEFAILURE => 'An exception has been raised while validating the input',
];
/**
* List of CCV names
*
* @var array
*/
protected $cardName = [
0 => self::AMERICAN_EXPRESS,
1 => self::DINERS_CLUB,
2 => self::DINERS_CLUB_US,
3 => self::DISCOVER,
4 => self::JCB,
5 => self::LASER,
6 => self::MAESTRO,
7 => self::MASTERCARD,
8 => self::SOLO,
9 => self::UNIONPAY,
10 => self::VISA,
11 => self::MIR,
];
/**
* List of allowed CCV lengths
*
* @var array
*/
protected $cardLength = [
self::AMERICAN_EXPRESS => [15],
self::DINERS_CLUB => [14],
self::DINERS_CLUB_US => [16],
self::DISCOVER => [16, 19],
self::JCB => [15, 16],
self::LASER => [16, 17, 18, 19],
self::MAESTRO => [12, 13, 14, 15, 16, 17, 18, 19],
self::MASTERCARD => [16],
self::SOLO => [16, 18, 19],
self::UNIONPAY => [16, 17, 18, 19],
self::VISA => [13, 16, 19],
self::MIR => [13, 16],
];
/**
* List of accepted CCV provider tags
*
* @var array
*/
protected $cardType = [
self::AMERICAN_EXPRESS => ['34', '37'],
self::DINERS_CLUB => ['300', '301', '302', '303', '304', '305', '36'],
self::DINERS_CLUB_US => ['54', '55'],
self::DISCOVER => [
'6011',
'622126',
'622127',
'622128',
'622129',
'62213',
'62214',
'62215',
'62216',
'62217',
'62218',
'62219',
'6222',
'6223',
'6224',
'6225',
'6226',
'6227',
'6228',
'62290',
'62291',
'622920',
'622921',
'622922',
'622923',
'622924',
'622925',
'644',
'645',
'646',
'647',
'648',
'649',
'65',
],
self::JCB => ['1800', '2131', '3528', '3529', '353', '354', '355', '356', '357', '358'],
self::LASER => ['6304', '6706', '6771', '6709'],
self::MAESTRO => [
'5018',
'5020',
'5038',
'6304',
'6759',
'6761',
'6762',
'6763',
'6764',
'6765',
'6766',
'6772',
],
self::MASTERCARD => [
'2221',
'2222',
'2223',
'2224',
'2225',
'2226',
'2227',
'2228',
'2229',
'223',
'224',
'225',
'226',
'227',
'228',
'229',
'23',
'24',
'25',
'26',
'271',
'2720',
'51',
'52',
'53',
'54',
'55',
],
self::SOLO => ['6334', '6767'],
self::UNIONPAY => [
'622126',
'622127',
'622128',
'622129',
'62213',
'62214',
'62215',
'62216',
'62217',
'62218',
'62219',
'6222',
'6223',
'6224',
'6225',
'6226',
'6227',
'6228',
'62290',
'62291',
'622920',
'622921',
'622922',
'622923',
'622924',
'622925',
],
self::VISA => ['4'],
self::MIR => ['2200', '2201', '2202', '2203', '2204'],
];
/**
* Options for this validator
*
* @var array
*/
protected $options = [
'service' => null, // Service callback for additional validation
'type' => [], // CCIs which are accepted by validation
];
/**
* Constructor
*
* @param string|array|Traversable $options OPTIONAL Type of CCI to allow
*/
public function __construct($options = [])
{
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
} elseif (! is_array($options)) {
$options = func_get_args();
$temp['type'] = array_shift($options);
if (! empty($options)) {
$temp['service'] = array_shift($options);
}
$options = $temp;
}
if (! array_key_exists('type', $options)) {
$options['type'] = self::ALL;
}
$this->setType($options['type']);
unset($options['type']);
if (array_key_exists('service', $options)) {
$this->setService($options['service']);
unset($options['service']);
}
parent::__construct($options);
}
/**
* Returns a list of accepted CCIs
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @return array
*/
public function getType()
{
return $this->options['type'];
}
/**
* Sets CCIs which are accepted by validation
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param string|array $type Type to allow for validation
* @return CreditCard Provides a fluid interface
*/
public function setType($type)
{
$this->options['type'] = [];
return $this->addType($type);
}
/**
* Adds a CCI to be accepted by validation
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param string|array $type Type to allow for validation
* @return $this Provides a fluid interface
*/
public function addType($type)
{
if (is_string($type)) {
$type = [$type];
}
foreach ($type as $typ) {
if ($typ === self::ALL) {
$this->options['type'] = array_keys($this->cardLength);
continue;
}
if (in_array($typ, $this->options['type'])) {
continue;
}
$constant = 'static::' . strtoupper($typ);
if (! defined($constant) || in_array(constant($constant), $this->options['type'])) {
continue;
}
$this->options['type'][] = constant($constant);
}
return $this;
}
/**
* Returns the actual set service
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @return callable
*/
public function getService()
{
return $this->options['service'];
}
/**
* Sets a new callback for service validation
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param callable $service
* @return $this
* @throws InvalidArgumentException On invalid service callback.
*/
public function setService($service)
{
if (! is_callable($service)) {
throw new InvalidArgumentException('Invalid callback given');
}
$this->options['service'] = $service;
return $this;
}
// The following rule is buggy for parameters attributes
// phpcs:disable SlevomatCodingStandard.TypeHints.ParameterTypeHintSpacing.NoSpaceBetweenTypeHintAndParameter
/**
* Returns true if and only if $value follows the Luhn algorithm (mod-10 checksum)
*
* @param mixed $value
* @return bool
*/
public function isValid(
#[SensitiveParameter]
$value
) {
$this->setValue($value);
if (! is_string($value)) {
$this->error(self::INVALID, $value);
return false;
}
if (! ctype_digit($value)) {
$this->error(self::CONTENT, $value);
return false;
}
$length = strlen($value);
$types = $this->getType();
$foundp = false;
$foundl = false;
foreach ($types as $type) {
foreach ($this->cardType[$type] as $prefix) {
if (str_starts_with($value, (string) $prefix)) {
$foundp = true;
if (in_array($length, $this->cardLength[$type])) {
$foundl = true;
break 2;
}
}
}
}
if ($foundp === false) {
$this->error(self::PREFIX, $value);
return false;
}
if ($foundl === false) {
$this->error(self::LENGTH, $value);
return false;
}
$sum = 0;
$weight = 2;
for ($i = $length - 2; $i >= 0; $i--) {
$digit = $weight * $value[$i];
$sum += floor($digit / 10) + $digit % 10;
$weight = $weight % 2 + 1;
}
$checksum = (10 - $sum % 10) % 10;
if ((string) $checksum !== $value[$length - 1]) {
$this->error(self::CHECKSUM, $value);
return false;
}
$service = $this->getService();
if (! empty($service)) {
try {
$callback = new Callback($service);
$callback->setOptions($this->getType());
if (! $callback->isValid($value)) {
$this->error(self::SERVICE, $value);
return false;
}
} catch (Exception) {
$this->error(self::SERVICEFAILURE, $value);
return false;
}
}
return true;
}
// phpcs:enable SlevomatCodingStandard.TypeHints.ParameterTypeHintSpacing.NoSpaceBetweenTypeHintAndParameter
}

View File

@@ -1,382 +0,0 @@
<?php
namespace Laminas\Validator;
use Laminas\Session\Container as SessionContainer;
use Laminas\Stdlib\ArrayUtils;
use Traversable;
use function explode;
use function is_array;
use function is_string;
use function md5;
use function random_bytes;
use function sprintf;
use function str_replace;
use function strtolower;
use function strtr;
/**
* @deprecated This validator will be removed in version 3.0 of this component. A replacement is available in
* version 2.21.0 of the laminas-session component: https://docs.laminas.dev/laminas-session/
*
* @final
*/
class Csrf extends AbstractValidator
{
/**
* Error codes
*
* @const string
*/
public const NOT_SAME = 'notSame';
/**
* Error messages
*
* @var array
*/
protected $messageTemplates = [
self::NOT_SAME => 'The form submitted did not originate from the expected site',
];
/**
* Actual hash used.
*
* @var mixed
*/
protected $hash;
/**
* Static cache of the session names to generated hashes
*
* @todo unused, left here to avoid BC breaks
* @var array
*/
protected static $hashCache;
/**
* Name of CSRF element (used to create non-colliding hashes)
*
* @var string
*/
protected $name = 'csrf';
/**
* Salt for CSRF token
*
* @var string
*/
protected $salt = 'salt';
/** @var SessionContainer */
protected $session;
/**
* TTL for CSRF token
*
* @var int|null
*/
protected $timeout = 300;
/**
* Constructor
*
* @param array|Traversable $options
*/
public function __construct($options = [])
{
parent::__construct($options);
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
}
if (! is_array($options)) {
$options = (array) $options;
}
foreach ($options as $key => $value) {
switch (strtolower($key)) {
case 'name':
$this->setName($value);
break;
case 'salt':
$this->setSalt($value);
break;
case 'session':
$this->setSession($value);
break;
case 'timeout':
$this->setTimeout($value);
break;
default:
// ignore unknown options
break;
}
}
}
/**
* Does the provided token match the one generated?
*
* @param mixed $value
* @param mixed $context
* @return bool
*/
public function isValid($value, $context = null)
{
if (! is_string($value)) {
return false;
}
$this->setValue($value);
$tokenId = $this->getTokenIdFromHash($value);
$hash = $this->getValidationToken($tokenId);
$tokenFromValue = $this->getTokenFromHash($value);
$tokenFromHash = $this->getTokenFromHash($hash);
if ($tokenFromValue === null || $tokenFromHash === null || ($tokenFromValue !== $tokenFromHash)) {
$this->error(self::NOT_SAME);
return false;
}
return true;
}
/**
* Set CSRF name
*
* @param string $name
* @return $this
*/
public function setName($name)
{
$this->name = (string) $name;
return $this;
}
/**
* Get CSRF name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set session container
*
* @return $this
*/
public function setSession(SessionContainer $session)
{
$this->session = $session;
if ($this->hash) {
$this->initCsrfToken();
}
return $this;
}
/**
* Get session container
*
* Instantiate session container if none currently exists
*
* @return SessionContainer
*/
public function getSession()
{
if (null === $this->session) {
// Using fully qualified name, to ensure polyfill class alias is used
$this->session = new SessionContainer($this->getSessionName());
}
return $this->session;
}
/**
* Salt for CSRF token
*
* @param string $salt
* @return $this
*/
public function setSalt($salt)
{
$this->salt = (string) $salt;
return $this;
}
/**
* Retrieve salt for CSRF token
*
* @return string
*/
public function getSalt()
{
return $this->salt;
}
/**
* Retrieve CSRF token
*
* If no CSRF token currently exists, or should be regenerated,
* generates one.
*
* @param bool $regenerate default false
* @return string
*/
public function getHash($regenerate = false)
{
if ((null === $this->hash) || $regenerate) {
$this->generateHash();
}
return $this->hash;
}
/**
* Get session namespace for CSRF token
*
* Generates a session namespace based on salt, element name, and class.
*
* @return string
*/
public function getSessionName()
{
return str_replace('\\', '_', self::class) . '_'
. $this->getSalt() . '_'
. strtr($this->getName(), ['[' => '_', ']' => '']);
}
/**
* Set timeout for CSRF session token
*
* @param int|null $ttl
* @return $this
*/
public function setTimeout($ttl)
{
$this->timeout = $ttl !== null ? (int) $ttl : null;
return $this;
}
/**
* Get CSRF session token timeout
*
* @return int|null
*/
public function getTimeout()
{
return $this->timeout;
}
/**
* Initialize CSRF token in session
*
* @return void
*/
protected function initCsrfToken()
{
$session = $this->getSession();
$timeout = $this->getTimeout();
if (null !== $timeout) {
$session->setExpirationSeconds($timeout);
}
$hash = $this->getHash();
$token = $this->getTokenFromHash($hash);
$tokenId = $this->getTokenIdFromHash($hash);
if (! $session->tokenList) {
$session->tokenList = [];
}
$session->tokenList[$tokenId] = $token;
$session->hash = $hash; // @todo remove this, left for BC
}
/**
* Generate CSRF token
*
* Generates CSRF token and stores both in {@link $hash} and element
* value.
*
* @return void
*/
protected function generateHash()
{
$token = md5($this->getSalt() . random_bytes(32) . $this->getName());
$this->hash = $this->formatHash($token, $this->generateTokenId());
$this->setValue($this->hash);
$this->initCsrfToken();
}
/**
* @return string
*/
protected function generateTokenId()
{
return md5(random_bytes(32));
}
/**
* Get validation token
*
* Retrieve token from session, if it exists.
*
* @param string $tokenId
* @return null|string
*/
protected function getValidationToken($tokenId = null)
{
$session = $this->getSession();
/**
* if no tokenId is passed we revert to the old behaviour
*
* @todo remove, here for BC
*/
if ($tokenId === null && isset($session->hash)) {
return $session->hash;
}
if ($tokenId !== null && isset($session->tokenList[$tokenId])) {
return $this->formatHash($session->tokenList[$tokenId], $tokenId);
}
return null;
}
/**
* @return string
*/
protected function formatHash(string $token, string $tokenId)
{
return sprintf('%s-%s', $token, $tokenId);
}
protected function getTokenFromHash(?string $hash): ?string
{
if (null === $hash) {
return null;
}
$data = explode('-', $hash);
return $data[0] ?: null;
}
protected function getTokenIdFromHash(string $hash): ?string
{
$data = explode('-', $hash);
if (! isset($data[1])) {
return null;
}
return $data[1];
}
}

View File

@@ -1,245 +0,0 @@
<?php
declare(strict_types=1);
namespace Laminas\Validator;
use DateTime;
use DateTimeImmutable;
use DateTimeInterface;
use Traversable;
use function array_shift;
use function func_get_args;
use function gettype;
use function implode;
use function is_array;
use function iterator_to_array;
/**
* Validates that a given value is a DateTime instance or can be converted into one.
*/
class Date extends AbstractValidator
{
/**#@+
* Validity constants
*/
public const INVALID = 'dateInvalid';
public const INVALID_DATE = 'dateInvalidDate';
public const FALSEFORMAT = 'dateFalseFormat';
/**#@-*/
/**
* Default format constant
*/
public const FORMAT_DEFAULT = 'Y-m-d';
/**
* Validation failure message template definitions
*
* @var string[]
*/
protected $messageTemplates = [
self::INVALID => 'Invalid type given. String, integer, array or DateTime expected',
self::INVALID_DATE => 'The input does not appear to be a valid date',
self::FALSEFORMAT => "The input does not fit the date format '%format%'",
];
/** @var string[] */
protected $messageVariables = [
'format' => 'format',
];
/** @var string */
protected $format = self::FORMAT_DEFAULT;
/** @var bool */
protected $strict = false;
/**
* Sets validator options
*
* @param string|array|Traversable $options OPTIONAL
*/
public function __construct($options = [])
{
if ($options instanceof Traversable) {
$options = iterator_to_array($options);
} elseif (! is_array($options)) {
$options = func_get_args();
$temp['format'] = array_shift($options);
$options = $temp;
}
parent::__construct($options);
}
/**
* Returns the format option
*
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @return string
*/
public function getFormat()
{
return $this->format;
}
/**
* Sets the format option
*
* Format cannot be null. It will always default to 'Y-m-d', even
* if null is provided.
*
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @param string|null $format
* @return $this provides a fluent interface
* @todo validate the format
*/
public function setFormat($format = self::FORMAT_DEFAULT)
{
$this->format = $format === null || $format === '' ? self::FORMAT_DEFAULT : $format;
return $this;
}
/**
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*/
public function setStrict(bool $strict): self
{
$this->strict = $strict;
return $this;
}
/**
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*/
public function isStrict(): bool
{
return $this->strict;
}
/**
* Returns true if $value is a DateTimeInterface instance or can be converted into one.
*
* @param string|numeric|array|DateTimeInterface $value
* @return bool
*/
public function isValid($value)
{
$this->setValue($value);
$date = $this->convertToDateTime($value);
if (! $date) {
$this->error(self::INVALID_DATE);
return false;
}
if ($this->isStrict() && $date->format($this->getFormat()) !== $value) {
$this->error(self::FALSEFORMAT);
return false;
}
return true;
}
/**
* Attempts to convert an int, string, or array to a DateTime object
*
* @param string|numeric|array|DateTimeInterface $param
* @param bool $addErrors
* @return false|DateTime
*/
protected function convertToDateTime($param, $addErrors = true)
{
if ($param instanceof DateTime) {
return $param;
}
if ($param instanceof DateTimeImmutable) {
return DateTime::createFromImmutable($param);
}
$type = gettype($param);
switch ($type) {
case 'string':
return $this->convertString($param, $addErrors);
case 'integer':
return $this->convertInteger($param);
case 'double':
return $this->convertDouble($param);
case 'array':
return $this->convertArray($param, $addErrors);
}
if ($addErrors) {
$this->error(self::INVALID);
}
return false;
}
/**
* Attempts to convert an integer into a DateTime object
*
* @param integer $value
* @return false|DateTime
*/
protected function convertInteger($value)
{
return DateTime::createFromFormat('U', (string) $value);
}
/**
* Attempts to convert an double into a DateTime object
*
* @param double $value
* @return false|DateTime
*/
protected function convertDouble($value)
{
return DateTime::createFromFormat('U', (string) $value);
}
/**
* Attempts to convert a string into a DateTime object
*
* @param string $value
* @param bool $addErrors
* @return false|DateTime
*/
protected function convertString($value, $addErrors = true)
{
$date = DateTime::createFromFormat($this->format, $value);
// Invalid dates can show up as warnings (ie. "2007-02-99")
// and still return a DateTime object.
$errors = DateTime::getLastErrors();
if ($errors === false) {
return $date;
}
if ($errors['warning_count'] > 0) {
if ($addErrors) {
$this->error(self::FALSEFORMAT);
}
return false;
}
return $date;
}
/**
* Implodes the array into a string and proxies to {@link convertString()}.
*
* @param bool $addErrors
* @return false|DateTime
* @todo enhance the implosion
*/
protected function convertArray(array $value, $addErrors = true)
{
return $this->convertString(implode('-', $value), $addErrors);
}
}

View File

@@ -1,212 +0,0 @@
<?php
declare(strict_types=1);
namespace Laminas\Validator;
use DateTimeImmutable;
use DateTimeInterface;
use DateTimeZone;
use Laminas\Validator\Exception\InvalidArgumentException;
use function assert;
use function get_debug_type;
use function is_string;
use function preg_match;
/**
* @psalm-type OptionsArgument = array{
* min?: string|DateTimeInterface|null,
* max?: string|DateTimeInterface|null,
* inclusiveMin?: bool,
* inclusiveMax?: bool,
* inputFormat?: string|null,
* }
*/
final class DateComparison extends AbstractValidator
{
public const ERROR_INVALID_TYPE = 'invalidType';
public const ERROR_INVALID_DATE = 'invalidDate';
public const ERROR_NOT_GREATER_INCLUSIVE = 'notGreaterInclusive';
public const ERROR_NOT_GREATER = 'notGreater';
public const ERROR_NOT_LESS_INCLUSIVE = 'notLessInclusive';
public const ERROR_NOT_LESS = 'notLess';
/** @var array<string, string> */
protected array $messageTemplates = [
self::ERROR_INVALID_TYPE => 'Expected a string or a date time instance but received "%type"',
self::ERROR_INVALID_DATE => 'Invalid date provided',
self::ERROR_NOT_GREATER_INCLUSIVE => 'A date equal to or after %min% is required',
self::ERROR_NOT_GREATER => 'A date after %min% is required',
self::ERROR_NOT_LESS_INCLUSIVE => 'A date equal to or before %max% is required',
self::ERROR_NOT_LESS => 'A date before %max% is required',
];
/** @var array<string, string> */
protected array $messageVariables = [
'type' => 'type',
'min' => 'minString',
'max' => 'maxString',
];
private readonly ?DateTimeInterface $min;
private readonly ?DateTimeInterface $max;
private readonly bool $inclusiveMin;
private readonly bool $inclusiveMax;
private readonly ?string $inputFormat;
/** Input type used in message variables */
protected ?string $type = null;
protected ?string $minString = null;
protected ?string $maxString = null;
/** @param OptionsArgument $options */
public function __construct(array $options = [])
{
parent::__construct($options);
$this->min = $this->dateInstanceBound($options['min'] ?? null);
$this->max = $this->dateInstanceBound($options['max'] ?? null);
$this->inclusiveMin = $options['inclusiveMin'] ?? true;
$this->inclusiveMax = $options['inclusiveMax'] ?? true;
$this->inputFormat = $options['inputFormat'] ?? null;
if ($this->min === null && $this->max === null) {
throw new InvalidArgumentException(
'At least one date boundary must be supplied',
);
}
$outputFormat = $this->inputFormat ?? 'jS F Y H:i:s';
if ($this->min !== null) {
$this->minString = $this->min->format($outputFormat);
}
if ($this->max !== null) {
$this->maxString = $this->max->format($outputFormat);
}
}
public function isValid(mixed $value): bool
{
$this->type = get_debug_type($value);
$this->value = $value;
if (! is_string($value) && ! $value instanceof DateTimeInterface) {
$this->error(self::ERROR_INVALID_TYPE);
return false;
}
$date = $this->valueToDate($value);
if ($date === null) {
$this->error(self::ERROR_INVALID_DATE);
return false;
}
if ($this->min !== null && $this->inclusiveMin && $date < $this->min) {
$this->error(self::ERROR_NOT_GREATER_INCLUSIVE);
return false;
}
if ($this->min !== null && ! $this->inclusiveMin && $date <= $this->min) {
$this->error(self::ERROR_NOT_GREATER);
return false;
}
if ($this->max !== null && $this->inclusiveMax && $date > $this->max) {
$this->error(self::ERROR_NOT_LESS_INCLUSIVE);
return false;
}
if ($this->max !== null && ! $this->inclusiveMax && $date >= $this->max) {
$this->error(self::ERROR_NOT_LESS);
return false;
}
return true;
}
private function valueToDate(string|DateTimeInterface $input): DateTimeInterface|null
{
if ($input instanceof DateTimeInterface) {
return $this->w3cDateFromString($input->format('Y-m-d\TH:i:s'));
}
if ($this->inputFormat !== null) {
$date = DateTimeImmutable::createFromFormat($this->inputFormat, $input, new DateTimeZone('UTC'));
if ($date instanceof DateTimeImmutable) {
return $date;
}
}
$date = $this->isoDateFromString($input);
if ($date !== null) {
return $date;
}
$date = $this->w3cDateFromString($input);
if ($date !== null) {
return $date;
}
return null;
}
private function dateInstanceBound(string|DateTimeInterface|null $dateTime): DateTimeInterface|null
{
if ($dateTime instanceof DateTimeInterface) {
return $this->w3cDateFromString($dateTime->format('Y-m-d\TH:i:s'));
}
if ($dateTime === null) {
return null;
}
$date = $this->isoDateFromString($dateTime);
if ($date !== null) {
return $date;
}
$date = $this->w3cDateFromString($dateTime);
if ($date !== null) {
return $date;
}
throw new InvalidArgumentException(
'Min/max date bounds must be either DateTime instances, or a string in one of the formats: '
. '"Y-m-d" for a date or "Y-m-d\TH:i:s" for date time',
);
}
private function isoDateFromString(string $input): DateTimeImmutable|null
{
if (! preg_match('/^\d{4}-[0-1]\d-[0-3]\d$/', $input)) {
return null;
}
$date = DateTimeImmutable::createFromFormat('!Y-m-d', $input, new DateTimeZone('UTC'));
assert($date !== false);
return $date;
}
private function w3cDateFromString(string $input): DateTimeImmutable|null
{
if (! preg_match('/^\d{4}-[0-1]\d-[0-3]\dT\d{1,2}:[0-5]\d:[0-5]\d$/', $input)) {
return null;
}
$date = DateTimeImmutable::createFromFormat('Y-m-d\TH:i:s', $input, new DateTimeZone('UTC'));
assert($date !== false);
return $date;
}
}

View File

@@ -1,540 +0,0 @@
<?php
declare(strict_types=1);
namespace Laminas\Validator;
use DateInterval;
use DateTime;
use DateTimeImmutable;
use DateTimeInterface;
use DateTimeZone;
use Laminas\Stdlib\ArrayUtils;
use Traversable;
use function array_combine;
use function array_count_values;
use function array_map;
use function array_shift;
use function ceil;
use function date_default_timezone_get;
use function explode;
use function floor;
use function func_get_args;
use function in_array;
use function is_array;
use function max;
use function min;
use function preg_match;
use function sprintf;
use function str_starts_with;
use const PHP_INT_MAX;
/** @final */
class DateStep extends Date
{
/**
* Validity constants
*/
public const NOT_STEP = 'dateStepNotStep';
/**
* Default format constant
*/
public const FORMAT_DEFAULT = DateTime::ISO8601;
/**
* Validation failure message template definitions
*
* @var string[]
*/
protected $messageTemplates = [
self::INVALID => 'Invalid type given. String, integer, array or DateTime expected',
self::INVALID_DATE => 'The input does not appear to be a valid date',
self::FALSEFORMAT => "The input does not fit the date format '%format%'",
self::NOT_STEP => 'The input is not a valid step',
];
/**
* Optional base date value
*
* @var string|int|DateTimeInterface
*/
protected $baseValue = '1970-01-01T00:00:00Z';
/**
* Date step interval (defaults to 1 day).
* Uses the DateInterval specification.
*
* @var DateInterval
*/
protected $step;
/**
* Optional timezone to be used when the baseValue
* and validation values do not contain timezone info
*
* @deprecated Since 2.61.0 - The timezone option is unused
*
* @var DateTimeZone
*/
protected $timezone;
/**
* Set default options for this instance
*
* @param string|array|Traversable $options
*/
public function __construct($options = [])
{
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
} elseif (! is_array($options)) {
$options = func_get_args();
$temp = [];
$temp['baseValue'] = array_shift($options);
if (! empty($options)) {
$temp['step'] = array_shift($options);
}
if (! empty($options)) {
$temp['format'] = array_shift($options);
}
if (! empty($options)) {
$temp['timezone'] = array_shift($options);
}
$options = $temp;
}
if (! isset($options['step'])) {
$options['step'] = new DateInterval('P1D');
}
if (! isset($options['timezone'])) {
$options['timezone'] = new DateTimeZone(date_default_timezone_get());
}
parent::__construct($options);
}
/**
* Sets the base value from which the step should be computed
*
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @param string|int|DateTimeInterface $baseValue
* @return $this
*/
public function setBaseValue($baseValue)
{
$this->baseValue = $baseValue;
return $this;
}
/**
* Returns the base value from which the step should be computed
*
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @return string|int|DateTimeInterface
*/
public function getBaseValue()
{
return $this->baseValue;
}
/**
* Sets the step date interval
*
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @return $this
*/
public function setStep(DateInterval $step)
{
$this->step = $step;
return $this;
}
/**
* Returns the step date interval
*
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @return DateInterval
*/
public function getStep()
{
return $this->step;
}
/**
* Returns the timezone option
*
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @return DateTimeZone
*/
public function getTimezone()
{
return $this->timezone;
}
/**
* Sets the timezone option
*
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @return $this
*/
public function setTimezone(DateTimeZone $timezone)
{
$this->timezone = $timezone;
return $this;
}
/**
* Supports formats with ISO week (W) definitions
*
* @see Date::convertString()
*
* @param string $value
* @param bool $addErrors
* @return DateTime|false
*/
protected function convertString($value, $addErrors = true)
{
// Custom week format support
if (
str_starts_with($this->format, 'Y-\WW')
&& preg_match('/^([0-9]{4})\-W([0-9]{2})/', $value, $matches)
) {
$date = new DateTime();
$date->setISODate((int) $matches[1], (int) $matches[2]);
} else {
$date = DateTime::createFromFormat($this->format, $value, new DateTimeZone('UTC'));
}
// Invalid dates can show up as warnings (ie. "2007-02-99")
// and still return a DateTime object.
$errors = DateTime::getLastErrors();
if (is_array($errors) && $errors['warning_count'] > 0) {
if ($addErrors) {
$this->error(self::FALSEFORMAT);
}
return false;
}
return $date;
}
/**
* Returns true if a date is within a valid step
*
* @param string|int|DateTimeInterface $value
* @return bool
* @throws Exception\InvalidArgumentException
*/
public function isValid($value)
{
if (! parent::isValid($value)) {
return false;
}
$valueDate = $this->convertToDateTime($value, false); // avoid duplicate errors
$baseDate = $this->convertToDateTime($this->baseValue, false);
if (false === $valueDate || false === $baseDate) {
return false;
}
$step = $this->getStep();
// Same date?
// phpcs:ignore SlevomatCodingStandard.Operators.DisallowEqualOperators.DisallowedEqualOperator
if ($valueDate == $baseDate) {
return true;
}
// Optimization for simple intervals.
// Handle intervals of just one date or time unit.
$intervalParts = explode('|', $step->format('%y|%m|%d|%h|%i|%s'));
$intervalParts = array_map('intval', $intervalParts);
$partCounts = array_count_values($intervalParts);
$unitKeys = ['years', 'months', 'days', 'hours', 'minutes', 'seconds'];
$intervalParts = array_combine($unitKeys, $intervalParts);
// Get absolute time difference to avoid special cases of missing/added time
$absoluteValueDate = new DateTime($valueDate->format('Y-m-d H:i:s'), new DateTimeZone('UTC'));
$absoluteBaseDate = new DateTime($baseDate->format('Y-m-d H:i:s'), new DateTimeZone('UTC'));
$timeDiff = $absoluteValueDate->diff($absoluteBaseDate, true);
$diffParts = array_map('intval', explode('|', $timeDiff->format('%y|%m|%d|%h|%i|%s')));
$diffParts = array_combine($unitKeys, $diffParts);
if (5 === $partCounts[0]) {
// Find the unit with the non-zero interval
$intervalUnit = 'days';
$stepValue = 1;
foreach ($intervalParts as $key => $value) {
if (0 !== $value) {
$intervalUnit = $key;
$stepValue = $value;
break;
}
}
// Check date units
if (in_array($intervalUnit, ['years', 'months', 'days'])) {
switch ($intervalUnit) {
case 'years':
if (
0 === $diffParts['months'] && 0 === $diffParts['days']
&& 0 === $diffParts['hours'] && 0 === $diffParts['minutes']
&& 0 === $diffParts['seconds']
) {
if (($diffParts['years'] % $stepValue) === 0) {
return true;
}
}
break;
case 'months':
if (
0 === $diffParts['days'] && 0 === $diffParts['hours']
&& 0 === $diffParts['minutes'] && 0 === $diffParts['seconds']
) {
$months = ($diffParts['years'] * 12) + $diffParts['months'];
if (($months % $stepValue) === 0) {
return true;
}
}
break;
case 'days':
if (
0 === $diffParts['hours'] && 0 === $diffParts['minutes']
&& 0 === $diffParts['seconds']
) {
$days = (int) $timeDiff->format('%a'); // Total days
if (($days % $stepValue) === 0) {
return true;
}
}
break;
}
$this->error(self::NOT_STEP);
return false;
}
// Check time units
if (in_array($intervalUnit, ['hours', 'minutes', 'seconds'])) {
// Simple test if $stepValue is 1.
if (1 === $stepValue) {
if (
'hours' === $intervalUnit
&& 0 === $diffParts['minutes'] && 0 === $diffParts['seconds']
) {
return true;
} elseif ('minutes' === $intervalUnit && 0 === $diffParts['seconds']) {
return true;
} elseif ('seconds' === $intervalUnit) {
return true;
}
$this->error(self::NOT_STEP);
return false;
}
// Simple test for same day, when using default baseDate
if (
$baseDate->format('Y-m-d') === $valueDate->format('Y-m-d')
&& $baseDate->format('Y-m-d') === '1970-01-01'
) {
switch ($intervalUnit) {
case 'hours':
if (0 === $diffParts['minutes'] && 0 === $diffParts['seconds']) {
if (($diffParts['hours'] % $stepValue) === 0) {
return true;
}
}
break;
case 'minutes':
if (0 === $diffParts['seconds']) {
$minutes = ($diffParts['hours'] * 60) + $diffParts['minutes'];
if (($minutes % $stepValue) === 0) {
return true;
}
}
break;
case 'seconds':
$seconds = ($diffParts['hours'] * 60 * 60)
+ ($diffParts['minutes'] * 60)
+ $diffParts['seconds'];
if (($seconds % $stepValue) === 0) {
return true;
}
break;
}
$this->error(self::NOT_STEP);
return false;
}
}
}
return $this->fallbackIncrementalIterationLogic($baseDate, $valueDate, $intervalParts, $diffParts, $step);
}
/**
* Fall back to slower (but accurate) method for complex intervals.
* Keep adding steps to the base date until a match is found
* or until the value is exceeded.
*
* This is really slow if the interval is small, especially if the
* default base date of 1/1/1970 is used. We can skip a chunk of
* iterations by starting at the lower bound of steps needed to reach
* the target
*
* @param int[] $intervalParts
* @param int[] $diffParts
* @throws Exception\InvalidArgumentException
*/
private function fallbackIncrementalIterationLogic(
DateTimeInterface $baseDate,
DateTimeInterface $valueDate,
array $intervalParts,
array $diffParts,
DateInterval $step
): bool {
[$minSteps, $requiredIterations] = $this->computeMinStepAndRequiredIterations($intervalParts, $diffParts);
$minimumInterval = $this->computeMinimumInterval($intervalParts, $minSteps);
$isIncrementalStepping = $baseDate < $valueDate;
if (! ($baseDate instanceof DateTime || $baseDate instanceof DateTimeImmutable)) {
throw new Exception\InvalidArgumentException(sprintf(
'Function %s requires the baseDate to be a DateTime or DateTimeImmutable instance.',
__FUNCTION__
));
}
for ($offsetIterations = 0; $offsetIterations < $requiredIterations; $offsetIterations += 1) {
if ($isIncrementalStepping) {
$baseDate = $baseDate->add($minimumInterval);
} else {
$baseDate = $baseDate->sub($minimumInterval);
}
}
while (
($isIncrementalStepping && $baseDate < $valueDate)
|| (! $isIncrementalStepping && $baseDate > $valueDate)
) {
if ($isIncrementalStepping) {
$baseDate = $baseDate->add($step);
} else {
$baseDate = $baseDate->sub($step);
}
// phpcs:ignore SlevomatCodingStandard.Operators.DisallowEqualOperators.DisallowedEqualOperator
if ($baseDate == $valueDate) {
return true;
}
}
$this->error(self::NOT_STEP);
return false;
}
/**
* Computes minimum interval to use for iterations while checking steps
*
* @param int[] $intervalParts
* @param int|float $minSteps
*/
private function computeMinimumInterval(array $intervalParts, $minSteps): DateInterval
{
return new DateInterval(sprintf(
'P%dY%dM%dDT%dH%dM%dS',
$intervalParts['years'] * $minSteps,
$intervalParts['months'] * $minSteps,
$intervalParts['days'] * $minSteps,
$intervalParts['hours'] * $minSteps,
$intervalParts['minutes'] * $minSteps,
$intervalParts['seconds'] * $minSteps
));
}
/**
* @param int[] $intervalParts
* @param int[] $diffParts
* @return int[] (ordered tuple containing minimum steps and required step iterations
* @psalm-return array{0: int, 1: int}
*/
private function computeMinStepAndRequiredIterations(array $intervalParts, array $diffParts): array
{
$minSteps = $this->computeMinSteps($intervalParts, $diffParts);
// If we use PHP_INT_MAX DateInterval::__construct falls over with a bad format error
// before we reach the max on 64 bit machines
$maxInteger = min(2 ** 31, PHP_INT_MAX);
// check for integer overflow and split $minimum interval if needed
$maximumInterval = max($intervalParts);
$requiredStepIterations = 1;
if (($minSteps * $maximumInterval) > $maxInteger) {
$requiredStepIterations = ceil(($minSteps * $maximumInterval) / $maxInteger);
$minSteps = floor($minSteps / $requiredStepIterations);
}
return [(int) $minSteps, $minSteps !== 0 ? (int) $requiredStepIterations : 0];
}
/**
* Multiply the step interval by the lower bound of steps to reach the target
*
* @param int[] $intervalParts
* @param int[] $diffParts
* @return float|int
*/
private function computeMinSteps(array $intervalParts, array $diffParts)
{
$intervalMaxSeconds = $this->computeIntervalMaxSeconds($intervalParts);
return 0 === $intervalMaxSeconds
? 0
: max(floor($this->computeDiffMinSeconds($diffParts) / $intervalMaxSeconds) - 1, 0);
}
/**
* Get upper bound of the given interval in seconds
* Converts a given `$intervalParts` array into seconds
*
* @param int[] $intervalParts
*/
private function computeIntervalMaxSeconds(array $intervalParts): int
{
return ($intervalParts['years'] * 60 * 60 * 24 * 366)
+ ($intervalParts['months'] * 60 * 60 * 24 * 31)
+ ($intervalParts['days'] * 60 * 60 * 24)
+ ($intervalParts['hours'] * 60 * 60)
+ ($intervalParts['minutes'] * 60)
+ $intervalParts['seconds'];
}
/**
* Get lower bound of difference in secondss
* Converts a given `$diffParts` array into seconds
*
* @param int[] $diffParts
*/
private function computeDiffMinSeconds(array $diffParts): int
{
return ($diffParts['years'] * 60 * 60 * 24 * 365)
+ ($diffParts['months'] * 60 * 60 * 24 * 28)
+ ($diffParts['days'] * 60 * 60 * 24)
+ ($diffParts['hours'] * 60 * 60)
+ ($diffParts['minutes'] * 60)
+ $diffParts['seconds'];
}
}

View File

@@ -1,317 +0,0 @@
<?php
namespace Laminas\Validator\Db;
use Laminas\Db\Adapter\Adapter as DbAdapter;
use Laminas\Db\Adapter\AdapterAwareInterface;
use Laminas\Db\Adapter\AdapterAwareTrait;
use Laminas\Db\Sql\Select;
use Laminas\Db\Sql\Sql;
use Laminas\Db\Sql\TableIdentifier;
use Laminas\Stdlib\ArrayUtils;
use Laminas\Validator\AbstractValidator;
use Laminas\Validator\Exception;
use Laminas\Validator\Exception\InvalidArgumentException;
use Laminas\Validator\Exception\RuntimeException;
use Traversable;
use function array_key_exists;
use function array_shift;
use function func_get_args;
use function func_num_args;
use function is_array;
/**
* Class for Database record validation
*
* @deprecated This class will be removed in version 3.0 of this component. There is no replacement.
*/
abstract class AbstractDb extends AbstractValidator implements AdapterAwareInterface
{
use AdapterAwareTrait;
/**
* Error constants
*/
public const ERROR_NO_RECORD_FOUND = 'noRecordFound';
public const ERROR_RECORD_FOUND = 'recordFound';
/** @var array<string, string> Message templates */
protected $messageTemplates = [
self::ERROR_NO_RECORD_FOUND => 'No record matching the input was found',
self::ERROR_RECORD_FOUND => 'A record matching the input was found',
];
/**
* Select object to use. can be set, or will be auto-generated
*
* @var Select
*/
protected $select;
/** @var string */
protected $schema;
/** @var string */
protected $table = '';
/** @var string */
protected $field = '';
/** @var mixed */
protected $exclude;
/**
* Provides basic configuration for use with Laminas\Validator\Db Validators
* Setting $exclude allows a single record to be excluded from matching.
* Exclude can either be a String containing a where clause, or an array with `field` and `value` keys
* to define the where clause added to the sql.
* A database adapter may optionally be supplied to avoid using the registered default adapter.
*
* The following option keys are supported:
* 'table' => The database table to validate against
* 'schema' => The schema keys
* 'field' => The field to check for a match
* 'exclude' => An optional where clause or field/value pair to exclude from the query
* 'adapter' => An optional database adapter to use
*
* @param array|Traversable|Select $options Options to use for this validator
* @throws InvalidArgumentException
*/
public function __construct($options = null)
{
parent::__construct($options);
if ($options instanceof Select) {
$this->setSelect($options);
return;
}
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
} elseif (func_num_args() > 1) {
$options = func_get_args();
$firstArgument = array_shift($options);
if (is_array($firstArgument)) {
$temp = ArrayUtils::iteratorToArray($firstArgument);
} else {
$temp['table'] = $firstArgument;
}
$temp['field'] = array_shift($options);
if (! empty($options)) {
$temp['exclude'] = array_shift($options);
}
if (! empty($options)) {
$temp['adapter'] = array_shift($options);
}
$options = $temp;
}
if (! array_key_exists('table', $options) && ! array_key_exists('schema', $options)) {
throw new Exception\InvalidArgumentException('Table or Schema option missing!');
}
if (! array_key_exists('field', $options)) {
throw new Exception\InvalidArgumentException('Field option missing!');
}
if (array_key_exists('adapter', $options)) {
$this->setAdapter($options['adapter']);
}
if (array_key_exists('exclude', $options)) {
$this->setExclude($options['exclude']);
}
$this->setField($options['field']);
if (array_key_exists('table', $options)) {
$this->setTable($options['table']);
}
if (array_key_exists('schema', $options)) {
$this->setSchema($options['schema']);
}
}
/**
* Returns the set adapter
*
* @throws RuntimeException When no database adapter is defined.
* @return DbAdapter
*/
public function getAdapter()
{
return $this->adapter;
}
/**
* Sets a new database adapter
*
* @return self Provides a fluent interface
*/
public function setAdapter(DbAdapter $adapter)
{
return $this->setDbAdapter($adapter);
}
/**
* Returns the set exclude clause
*
* @return string|array
*/
public function getExclude()
{
return $this->exclude;
}
/**
* Sets a new exclude clause
*
* @param string|array $exclude
* @return $this Provides a fluent interface
*/
public function setExclude($exclude)
{
$this->exclude = $exclude;
$this->select = null;
return $this;
}
/**
* Returns the set field
*
* @return string|array
*/
public function getField()
{
return $this->field;
}
/**
* Sets a new field
*
* @param string $field
* @return $this
*/
public function setField($field)
{
$this->field = (string) $field;
$this->select = null;
return $this;
}
/**
* Returns the set table
*
* @return string
*/
public function getTable()
{
return $this->table;
}
/**
* Sets a new table
*
* @param string $table
* @return $this Provides a fluent interface
*/
public function setTable($table)
{
$this->table = (string) $table;
$this->select = null;
return $this;
}
/**
* Returns the set schema
*
* @return string
*/
public function getSchema()
{
return $this->schema;
}
/**
* Sets a new schema
*
* @param string $schema
* @return $this Provides a fluent interface
*/
public function setSchema($schema)
{
$this->schema = $schema;
$this->select = null;
return $this;
}
/**
* Sets the select object to be used by the validator
*
* @return $this Provides a fluent interface
*/
public function setSelect(Select $select)
{
$this->select = $select;
return $this;
}
/**
* Gets the select object to be used by the validator.
* If no select object was supplied to the constructor,
* then it will auto-generate one from the given table,
* schema, field, and adapter options.
*
* @return Select The Select object which will be used
*/
public function getSelect()
{
if ($this->select instanceof Select) {
return $this->select;
}
// Build select object
$select = new Select();
$tableIdentifier = new TableIdentifier($this->table, $this->schema);
$select->from($tableIdentifier)->columns([$this->field]);
$select->where->equalTo($this->field, null);
if ($this->exclude !== null) {
if (is_array($this->exclude)) {
$select->where->notEqualTo(
$this->exclude['field'],
$this->exclude['value']
);
} else {
$select->where($this->exclude);
}
}
$this->select = $select;
return $this->select;
}
/**
* Run query and returns matches, or null if no matches are found.
*
* @param string $value
* @return array when matches are found.
*/
protected function query($value)
{
$sql = new Sql($this->getAdapter());
$select = $this->getSelect();
$statement = $sql->prepareStatementForSqlObject($select);
$parameters = $statement->getParameterContainer();
$parameters['where1'] = $value;
$result = $statement->execute();
return $result->current();
}
}

View File

@@ -1,38 +0,0 @@
<?php
namespace Laminas\Validator\Db;
use Laminas\Validator\Exception;
/**
* Confirms a record does not exist in a table.
*
* @deprecated This class will be removed in version 3.0 of this component. There is no replacement.
*/
class NoRecordExists extends AbstractDb
{
/**
* @param mixed $value
* @return bool
*/
public function isValid($value)
{
/*
* Check for an adapter being defined. If not, throw an exception.
*/
if (null === $this->adapter) {
throw new Exception\RuntimeException('No database adapter present');
}
$valid = true;
$this->setValue($value);
$result = $this->query($value);
if ($result) {
$valid = false;
$this->error(self::ERROR_RECORD_FOUND);
}
return $valid;
}
}

View File

@@ -1,38 +0,0 @@
<?php
namespace Laminas\Validator\Db;
use Laminas\Validator\Exception;
/**
* Confirms a record exists in a table.
*
* @deprecated This class will be removed in version 3.0 of this component. There is no replacement.
*/
class RecordExists extends AbstractDb
{
/**
* @param mixed $value
* @return bool
*/
public function isValid($value)
{
/*
* Check for an adapter being defined. If not, throw an exception.
*/
if (null === $this->adapter) {
throw new Exception\RuntimeException('No database adapter present');
}
$valid = true;
$this->setValue($value);
$result = $this->query($value);
if (! $result) {
$valid = false;
$this->error(self::ERROR_NO_RECORD_FOUND);
}
return $valid;
}
}

View File

@@ -1,67 +0,0 @@
<?php
namespace Laminas\Validator;
use Laminas\Filter\Digits as DigitsFilter;
use function is_float;
use function is_int;
use function is_string;
/** @final */
class Digits extends AbstractValidator
{
public const NOT_DIGITS = 'notDigits';
public const STRING_EMPTY = 'digitsStringEmpty';
public const INVALID = 'digitsInvalid';
/**
* Digits filter used for validation
*
* @var DigitsFilter|null
*/
protected static $filter;
/**
* Validation failure message template definitions
*
* @var array
*/
protected $messageTemplates = [
self::NOT_DIGITS => 'The input must contain only digits',
self::STRING_EMPTY => 'The input is an empty string',
self::INVALID => 'Invalid type given. String, integer or float expected',
];
/**
* Returns true if and only if $value only contains digit characters
*
* @param mixed $value
* @return bool
*/
public function isValid($value)
{
if (! is_string($value) && ! is_int($value) && ! is_float($value)) {
$this->error(self::INVALID);
return false;
}
$this->setValue((string) $value);
if ('' === $this->getValue()) {
$this->error(self::STRING_EMPTY);
return false;
}
if (null === static::$filter) {
static::$filter = new DigitsFilter();
}
if ($this->getValue() !== static::$filter->filter($this->getValue())) {
$this->error(self::NOT_DIGITS);
return false;
}
return true;
}
}

View File

@@ -1,598 +0,0 @@
<?php
namespace Laminas\Validator;
use Traversable;
use UConverter;
use function array_combine;
use function array_flip;
use function array_keys;
use function array_shift;
use function arsort;
use function checkdnsrr;
use function defined;
use function extension_loaded;
use function func_get_args;
use function function_exists;
use function gethostbynamel;
use function getmxrr;
use function idn_to_ascii;
use function idn_to_utf8;
use function is_array;
use function is_string;
use function preg_match;
use function str_contains;
use function strlen;
use function trim;
use const INTL_IDNA_VARIANT_UTS46;
/** @final */
class EmailAddress extends AbstractValidator
{
public const INVALID = 'emailAddressInvalid';
public const INVALID_FORMAT = 'emailAddressInvalidFormat';
public const INVALID_HOSTNAME = 'emailAddressInvalidHostname';
public const INVALID_MX_RECORD = 'emailAddressInvalidMxRecord';
public const INVALID_SEGMENT = 'emailAddressInvalidSegment';
public const DOT_ATOM = 'emailAddressDotAtom';
public const QUOTED_STRING = 'emailAddressQuotedString';
public const INVALID_LOCAL_PART = 'emailAddressInvalidLocalPart';
public const LENGTH_EXCEEDED = 'emailAddressLengthExceeded';
// phpcs:disable Generic.Files.LineLength.TooLong
/** @var array<string, string> */
protected $messageTemplates = [
self::INVALID => "Invalid type given. String expected",
self::INVALID_FORMAT => "The input is not a valid email address. Use the basic format local-part@hostname",
self::INVALID_HOSTNAME => "'%hostname%' is not a valid hostname for the email address",
self::INVALID_MX_RECORD => "'%hostname%' does not appear to have any valid MX or A records for the email address",
self::INVALID_SEGMENT => "'%hostname%' is not in a routable network segment. The email address should not be resolved from public network",
self::DOT_ATOM => "'%localPart%' can not be matched against dot-atom format",
self::QUOTED_STRING => "'%localPart%' can not be matched against quoted-string format",
self::INVALID_LOCAL_PART => "'%localPart%' is not a valid local part for the email address",
self::LENGTH_EXCEEDED => "The input exceeds the allowed length",
];
// phpcs:enable
/** @var array */
protected $messageVariables = [
'hostname' => 'hostname',
'localPart' => 'localPart',
];
/** @var string */
protected $hostname;
/** @var string */
protected $localPart;
/**
* Returns the found mx record information
*
* @var array
*/
protected $mxRecord = [];
/**
* Internal options array
*
* @var array<string, mixed>
*/
protected $options = [
'useMxCheck' => false,
'useDeepMxCheck' => false,
'useDomainCheck' => true,
'allow' => Hostname::ALLOW_DNS,
'strict' => true,
'hostnameValidator' => null,
];
/**
* Instantiates hostname validator for local use
*
* The following additional option keys are supported:
* 'hostnameValidator' => A hostname validator, see Laminas\Validator\Hostname
* 'allow' => Options for the hostname validator, see Laminas\Validator\Hostname::ALLOW_*
* 'strict' => Whether to adhere to strictest requirements in the spec
* 'useMxCheck' => If MX check should be enabled, boolean
* 'useDeepMxCheck' => If a deep MX check should be done, boolean
*
* @param array|Traversable $options OPTIONAL
*/
public function __construct($options = [])
{
if (! is_array($options)) {
$options = func_get_args();
$temp['allow'] = array_shift($options);
if (! empty($options)) {
$temp['useMxCheck'] = array_shift($options);
}
if (! empty($options)) {
$temp['hostnameValidator'] = array_shift($options);
}
$options = $temp;
}
parent::__construct($options);
}
/**
* Sets the validation failure message template for a particular key
* Adds the ability to set messages to the attached hostname validator
*
* @param string $messageString
* @param string $messageKey OPTIONAL
* @return AbstractValidator Provides a fluent interface
*/
public function setMessage($messageString, $messageKey = null)
{
if ($messageKey === null) {
$this->getHostnameValidator()->setMessage($messageString);
parent::setMessage($messageString);
return $this;
}
if (! isset($this->messageTemplates[$messageKey])) {
$this->getHostnameValidator()->setMessage($messageString, $messageKey);
} else {
parent::setMessage($messageString, $messageKey);
}
return $this;
}
/**
* Returns the set hostname validator
*
* If was not previously set then lazy load a new one
*
* @deprecated Since 2.61.0 - All option getters and setters will be removed in 3.0
*
* @return Hostname
*/
public function getHostnameValidator()
{
if (! isset($this->options['hostnameValidator'])) {
$this->options['hostnameValidator'] = new Hostname($this->getAllow());
}
return $this->options['hostnameValidator'];
}
/**
* @deprecated Since 2.61.0 - All option getters and setters will be removed in 3.0
*
* @param Hostname $hostnameValidator OPTIONAL
* @return $this Provides a fluent interface
*/
public function setHostnameValidator(?Hostname $hostnameValidator = null)
{
$this->options['hostnameValidator'] = $hostnameValidator;
return $this;
}
/**
* Returns the allow option of the attached hostname validator
*
* @deprecated Since 2.61.0 - All option getters and setters will be removed in 3.0
*
* @return int
*/
public function getAllow()
{
return $this->options['allow'];
}
/**
* Sets the allow option of the hostname validator to use
*
* @deprecated Since 2.61.0 - All option getters and setters will be removed in 3.0
*
* @param int $allow
* @return $this Provides a fluent interface
*/
public function setAllow($allow)
{
$this->options['allow'] = $allow;
if (isset($this->options['hostnameValidator'])) {
$this->options['hostnameValidator']->setAllow($allow);
}
return $this;
}
/**
* Whether MX checking via getmxrr is supported or not
*
* @deprecated Since 2.61.0 - All option getters and setters will be removed in 3.0
*
* @return bool
*/
public function isMxSupported()
{
return function_exists('getmxrr');
}
/**
* Returns the set validateMx option
*
* @deprecated Since 2.61.0 - All option getters and setters will be removed in 3.0
*
* @return bool
*/
public function getMxCheck()
{
return $this->options['useMxCheck'];
}
/**
* Set whether we check for a valid MX record via DNS
*
* This only applies when DNS hostnames are validated
*
* @deprecated Since 2.61.0 - All option getters and setters will be removed in 3.0
*
* @param bool $mx Set allowed to true to validate for MX records, and false to not validate them
* @return $this Fluid Interface
*/
public function useMxCheck($mx)
{
$this->options['useMxCheck'] = (bool) $mx;
return $this;
}
/**
* Returns the set deepMxCheck option
*
* @deprecated Since 2.61.0 - All option getters and setters will be removed in 3.0
*
* @return bool
*/
public function getDeepMxCheck()
{
return $this->options['useDeepMxCheck'];
}
/**
* Use deep validation for MX records
*
* @deprecated Since 2.61.0 - All option getters and setters will be removed in 3.0
*
* @param bool $deep Set deep to true to perform a deep validation process for MX records
* @return $this Fluid Interface
*/
public function useDeepMxCheck($deep)
{
$this->options['useDeepMxCheck'] = (bool) $deep;
return $this;
}
/**
* Returns the set domainCheck option
*
* @deprecated Since 2.61.0 - All option getters and setters will be removed in 3.0
*
* @return bool
*/
public function getDomainCheck()
{
return $this->options['useDomainCheck'];
}
/**
* Sets if the domain should also be checked
* or only the local part of the email address
*
* @deprecated Since 2.61.0 - All option getters and setters will be removed in 3.0
*
* @param bool $domain
* @return $this Fluid Interface
*/
public function useDomainCheck($domain = true)
{
$this->options['useDomainCheck'] = (bool) $domain;
return $this;
}
/**
* Returns whether the given host is a reserved IP, or a hostname that resolves to a reserved IP
*
* @param string $host
* @return bool Returns false when minimal one of the given addresses is not reserved
*/
protected function isReserved($host)
{
$validator = new HostWithPublicIPv4Address();
return ! $validator->isValid($host);
}
/**
* Internal method to validate the local part of the email address
*
* @return bool
*/
protected function validateLocalPart()
{
// First try to match the local part on the common dot-atom format
// Dot-atom characters are: 1*atext *("." 1*atext)
// atext: ALPHA / DIGIT / and "!", "#", "$", "%", "&", "'", "*",
// "+", "-", "/", "=", "?", "^", "_", "`", "{", "|", "}", "~"
$atext = 'a-zA-Z0-9\x21\x23\x24\x25\x26\x27\x2a\x2b\x2d\x2f\x3d\x3f\x5e\x5f\x60\x7b\x7c\x7d\x7e';
if (preg_match('/^[' . $atext . ']+(\x2e+[' . $atext . ']+)*$/', $this->localPart)) {
return true;
}
if ($this->validateInternationalizedLocalPart($this->localPart)) {
return true;
}
// Try quoted string format (RFC 5321 Chapter 4.1.2)
// Quoted-string characters are: DQUOTE *(qtext/quoted-pair) DQUOTE
$qtext = '\x20-\x21\x23-\x5b\x5d-\x7e'; // %d32-33 / %d35-91 / %d93-126
$quotedPair = '\x20-\x7e'; // %d92 %d32-126
if (preg_match('/^"([' . $qtext . ']|\x5c[' . $quotedPair . '])*"$/', $this->localPart)) {
return true;
}
$this->error(self::DOT_ATOM);
$this->error(self::QUOTED_STRING);
$this->error(self::INVALID_LOCAL_PART);
return false;
}
/**
* @param string $localPart Address local part to validate.
* @return bool
*/
protected function validateInternationalizedLocalPart($localPart)
{
if (
extension_loaded('intl')
&& false === UConverter::transcode($localPart, 'UTF-8', 'UTF-8')
) {
// invalid utf?
return false;
}
$atext = 'a-zA-Z0-9\x21\x23\x24\x25\x26\x27\x2a\x2b\x2d\x2f\x3d\x3f\x5e\x5f\x60\x7b\x7c\x7d\x7e';
// RFC 6532 extends atext to include non-ascii utf
// @see https://tools.ietf.org/html/rfc6532#section-3.1
$uatext = $atext . '\x{80}-\x{FFFF}';
return (bool) preg_match('/^[' . $uatext . ']+(\x2e+[' . $uatext . ']+)*$/u', $localPart);
}
/**
* Returns the found MX Record information after validation including weight for further processing
*
* @deprecated Since 2.61.0 - All option getters and setters will be removed in 3.0
*
* @return array
*/
public function getMXRecord()
{
return $this->mxRecord;
}
/**
* Internal method to validate the servers MX records
*
* @return bool|string[]
* @psalm-return bool|list<string>
*/
protected function validateMXRecords()
{
$mxHosts = [];
$weight = [];
$result = getmxrr($this->hostname, $mxHosts, $weight);
if (! empty($mxHosts) && ! empty($weight)) {
$this->mxRecord = array_combine($mxHosts, $weight) ?: [];
} else {
$this->mxRecord = [];
}
arsort($this->mxRecord);
// Fallback to IPv4 hosts if no MX record found (RFC 2821 SS 5).
if (! $result) {
$result = gethostbynamel($this->hostname);
if (is_array($result)) {
$this->mxRecord = array_flip($result);
}
}
if ($result === false) {
$this->error(self::INVALID_MX_RECORD);
return false;
}
if (! $this->options['useDeepMxCheck']) {
return $result;
}
$validAddress = false;
$reserved = true;
foreach (array_keys($this->mxRecord) as $hostname) {
$res = $this->isReserved($hostname);
if (! $res) {
$reserved = false;
}
if (trim($hostname) === '') {
continue;
}
if (
! $res
&& (checkdnsrr($hostname, 'A')
|| checkdnsrr($hostname, 'AAAA')
|| checkdnsrr($hostname, 'A6'))
) {
$validAddress = true;
break;
}
}
if (! $validAddress) {
$result = false;
$error = $reserved ? self::INVALID_SEGMENT : self::INVALID_MX_RECORD;
$this->error($error);
}
return $result;
}
/**
* Internal method to validate the hostname part of the email address
*
* @return bool|string[]
* @psalm-return bool|list<string>
*/
protected function validateHostnamePart()
{
$hostname = $this->getHostnameValidator()->setTranslator($this->getTranslator())
->isValid($this->hostname);
if (! $hostname) {
$this->error(self::INVALID_HOSTNAME);
// Get messages and errors from hostnameValidator
foreach ($this->getHostnameValidator()->getMessages() as $code => $message) {
$this->abstractOptions['messages'][$code] = $message;
}
} elseif ($this->options['useMxCheck']) {
// MX check on hostname
$hostname = $this->validateMXRecords();
}
return $hostname;
}
/**
* Splits the given value in hostname and local part of the email address
*
* @param string $value Email address to be split
* @return bool Returns false when the email can not be split
*/
protected function splitEmailParts($value)
{
$value = is_string($value) ? $value : '';
// Split email address up and disallow '..'
if (
str_contains($value, '..')
|| ! preg_match('/^(.+)@([^@]+)$/', $value, $matches)
) {
return false;
}
$this->localPart = $matches[1];
$this->hostname = $this->idnToAscii($matches[2]);
return true;
}
/**
* Defined by Laminas\Validator\ValidatorInterface
*
* Returns true if and only if $value is a valid email address
* according to RFC2822
*
* @link http://www.ietf.org/rfc/rfc2822.txt RFC2822
* @link http://www.columbia.edu/kermit/ascii.html US-ASCII characters
*
* @param string $value
* @return bool
*/
public function isValid($value)
{
if (! is_string($value)) {
$this->error(self::INVALID);
return false;
}
$length = true;
$this->setValue($value);
// Split email address up and disallow '..'
if (! $this->splitEmailParts($this->getValue())) {
$this->error(self::INVALID_FORMAT);
return false;
}
if ($this->getOption('strict') && (strlen($this->localPart) > 64) || (strlen($this->hostname) > 255)) {
$length = false;
$this->error(self::LENGTH_EXCEEDED);
}
// Match hostname part
$hostname = false;
if ($this->options['useDomainCheck']) {
$hostname = $this->validateHostnamePart();
}
$local = $this->validateLocalPart();
// If both parts valid, return true
return ($local && $length) && (! $this->options['useDomainCheck'] || $hostname !== false);
}
/**
* Safely convert UTF-8 encoded domain name to ASCII
*
* @param string $email the UTF-8 encoded email
* @return string
*/
protected function idnToAscii($email)
{
if (extension_loaded('intl')) {
if (defined('INTL_IDNA_VARIANT_UTS46')) {
$value = idn_to_ascii($email, 0, INTL_IDNA_VARIANT_UTS46);
return $value !== false ? $value : $email;
}
$value = idn_to_ascii($email);
return $value !== false ? $value : $email;
}
return $email;
}
/**
* Safely convert ASCII encoded domain name to UTF-8
*
* @param string $email the ASCII encoded email
* @return string
*/
protected function idnToUtf8($email)
{
if (strlen($email) === 0) {
return $email;
}
if (extension_loaded('intl')) {
// The documentation does not clarify what kind of failure
// can happen in idn_to_utf8. One can assume if the source
// is not IDN encoded, it would fail, but it usually returns
// the source string in those cases.
// But not when the source string is long enough.
// Thus we default to source string ourselves.
if (defined('INTL_IDNA_VARIANT_UTS46')) {
$value = idn_to_utf8($email, 0, INTL_IDNA_VARIANT_UTS46);
return $value !== false ? $value : $email;
}
$value = idn_to_utf8($email);
return $value !== false ? $value : $email;
}
return $email;
}
}

View File

@@ -1,12 +0,0 @@
<?php
namespace Laminas\Validator\Exception;
/**
* @deprecated This file will be removed in 3.0
*
* @final
*/
class BadMethodCallException extends \BadMethodCallException implements ExceptionInterface
{
}

View File

@@ -1,7 +0,0 @@
<?php
namespace Laminas\Validator\Exception;
interface ExceptionInterface
{
}

View File

@@ -1,12 +0,0 @@
<?php
namespace Laminas\Validator\Exception;
/**
* @deprecated This file will be removed in 3.0
*
* @final
*/
class ExtensionNotLoadedException extends RuntimeException
{
}

View File

@@ -1,7 +0,0 @@
<?php
namespace Laminas\Validator\Exception;
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
}

View File

@@ -1,12 +0,0 @@
<?php
namespace Laminas\Validator\Exception;
/**
* @deprecated Since 2.61.0 - This exception will be removed in 3.0
*
* @final
*/
class InvalidMagicMimeFileException extends InvalidArgumentException
{
}

View File

@@ -1,7 +0,0 @@
<?php
namespace Laminas\Validator\Exception;
class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}

View File

@@ -1,221 +0,0 @@
<?php
namespace Laminas\Validator;
use Laminas\ServiceManager\ServiceManager;
use Laminas\Stdlib\ArrayUtils;
use Traversable;
use function explode;
use function is_array;
use function is_string;
use function sprintf;
/**
* @psalm-import-type ValidatorSpecification from ValidatorInterface
* @final
*/
class Explode extends AbstractValidator implements ValidatorPluginManagerAwareInterface
{
public const INVALID = 'explodeInvalid';
/** @var null|ValidatorPluginManager */
protected $pluginManager;
/** @var array */
protected $messageTemplates = [
self::INVALID => 'Invalid type given',
];
/** @var array */
protected $messageVariables = [];
/** @var non-empty-string */
protected $valueDelimiter = ',';
/** @var ValidatorInterface|null */
protected $validator;
/** @var bool */
protected $breakOnFirstFailure = false;
/**
* Sets the delimiter string that the values will be split upon
*
* @deprecated Since 2.60.0 all option setters and getters are deprecated for removal in 3.0
*
* @param non-empty-string $delimiter
* @return $this
*/
public function setValueDelimiter($delimiter)
{
$this->valueDelimiter = $delimiter;
return $this;
}
/**
* Returns the delimiter string that the values will be split upon
*
* @deprecated Since 2.60.0 all option setters and getters are deprecated for removal in 3.0
*
* @return non-empty-string
*/
public function getValueDelimiter()
{
return $this->valueDelimiter;
}
/**
* Set validator plugin manager
*
* @deprecated Since 2.60.0 all option setters and getters are deprecated for removal in 3.0
*
* @return void
*/
public function setValidatorPluginManager(ValidatorPluginManager $pluginManager)
{
$this->pluginManager = $pluginManager;
}
/**
* Get validator plugin manager
*
* @deprecated Since 2.60.0 all option setters and getters are deprecated for removal in 3.0
*
* @return ValidatorPluginManager
*/
public function getValidatorPluginManager()
{
if (! $this->pluginManager) {
$this->pluginManager = new ValidatorPluginManager(new ServiceManager());
}
return $this->pluginManager;
}
/**
* Sets the Validator for validating each value
*
* @deprecated Since 2.60.0 all option setters and getters are deprecated for removal in 3.0
*
* @param ValidatorInterface|ValidatorSpecification $validator
* @return $this
* @throws Exception\RuntimeException
*/
public function setValidator($validator)
{
if (is_array($validator)) {
if (! isset($validator['name'])) {
throw new Exception\RuntimeException(
'Invalid validator specification provided; does not include "name" key'
);
}
$name = $validator['name'];
$options = $validator['options'] ?? [];
/** @psalm-suppress MixedAssignment $validator */
$validator = $this->getValidatorPluginManager()->get($name, $options);
}
if (! $validator instanceof ValidatorInterface) {
throw new Exception\RuntimeException(
'Invalid validator given'
);
}
$this->validator = $validator;
return $this;
}
/**
* Gets the Validator for validating each value
*
* @deprecated Since 2.60.0 all option setters and getters are deprecated for removal in 3.0
*
* @return ValidatorInterface|null
*/
public function getValidator()
{
return $this->validator;
}
/**
* Set break on first failure setting
*
* @deprecated Since 2.60.0 all option setters and getters are deprecated for removal in 3.0
*
* @param bool $break
* @return $this
*/
public function setBreakOnFirstFailure($break)
{
$this->breakOnFirstFailure = (bool) $break;
return $this;
}
/**
* Get break on first failure setting
*
* @deprecated Since 2.60.0 all option setters and getters are deprecated for removal in 3.0
*
* @return bool
*/
public function isBreakOnFirstFailure()
{
return $this->breakOnFirstFailure;
}
/**
* Defined by Laminas\Validator\ValidatorInterface
*
* Returns true if all values validate true
*
* @param mixed $value
* @param mixed $context Extra "context" to provide the composed validator
* @return bool
* @throws Exception\RuntimeException
*/
public function isValid($value, $context = null)
{
$this->setValue($value);
if ($value instanceof Traversable) {
$value = ArrayUtils::iteratorToArray($value);
}
if (is_array($value)) {
$values = $value;
} elseif (is_string($value)) {
$delimiter = $this->getValueDelimiter();
// Skip explode if delimiter is null,
// used when value is expected to be either an
// array when multiple values and a string for
// single values (ie. MultiCheckbox form behavior)
$values = null !== $delimiter
? explode($this->valueDelimiter, $value)
: [$value];
} else {
$values = [$value];
}
$validator = $this->getValidator();
if (! $validator) {
throw new Exception\RuntimeException(sprintf(
'%s expects a validator to be set; none given',
__METHOD__
));
}
foreach ($values as $value) {
if (! $validator->isValid($value, $context)) {
$this->abstractOptions['messages'][] = $validator->getMessages();
if ($this->isBreakOnFirstFailure()) {
return false;
}
}
}
return $this->abstractOptions['messages'] === [];
}
}

View File

@@ -1,294 +0,0 @@
<?php
namespace Laminas\Validator\File;
use Laminas\Validator\AbstractValidator;
use Laminas\Validator\Exception;
use Psr\Http\Message\UploadedFileInterface;
use Traversable;
use function array_key_exists;
use function array_shift;
use function count;
use function dirname;
use function func_get_args;
use function func_num_args;
use function is_array;
use function is_numeric;
use function is_string;
use const DIRECTORY_SEPARATOR;
/**
* Validator for counting all given files
*
* @final
*/
class Count extends AbstractValidator
{
/**#@+
*
* @const string Error constants
*/
public const TOO_MANY = 'fileCountTooMany';
public const TOO_FEW = 'fileCountTooFew';
/**#@-*/
/** @var array Error message templates */
protected $messageTemplates = [
self::TOO_MANY => "Too many files, maximum '%max%' are allowed but '%count%' are given",
self::TOO_FEW => "Too few files, minimum '%min%' are expected but '%count%' are given",
];
/** @var array Error message template variables */
protected $messageVariables = [
'min' => ['options' => 'min'],
'max' => ['options' => 'max'],
'count' => 'count',
];
/**
* Actual filecount
*
* @var int
*/
protected $count;
/**
* Internal file array
*
* @var array
*/
protected $files;
/**
* Options for this validator
*
* @var array
*/
protected $options = [
'min' => null, // Minimum file count, if null there is no minimum file count
'max' => null, // Maximum file count, if null there is no maximum file count
];
/**
* Sets validator options
*
* Min limits the file count, when used with max=null it is the maximum file count
* It also accepts an array with the keys 'min' and 'max'
*
* If $options is an integer, it will be used as maximum file count
* As Array is accepts the following keys:
* 'min': Minimum filecount
* 'max': Maximum filecount
*
* @param int|array|Traversable $options Options for the adapter
*/
public function __construct($options = null)
{
if (1 < func_num_args()) {
$args = func_get_args();
$options = [
'min' => array_shift($args),
'max' => array_shift($args),
];
}
if (is_string($options) || is_numeric($options)) {
$options = ['max' => $options];
}
parent::__construct($options);
}
/**
* Returns the minimum file count
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @return int
*/
public function getMin()
{
return $this->options['min'];
}
/**
* Sets the minimum file count
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param int|array $min The minimum file count
* @return $this Provides a fluent interface
* @throws Exception\InvalidArgumentException When min is greater than max.
*/
public function setMin($min)
{
if (is_array($min) && isset($min['min'])) {
$min = $min['min'];
}
if (! is_numeric($min)) {
throw new Exception\InvalidArgumentException('Invalid options to validator provided');
}
$min = (int) $min;
if (($this->getMax() !== null) && ($min > $this->getMax())) {
throw new Exception\InvalidArgumentException(
"The minimum must be less than or equal to the maximum file count, but {$min} > {$this->getMax()}"
);
}
$this->options['min'] = $min;
return $this;
}
/**
* Returns the maximum file count
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @return int
*/
public function getMax()
{
return $this->options['max'];
}
/**
* Sets the maximum file count
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param int|array $max The maximum file count
* @return $this Provides a fluent interface
* @throws Exception\InvalidArgumentException When max is smaller than min.
*/
public function setMax($max)
{
if (is_array($max) && isset($max['max'])) {
$max = $max['max'];
}
if (! is_numeric($max)) {
throw new Exception\InvalidArgumentException('Invalid options to validator provided');
}
$max = (int) $max;
if (($this->getMin() !== null) && ($max < $this->getMin())) {
throw new Exception\InvalidArgumentException(
"The maximum must be greater than or equal to the minimum file count, but {$max} < {$this->getMin()}"
);
}
$this->options['max'] = $max;
return $this;
}
/**
* Adds a file for validation
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param string|array|UploadedFileInterface $file
* @return $this
*/
public function addFile($file)
{
if (is_string($file)) {
$file = [$file];
}
if (is_array($file)) {
foreach ($file as $name) {
if (! isset($this->files[$name]) && ! empty($name)) {
$this->files[$name] = $name;
}
}
}
if ($file instanceof UploadedFileInterface && is_string($file->getClientFilename())) {
$this->files[(string) $file->getClientFilename()] = $file->getClientFilename();
}
return $this;
}
/**
* Returns true if and only if the file count of all checked files is at least min and
* not bigger than max (when max is not null). Attention: When checking with set min you
* must give all files with the first call, otherwise you will get a false.
*
* @param string|array|UploadedFileInterface $value Filenames to check for count
* @param array $file File data from \Laminas\File\Transfer\Transfer
* @return bool
*/
public function isValid($value, $file = null)
{
if ($this->isUploadedFilterInterface($value)) {
$this->addFile($value);
} elseif ($file !== null) {
if (! array_key_exists('destination', $file)) {
$file['destination'] = dirname($value);
}
if (array_key_exists('tmp_name', $file)) {
$value = $file['destination'] . DIRECTORY_SEPARATOR . $file['name'];
}
}
if (($file === null) || ! empty($file['tmp_name'])) {
$this->addFile($value);
}
$this->count = count($this->files);
if (($this->getMax() !== null) && ($this->count > $this->getMax())) {
return $this->throwError($file, self::TOO_MANY);
}
if (($this->getMin() !== null) && ($this->count < $this->getMin())) {
return $this->throwError($file, self::TOO_FEW);
}
return true;
}
/**
* Throws an error of the given type
*
* @param string|null|array $file
* @param string $errorType
* @return false
*/
protected function throwError($file, $errorType)
{
if ($file !== null) {
if (is_array($file)) {
if (array_key_exists('name', $file)) {
$this->value = $file['name'];
}
} elseif (is_string($file)) {
$this->value = $file;
}
}
$this->error($errorType);
return false;
}
/**
* Checks if the type of uploaded file is UploadedFileInterface.
*
* @param string|array|UploadedFileInterface $value Filenames to check for count
* @return bool
*/
private function isUploadedFilterInterface($value)
{
if ($value instanceof UploadedFileInterface) {
return true;
}
return false;
}
}

View File

@@ -1,120 +0,0 @@
<?php
namespace Laminas\Validator\File;
use function array_keys;
use function array_unique;
use function hash_file;
use function is_readable;
/**
* Validator for the crc32 hash of given files
*
* @deprecated Since 2.61.0 Use the {@link Hash} validator and specify `cr32` as the algorithm
*
* @final
*/
class Crc32 extends Hash
{
use FileInformationTrait;
/**
* @const string Error constants
*/
public const DOES_NOT_MATCH = 'fileCrc32DoesNotMatch';
public const NOT_DETECTED = 'fileCrc32NotDetected';
public const NOT_FOUND = 'fileCrc32NotFound';
/** @var array Error message templates */
protected $messageTemplates = [
self::DOES_NOT_MATCH => 'File does not match the given crc32 hashes',
self::NOT_DETECTED => 'A crc32 hash could not be evaluated for the given file',
self::NOT_FOUND => 'File is not readable or does not exist',
];
/**
* Options for this validator
*
* @var string
*/
protected $options = [
'algorithm' => 'crc32',
'hash' => null,
];
/**
* Returns all set crc32 hashes
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @return array
*/
public function getCrc32()
{
return $this->getHash();
}
/**
* Sets the crc32 hash for one or multiple files
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param string|array $options
* @return $this Provides a fluent interface
*/
public function setCrc32($options)
{
$this->setHash($options);
return $this;
}
/**
* Adds the crc32 hash for one or multiple files
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param string|array $options
* @return $this Provides a fluent interface
*/
public function addCrc32($options)
{
$this->addHash($options);
return $this;
}
/**
* Returns true if and only if the given file confirms the set hash
*
* @param string|array $value Filename to check for hash
* @param array $file File data from \Laminas\File\Transfer\Transfer (optional)
* @return bool
*/
public function isValid($value, $file = null)
{
$fileInfo = $this->getFileInfo($value, $file);
$this->setValue($fileInfo['filename']);
// Is file readable ?
if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) {
$this->error(self::NOT_FOUND);
return false;
}
$hashes = array_unique(array_keys($this->getHash()));
$filehash = hash_file('crc32', $fileInfo['file']);
if ($filehash === false) {
$this->error(self::NOT_DETECTED);
return false;
}
foreach ($hashes as $hash) {
if ($filehash === $hash) {
return true;
}
}
$this->error(self::DOES_NOT_MATCH);
return false;
}
}

View File

@@ -1,74 +0,0 @@
<?php
namespace Laminas\Validator\File;
use function in_array;
use function is_readable;
use function strrpos;
use function strtolower;
use function substr;
/**
* Validator for the excluding file extensions
*
* @final
*/
class ExcludeExtension extends Extension
{
use FileInformationTrait;
/**
* @const string Error constants
*/
public const FALSE_EXTENSION = 'fileExcludeExtensionFalse';
public const NOT_FOUND = 'fileExcludeExtensionNotFound';
/** @var array Error message templates */
protected $messageTemplates = [
self::FALSE_EXTENSION => 'File has an incorrect extension',
self::NOT_FOUND => 'File is not readable or does not exist',
];
/**
* Returns true if and only if the file extension of $value is not included in the
* set extension list
*
* @param string|array $value Real file to check for extension
* @param array $file File data from \Laminas\File\Transfer\Transfer (optional)
* @return bool
*/
public function isValid($value, $file = null)
{
$fileInfo = $this->getFileInfo($value, $file);
// Is file readable ?
if (
! $this->getAllowNonExistentFile()
&& (empty($fileInfo['file']) || false === is_readable($fileInfo['file']))
) {
$this->error(self::NOT_FOUND);
return false;
}
$this->setValue($fileInfo['filename']);
$extension = substr($fileInfo['filename'], strrpos($fileInfo['filename'], '.') + 1);
$extensions = $this->getExtension();
if ($this->getCase() && (! in_array($extension, $extensions))) {
return true;
} elseif (! $this->getCase()) {
foreach ($extensions as $ext) {
if (strtolower($ext) === strtolower($extension)) {
$this->error(self::FALSE_EXTENSION);
return false;
}
}
return true;
}
$this->error(self::FALSE_EXTENSION);
return false;
}
}

View File

@@ -1,102 +0,0 @@
<?php
namespace Laminas\Validator\File;
use Psr\Http\Message\UploadedFileInterface;
use function array_merge;
use function class_exists;
use function explode;
use function finfo_file;
use function finfo_open;
use function in_array;
use function is_readable;
use function is_string;
use const FILEINFO_MIME_TYPE;
/**
* Validator for the mime type of a file
*
* @final
*/
class ExcludeMimeType extends MimeType
{
use FileInformationTrait;
public const FALSE_TYPE = 'fileExcludeMimeTypeFalse';
public const NOT_DETECTED = 'fileExcludeMimeTypeNotDetected';
public const NOT_READABLE = 'fileExcludeMimeTypeNotReadable';
/** @inheritDoc */
protected $messageTemplates = [
self::FALSE_TYPE => "File has an incorrect mimetype of '%type%'",
self::NOT_DETECTED => 'The mimetype could not be detected from the file',
self::NOT_READABLE => 'File is not readable or does not exist',
];
/**
* Returns true if the mimetype of the file does not matche the given ones. Also parts
* of mimetypes can be checked. If you give for example "image" all image
* mime types will not be accepted like "image/gif", "image/jpeg" and so on.
*
* @param string|array|UploadedFileInterface $value Real file to check for mimetype
* @param array $file File data from \Laminas\File\Transfer\Transfer (optional)
* @return bool
*/
public function isValid($value, $file = null)
{
$fileInfo = $this->getFileInfo($value, $file, true);
$this->setValue($fileInfo['filename']);
// Is file readable ?
if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) {
$this->error(self::NOT_READABLE);
return false;
}
$mimefile = $this->getMagicFile();
if (class_exists('finfo', false)) {
if (! $this->isMagicFileDisabled() && (is_string($mimefile) && empty($this->finfo))) {
$this->finfo = finfo_open(FILEINFO_MIME_TYPE, $mimefile);
}
if (empty($this->finfo)) {
$this->finfo = finfo_open(FILEINFO_MIME_TYPE);
}
$this->type = null;
if (! empty($this->finfo)) {
$this->type = finfo_file($this->finfo, $fileInfo['file']);
}
}
if (! is_string($this->type) && $this->getHeaderCheck()) {
$this->type = $fileInfo['filetype'];
}
if (! is_string($this->type)) {
$this->error(self::NOT_DETECTED);
return false;
}
$mimetype = $this->getMimeType(true);
if (in_array($this->type, $mimetype)) {
$this->error(self::FALSE_TYPE);
return false;
}
$types = explode('/', $this->type);
$types = array_merge($types, explode('-', $this->type));
$types = array_merge($types, explode(';', $this->type));
foreach ($mimetype as $mime) {
if (in_array($mime, $types)) {
$this->error(self::FALSE_TYPE);
return false;
}
}
return true;
}
}

View File

@@ -1,189 +0,0 @@
<?php
namespace Laminas\Validator\File;
use Laminas\Validator\AbstractValidator;
use Laminas\Validator\Exception;
use Traversable;
use function array_key_exists;
use function array_unique;
use function explode;
use function file_exists;
use function implode;
use function is_array;
use function is_string;
use function trim;
use const DIRECTORY_SEPARATOR;
/**
* Validator which checks if the file already exists in the directory
*/
class Exists extends AbstractValidator
{
use FileInformationTrait;
/**
* @const string Error constants
*/
public const DOES_NOT_EXIST = 'fileExistsDoesNotExist';
/** @var array Error message templates */
protected $messageTemplates = [
self::DOES_NOT_EXIST => 'File does not exist',
];
/**
* Options for this validator
*
* @var array
*/
protected $options = [
'directory' => null, // internal list of directories
];
/** @var array Error message template variables */
protected $messageVariables = [
'directory' => ['options' => 'directory'],
];
/**
* Sets validator options
*
* @param string|array|Traversable $options
*/
public function __construct($options = null)
{
if (is_string($options)) {
$options = explode(',', $options);
}
if (is_array($options) && ! array_key_exists('directory', $options)) {
$options = ['directory' => $options];
}
parent::__construct($options);
}
/**
* Returns the set file directories which are checked
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param bool $asArray Returns the values as array; when false, a concatenated string is returned
* @return string|null
*/
public function getDirectory($asArray = false)
{
$asArray = (bool) $asArray;
$directory = $this->options['directory'];
if ($asArray && isset($directory)) {
$directory = explode(',', (string) $directory);
}
return $directory;
}
/**
* Sets the file directory which will be checked
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param string|array $directory The directories to validate
* @return self Provides a fluent interface
*/
public function setDirectory($directory)
{
$this->options['directory'] = null;
$this->addDirectory($directory);
return $this;
}
/**
* Adds the file directory which will be checked
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param string|array $directory The directory to add for validation
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function addDirectory($directory)
{
$directories = $this->getDirectory(true);
if (! isset($directories)) {
$directories = [];
}
if (is_string($directory)) {
$directory = explode(',', $directory);
} elseif (! is_array($directory)) {
throw new Exception\InvalidArgumentException('Invalid options to validator provided');
}
foreach ($directory as $content) {
if (empty($content) || ! is_string($content)) {
continue;
}
$directories[] = trim($content);
}
$directories = array_unique($directories);
// Sanity check to ensure no empty values
foreach ($directories as $key => $dir) {
if (empty($dir)) {
unset($directories[$key]);
}
}
$this->options['directory'] = ! empty($directory)
? implode(',', $directories) : null;
return $this;
}
/**
* Returns true if and only if the file already exists in the set directories
*
* @param string|array $value Real file to check for existence
* @param array $file File data from \Laminas\File\Transfer\Transfer (optional)
* @return bool
*/
public function isValid($value, $file = null)
{
$fileInfo = $this->getFileInfo($value, $file, false, true);
$this->setValue($fileInfo['filename']);
$check = false;
$directories = $this->getDirectory(true);
if (! isset($directories)) {
$check = true;
if (! file_exists($fileInfo['file'])) {
$this->error(self::DOES_NOT_EXIST);
return false;
}
} else {
foreach ($directories as $directory) {
if (! isset($directory) || '' === $directory) {
continue;
}
$check = true;
if (! file_exists($directory . DIRECTORY_SEPARATOR . $fileInfo['basename'])) {
$this->error(self::DOES_NOT_EXIST);
return false;
}
}
}
if (! $check) {
$this->error(self::DOES_NOT_EXIST);
return false;
}
return true;
}
}

View File

@@ -1,256 +0,0 @@
<?php
namespace Laminas\Validator\File;
use Laminas\Stdlib\ArrayUtils;
use Laminas\Validator\AbstractValidator;
use Traversable;
use function array_key_exists;
use function array_unique;
use function explode;
use function func_get_arg;
use function func_num_args;
use function implode;
use function in_array;
use function is_array;
use function is_readable;
use function is_string;
use function strrpos;
use function strtolower;
use function substr;
use function trim;
/**
* Validator for the file extension of a file
*/
class Extension extends AbstractValidator
{
use FileInformationTrait;
/**
* @const string Error constants
*/
public const FALSE_EXTENSION = 'fileExtensionFalse';
public const NOT_FOUND = 'fileExtensionNotFound';
/** @var array<string, string> Error message templates */
protected $messageTemplates = [
self::FALSE_EXTENSION => 'File has an incorrect extension',
self::NOT_FOUND => 'File is not readable or does not exist',
];
/**
* Options for this validator
*
* @var array
*/
protected $options = [
'case' => false, // Validate case sensitive
'extension' => '', // List of extensions
'allowNonExistentFile' => false, // Allow validation even if file does not exist
];
/** @var array Error message template variables */
protected $messageVariables = [
'extension' => ['options' => 'extension'],
];
/**
* Sets validator options
*
* @param string|array|Traversable $options
*/
public function __construct($options = null)
{
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
}
$case = null;
if (1 < func_num_args()) {
$case = func_get_arg(1);
}
if (is_array($options)) {
if (isset($options['case'])) {
$case = $options['case'];
unset($options['case']);
}
if (! array_key_exists('extension', $options)) {
$options = ['extension' => $options];
}
} else {
$options = ['extension' => $options];
}
if ($case !== null) {
$options['case'] = $case;
}
parent::__construct($options);
}
/**
* Returns the case option
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @return bool
*/
public function getCase()
{
return $this->options['case'];
}
/**
* Sets the case to use
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param bool $case
* @return $this Provides a fluent interface
*/
public function setCase($case)
{
$this->options['case'] = (bool) $case;
return $this;
}
/**
* Returns the set file extension
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @return array
*/
public function getExtension()
{
if (
! array_key_exists('extension', $this->options)
|| ! is_string($this->options['extension'])
) {
return [];
}
return explode(',', $this->options['extension']);
}
/**
* Sets the file extensions
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param string|array $extension The extensions to validate
* @return $this Provides a fluent interface
*/
public function setExtension($extension)
{
$this->options['extension'] = null;
$this->addExtension($extension);
return $this;
}
/**
* Adds the file extensions
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param string|array $extension The extensions to add for validation
* @return $this Provides a fluent interface
*/
public function addExtension($extension)
{
$extensions = $this->getExtension();
if (is_string($extension)) {
$extension = explode(',', $extension);
}
foreach ($extension as $content) {
if (empty($content) || ! is_string($content)) {
continue;
}
$extensions[] = trim($content);
}
$extensions = array_unique($extensions);
// Sanity check to ensure no empty values
foreach ($extensions as $key => $ext) {
if (empty($ext)) {
unset($extensions[$key]);
}
}
$this->options['extension'] = implode(',', $extensions);
return $this;
}
/**
* Returns whether or not to allow validation of non-existent files.
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @return bool
*/
public function getAllowNonExistentFile()
{
return $this->options['allowNonExistentFile'];
}
/**
* Sets the flag indicating whether or not to allow validation of non-existent files.
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param bool $flag Whether or not to allow validation of non-existent files.
* @return $this Provides a fluent interface
*/
public function setAllowNonExistentFile($flag)
{
$this->options['allowNonExistentFile'] = (bool) $flag;
return $this;
}
/**
* Returns true if and only if the file extension of $value is included in the
* set extension list
*
* @param string|array $value Real file to check for extension
* @param array $file File data from \Laminas\File\Transfer\Transfer (optional)
* @return bool
*/
public function isValid($value, $file = null)
{
$fileInfo = $this->getFileInfo($value, $file);
// Is file readable ?
if (
! $this->getAllowNonExistentFile()
&& (empty($fileInfo['file']) || false === is_readable($fileInfo['file']))
) {
$this->error(self::NOT_FOUND);
return false;
}
$this->setValue($fileInfo['filename']);
$extension = substr($fileInfo['filename'], strrpos($fileInfo['filename'], '.') + 1);
$extensions = $this->getExtension();
if ($this->getCase() && (in_array($extension, $extensions))) {
return true;
} elseif (! $this->getCase()) {
foreach ($extensions as $ext) {
if (strtolower($ext) === strtolower($extension)) {
return true;
}
}
}
$this->error(self::FALSE_EXTENSION);
return false;
}
}

View File

@@ -1,167 +0,0 @@
<?php
namespace Laminas\Validator\File;
use Laminas\Validator\Exception;
use Psr\Http\Message\UploadedFileInterface;
use function basename;
use function is_array;
use function is_string;
/**
* @deprecated Since 2.61.0 - This internal trait will be removed in 3.0
*/
trait FileInformationTrait
{
/**
* Returns array if the procedure is identified
*
* @param string|array|object $value Filename to check
* @param null|array $file File data (when using legacy Laminas_File_Transfer API)
* @param bool $hasType Return with filetype (optional)
* @param bool $hasBasename Return with basename - is calculated from location path (optional)
* @return array
*/
protected function getFileInfo(
$value,
?array $file = null,
$hasType = false,
$hasBasename = false
) {
if (is_string($value) && is_array($file)) {
return $this->getLegacyFileInfo($file, $hasType, $hasBasename);
}
if (is_array($value)) {
return $this->getSapiFileInfo($value, $hasType, $hasBasename);
}
if ($value instanceof UploadedFileInterface) {
return $this->getPsr7FileInfo($value, $hasType, $hasBasename);
}
return $this->getFileBasedFileInfo($value, $hasType, $hasBasename);
}
/**
* Generate file information array with legacy Laminas_File_Transfer API
*
* @param array $file File data
* @param bool $hasType Return with filetype
* @param bool $hasBasename Basename is calculated from location path
* @return array
*/
private function getLegacyFileInfo(
array $file,
$hasType = false,
$hasBasename = false
) {
$fileInfo = [];
$fileInfo['filename'] = $file['name'];
$fileInfo['file'] = $file['tmp_name'];
if ($hasBasename) {
$fileInfo['basename'] = basename($fileInfo['file']);
}
if ($hasType) {
$fileInfo['filetype'] = $file['type'];
}
return $fileInfo;
}
/**
* Generate file information array with SAPI
*
* @param array $file File data from SAPI
* @param bool $hasType Return with filetype
* @param bool $hasBasename Filename is calculated from location path
* @return array
*/
private function getSapiFileInfo(
array $file,
$hasType = false,
$hasBasename = false
) {
if (! isset($file['tmp_name']) || ! isset($file['name'])) {
throw new Exception\InvalidArgumentException(
'Value array must be in $_FILES format'
);
}
$fileInfo = [];
$fileInfo['file'] = $file['tmp_name'];
$fileInfo['filename'] = $file['name'];
if ($hasBasename) {
$fileInfo['basename'] = basename($fileInfo['file']);
}
if ($hasType) {
$fileInfo['filetype'] = $file['type'];
}
return $fileInfo;
}
/**
* Generate file information array with PSR-7 UploadedFileInterface
*
* @param bool $hasType Return with filetype
* @param bool $hasBasename Filename is calculated from location path
* @return array
*/
private function getPsr7FileInfo(
UploadedFileInterface $file,
$hasType = false,
$hasBasename = false
) {
$fileInfo = [];
$fileInfo['file'] = $file->getStream()->getMetadata('uri');
$fileInfo['filename'] = $file->getClientFilename();
if ($hasBasename) {
$fileInfo['basename'] = basename($fileInfo['file']);
}
if ($hasType) {
$fileInfo['filetype'] = $file->getClientMediaType();
}
return $fileInfo;
}
/**
* Generate file information array with base method
*
* @param string $file File path
* @param bool $hasType Return with filetype
* @param bool $hasBasename Filename is calculated from location path
* @return array
*/
private function getFileBasedFileInfo(
$file,
$hasType = false,
$hasBasename = false
) {
$fileInfo = [];
$fileInfo['file'] = $file;
$fileInfo['filename'] = basename($fileInfo['file']);
if ($hasBasename) {
$fileInfo['basename'] = basename($fileInfo['file']);
}
if ($hasType) {
$fileInfo['filetype'] = null;
}
return $fileInfo;
}
}

View File

@@ -1,186 +0,0 @@
<?php
namespace Laminas\Validator\File;
use Laminas\Stdlib\ArrayUtils;
use Laminas\Stdlib\ErrorHandler;
use Laminas\Validator\Exception;
use Laminas\Validator\Exception\InvalidArgumentException;
use Traversable;
use function array_key_exists;
use function array_shift;
use function filesize;
use function func_get_args;
use function func_num_args;
use function is_array;
use function is_readable;
use function is_scalar;
use function is_string;
/**
* Validator for the size of all files which will be validated in sum
*
* @final
*/
class FilesSize extends Size
{
/**
* @const string Error constants
*/
public const TOO_BIG = 'fileFilesSizeTooBig';
public const TOO_SMALL = 'fileFilesSizeTooSmall';
public const NOT_READABLE = 'fileFilesSizeNotReadable';
/** @var array Error message templates */
protected $messageTemplates = [
self::TOO_BIG => "All files in sum should have a maximum size of '%max%' but '%size%' were detected",
self::TOO_SMALL => "All files in sum should have a minimum size of '%min%' but '%size%' were detected",
self::NOT_READABLE => 'One or more files can not be read',
];
/**
* Internal file array
*
* @var array
*/
protected $files;
/**
* Sets validator options
*
* Min limits the used disk space for all files, when used with max=null it is the maximum file size
* It also accepts an array with the keys 'min' and 'max'
*
* @param int|array|Traversable $options Options for this validator
* @throws InvalidArgumentException
*/
public function __construct($options = null)
{
$this->files = [];
$this->setSize(0);
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
} elseif (is_scalar($options)) {
$options = ['max' => $options];
} elseif (! is_array($options)) {
throw new Exception\InvalidArgumentException('Invalid options to validator provided');
}
if (1 < func_num_args()) {
$argv = func_get_args();
array_shift($argv);
$options['max'] = array_shift($argv);
if (! empty($argv)) {
$options['useByteString'] = array_shift($argv);
}
}
parent::__construct($options);
}
/**
* Returns true if and only if the disk usage of all files is at least min and
* not bigger than max (when max is not null).
*
* @param string|array $value Real file to check for size
* @param array $file File data from \Laminas\File\Transfer\Transfer
* @return bool
*/
public function isValid($value, $file = null)
{
if (is_string($value)) {
$value = [$value];
} elseif (is_array($value) && isset($value['tmp_name'])) {
$value = [$value];
}
$min = $this->getMin(true);
$max = $this->getMax(true);
$size = $this->getSize();
foreach ($value as $files) {
if (is_array($files)) {
if (! isset($files['tmp_name']) || ! isset($files['name'])) {
throw new Exception\InvalidArgumentException(
'Value array must be in $_FILES format'
);
}
$file = $files;
$files = $files['tmp_name'];
}
// Is file readable ?
if (empty($files) || false === is_readable($files)) {
$this->throwError($file, self::NOT_READABLE);
continue;
}
if (! isset($this->files[$files])) {
$this->files[$files] = $files;
} else {
// file already counted... do not count twice
continue;
}
// limited to 2GB files
ErrorHandler::start();
$size += filesize($files);
ErrorHandler::stop();
$this->size = $size;
if (($max !== null) && ($max < $size)) {
if ($this->getByteString()) {
$this->options['max'] = $this->toByteString($max);
$this->size = $this->toByteString($size);
$this->throwError($file, self::TOO_BIG);
$this->options['max'] = $max;
$this->size = $size;
} else {
$this->throwError($file, self::TOO_BIG);
}
}
}
// Check that aggregate files are >= minimum size
if (($min !== null) && ($size < $min)) {
if ($this->getByteString()) {
$this->options['min'] = $this->toByteString($min);
$this->size = $this->toByteString($size);
$this->throwError($file, self::TOO_SMALL);
$this->options['min'] = $min;
$this->size = $size;
} else {
$this->throwError($file, self::TOO_SMALL);
}
}
if ($this->getMessages()) {
return false;
}
return true;
}
/**
* Throws an error of the given type
*
* @param string|null|array $file
* @param string $errorType
* @return false
*/
protected function throwError($file, $errorType)
{
if ($file !== null) {
if (is_array($file)) {
if (array_key_exists('name', $file)) {
$this->value = $file['name'];
}
} elseif (is_string($file)) {
$this->value = $file;
}
}
$this->error($errorType);
return false;
}
}

View File

@@ -1,187 +0,0 @@
<?php
namespace Laminas\Validator\File;
use Laminas\Validator\AbstractValidator;
use Laminas\Validator\Exception;
use function array_key_exists;
use function array_unique;
use function array_values;
use function func_get_arg;
use function func_num_args;
use function get_debug_type;
use function hash_algos;
use function hash_file;
use function in_array;
use function is_array;
use function is_readable;
use function is_scalar;
use function is_string;
use function sprintf;
/**
* Validator for the hash of given files
*/
class Hash extends AbstractValidator
{
use FileInformationTrait;
/**
* @const string Error constants
*/
public const DOES_NOT_MATCH = 'fileHashDoesNotMatch';
public const NOT_DETECTED = 'fileHashHashNotDetected';
public const NOT_FOUND = 'fileHashNotFound';
/** @var array Error message templates */
protected $messageTemplates = [
self::DOES_NOT_MATCH => 'File does not match the given hashes',
self::NOT_DETECTED => 'A hash could not be evaluated for the given file',
self::NOT_FOUND => 'File is not readable or does not exist',
];
/**
* Options for this validator
*
* @var string
*/
protected $options = [
'algorithm' => 'crc32',
'hash' => null,
];
/**
* Sets validator options
*
* @param string|array $options
*/
public function __construct($options = null)
{
if (
is_scalar($options) ||
(is_array($options) && ! array_key_exists('hash', $options))
) {
$options = ['hash' => $options];
}
if (1 < func_num_args()) {
$options['algorithm'] = func_get_arg(1);
}
// The combination of parent and local logic requires us to have the "algorithm" key before the "hash" key
// in the array, or else the default algorithm will be used instead of the passed one.
if (isset($options['algorithm'])) {
$options = ['algorithm' => $options['algorithm']] + $options;
}
parent::__construct($options);
}
/**
* Returns the set hash values as array, the hash as key and the algorithm the value
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @return array
*/
public function getHash()
{
return $this->options['hash'];
}
/**
* Sets the hash for one or multiple files
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param string|array $options
* @return $this Provides a fluent interface
*/
public function setHash($options)
{
$this->options['hash'] = null;
$this->addHash($options);
return $this;
}
/**
* Adds the hash for one or multiple files
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param string|array $options
* @return $this Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function addHash($options)
{
if (is_string($options)) {
$options = [$options];
} elseif (! is_array($options)) {
throw new Exception\InvalidArgumentException('False parameter given');
}
$known = hash_algos();
if (! isset($options['algorithm'])) {
$algorithm = $this->options['algorithm'];
} else {
$algorithm = $options['algorithm'];
unset($options['algorithm']);
}
if (! in_array($algorithm, $known)) {
throw new Exception\InvalidArgumentException("Unknown algorithm '{$algorithm}'");
}
foreach ($options as $value) {
if (! is_string($value)) {
throw new Exception\InvalidArgumentException(sprintf(
'Hash must be a string, %s received',
get_debug_type($value)
));
}
$this->options['hash'][$value] = $algorithm;
}
return $this;
}
/**
* Returns true if and only if the given file confirms the set hash
*
* @param string|array $value File to check for hash
* @param array $file File data from \Laminas\File\Transfer\Transfer (optional)
* @return bool
*/
public function isValid($value, $file = null)
{
$fileInfo = $this->getFileInfo($value, $file);
$this->setValue($fileInfo['filename']);
// Is file readable ?
if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) {
$this->error(self::NOT_FOUND);
return false;
}
$algos = array_unique(array_values($this->getHash()));
foreach ($algos as $algorithm) {
$filehash = hash_file($algorithm, $fileInfo['file']);
if ($filehash === false) {
$this->error(self::NOT_DETECTED);
return false;
}
if (isset($this->getHash()[$filehash]) && $this->getHash()[$filehash] === $algorithm) {
return true;
}
}
$this->error(self::DOES_NOT_MATCH);
return false;
}
}

View File

@@ -1,407 +0,0 @@
<?php
namespace Laminas\Validator\File;
use Laminas\Stdlib\ErrorHandler;
use Laminas\Validator\AbstractValidator;
use Laminas\Validator\Exception;
use Traversable;
use function array_shift;
use function func_get_args;
use function func_num_args;
use function getimagesize;
use function is_array;
use function is_readable;
/**
* Validator for the image size of an image file
*
* @final
*/
class ImageSize extends AbstractValidator
{
use FileInformationTrait;
/**
* @const string Error constants
*/
public const WIDTH_TOO_BIG = 'fileImageSizeWidthTooBig';
public const WIDTH_TOO_SMALL = 'fileImageSizeWidthTooSmall';
public const HEIGHT_TOO_BIG = 'fileImageSizeHeightTooBig';
public const HEIGHT_TOO_SMALL = 'fileImageSizeHeightTooSmall';
public const NOT_DETECTED = 'fileImageSizeNotDetected';
public const NOT_READABLE = 'fileImageSizeNotReadable';
/** @var array Error message template */
protected $messageTemplates = [
self::WIDTH_TOO_BIG => "Maximum allowed width for image should be '%maxwidth%' but '%width%' detected",
self::WIDTH_TOO_SMALL => "Minimum expected width for image should be '%minwidth%' but '%width%' detected",
self::HEIGHT_TOO_BIG => "Maximum allowed height for image should be '%maxheight%' but '%height%' detected",
self::HEIGHT_TOO_SMALL => "Minimum expected height for image should be '%minheight%' but '%height%' detected",
self::NOT_DETECTED => 'The size of image could not be detected',
self::NOT_READABLE => 'File is not readable or does not exist',
];
/** @var array Error message template variables */
protected $messageVariables = [
'minwidth' => ['options' => 'minWidth'],
'maxwidth' => ['options' => 'maxWidth'],
'minheight' => ['options' => 'minHeight'],
'maxheight' => ['options' => 'maxHeight'],
'width' => 'width',
'height' => 'height',
];
/**
* Detected width
*
* @var int
*/
protected $width;
/**
* Detected height
*
* @var int
*/
protected $height;
/**
* Options for this validator
*
* @var array
*/
protected $options = [
'minWidth' => null, // Minimum image width
'maxWidth' => null, // Maximum image width
'minHeight' => null, // Minimum image height
'maxHeight' => null, // Maximum image height
];
/**
* Sets validator options
*
* Accepts the following option keys:
* - minheight
* - minwidth
* - maxheight
* - maxwidth
*
* @param null|array|Traversable $options
*/
public function __construct($options = null)
{
if (1 < func_num_args()) {
if (! is_array($options)) {
$options = ['minWidth' => $options];
}
$argv = func_get_args();
array_shift($argv);
$options['minHeight'] = array_shift($argv);
if (! empty($argv)) {
$options['maxWidth'] = array_shift($argv);
if (! empty($argv)) {
$options['maxHeight'] = array_shift($argv);
}
}
}
parent::__construct($options);
}
/**
* Returns the minimum allowed width
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @return int
*/
public function getMinWidth()
{
return $this->options['minWidth'];
}
/**
* Sets the minimum allowed width
*
* @param int $minWidth
* @return $this Provides a fluid interface
* @throws Exception\InvalidArgumentException When minwidth is greater than maxwidth.
*/
public function setMinWidth($minWidth)
{
if (($this->getMaxWidth() !== null) && ($minWidth > $this->getMaxWidth())) {
throw new Exception\InvalidArgumentException(
'The minimum image width must be less than or equal to the '
. " maximum image width, but {$minWidth} > {$this->getMaxWidth()}"
);
}
$this->options['minWidth'] = (int) $minWidth;
return $this;
}
/**
* Returns the maximum allowed width
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @return int
*/
public function getMaxWidth()
{
return $this->options['maxWidth'];
}
/**
* Sets the maximum allowed width
*
* @param int $maxWidth
* @return $this Provides a fluid interface
* @throws Exception\InvalidArgumentException When maxwidth is less than minwidth.
*/
public function setMaxWidth($maxWidth)
{
if (($this->getMinWidth() !== null) && ($maxWidth < $this->getMinWidth())) {
throw new Exception\InvalidArgumentException(
'The maximum image width must be greater than or equal to the '
. "minimum image width, but {$maxWidth} < {$this->getMinWidth()}"
);
}
$this->options['maxWidth'] = (int) $maxWidth;
return $this;
}
/**
* Returns the minimum allowed height
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @return int
*/
public function getMinHeight()
{
return $this->options['minHeight'];
}
/**
* Sets the minimum allowed height
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param int $minHeight
* @return $this Provides a fluid interface
* @throws Exception\InvalidArgumentException When minheight is greater than maxheight.
*/
public function setMinHeight($minHeight)
{
if (($this->getMaxHeight() !== null) && ($minHeight > $this->getMaxHeight())) {
throw new Exception\InvalidArgumentException(
'The minimum image height must be less than or equal to the '
. " maximum image height, but {$minHeight} > {$this->getMaxHeight()}"
);
}
$this->options['minHeight'] = (int) $minHeight;
return $this;
}
/**
* Returns the maximum allowed height
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @return int
*/
public function getMaxHeight()
{
return $this->options['maxHeight'];
}
/**
* Sets the maximum allowed height
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param int $maxHeight
* @return $this Provides a fluid interface
* @throws Exception\InvalidArgumentException When maxheight is less than minheight.
*/
public function setMaxHeight($maxHeight)
{
if (($this->getMinHeight() !== null) && ($maxHeight < $this->getMinHeight())) {
throw new Exception\InvalidArgumentException(
'The maximum image height must be greater than or equal to the '
. "minimum image height, but {$maxHeight} < {$this->getMinHeight()}"
);
}
$this->options['maxHeight'] = (int) $maxHeight;
return $this;
}
/**
* Returns the set minimum image sizes
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @return array
*/
public function getImageMin()
{
return ['minWidth' => $this->getMinWidth(), 'minHeight' => $this->getMinHeight()];
}
/**
* Returns the set maximum image sizes
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @return array
*/
public function getImageMax()
{
return ['maxWidth' => $this->getMaxWidth(), 'maxHeight' => $this->getMaxHeight()];
}
/**
* Returns the set image width sizes
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @return array
*/
public function getImageWidth()
{
return ['minWidth' => $this->getMinWidth(), 'maxWidth' => $this->getMaxWidth()];
}
/**
* Returns the set image height sizes
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @return array
*/
public function getImageHeight()
{
return ['minHeight' => $this->getMinHeight(), 'maxHeight' => $this->getMaxHeight()];
}
/**
* Sets the minimum image size
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param array $options The minimum image dimensions
* @return $this Provides a fluent interface
*/
public function setImageMin($options)
{
$this->setOptions($options);
return $this;
}
/**
* Sets the maximum image size
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param array|Traversable $options The maximum image dimensions
* @return $this Provides a fluent interface
*/
public function setImageMax($options)
{
$this->setOptions($options);
return $this;
}
/**
* Sets the minimum and maximum image width
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param array $options The image width dimensions
* @return $this Provides a fluent interface
*/
public function setImageWidth($options)
{
$this->setImageMin($options);
$this->setImageMax($options);
return $this;
}
/**
* Sets the minimum and maximum image height
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param array $options The image height dimensions
* @return $this Provides a fluent interface
*/
public function setImageHeight($options)
{
$this->setImageMin($options);
$this->setImageMax($options);
return $this;
}
/**
* Returns true if and only if the image size of $value is at least min and
* not bigger than max
*
* @param string|array $value Real file to check for image size
* @param array $file File data from \Laminas\File\Transfer\Transfer (optional)
* @return bool
*/
public function isValid($value, $file = null)
{
$fileInfo = $this->getFileInfo($value, $file);
$this->setValue($fileInfo['filename']);
// Is file readable ?
if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) {
$this->error(self::NOT_READABLE);
return false;
}
ErrorHandler::start();
$size = getimagesize($fileInfo['file']);
ErrorHandler::stop();
if (empty($size) || ($size[0] === 0) || ($size[1] === 0)) {
$this->error(self::NOT_DETECTED);
return false;
}
$this->width = $size[0];
$this->height = $size[1];
if ($this->width < $this->getMinWidth()) {
$this->error(self::WIDTH_TOO_SMALL);
}
if (($this->getMaxWidth() !== null) && ($this->getMaxWidth() < $this->width)) {
$this->error(self::WIDTH_TOO_BIG);
}
if ($this->height < $this->getMinHeight()) {
$this->error(self::HEIGHT_TOO_SMALL);
}
if (($this->getMaxHeight() !== null) && ($this->getMaxHeight() < $this->height)) {
$this->error(self::HEIGHT_TOO_BIG);
}
if ($this->getMessages()) {
return false;
}
return true;
}
}

View File

@@ -1,86 +0,0 @@
<?php
namespace Laminas\Validator\File;
use Laminas\Stdlib\ArrayUtils;
use Traversable;
/**
* Validator which checks if the file already exists in the directory
*
* @final
*/
class IsCompressed extends MimeType
{
/**
* @const string Error constants
*/
public const FALSE_TYPE = 'fileIsCompressedFalseType';
public const NOT_DETECTED = 'fileIsCompressedNotDetected';
public const NOT_READABLE = 'fileIsCompressedNotReadable';
/** @inheritDoc */
protected $messageTemplates = [
self::FALSE_TYPE => "File is not compressed, '%type%' detected",
self::NOT_DETECTED => 'The mimetype could not be detected from the file',
self::NOT_READABLE => 'File is not readable or does not exist',
];
/**
* Sets validator options
*
* @param string|array|Traversable $options
*/
public function __construct($options = [])
{
// http://hul.harvard.edu/ois/systems/wax/wax-public-help/mimetypes.htm
$default = [
'application/arj',
'application/gnutar',
'application/lha',
'application/lzx',
'application/vnd.ms-cab-compressed',
'application/x-ace-compressed',
'application/x-arc',
'application/x-archive',
'application/x-arj',
'application/x-bzip',
'application/x-bzip2',
'application/x-cab-compressed',
'application/x-compress',
'application/x-compressed',
'application/x-cpio',
'application/x-debian-package',
'application/x-eet',
'application/x-gzip',
'application/x-java-pack200',
'application/x-lha',
'application/x-lharc',
'application/x-lzh',
'application/x-lzma',
'application/x-lzx',
'application/x-rar',
'application/x-sit',
'application/x-stuffit',
'application/x-tar',
'application/zip',
'application/x-zip',
'application/zoo',
'multipart/x-gzip',
];
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
}
if ($options === null) {
$options = [];
}
parent::__construct($options);
if (! $this->getMimeType()) {
$this->setMimeType($default);
}
}
}

View File

@@ -1,112 +0,0 @@
<?php
namespace Laminas\Validator\File;
use Laminas\Stdlib\ArrayUtils;
use Traversable;
/**
* Validator which checks if the file is an image
*
* @final
*/
class IsImage extends MimeType
{
/**
* @const string Error constants
*/
public const FALSE_TYPE = 'fileIsImageFalseType';
public const NOT_DETECTED = 'fileIsImageNotDetected';
public const NOT_READABLE = 'fileIsImageNotReadable';
/** @inheritDoc */
protected $messageTemplates = [
self::FALSE_TYPE => "File is no image, '%type%' detected",
self::NOT_DETECTED => 'The mimetype could not be detected from the file',
self::NOT_READABLE => 'File is not readable or does not exist',
];
/**
* Sets validator options
*
* @param array|Traversable|string $options
*/
public function __construct($options = [])
{
// http://www.iana.org/assignments/media-types/media-types.xhtml#image
$default = [
'application/cdf',
'application/dicom',
'application/fractals',
'application/postscript',
'application/vnd.hp-hpgl',
'application/vnd.oasis.opendocument.graphics',
'application/x-cdf',
'application/x-cmu-raster',
'application/x-ima',
'application/x-inventor',
'application/x-koan',
'application/x-portable-anymap',
'application/x-world-x-3dmf',
'image/bmp',
'image/c',
'image/cgm',
'image/fif',
'image/gif',
'image/heic',
'image/heif',
'image/jpeg',
'image/jpm',
'image/jpx',
'image/jp2',
'image/naplps',
'image/pjpeg',
'image/png',
'image/svg',
'image/svg+xml',
'image/tiff',
'image/vnd.adobe.photoshop',
'image/vnd.djvu',
'image/vnd.fpx',
'image/vnd.net-fpx',
'image/webp',
'image/x-cmu-raster',
'image/x-cmx',
'image/x-coreldraw',
'image/x-cpi',
'image/x-emf',
'image/x-ico',
'image/x-icon',
'image/x-jg',
'image/x-ms-bmp',
'image/x-niff',
'image/x-pict',
'image/x-pcx',
'image/x-png',
'image/x-portable-anymap',
'image/x-portable-bitmap',
'image/x-portable-greymap',
'image/x-portable-pixmap',
'image/x-quicktime',
'image/x-rgb',
'image/x-tiff',
'image/x-unknown',
'image/x-windows-bmp',
'image/x-xpmi',
];
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
}
if ($options === null) {
$options = [];
}
parent::__construct($options);
if (! $this->getMimeType()) {
$this->setMimeType($default);
}
}
}

View File

@@ -1,120 +0,0 @@
<?php
namespace Laminas\Validator\File;
use function array_keys;
use function array_unique;
use function hash_file;
use function is_readable;
/**
* Validator for the md5 hash of given files
*
* @deprecated Since 2.61.0 Use the {@link Hash} validator and specify `md5` as the algorithm
*
* @final
*/
class Md5 extends Hash
{
use FileInformationTrait;
/**
* @const string Error constants
*/
public const DOES_NOT_MATCH = 'fileMd5DoesNotMatch';
public const NOT_DETECTED = 'fileMd5NotDetected';
public const NOT_FOUND = 'fileMd5NotFound';
/** @var array Error message templates */
protected $messageTemplates = [
self::DOES_NOT_MATCH => 'File does not match the given md5 hashes',
self::NOT_DETECTED => 'An md5 hash could not be evaluated for the given file',
self::NOT_FOUND => 'File is not readable or does not exist',
];
/**
* Options for this validator
*
* @var string
*/
protected $options = [
'algorithm' => 'md5',
'hash' => null,
];
/**
* Returns all set md5 hashes
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @return array
*/
public function getMd5()
{
return $this->getHash();
}
/**
* Sets the md5 hash for one or multiple files
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param string|array $options
* @return Hash Provides a fluent interface
*/
public function setMd5($options)
{
$this->setHash($options);
return $this;
}
/**
* Adds the md5 hash for one or multiple files
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param string|array $options
* @return Hash Provides a fluent interface
*/
public function addMd5($options)
{
$this->addHash($options);
return $this;
}
/**
* Returns true if and only if the given file confirms the set hash
*
* @param string|array $value Filename to check for hash
* @param array $file File data from \Laminas\File\Transfer\Transfer (optional)
* @return bool
*/
public function isValid($value, $file = null)
{
$fileInfo = $this->getFileInfo($value, $file);
$this->setValue($fileInfo['filename']);
// Is file readable ?
if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) {
$this->error(self::NOT_FOUND);
return false;
}
$hashes = array_unique(array_keys($this->getHash()));
$filehash = hash_file('md5', $fileInfo['file']);
if ($filehash === false) {
$this->error(self::NOT_DETECTED);
return false;
}
foreach ($hashes as $hash) {
if ($filehash === $hash) {
return true;
}
}
$this->error(self::DOES_NOT_MATCH);
return false;
}
}

View File

@@ -1,431 +0,0 @@
<?php
namespace Laminas\Validator\File;
use finfo;
use Laminas\Stdlib\ArrayUtils;
use Laminas\Stdlib\ErrorHandler;
use Laminas\Validator\AbstractValidator;
use Laminas\Validator\Exception;
use Psr\Http\Message\UploadedFileInterface;
use Traversable;
use function array_filter;
use function array_key_exists;
use function array_keys;
use function array_merge;
use function array_unique;
use function class_exists;
use function explode;
use function finfo_file;
use function finfo_open;
use function getenv;
use function implode;
use function in_array;
use function is_array;
use function is_file;
use function is_int;
use function is_readable;
use function is_string;
use function sprintf;
use function trim;
use const E_NOTICE;
use const E_WARNING;
use const FILEINFO_MIME_TYPE;
/**
* Validator for the mime type of a file
*/
class MimeType extends AbstractValidator
{
use FileInformationTrait;
/**#@+
*
* @const Error type constants
*/
public const FALSE_TYPE = 'fileMimeTypeFalse';
public const NOT_DETECTED = 'fileMimeTypeNotDetected';
public const NOT_READABLE = 'fileMimeTypeNotReadable';
/**#@-*/
/** @var array<string, string> */
protected $messageTemplates = [
self::FALSE_TYPE => "File has an incorrect mimetype of '%type%'",
self::NOT_DETECTED => 'The mimetype could not be detected from the file',
self::NOT_READABLE => 'File is not readable or does not exist',
];
/** @var array */
protected $messageVariables = [
'type' => 'type',
];
/** @var string */
protected $type;
/**
* Finfo object to use
*
* @var finfo|null
*/
protected $finfo;
/**
* If no environment variable 'MAGIC' is set, try and autodiscover it based on common locations
*
* @var list<non-empty-string>
*/
protected $magicFiles = [
'/usr/share/misc/magic',
'/usr/share/misc/magic.mime',
'/usr/share/misc/magic.mgc',
'/usr/share/mime/magic',
'/usr/share/mime/magic.mime',
'/usr/share/mime/magic.mgc',
'/usr/share/file/magic',
'/usr/share/file/magic.mime',
'/usr/share/file/magic.mgc',
];
/**
* Options for this validator
*
* @var array
*/
protected $options = [
'enableHeaderCheck' => false, // Allow header check
'disableMagicFile' => false, // Disable usage of magicfile
'magicFile' => null, // Magicfile to use
'mimeType' => null, // Mimetype to allow
];
/**
* Sets validator options
*
* Mimetype to accept
* - NULL means default PHP usage by using the environment variable 'magic'
* - FALSE means disabling searching for mimetype, should be used for PHP 5.3
* - A string is the mimetype file to use
*
* @param string|array|Traversable $options
*/
public function __construct($options = null)
{
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
} elseif (is_string($options)) {
$this->setMimeType($options);
$options = [];
} elseif (is_array($options)) {
if (isset($options['magicFile'])) {
$this->setMagicFile($options['magicFile']);
unset($options['magicFile']);
}
if (isset($options['enableHeaderCheck'])) {
$this->enableHeaderCheck((bool) $options['enableHeaderCheck']);
unset($options['enableHeaderCheck']);
}
if (array_key_exists('mimeType', $options)) {
$this->setMimeType($options['mimeType']);
unset($options['mimeType']);
}
// Handle cases where mimetypes are interspersed with options, or
// options are simply an array of mime types
foreach (array_keys($options) as $key) {
if (! is_int($key)) {
continue;
}
$this->addMimeType($options[$key]);
unset($options[$key]);
}
}
parent::__construct($options);
}
/**
* Returns the actual set magicfile
*
* @deprecated Since 2.61.0 - All option getters and setters will be removed in 3.0
*
* @return string|false
*/
public function getMagicFile()
{
if (null === $this->options['magicFile']) {
$magic = getenv('magic');
if (is_string($magic) && $magic !== '') {
$this->setMagicFile($magic);
if ($this->options['magicFile'] === null) {
$this->options['magicFile'] = false;
}
return $this->options['magicFile'];
}
foreach ($this->magicFiles as $file) {
try {
$this->setMagicFile($file);
} catch (Exception\ExceptionInterface) {
// suppressing errors which are thrown due to open_basedir restrictions
continue;
}
if (is_string($this->options['magicFile'])) {
return $this->options['magicFile'];
}
}
if ($this->options['magicFile'] === null) {
$this->options['magicFile'] = false;
}
}
return $this->options['magicFile'];
}
/**
* Sets the magicfile to use
* if null, the MAGIC constant from php is used
* if the MAGIC file is erroneous, no file will be set
* if false, the default MAGIC file from PHP will be used
*
* @deprecated Since 2.61.0 - All option getters and setters will be removed in 3.0
*
* @param string $file
* @return self Provides fluid interface
* @throws Exception\InvalidArgumentException
* @throws Exception\InvalidMagicMimeFileException
* @throws Exception\RuntimeException When finfo can not read the magicfile.
*/
public function setMagicFile($file)
{
if ($file === false) {
$this->options['magicFile'] = false;
} elseif (empty($file)) {
$this->options['magicFile'] = null;
} elseif (! class_exists('finfo', false)) {
$this->options['magicFile'] = null;
throw new Exception\RuntimeException('Magicfile can not be set; there is no finfo extension installed');
} elseif (! is_file($file) || ! is_readable($file)) {
throw new Exception\InvalidArgumentException(sprintf(
'The given magicfile ("%s") could not be read',
$file
));
} else {
ErrorHandler::start(E_NOTICE | E_WARNING);
$this->finfo = finfo_open(FILEINFO_MIME_TYPE, $file);
$error = ErrorHandler::stop();
if (empty($this->finfo)) {
$this->finfo = null;
throw new Exception\InvalidMagicMimeFileException(sprintf(
'The given magicfile ("%s") could not be used by ext/finfo',
$file
), 0, $error);
}
$this->options['magicFile'] = $file;
}
return $this;
}
/**
* Disables usage of MagicFile
*
* @deprecated Since 2.61.0 - All option getters and setters will be removed in 3.0
*
* @param bool $disable False disables usage of magic file; true enables it.
* @return self Provides fluid interface
*/
public function disableMagicFile($disable)
{
$this->options['disableMagicFile'] = (bool) $disable;
return $this;
}
/**
* Is usage of MagicFile disabled?
*
* @deprecated Since 2.61.0 - All option getters and setters will be removed in 3.0
*
* @return bool
*/
public function isMagicFileDisabled()
{
return $this->options['disableMagicFile'];
}
/**
* Returns the Header Check option
*
* @deprecated Since 2.61.0 - All option getters and setters will be removed in 3.0
*
* @return bool
*/
public function getHeaderCheck()
{
return $this->options['enableHeaderCheck'];
}
/**
* Defines if the http header should be used
* Note that this is unsafe and therefor the default value is false
*
* @deprecated Since 2.61.0 - All option getters and setters will be removed in 3.0
*
* @param bool $headerCheck
* @return self Provides fluid interface
*/
public function enableHeaderCheck($headerCheck = true)
{
$this->options['enableHeaderCheck'] = (bool) $headerCheck;
return $this;
}
/**
* Returns the set mimetypes
*
* @deprecated Since 2.61.0 - All option getters and setters will be removed in 3.0
*
* @param bool $asArray Returns the values as array, when false a concatenated string is returned
* @return string|list<string>
* @psalm-return ($asArray is true ? list<string> : string)
*/
public function getMimeType($asArray = false)
{
$asArray = (bool) $asArray;
$mimetype = (string) $this->options['mimeType'];
if ($asArray) {
$mimetype = explode(',', $mimetype);
}
return $mimetype;
}
/**
* Sets the mimetypes
*
* @deprecated Since 2.61.0 - All option getters and setters will be removed in 3.0
*
* @param string|list<string> $mimetype The mimetypes to validate
* @return self Provides a fluent interface
*/
public function setMimeType($mimetype)
{
$this->options['mimeType'] = null;
$this->addMimeType($mimetype);
return $this;
}
/**
* Adds the mimetypes
*
* @deprecated Since 2.61.0 - All option getters and setters will be removed in 3.0
*
* @param string|list<string> $mimetype The mimetypes to add for validation
* @throws Exception\InvalidArgumentException
* @return self Provides a fluent interface
*/
public function addMimeType($mimetype)
{
$mimetypes = $this->getMimeType(true);
if (is_string($mimetype)) {
$mimetype = explode(',', $mimetype);
} elseif (! is_array($mimetype)) {
throw new Exception\InvalidArgumentException('Invalid options to validator provided');
}
if (isset($mimetype['magicFile'])) {
unset($mimetype['magicFile']);
}
foreach ($mimetype as $content) {
if (! is_string($content) || $content === '') {
continue;
}
$mimetypes[] = trim($content);
}
$mimetypes = array_unique(array_filter($mimetypes));
$this->options['mimeType'] = implode(',', $mimetypes);
return $this;
}
/**
* Defined by Laminas\Validator\ValidatorInterface
*
* Returns true if the mimetype of the file matches the given ones. Also parts
* of mimetypes can be checked. If you give for example "image" all image
* mime types will be accepted like "image/gif", "image/jpeg" and so on.
*
* @param string|array|UploadedFileInterface $value Real file to check for mimetype
* @param array $file File data from \Laminas\File\Transfer\Transfer (optional)
* @return bool
*/
public function isValid($value, $file = null)
{
$fileInfo = $this->getFileInfo($value, $file, true);
$this->setValue($fileInfo['filename']);
// Is file readable ?
if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) {
$this->error(static::NOT_READABLE);
return false;
}
$mimefile = $this->getMagicFile();
if (class_exists('finfo', false)) {
if (! $this->isMagicFileDisabled() && (is_string($mimefile) && empty($this->finfo))) {
ErrorHandler::start(E_NOTICE | E_WARNING);
$this->finfo = finfo_open(FILEINFO_MIME_TYPE, $mimefile);
ErrorHandler::stop();
}
if (empty($this->finfo)) {
ErrorHandler::start(E_NOTICE | E_WARNING);
$this->finfo = finfo_open(FILEINFO_MIME_TYPE);
ErrorHandler::stop();
}
$this->type = null;
if (! empty($this->finfo)) {
$this->type = finfo_file($this->finfo, $fileInfo['file']);
unset($this->finfo);
}
}
if ($this->type === null && $this->getHeaderCheck()) {
$this->type = $fileInfo['filetype'];
}
if ($this->type === null) {
$this->error(static::NOT_DETECTED);
return false;
}
$mimetype = $this->getMimeType(true);
if (in_array($this->type, $mimetype)) {
return true;
}
$types = explode('/', $this->type);
$types = array_merge($types, explode('-', $this->type));
$types = array_merge($types, explode(';', $this->type));
foreach ($mimetype as $mime) {
if (in_array($mime, $types)) {
return true;
}
}
$this->error(static::FALSE_TYPE);
return false;
}
}

View File

@@ -1,70 +0,0 @@
<?php
namespace Laminas\Validator\File;
use function file_exists;
use const DIRECTORY_SEPARATOR;
/**
* Validator which checks if the destination file does not exist
*
* @final
*/
class NotExists extends Exists
{
use FileInformationTrait;
/**
* @const string Error constants
*/
public const DOES_EXIST = 'fileNotExistsDoesExist';
/** @var array Error message templates */
protected $messageTemplates = [
self::DOES_EXIST => 'File exists',
];
/**
* Returns true if and only if the file does not exist in the set destinations
*
* @param string|array $value Real file to check for existence
* @param array $file File data from \Laminas\File\Transfer\Transfer (optional)
* @return bool
*/
public function isValid($value, $file = null)
{
$fileInfo = $this->getFileInfo($value, $file, false, true);
$this->setValue($fileInfo['filename']);
$check = false;
$directories = $this->getDirectory(true);
if (! isset($directories)) {
$check = true;
if (file_exists($fileInfo['file'])) {
$this->error(self::DOES_EXIST);
return false;
}
} else {
foreach ($directories as $directory) {
if (! isset($directory) || '' === $directory) {
continue;
}
$check = true;
if (file_exists($directory . DIRECTORY_SEPARATOR . $fileInfo['basename'])) {
$this->error(self::DOES_EXIST);
return false;
}
}
}
if (! $check) {
$this->error(self::DOES_EXIST);
return false;
}
return true;
}
}

View File

@@ -1,120 +0,0 @@
<?php
namespace Laminas\Validator\File;
use function array_keys;
use function array_unique;
use function hash_file;
use function is_readable;
/**
* Validator for the sha1 hash of given files
*
* @deprecated Since 2.61.0 Use the {@link Hash} validator and specify `sha1` as the algorithm
*
* @final
*/
class Sha1 extends Hash
{
use FileInformationTrait;
/**
* @const string Error constants
*/
public const DOES_NOT_MATCH = 'fileSha1DoesNotMatch';
public const NOT_DETECTED = 'fileSha1NotDetected';
public const NOT_FOUND = 'fileSha1NotFound';
/** @var array Error message templates */
protected $messageTemplates = [
self::DOES_NOT_MATCH => 'File does not match the given sha1 hashes',
self::NOT_DETECTED => 'A sha1 hash could not be evaluated for the given file',
self::NOT_FOUND => 'File is not readable or does not exist',
];
/**
* Options for this validator
*
* @var string
*/
protected $options = [
'algorithm' => 'sha1',
'hash' => null,
];
/**
* Returns all set sha1 hashes
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @return array
*/
public function getSha1()
{
return $this->getHash();
}
/**
* Sets the sha1 hash for one or multiple files
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param string|array $options
* @return Hash Provides a fluent interface
*/
public function setSha1($options)
{
$this->setHash($options);
return $this;
}
/**
* Adds the sha1 hash for one or multiple files
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param string|array $options
* @return Hash Provides a fluent interface
*/
public function addSha1($options)
{
$this->addHash($options);
return $this;
}
/**
* Returns true if and only if the given file confirms the set hash
*
* @param (int|string)[]|string $value Filename to check for hash
* @param array $file File data from \Laminas\File\Transfer\Transfer (optional)
* @return bool
*/
public function isValid($value, $file = null)
{
$fileInfo = $this->getFileInfo($value, $file);
$this->setValue($fileInfo['filename']);
// Is file readable ?
if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) {
$this->error(self::NOT_FOUND);
return false;
}
$hashes = array_unique(array_keys($this->getHash()));
$filehash = hash_file('sha1', $fileInfo['file']);
if ($filehash === false) {
$this->error(self::NOT_DETECTED);
return false;
}
foreach ($hashes as $hash) {
if ($filehash === $hash) {
return true;
}
}
$this->error(self::DOES_NOT_MATCH);
return false;
}
}

View File

@@ -1,375 +0,0 @@
<?php
namespace Laminas\Validator\File;
use Laminas\Stdlib\ErrorHandler;
use Laminas\Validator\AbstractValidator;
use Laminas\Validator\Exception;
use Traversable;
use function array_shift;
use function filesize;
use function func_get_args;
use function func_num_args;
use function is_numeric;
use function is_readable;
use function is_string;
use function round;
use function sprintf;
use function strtoupper;
use function substr;
use function trim;
/**
* Validator for the maximum size of a file up to a max of 2GB
*/
class Size extends AbstractValidator
{
use FileInformationTrait;
/**
* @const string Error constants
*/
public const TOO_BIG = 'fileSizeTooBig';
public const TOO_SMALL = 'fileSizeTooSmall';
public const NOT_FOUND = 'fileSizeNotFound';
/** @var array Error message templates */
protected $messageTemplates = [
self::TOO_BIG => "Maximum allowed size for file is '%max%' but '%size%' detected",
self::TOO_SMALL => "Minimum expected size for file is '%min%' but '%size%' detected",
self::NOT_FOUND => 'File is not readable or does not exist',
];
/** @var array Error message template variables */
protected $messageVariables = [
'min' => ['options' => 'min'],
'max' => ['options' => 'max'],
'size' => 'size',
];
/**
* Detected size
*
* @var int
*/
protected $size;
/**
* Options for this validator
*
* @var array
*/
protected $options = [
'min' => null, // Minimum file size, if null there is no minimum
'max' => null, // Maximum file size, if null there is no maximum
'useByteString' => true, // Use byte string?
];
/**
* Sets validator options
*
* If $options is an integer, it will be used as maximum file size
* As Array is accepts the following keys:
* 'min': Minimum file size
* 'max': Maximum file size
* 'useByteString': Use bytestring or real size for messages
*
* @param int|array|Traversable $options Options for the adapter
*/
public function __construct($options = null)
{
if (is_string($options) || is_numeric($options)) {
$options = ['max' => $options];
}
if (1 < func_num_args()) {
$argv = func_get_args();
array_shift($argv);
$options['max'] = array_shift($argv);
if (! empty($argv)) {
$options['useByteString'] = array_shift($argv);
}
}
parent::__construct($options);
}
/**
* Should messages return bytes as integer or as string in SI notation
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param bool $byteString Use bytestring ?
* @return self
*/
public function useByteString($byteString = true)
{
$this->options['useByteString'] = (bool) $byteString;
return $this;
}
/**
* Will bytestring be used?
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @return bool
*/
public function getByteString()
{
return $this->options['useByteString'];
}
/**
* Returns the minimum file size
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param bool $raw Whether or not to force return of the raw value (defaults off)
* @return int|string
*/
public function getMin($raw = false)
{
$min = $this->options['min'];
if (! $raw && $this->getByteString()) {
$min = $this->toByteString($min);
}
return $min;
}
/**
* Sets the minimum file size
*
* File size can be an integer or a byte string
* This includes 'B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'
* For example: 2000, 2MB, 0.2GB
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param int|string $min The minimum file size
* @return $this Provides a fluent interface
* @throws Exception\InvalidArgumentException When min is greater than max.
*/
public function setMin($min)
{
if (! is_string($min) && ! is_numeric($min)) {
throw new Exception\InvalidArgumentException('Invalid options to validator provided');
}
$min = (int) $this->fromByteString($min);
$max = $this->getMax(true);
if (($max !== null) && ($min > $max)) {
throw new Exception\InvalidArgumentException(
"The minimum must be less than or equal to the maximum file size, but $min > $max"
);
}
$this->options['min'] = $min;
return $this;
}
/**
* Returns the maximum file size
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param bool $raw Whether or not to force return of the raw value (defaults off)
* @return int|string
*/
public function getMax($raw = false)
{
$max = $this->options['max'];
if (! $raw && $this->getByteString()) {
$max = $this->toByteString($max);
}
return $max;
}
/**
* Sets the maximum file size
*
* File size can be an integer or a byte string
* This includes 'B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'
* For example: 2000, 2MB, 0.2GB
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param int|string $max The maximum file size
* @return $this Provides a fluent interface
* @throws Exception\InvalidArgumentException When max is smaller than min.
*/
public function setMax($max)
{
if (! is_string($max) && ! is_numeric($max)) {
throw new Exception\InvalidArgumentException('Invalid options to validator provided');
}
$max = (int) $this->fromByteString($max);
$min = $this->getMin(true);
if (($min !== null) && ($max < $min)) {
throw new Exception\InvalidArgumentException(
"The maximum must be greater than or equal to the minimum file size, but $max < $min"
);
}
$this->options['max'] = $max;
return $this;
}
/**
* Retrieve current detected file size
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @return int
*/
protected function getSize()
{
return $this->size;
}
/**
* Set current size
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param int $size
* @return $this
*/
protected function setSize($size)
{
$this->size = $size;
return $this;
}
/**
* Returns true if and only if the file size of $value is at least min and
* not bigger than max (when max is not null).
*
* @param string|array $value File to check for size
* @param array $file File data from \Laminas\File\Transfer\Transfer (optional)
* @return bool
*/
public function isValid($value, $file = null)
{
$fileInfo = $this->getFileInfo($value, $file);
$this->setValue($fileInfo['filename']);
// Is file readable ?
if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) {
$this->error(self::NOT_FOUND);
return false;
}
// limited to 4GB files
ErrorHandler::start();
$size = sprintf('%u', filesize($fileInfo['file']));
ErrorHandler::stop();
$this->size = $size;
// Check to see if it's smaller than min size
$min = $this->getMin(true);
$max = $this->getMax(true);
if (($min !== null) && ($size < $min)) {
if ($this->getByteString()) {
$this->options['min'] = $this->toByteString($min);
$this->size = $this->toByteString($size);
$this->error(self::TOO_SMALL);
$this->options['min'] = $min;
$this->size = $size;
} else {
$this->error(self::TOO_SMALL);
}
}
// Check to see if it's larger than max size
if (($max !== null) && ($max < $size)) {
if ($this->getByteString()) {
$this->options['max'] = $this->toByteString($max);
$this->size = $this->toByteString($size);
$this->error(self::TOO_BIG);
$this->options['max'] = $max;
$this->size = $size;
} else {
$this->error(self::TOO_BIG);
}
}
if ($this->getMessages()) {
return false;
}
return true;
}
/**
* Returns the formatted size
*
* @param int $size
* @return string
*/
protected function toByteString($size)
{
$sizes = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
for ($i = 0; $size >= 1024 && $i < 9; $i++) {
$size /= 1024;
}
return round($size, 2) . $sizes[$i];
}
/**
* Returns the unformatted size
*
* @param string $size
* @return float|int|string
*/
protected function fromByteString($size)
{
if (is_numeric($size)) {
return (int) $size;
}
$type = trim(substr($size, -2, 1));
$value = substr($size, 0, -1);
if (! is_numeric($value)) {
$value = trim(substr($value, 0, -1));
}
switch (strtoupper($type)) {
case 'Y':
$value *= 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024;
break;
case 'Z':
$value *= 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024;
break;
case 'E':
$value *= 1024 * 1024 * 1024 * 1024 * 1024 * 1024;
break;
case 'P':
$value *= 1024 * 1024 * 1024 * 1024 * 1024;
break;
case 'T':
$value *= 1024 * 1024 * 1024 * 1024;
break;
case 'G':
$value *= 1024 * 1024 * 1024;
break;
case 'M':
$value *= 1024 * 1024;
break;
case 'K':
$value *= 1024;
break;
default:
break;
}
return $value;
}
}

View File

@@ -1,278 +0,0 @@
<?php
namespace Laminas\Validator\File;
use Laminas\Validator\AbstractValidator;
use Laminas\Validator\Exception;
use Psr\Http\Message\UploadedFileInterface;
use Traversable;
use function array_key_exists;
use function array_merge;
use function count;
use function is_array;
use function is_countable;
use function is_string;
use function is_uploaded_file;
/**
* Validator for the maximum size of a file up to a max of 2GB
*
* @deprecated Since 2.61.0 Use the {@link UploadFile} validator instead
*
* @final
*/
class Upload extends AbstractValidator
{
/**
* @const string Error constants
*/
public const INI_SIZE = 'fileUploadErrorIniSize';
public const FORM_SIZE = 'fileUploadErrorFormSize';
public const PARTIAL = 'fileUploadErrorPartial';
public const NO_FILE = 'fileUploadErrorNoFile';
public const NO_TMP_DIR = 'fileUploadErrorNoTmpDir';
public const CANT_WRITE = 'fileUploadErrorCantWrite';
public const EXTENSION = 'fileUploadErrorExtension';
public const ATTACK = 'fileUploadErrorAttack';
public const FILE_NOT_FOUND = 'fileUploadErrorFileNotFound';
public const UNKNOWN = 'fileUploadErrorUnknown';
/** @var array<string, string> Error message templates */
protected $messageTemplates = [
self::INI_SIZE => "File '%value%' exceeds upload_max_filesize directive in php.ini",
self::FORM_SIZE => "File '%value%' exceeds the MAX_FILE_SIZE directive that was "
. 'specified in the HTML form',
self::PARTIAL => "File '%value%' was only partially uploaded",
self::NO_FILE => "File '%value%' was not uploaded",
self::NO_TMP_DIR => "Missing a temporary folder to store '%value%'",
self::CANT_WRITE => "Failed to write file '%value%' to disk",
self::EXTENSION => "A PHP extension stopped uploading the file '%value%'",
self::ATTACK => "File '%value%' was illegally uploaded. This could be a possible attack",
self::FILE_NOT_FOUND => "File '%value%' was not found",
self::UNKNOWN => "Unknown error while uploading file '%value%'",
];
/** @var array<string, mixed> */
protected $options = [
'files' => [],
];
/**
* Sets validator options
*
* The array $files must be given in syntax of Laminas\File\Transfer\Transfer to be checked
* If no files are given the $_FILES array will be used automatically.
* NOTE: This validator will only work with HTTP POST uploads!
*
* @param array|Traversable $options Array of files in syntax of \Laminas\File\Transfer\Transfer
*/
public function __construct($options = [])
{
if (is_array($options) && ! array_key_exists('files', $options)) {
$options = ['files' => $options];
}
parent::__construct($options);
}
/**
* Returns the array of set files
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param string $file (Optional) The file to return in detail
* @return array
* @throws Exception\InvalidArgumentException If file is not found.
*/
public function getFiles($file = null)
{
if ($file !== null) {
$return = [];
foreach ($this->options['files'] as $name => $content) {
if ($name === $file) {
$return[$file] = $this->options['files'][$name];
}
if ($content instanceof UploadedFileInterface) {
if ($content->getClientFilename() === $file) {
$return[$name] = $this->options['files'][$name];
}
} elseif ($content['name'] === $file) {
$return[$name] = $this->options['files'][$name];
}
}
if (! $return) {
throw new Exception\InvalidArgumentException("The file '$file' was not found");
}
return $return;
}
return $this->options['files'];
}
/**
* Sets the files to be checked
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param array $files The files to check in syntax of \Laminas\File\Transfer\Transfer
* @return $this Provides a fluent interface
*/
public function setFiles($files = [])
{
if (
null === $files
|| ((is_countable($files))
&& count($files) === 0)
) {
$this->options['files'] = $_FILES;
} else {
$this->options['files'] = $files;
}
if ($this->options['files'] === null) {
$this->options['files'] = [];
}
foreach ($this->options['files'] as $file => $content) {
if (
! $content instanceof UploadedFileInterface
&& ! isset($content['error'])
) {
unset($this->options['files'][$file]);
}
}
return $this;
}
/**
* Returns true if and only if the file was uploaded without errors
*
* @param string $value Single file to check for upload errors, when giving null the $_FILES array
* from initialization will be used
* @param mixed $file
* @return bool
*/
public function isValid($value, $file = null)
{
$files = [];
$this->setValue($value);
if (array_key_exists($value, $this->getFiles())) {
$files = array_merge($files, $this->getFiles($value));
} else {
foreach ($this->getFiles() as $file => $content) {
if ($content instanceof UploadedFileInterface) {
if ($content->getClientFilename() === $value) {
$files = array_merge($files, $this->getFiles($file));
}
// PSR cannot search by tmp_name because it does not have
// a public interface to get it, only user defined name
// from form field.
continue;
}
if (isset($content['name']) && ($content['name'] === $value)) {
$files = array_merge($files, $this->getFiles($file));
}
if (isset($content['tmp_name']) && ($content['tmp_name'] === $value)) {
$files = array_merge($files, $this->getFiles($file));
}
}
}
if (empty($files)) {
return $this->throwError($file, self::FILE_NOT_FOUND);
}
foreach ($files as $file => $content) {
$this->value = $file;
$error = $content instanceof UploadedFileInterface
? $content->getError()
: $content['error'];
switch ($error) {
case 0:
if ($content instanceof UploadedFileInterface) {
// done!
break;
}
// For standard SAPI environments, check that the upload
// was valid
if (! is_uploaded_file($content['tmp_name'])) {
$this->throwError($content, self::ATTACK);
}
break;
case 1:
$this->throwError($content, self::INI_SIZE);
break;
case 2:
$this->throwError($content, self::FORM_SIZE);
break;
case 3:
$this->throwError($content, self::PARTIAL);
break;
case 4:
$this->throwError($content, self::NO_FILE);
break;
case 6:
$this->throwError($content, self::NO_TMP_DIR);
break;
case 7:
$this->throwError($content, self::CANT_WRITE);
break;
case 8:
$this->throwError($content, self::EXTENSION);
break;
default:
$this->throwError($content, self::UNKNOWN);
break;
}
}
if ($this->getMessages()) {
return false;
}
return true;
}
/**
* Throws an error of the given type
*
* @param array|string|UploadedFileInterface $file
* @param string $errorType
* @return false
*/
protected function throwError($file, $errorType)
{
if ($file !== null) {
if (is_array($file)) {
if (array_key_exists('name', $file)) {
$this->value = $file['name'];
}
} elseif (is_string($file)) {
$this->value = $file;
} elseif ($file instanceof UploadedFileInterface) {
$this->value = $file->getClientFilename();
}
}
$this->error($errorType);
return false;
}
}

View File

@@ -1,177 +0,0 @@
<?php
namespace Laminas\Validator\File;
use Laminas\Validator\AbstractValidator;
use Laminas\Validator\Exception;
use Psr\Http\Message\UploadedFileInterface;
use function basename;
use function is_array;
use function is_file;
use function is_string;
use function is_uploaded_file;
use const UPLOAD_ERR_CANT_WRITE;
use const UPLOAD_ERR_EXTENSION;
use const UPLOAD_ERR_FORM_SIZE;
use const UPLOAD_ERR_INI_SIZE;
use const UPLOAD_ERR_NO_FILE;
use const UPLOAD_ERR_NO_TMP_DIR;
use const UPLOAD_ERR_OK;
use const UPLOAD_ERR_PARTIAL;
/**
* Validator for the maximum size of a file up to a max of 2GB
*
* @final
*/
class UploadFile extends AbstractValidator
{
/**
* @const string Error constants
*/
public const INI_SIZE = 'fileUploadFileErrorIniSize';
public const FORM_SIZE = 'fileUploadFileErrorFormSize';
public const PARTIAL = 'fileUploadFileErrorPartial';
public const NO_FILE = 'fileUploadFileErrorNoFile';
public const NO_TMP_DIR = 'fileUploadFileErrorNoTmpDir';
public const CANT_WRITE = 'fileUploadFileErrorCantWrite';
public const EXTENSION = 'fileUploadFileErrorExtension';
public const ATTACK = 'fileUploadFileErrorAttack';
public const FILE_NOT_FOUND = 'fileUploadFileErrorFileNotFound';
public const UNKNOWN = 'fileUploadFileErrorUnknown';
/** @var array Error message templates */
protected $messageTemplates = [
self::INI_SIZE => 'The uploaded file exceeds the upload_max_filesize directive in php.ini',
self::FORM_SIZE => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was '
. 'specified in the HTML form',
self::PARTIAL => 'The uploaded file was only partially uploaded',
self::NO_FILE => 'No file was uploaded',
self::NO_TMP_DIR => 'Missing a temporary folder',
self::CANT_WRITE => 'Failed to write file to disk',
self::EXTENSION => 'A PHP extension stopped the file upload',
self::ATTACK => 'File was illegally uploaded. This could be a possible attack',
self::FILE_NOT_FOUND => 'File was not found',
self::UNKNOWN => 'Unknown error while uploading file',
];
/**
* Returns true if and only if the file was uploaded without errors
*
* @param string|array|UploadedFileInterface $value File to check for upload errors
* @return bool
* @throws Exception\InvalidArgumentException
*/
public function isValid($value)
{
if (is_array($value)) {
if (! isset($value['tmp_name']) || ! isset($value['name']) || ! isset($value['error'])) {
throw new Exception\InvalidArgumentException(
'Value array must be in $_FILES format'
);
}
return $this->validateUploadedFile(
$value['error'],
$value['name'],
$value['tmp_name']
);
}
if ($value instanceof UploadedFileInterface) {
return $this->validatePsr7UploadedFile($value);
}
if (is_string($value)) {
return $this->validateUploadedFile(0, basename($value), $value);
}
$this->error(self::UNKNOWN);
return false;
}
/**
* @param int $error UPLOAD_ERR_* constant value
* @return bool
*/
private function validateFileFromErrorCode($error)
{
switch ($error) {
case UPLOAD_ERR_OK:
return true;
case UPLOAD_ERR_INI_SIZE:
$this->error(self::INI_SIZE);
return false;
case UPLOAD_ERR_FORM_SIZE:
$this->error(self::FORM_SIZE);
return false;
case UPLOAD_ERR_PARTIAL:
$this->error(self::PARTIAL);
return false;
case UPLOAD_ERR_NO_FILE:
$this->error(self::NO_FILE);
return false;
case UPLOAD_ERR_NO_TMP_DIR:
$this->error(self::NO_TMP_DIR);
return false;
case UPLOAD_ERR_CANT_WRITE:
$this->error(self::CANT_WRITE);
return false;
case UPLOAD_ERR_EXTENSION:
$this->error(self::EXTENSION);
return false;
default:
$this->error(self::UNKNOWN);
return false;
}
}
/**
* @param int $error UPLOAD_ERR_* constant
* @param string $filename
* @param string $uploadedFile Name of uploaded file (gen tmp_name)
* @return bool
*/
private function validateUploadedFile($error, $filename, $uploadedFile)
{
$this->setValue($filename);
// Normal errors can be validated normally
if ($error !== UPLOAD_ERR_OK) {
return $this->validateFileFromErrorCode($error);
}
// Did we get no name? Is the file missing?
if (empty($uploadedFile) || false === is_file($uploadedFile)) {
$this->error(self::FILE_NOT_FOUND);
return false;
}
// Do we have an invalid upload?
if (! is_uploaded_file($uploadedFile)) {
$this->error(self::ATTACK);
return false;
}
return true;
}
/**
* @return bool
*/
private function validatePsr7UploadedFile(UploadedFileInterface $uploadedFile)
{
$this->setValue($uploadedFile);
return $this->validateFileFromErrorCode($uploadedFile->getError());
}
}

View File

@@ -1,214 +0,0 @@
<?php
namespace Laminas\Validator\File;
use Laminas\Validator\AbstractValidator;
use Laminas\Validator\Exception;
use Traversable;
use function array_shift;
use function file_get_contents;
use function func_get_args;
use function func_num_args;
use function is_array;
use function is_numeric;
use function is_readable;
use function is_string;
use function str_word_count;
/**
* Validator for counting all words in a file
*
* @final
*/
class WordCount extends AbstractValidator
{
use FileInformationTrait;
/**
* @const string Error constants
*/
public const TOO_MUCH = 'fileWordCountTooMuch';
public const TOO_LESS = 'fileWordCountTooLess';
public const NOT_FOUND = 'fileWordCountNotFound';
/** @var array Error message templates */
protected $messageTemplates = [
self::TOO_MUCH => "Too many words, maximum '%max%' are allowed but '%count%' were counted",
self::TOO_LESS => "Too few words, minimum '%min%' are expected but '%count%' were counted",
self::NOT_FOUND => 'File is not readable or does not exist',
];
/** @var array Error message template variables */
protected $messageVariables = [
'min' => ['options' => 'min'],
'max' => ['options' => 'max'],
'count' => 'count',
];
/**
* Word count
*
* @var int
*/
protected $count;
/**
* Options for this validator
*
* @var array
*/
protected $options = [
'min' => null, // Minimum word count, if null there is no minimum word count
'max' => null, // Maximum word count, if null there is no maximum word count
];
/**
* Sets validator options
*
* Min limits the word count, when used with max=null it is the maximum word count
* It also accepts an array with the keys 'min' and 'max'
*
* If $options is an integer, it will be used as maximum word count
* As Array is accepts the following keys:
* 'min': Minimum word count
* 'max': Maximum word count
*
* @param int|array|Traversable $options Options for the adapter
*/
public function __construct($options = null)
{
if (1 < func_num_args()) {
$args = func_get_args();
$options = [
'min' => array_shift($args),
'max' => array_shift($args),
];
}
if (is_string($options) || is_numeric($options)) {
$options = ['max' => $options];
}
parent::__construct($options);
}
/**
* Returns the minimum word count
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @return int
*/
public function getMin()
{
return $this->options['min'];
}
/**
* Sets the minimum word count
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param int|array $min The minimum word count
* @return $this Provides a fluent interface
* @throws Exception\InvalidArgumentException When min is greater than max.
*/
public function setMin($min)
{
if (is_array($min) && isset($min['min'])) {
$min = $min['min'];
}
if (! is_numeric($min)) {
throw new Exception\InvalidArgumentException('Invalid options to validator provided');
}
$min = (int) $min;
if (($this->getMax() !== null) && ($min > $this->getMax())) {
throw new Exception\InvalidArgumentException(
"The minimum must be less than or equal to the maximum word count, but $min > {$this->getMax()}"
);
}
$this->options['min'] = $min;
return $this;
}
/**
* Returns the maximum word count
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @return int
*/
public function getMax()
{
return $this->options['max'];
}
/**
* Sets the maximum file count
*
* @deprecated Since 2.61.0 - All getters and setters will be removed in 3.0
*
* @param int|array $max The maximum word count
* @return $this Provides a fluent interface
* @throws Exception\InvalidArgumentException When max is smaller than min.
*/
public function setMax($max)
{
if (is_array($max) && isset($max['max'])) {
$max = $max['max'];
}
if (! is_numeric($max)) {
throw new Exception\InvalidArgumentException('Invalid options to validator provided');
}
$max = (int) $max;
if (($this->getMin() !== null) && ($max < $this->getMin())) {
throw new Exception\InvalidArgumentException(
"The maximum must be greater than or equal to the minimum word count, but $max < {$this->getMin()}"
);
}
$this->options['max'] = $max;
return $this;
}
/**
* Returns true if and only if the counted words are at least min and
* not bigger than max (when max is not null).
*
* @param string|array $value Filename to check for word count
* @param array $file File data from \Laminas\File\Transfer\Transfer (optional)
* @return bool
*/
public function isValid($value, $file = null)
{
$fileInfo = $this->getFileInfo($value, $file);
$this->setValue($fileInfo['filename']);
// Is file readable ?
if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) {
$this->error(self::NOT_FOUND);
return false;
}
$content = file_get_contents($fileInfo['file']);
$this->count = str_word_count($content);
if (($this->getMax() !== null) && ($this->count > $this->getMax())) {
$this->error(self::TOO_MUCH);
return false;
}
if (($this->getMin() !== null) && ($this->count < $this->getMin())) {
$this->error(self::TOO_LESS);
return false;
}
return true;
}
}

View File

@@ -1,112 +0,0 @@
<?php
namespace Laminas\Validator;
use function explode;
use function is_numeric;
use function preg_match;
use function preg_match_all;
use function preg_replace;
use function str_contains;
use function str_replace;
final class GpsPoint extends AbstractValidator
{
public const OUT_OF_BOUNDS = 'gpsPointOutOfBounds';
public const CONVERT_ERROR = 'gpsPointConvertError';
public const INCOMPLETE_COORDINATE = 'gpsPointIncompleteCoordinate';
protected array $messageTemplates = [
self::OUT_OF_BOUNDS => '%value% is out of Bounds.',
self::CONVERT_ERROR => '%value% can not converted into a Decimal Degree Value.',
self::INCOMPLETE_COORDINATE => '%value% did not provided a complete Coordinate',
];
/**
* Returns true if and only if $value meets the validation requirements
*
* If $value fails validation, then this method returns false, and
* getMessages() will return an array of messages that explain why the
* validation failed.
*
* @throws Exception\RuntimeException If validation of $value is impossible.
*/
public function isValid(mixed $value): bool
{
if (! str_contains($value, ',')) {
$this->error(self::INCOMPLETE_COORDINATE, $value);
return false;
}
[$lat, $long] = explode(',', $value);
return $this->isValidCoordinate($lat, 90.0000) && $this->isValidCoordinate($long, 180.000);
}
private function isValidCoordinate(string $value, float $maxBoundary): bool
{
$this->value = $value;
$value = $this->removeWhiteSpace($value);
if ($this->isDMSValue($value)) {
$value = $this->convertValue($value);
} else {
$value = $this->removeDegreeSign($value);
}
if ($value === false) {
$this->error(self::CONVERT_ERROR);
return false;
}
$castedValue = (float) $value;
if (! is_numeric($value) && $castedValue === 0.0) {
$this->error(self::CONVERT_ERROR);
return false;
}
if (! $this->isValueInbound($castedValue, $maxBoundary)) {
$this->error(self::OUT_OF_BOUNDS);
return false;
}
return true;
}
/**
* Determines if the give value is a Degrees Minutes Second Definition
*/
private function isDMSValue(string $value): bool
{
return preg_match('/([°\'"]+[NESW])/', $value) > 0;
}
private function convertValue(string $value): false|float
{
$matches = [];
$result = preg_match_all('/(\d{1,3})°(\d{1,2})\'(\d{1,2}[\.\d]{0,6})"[NESW]/i', $value, $matches);
if ($result === false || $result === 0) {
return false;
}
return $matches[1][0] + $matches[2][0] / 60 + ((float) $matches[3][0]) / 3600;
}
private function removeWhiteSpace(string $value): string
{
return preg_replace('/\s/', '', $value);
}
private function removeDegreeSign(string $value): string
{
return str_replace('°', '', $value);
}
private function isValueInbound(float $value, float $boundary): bool
{
$max = $boundary;
$min = -1 * $boundary;
return $min <= $value && $value <= $max;
}
}

View File

@@ -1,158 +0,0 @@
<?php
namespace Laminas\Validator;
use Laminas\Stdlib\ArrayUtils;
use Traversable;
use function array_key_exists;
use function array_shift;
use function func_get_args;
use function is_array;
/**
* @deprecated Since 2.60.0 - This validator has been superseded by the NumberComparison and DateComparison validators
*
* @final
*/
class GreaterThan extends AbstractValidator
{
public const NOT_GREATER = 'notGreaterThan';
public const NOT_GREATER_INCLUSIVE = 'notGreaterThanInclusive';
/**
* Validation failure message template definitions
*
* @var array
*/
protected $messageTemplates = [
self::NOT_GREATER => "The input is not greater than '%min%'",
self::NOT_GREATER_INCLUSIVE => "The input is not greater than or equal to '%min%'",
];
/** @var array */
protected $messageVariables = [
'min' => 'min',
];
/**
* Minimum value
*
* @var mixed
*/
protected $min;
/**
* Whether to do inclusive comparisons, allowing equivalence to max
*
* If false, then strict comparisons are done, and the value may equal
* the min option
*
* @var bool
*/
protected $inclusive;
/**
* Sets validator options
*
* @param array|Traversable $options
* @throws Exception\InvalidArgumentException
*/
public function __construct($options = null)
{
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
}
if (! is_array($options)) {
$options = func_get_args();
$temp['min'] = array_shift($options);
if (! empty($options)) {
$temp['inclusive'] = array_shift($options);
}
$options = $temp;
}
if (! array_key_exists('min', $options)) {
throw new Exception\InvalidArgumentException("Missing option 'min'");
}
if (! array_key_exists('inclusive', $options)) {
$options['inclusive'] = false;
}
$this->setMin($options['min'])
->setInclusive($options['inclusive']);
parent::__construct($options);
}
/**
* Returns the min option
*
* @return mixed
*/
public function getMin()
{
return $this->min;
}
/**
* Sets the min option
*
* @return $this Provides a fluent interface
*/
public function setMin(mixed $min)
{
$this->min = $min;
return $this;
}
/**
* Returns the inclusive option
*
* @return bool
*/
public function getInclusive()
{
return $this->inclusive;
}
/**
* Sets the inclusive option
*
* @param bool $inclusive
* @return $this Provides a fluent interface
*/
public function setInclusive($inclusive)
{
$this->inclusive = $inclusive;
return $this;
}
/**
* Returns true if and only if $value is greater than min option
*
* @param mixed $value
* @return bool
*/
public function isValid($value)
{
$this->setValue($value);
if ($this->inclusive) {
if ($this->min > $value) {
$this->error(self::NOT_GREATER_INCLUSIVE);
return false;
}
} else {
if ($this->min >= $value) {
$this->error(self::NOT_GREATER);
return false;
}
}
return true;
}
}

View File

@@ -1,46 +0,0 @@
<?php
namespace Laminas\Validator;
use function ctype_xdigit;
use function is_int;
use function is_string;
/** @final */
class Hex extends AbstractValidator
{
public const INVALID = 'hexInvalid';
public const NOT_HEX = 'notHex';
/**
* Validation failure message template definitions
*
* @var array
*/
protected $messageTemplates = [
self::INVALID => 'Invalid type given. String expected',
self::NOT_HEX => 'The input contains non-hexadecimal characters',
];
/**
* Returns true if and only if $value contains only hexadecimal digit characters
*
* @param mixed $value
* @return bool
*/
public function isValid($value)
{
if (! is_string($value) && ! is_int($value)) {
$this->error(self::INVALID);
return false;
}
$this->setValue($value);
if (! ctype_xdigit((string) $value)) {
$this->error(self::NOT_HEX);
return false;
}
return true;
}
}

View File

@@ -1,150 +0,0 @@
<?php
declare(strict_types=1);
namespace Laminas\Validator;
use function explode;
use function filter_var;
use function get_debug_type;
use function gethostbynamel;
use function ip2long;
use function is_array;
use function is_string;
use function pow;
use const FILTER_FLAG_GLOBAL_RANGE;
use const FILTER_FLAG_IPV4;
use const FILTER_FLAG_NO_PRIV_RANGE;
use const FILTER_FLAG_NO_RES_RANGE;
use const FILTER_VALIDATE_IP;
final class HostWithPublicIPv4Address extends AbstractValidator
{
/**
* Reserved CIDRs are extracted from IANA with additions from Wikipedia
*
* @link https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
* @link https://en.wikipedia.org/wiki/Reserved_IP_addresses
*/
private const RESERVED_CIDR = [
'0.0.0.0/8',
'0.0.0.0/32',
'10.0.0.0/8',
'100.64.0.0/10',
'127.0.0.0/8',
'169.254.0.0/16',
'172.16.0.0/12',
'192.0.0.0/24',
'192.0.0.0/29',
'192.0.0.8/32',
'192.0.0.9/32',
'192.0.0.10/32',
'192.0.0.170/32',
'192.0.0.171/32',
'192.0.2.0/24',
'192.31.196.0/24',
'192.52.193.0/24',
'192.88.99.0/24',
'192.168.0.0/16',
'192.175.48.0/24',
'198.18.0.0/15',
'198.51.100.0/24',
'203.0.113.0/24',
'224.0.0.0/4', // Wikipedia
'233.252.0.0/24', // Wikipedia
'240.0.0.0/4',
'255.255.255.255/32',
];
public const ERROR_NOT_STRING = 'hostnameNotString';
public const ERROR_HOSTNAME_NOT_RESOLVED = 'hostnameNotResolved';
public const ERROR_PRIVATE_IP_FOUND = 'privateIpAddressFound';
/** @var array<non-empty-string, non-empty-string> */
protected array $messageTemplates = [
self::ERROR_NOT_STRING => 'Expected a string hostname but received %type%',
self::ERROR_HOSTNAME_NOT_RESOLVED => 'The hostname "%value%" cannot be resolved',
self::ERROR_PRIVATE_IP_FOUND => 'The hostname "%value%" resolves to at least one reserved IPv4 address',
];
protected string $type = 'null';
/** @var array<non-empty-string, non-empty-string> */
protected array $messageVariables = [
'type' => 'type',
'value' => 'value',
];
public function isValid(mixed $value): bool
{
$this->type = get_debug_type($value);
if (! is_string($value)) {
$this->error(self::ERROR_NOT_STRING);
return false;
}
$this->value = $value;
if (filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false) {
$addressList = gethostbynamel($value);
} else {
$addressList = [$value];
}
if (! is_array($addressList)) {
$this->error(self::ERROR_HOSTNAME_NOT_RESOLVED);
return false;
}
$privateAddressWasFound = false;
$filterFlags = FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_GLOBAL_RANGE;
foreach ($addressList as $server) {
/**
* Initially test with PHP's built-in filter_var features as this will be quicker than checking
* presence with a CIDR
*/
if (filter_var($server, FILTER_VALIDATE_IP, $filterFlags) === false) {
$privateAddressWasFound = true;
break;
}
if ($this->inReservedCidr($server)) {
$privateAddressWasFound = true;
break;
}
}
if ($privateAddressWasFound) {
$this->error(self::ERROR_PRIVATE_IP_FOUND);
return false;
}
return true;
}
private function inReservedCidr(string $ip): bool
{
foreach (self::RESERVED_CIDR as $cidr) {
$cidr = explode('/', $cidr);
$startIp = ip2long($cidr[0]);
$endIp = ip2long($cidr[0]) + pow(2, 32 - (int) $cidr[1]) - 1;
$int = ip2long($ip);
if ($int >= $startIp && $int <= $endIp) {
return true;
}
}
return false;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,316 +0,0 @@
<?php // phpcs:disable PSR12.Files.FileHeader.IncorrectOrder
namespace Laminas\Validator\Hostname;
/**
* Resource file for chinese idn validation
*/
return [
1 => '/^[\x{002d}0-9a-z\x{3447}\x{3473}\x{359E}\x{360E}\x{361A}\x{3918}\x{396E}\x{39CF}\x{39D0}'
. '\x{39DF}\x{3A73}\x{3B4E}\x{3C6E}\x{3CE0}\x{4056}\x{415F}\x{4337}\x{43AC}'
. '\x{43B1}\x{43DD}\x{44D6}\x{464C}\x{4661}\x{4723}\x{4729}\x{477C}\x{478D}'
. '\x{4947}\x{497A}\x{497D}\x{4982}\x{4983}\x{4985}\x{4986}\x{499B}\x{499F}'
. '\x{49B6}\x{49B7}\x{4C77}\x{4C9F}-\x{4CA3}\x{4D13}-\x{4D19}\x{4DAE}'
. '\x{4E00}-\x{4E11}\x{4E13}-\x{4E28}\x{4E2A}-\x{4E54}\x{4E56}-\x{4E67}'
. '\x{4E69}-\x{4E78}\x{4E7A}-\x{4E89}\x{4E8B}-\x{4E95}\x{4E97}-\x{4EA2}'
. '\x{4EA4}-\x{4EBB}\x{4EBD}-\x{4ECB}\x{4ECD}-\x{4EE6}\x{4EE8}-\x{4EEC}'
. '\x{4EEF}-\x{4EF7}\x{4EFB}\x{4EFD}\x{4EFF}-\x{4F06}\x{4F08}-\x{4F15}'
. '\x{4F17}-\x{4F27}\x{4F29}-\x{4F30}\x{4F32}-\x{4F34}\x{4F36}\x{4F38}-\x{4F3F}'
. '\x{4F41}-\x{4F43}\x{4F45}-\x{4F70}\x{4F72}-\x{4F8B}\x{4F8D}\x{4F8F}-\x{4FA1}'
. '\x{4FA3}-\x{4FAC}\x{4FAE}-\x{4FBC}\x{4FBE}-\x{4FC5}\x{4FC7}\x{4FC9}-\x{4FCB}'
. '\x{4FCD}-\x{4FE1}\x{4FE3}-\x{4FFB}\x{4FFE}-\x{500F}\x{5011}-\x{5033}'
. '\x{5035}-\x{5037}\x{5039}-\x{503C}\x{503E}-\x{5041}\x{5043}-\x{504F}\x{5051}'
. '\x{5053}-\x{5057}\x{5059}-\x{507B}\x{507D}-\x{5080}\x{5082}-\x{5092}'
. '\x{5094}-\x{5096}\x{5098}-\x{509E}\x{50A2}-\x{50B8}\x{50BA}-\x{50C2}'
. '\x{50C4}-\x{50D7}\x{50D9}-\x{50DE}\x{50E0}\x{50E3}-\x{50EA}\x{50EC}-\x{50F3}'
. '\x{50F5}\x{50F6}\x{50F8}-\x{511A}\x{511C}-\x{5127}\x{5129}\x{512A}'
. '\x{512C}-\x{5141}\x{5143}-\x{5149}\x{514B}-\x{514E}\x{5150}-\x{5152}'
. '\x{5154}-\x{5157}\x{5159}-\x{515F}\x{5161}-\x{5163}\x{5165}-\x{5171}'
. '\x{5173}-\x{517D}\x{517F}-\x{5182}\x{5185}-\x{518D}\x{518F}-\x{51A0}\x{51A2}'
. '\x{51A4}-\x{51A8}\x{51AA}-\x{51AC}\x{51AE}-\x{51B3}\x{51B5}-\x{51B7}\x{51B9}'
. '\x{51BB}-\x{51C1}\x{51C3}-\x{51D1}\x{51D4}-\x{51DE}\x{51E0}-\x{51E5}'
. '\x{51E7}-\x{51EB}\x{51ED}\x{51EF}-\x{51F1}\x{51F3}-\x{5226}\x{5228}-\x{524E}'
. '\x{5250}-\x{5252}\x{5254}-\x{5265}\x{5267}-\x{5270}\x{5272}-\x{5278}'
. '\x{527A}-\x{5284}\x{5286}-\x{528D}\x{528F}-\x{52A3}\x{52A5}-\x{52C3}\x{52C6}'
. '\x{52C7}\x{52C9}-\x{52CB}\x{52CD}\x{52CF}\x{52D0}\x{52D2}\x{52D3}'
. '\x{52D5}-\x{52E0}\x{52E2}-\x{52E4}\x{52E6}-\x{52ED}\x{52EF}-\x{5302}'
. '\x{5305}-\x{5317}\x{5319}\x{531A}\x{531C}\x{531D}\x{531F}-\x{5326}\x{5328}'
. '\x{532A}-\x{5331}\x{5333}\x{5334}\x{5337}\x{5339}-\x{5341}\x{5343}-\x{535A}'
. '\x{535C}\x{535E}-\x{5367}\x{5369}\x{536B}\x{536C}\x{536E}-\x{537F}'
. '\x{5381}-\x{53A0}\x{53A2}-\x{53A9}\x{53AC}-\x{53AE}\x{53B0}-\x{53B9}'
. '\x{53BB}-\x{53C4}\x{53C6}-\x{53CE}\x{53D0}-\x{53D9}\x{53DB}\x{53DC}'
. '\x{53DF}-\x{53E6}\x{53E8}-\x{53FE}\x{5401}-\x{5419}\x{541B}-\x{5421}'
. '\x{5423}-\x{544B}\x{544D}-\x{545C}\x{545E}-\x{5468}\x{546A}-\x{5489}'
. '\x{548B}-\x{54B4}\x{54B6}-\x{54F5}\x{54F7}-\x{5514}\x{5516}\x{5517}'
. '\x{551A}-\x{5546}\x{5548}-\x{555F}\x{5561}-\x{5579}\x{557B}-\x{55DF}'
. '\x{55E1}-\x{55F7}\x{55F9}-\x{5604}\x{5606}-\x{5609}\x{560C}-\x{561F}'
. '\x{5621}-\x{562A}\x{562C}-\x{5636}\x{5638}-\x{563B}\x{563D}-\x{5643}'
. '\x{5645}-\x{564A}\x{564C}-\x{5650}\x{5652}-\x{5655}\x{5657}-\x{565E}\x{5660}'
. '\x{5662}-\x{5674}\x{5676}-\x{567C}\x{567E}-\x{5687}\x{568A}\x{568C}-\x{5695}'
. '\x{5697}-\x{569D}\x{569F}-\x{56A1}\x{56A3}-\x{56B9}\x{56BB}-\x{56CE}'
. '\x{56D0}-\x{56D8}\x{56DA}-\x{56E5}\x{56E7}-\x{56F5}\x{56F7}\x{56F9}\x{56FA}'
. '\x{56FD}-\x{5704}\x{5706}-\x{5710}\x{5712}-\x{5716}\x{5718}-\x{5720}\x{5722}'
. '\x{5723}\x{5725}-\x{573C}\x{573E}-\x{5742}\x{5744}-\x{5747}\x{5749}-\x{5754}'
. '\x{5757}\x{5759}-\x{5762}\x{5764}-\x{576D}\x{576F}-\x{5777}\x{5779}-\x{5780}'
. '\x{5782}-\x{5786}\x{5788}-\x{5795}\x{5797}-\x{57A7}\x{57A9}-\x{57C9}'
. '\x{57CB}-\x{57D0}\x{57D2}-\x{57D6}\x{57D8}-\x{57DA}\x{57DC}\x{57DD}'
. '\x{57DF}-\x{5816}\x{5819}-\x{5840}\x{5842}-\x{584F}\x{5851}-\x{5855}'
. '\x{5857}-\x{585F}\x{5861}-\x{5865}\x{5868}-\x{5876}\x{5878}-\x{5894}'
. '\x{5896}-\x{58A9}\x{58AB}-\x{58B4}\x{58B7}-\x{58BF}\x{58C1}\x{58C2}'
. '\x{58C5}-\x{58CB}\x{58CE}\x{58CF}\x{58D1}-\x{58DB}\x{58DD}-\x{58E0}'
. '\x{58E2}-\x{58E5}\x{58E7}-\x{58F4}\x{58F6}-\x{5900}\x{5902}-\x{5904}\x{5906}'
. '\x{5907}\x{5909}-\x{5910}\x{5912}\x{5914}-\x{5922}\x{5924}-\x{5932}\x{5934}'
. '\x{5935}\x{5937}-\x{5958}\x{595A}\x{595C}-\x{599A}\x{599C}-\x{59B6}'
. '\x{59B8}-\x{59E6}\x{59E8}-\x{5A23}\x{5A25}\x{5A27}-\x{5A2B}\x{5A2D}-\x{5A2F}'
. '\x{5A31}-\x{5A53}\x{5A55}-\x{5A58}\x{5A5A}-\x{5A6E}\x{5A70}\x{5A72}-\x{5A86}'
. '\x{5A88}-\x{5A8C}\x{5A8E}-\x{5AAA}\x{5AAC}-\x{5ACF}\x{5AD1}\x{5AD2}'
. '\x{5AD4}-\x{5AEE}\x{5AF1}-\x{5B09}\x{5B0B}\x{5B0C}\x{5B0E}-\x{5B38}'
. '\x{5B3A}-\x{5B45}\x{5B47}-\x{5B4E}\x{5B50}\x{5B51}\x{5B53}-\x{5B5F}'
. '\x{5B62}-\x{5B6E}\x{5B70}-\x{5B78}\x{5B7A}-\x{5B7D}\x{5B7F}-\x{5B85}'
. '\x{5B87}-\x{5B8F}\x{5B91}-\x{5BA8}\x{5BAA}-\x{5BB1}\x{5BB3}-\x{5BB6}'
. '\x{5BB8}-\x{5BBB}\x{5BBD}-\x{5BC7}\x{5BCA}-\x{5BD6}\x{5BD8}\x{5BD9}'
. '\x{5BDB}-\x{5BFD}\x{5BFF}\x{5C01}\x{5C03}-\x{5C1A}\x{5C1C}-\x{5C22}\x{5C24}'
. '\x{5C25}\x{5C27}\x{5C28}\x{5C2A}-\x{5C35}\x{5C37}-\x{5C59}\x{5C5B}-\x{5C84}'
. '\x{5C86}-\x{5CB3}\x{5CB5}-\x{5CB8}\x{5CBA}-\x{5CBF}\x{5CC1}-\x{5CD4}'
. '\x{5CD6}-\x{5CDC}\x{5CDE}-\x{5CF4}\x{5CF6}-\x{5D2A}\x{5D2C}-\x{5D2E}'
. '\x{5D30}-\x{5D3A}\x{5D3C}-\x{5D52}\x{5D54}-\x{5D56}\x{5D58}-\x{5D5B}'
. '\x{5D5D}-\x{5D5F}\x{5D61}-\x{5D82}\x{5D84}-\x{5D95}\x{5D97}-\x{5DA2}'
. '\x{5DA5}-\x{5DAA}\x{5DAC}-\x{5DB2}\x{5DB4}-\x{5DB8}\x{5DBA}-\x{5DC3}'
. '\x{5DC5}-\x{5DD6}\x{5DD8}\x{5DD9}\x{5DDB}\x{5DDD}-\x{5DF5}\x{5DF7}-\x{5E11}'
. '\x{5E13}-\x{5E3E}\x{5E40}-\x{5E47}\x{5E49}-\x{5E50}\x{5E52}-\x{5E91}'
. '\x{5E93}-\x{5EB9}\x{5EBB}-\x{5EBF}\x{5EC1}-\x{5EEA}\x{5EEC}-\x{5EF8}'
. '\x{5EFA}-\x{5F08}\x{5F0A}-\x{5F0D}\x{5F0F}\x{5F11}-\x{5F3A}\x{5F3C}'
. '\x{5F3E}-\x{5F8E}\x{5F90}-\x{5F99}\x{5F9B}-\x{5FA2}\x{5FA5}-\x{5FAF}'
. '\x{5FB1}-\x{5FC1}\x{5FC3}-\x{5FCD}\x{5FCF}-\x{5FDA}\x{5FDC}-\x{5FDE}\x{5FE0}'
. '\x{5FE1}\x{5FE3}-\x{5FEB}\x{5FED}-\x{5FFB}\x{5FFD}-\x{6022}\x{6024}-\x{6055}'
. '\x{6057}-\x{605F}\x{6062}-\x{6070}\x{6072}\x{6073}\x{6075}-\x{6090}\x{6092}'
. '\x{6094}-\x{60A4}\x{60A6}-\x{60A8}\x{60AA}-\x{60D1}\x{60D3}-\x{60D5}'
. '\x{60D7}-\x{60DD}\x{60DF}-\x{60E2}\x{60E4}\x{60E6}-\x{60FC}\x{60FE}-\x{6101}'
. '\x{6103}-\x{6106}\x{6108}-\x{6110}\x{6112}-\x{611D}\x{611F}\x{6120}'
. '\x{6122}-\x{6130}\x{6132}\x{6134}\x{6136}\x{6137}\x{613A}-\x{615F}'
. '\x{6161}-\x{616E}\x{6170}-\x{617A}\x{617C}\x{617E}\x{6180}-\x{6185}'
. '\x{6187}-\x{6196}\x{6198}-\x{619B}\x{619D}-\x{61B8}\x{61BA}\x{61BC}-\x{61D2}'
. '\x{61D4}\x{61D6}-\x{61EB}\x{61ED}\x{61EE}\x{61F0}-\x{61F3}\x{61F5}-\x{6204}'
. '\x{6206}-\x{6234}\x{6236}-\x{6238}\x{623A}-\x{6256}\x{6258}-\x{6281}'
. '\x{6283}-\x{628C}\x{628E}-\x{629C}\x{629E}-\x{62A5}\x{62A7}-\x{62DD}'
. '\x{62DF}-\x{62E9}\x{62EB}-\x{6309}\x{630B}-\x{6316}\x{6318}-\x{6330}'
. '\x{6332}-\x{6334}\x{6336}\x{6338}-\x{633E}\x{6340}-\x{635A}\x{635C}-\x{637E}'
. '\x{6380}-\x{638A}\x{638C}-\x{6392}\x{6394}-\x{63BA}\x{63BC}-\x{63D0}'
. '\x{63D2}-\x{6406}\x{6408}-\x{643A}\x{643D}-\x{6441}\x{6443}-\x{6448}'
. '\x{644A}-\x{6459}\x{645B}-\x{647D}\x{647F}-\x{6485}\x{6487}-\x{64A0}'
. '\x{64A2}-\x{64AE}\x{64B0}-\x{64B5}\x{64B7}-\x{64C7}\x{64C9}-\x{64D4}'
. '\x{64D6}-\x{64E0}\x{64E2}-\x{64E4}\x{64E6}-\x{64ED}\x{64EF}-\x{64F4}'
. '\x{64F6}-\x{64F8}\x{64FA}-\x{6501}\x{6503}-\x{6509}\x{650B}-\x{651E}'
. '\x{6520}-\x{6527}\x{6529}-\x{653F}\x{6541}\x{6543}-\x{6559}\x{655B}-\x{655E}'
. '\x{6560}-\x{656C}\x{656E}-\x{657C}\x{657E}-\x{6589}\x{658B}-\x{6599}'
. '\x{659B}-\x{65B4}\x{65B6}-\x{65BD}\x{65BF}-\x{65C7}\x{65CA}-\x{65D0}'
. '\x{65D2}-\x{65D7}\x{65DA}\x{65DB}\x{65DD}-\x{65E3}\x{65E5}-\x{65E9}'
. '\x{65EB}-\x{65F8}\x{65FA}-\x{65FD}\x{6600}-\x{6616}\x{6618}-\x{661D}'
. '\x{661F}-\x{662B}\x{662D}-\x{6636}\x{6639}\x{663A}\x{663C}-\x{663E}'
. '\x{6640}-\x{6647}\x{6649}-\x{664C}\x{664E}-\x{665F}\x{6661}\x{6662}'
. '\x{6664}-\x{6666}\x{6668}-\x{6691}\x{6693}-\x{669B}\x{669D}\x{669F}-\x{66AB}'
. '\x{66AE}-\x{66CF}\x{66D1}\x{66D2}\x{66D4}-\x{66D6}\x{66D8}-\x{66DE}'
. '\x{66E0}-\x{66EE}\x{66F0}-\x{66FC}\x{66FE}-\x{6701}\x{6703}-\x{6706}'
. '\x{6708}-\x{6718}\x{671A}-\x{6723}\x{6725}-\x{6728}\x{672A}-\x{6766}'
. '\x{6768}-\x{6787}\x{6789}-\x{6795}\x{6797}-\x{67A8}\x{67AA}-\x{67BC}\x{67BE}'
. '\x{67C0}-\x{67D4}\x{67D6}\x{67D8}-\x{67F8}\x{67FA}-\x{6800}\x{6802}-\x{6814}'
. '\x{6816}-\x{681D}\x{681F}-\x{6826}\x{6828}-\x{682F}\x{6831}-\x{6857}\x{685B}'
. '\x{685D}\x{6860}-\x{6879}\x{687B}-\x{6894}\x{6896}-\x{6898}\x{689A}-\x{68A4}'
. '\x{68A6}-\x{68B7}\x{68B9}\x{68BB}-\x{68C2}\x{68C4}\x{68C6}-\x{68D8}'
. '\x{68DA}-\x{68E1}\x{68E3}\x{68E4}\x{68E6}-\x{68FF}\x{6901}-\x{6908}'
. '\x{690A}-\x{693D}\x{693F}-\x{694C}\x{694E}-\x{699E}\x{69A0}\x{69A1}'
. '\x{69A3}-\x{69BF}\x{69C1}-\x{69D0}\x{69D3}\x{69D4}\x{69D8}-\x{69F8}'
. '\x{69FA}-\x{6A02}\x{6A04}-\x{6A0B}\x{6A0D}-\x{6A1B}\x{6A1D}-\x{6A23}'
. '\x{6A25}-\x{6A36}\x{6A38}-\x{6A49}\x{6A4B}-\x{6A52}\x{6A54}-\x{6A5B}'
. '\x{6A5D}-\x{6A6D}\x{6A6F}\x{6A71}-\x{6A85}\x{6A87}-\x{6A89}\x{6A8B}-\x{6A8E}'
. '\x{6A90}-\x{6A98}\x{6A9A}-\x{6A9C}\x{6A9E}-\x{6AA9}\x{6AAB}-\x{6AB0}'
. '\x{6AB2}-\x{6ABD}\x{6ABF}\x{6AC1}-\x{6AC3}\x{6AC5}-\x{6AC7}\x{6ACA}-\x{6AD7}'
. '\x{6AD9}-\x{6AE8}\x{6AEA}-\x{6B0D}\x{6B0F}-\x{6B1A}\x{6B1C}-\x{6B2D}'
. '\x{6B2F}-\x{6B34}\x{6B36}-\x{6B3F}\x{6B41}-\x{6B56}\x{6B59}-\x{6B5C}'
. '\x{6B5E}-\x{6B67}\x{6B69}-\x{6B6B}\x{6B6D}\x{6B6F}\x{6B70}\x{6B72}-\x{6B74}'
. '\x{6B76}-\x{6B7C}\x{6B7E}-\x{6BB0}\x{6BB2}-\x{6BB7}\x{6BB9}-\x{6BE8}'
. '\x{6BEA}-\x{6BF0}\x{6BF2}\x{6BF3}\x{6BF5}-\x{6BF9}\x{6BFB}-\x{6C09}'
. '\x{6C0B}-\x{6C16}\x{6C18}-\x{6C1B}\x{6C1D}-\x{6C2C}\x{6C2E}-\x{6C38}\x{6C3A}'
. '\x{6C3B}\x{6C3D}-\x{6C44}\x{6C46}-\x{6C6B}\x{6C6D}\x{6C6F}-\x{6C9F}'
. '\x{6CA1}-\x{6CD7}\x{6CD9}-\x{6CF3}\x{6CF5}-\x{6D01}\x{6D03}-\x{6D1B}'
. '\x{6D1D}-\x{6D23}\x{6D25}-\x{6D70}\x{6D72}-\x{6D80}\x{6D82}-\x{6D95}'
. '\x{6D97}-\x{6D9B}\x{6D9D}-\x{6DAF}\x{6DB2}-\x{6DB5}\x{6DB7}-\x{6DFD}\x{6E00}'
. '\x{6E03}-\x{6E05}\x{6E07}-\x{6E11}\x{6E14}-\x{6E17}\x{6E19}-\x{6E29}'
. '\x{6E2B}-\x{6E4B}\x{6E4D}-\x{6E6B}\x{6E6D}-\x{6E75}\x{6E77}-\x{6E79}'
. '\x{6E7E}-\x{6E8A}\x{6E8D}-\x{6E94}\x{6E96}-\x{6EDA}\x{6EDC}\x{6EDE}-\x{6EE2}'
. '\x{6EE4}-\x{6F03}\x{6F05}-\x{6F0A}\x{6F0C}-\x{6F41}\x{6F43}-\x{6F47}\x{6F49}'
. '\x{6F4B}-\x{6F78}\x{6F7A}-\x{6F97}\x{6F99}\x{6F9B}-\x{6F9E}\x{6FA0}-\x{6FB6}'
. '\x{6FB8}-\x{6FC4}\x{6FC6}-\x{6FCF}\x{6FD1}\x{6FD2}\x{6FD4}-\x{6FF4}'
. '\x{6FF6}-\x{6FFC}\x{6FFE}-\x{700F}\x{7011}\x{7012}\x{7014}-\x{701D}'
. '\x{701F}-\x{7046}\x{7048}-\x{704A}\x{704C}\x{704D}\x{704F}-\x{7071}'
. '\x{7074}-\x{707A}\x{707C}-\x{7080}\x{7082}-\x{708C}\x{708E}-\x{7096}'
. '\x{7098}-\x{709A}\x{709C}-\x{70A9}\x{70AB}-\x{70B1}\x{70B3}-\x{70B5}'
. '\x{70B7}-\x{70D4}\x{70D6}-\x{70FD}\x{70FF}-\x{7107}\x{7109}-\x{7113}'
. '\x{7115}-\x{7123}\x{7125}-\x{7132}\x{7135}-\x{713B}\x{713D}-\x{7154}\x{7156}'
. '\x{7158}-\x{716A}\x{716C}\x{716E}-\x{718C}\x{718E}-\x{7195}\x{7197}-\x{71A5}'
. '\x{71A7}-\x{71AA}\x{71AC}-\x{71B5}\x{71B7}-\x{71CB}\x{71CD}-\x{71D2}'
. '\x{71D4}-\x{71F2}\x{71F4}-\x{71F9}\x{71FB}-\x{71FF}\x{7201}-\x{720A}'
. '\x{720C}-\x{7210}\x{7212}-\x{7214}\x{7216}\x{7218}-\x{721F}\x{7221}-\x{7223}'
. '\x{7226}-\x{722E}\x{7230}-\x{7233}\x{7235}-\x{7244}\x{7246}-\x{724D}\x{724F}'
. '\x{7251}-\x{7254}\x{7256}-\x{729F}\x{72A1}-\x{72AA}\x{72AC}-\x{72BD}'
. '\x{72BF}-\x{7301}\x{7303}-\x{730F}\x{7311}-\x{731E}\x{7320}-\x{7327}'
. '\x{7329}-\x{732E}\x{7330}-\x{734E}\x{7350}-\x{7352}\x{7354}-\x{7362}'
. '\x{7364}-\x{739B}\x{739D}-\x{73C0}\x{73C2}-\x{73E0}\x{73E2}\x{73E3}'
. '\x{73E5}-\x{73F2}\x{73F4}-\x{73FA}\x{73FC}-\x{7417}\x{7419}-\x{7438}'
. '\x{743A}-\x{743D}\x{743F}-\x{7446}\x{7448}\x{744A}-\x{7457}\x{7459}-\x{745F}'
. '\x{7461}-\x{747A}\x{747C}-\x{7483}\x{7485}-\x{7495}\x{7497}-\x{749C}'
. '\x{749E}-\x{74A1}\x{74A3}-\x{74C6}\x{74CA}\x{74CB}\x{74CD}-\x{74EA}'
. '\x{74EC}-\x{750D}\x{750F}-\x{751F}\x{7521}-\x{7533}\x{7535}-\x{7540}'
. '\x{7542}-\x{7549}\x{754B}-\x{7551}\x{7553}\x{7554}\x{7556}-\x{755D}\x{755F}'
. '\x{7560}\x{7562}-\x{7570}\x{7572}\x{7574}-\x{7579}\x{757C}-\x{7584}'
. '\x{7586}-\x{758D}\x{758F}-\x{75A8}\x{75AA}-\x{75B6}\x{75B8}-\x{75DB}'
. '\x{75DD}-\x{75E8}\x{75EA}-\x{75ED}\x{75EF}-\x{762B}\x{762D}-\x{7643}'
. '\x{7646}-\x{764D}\x{764F}\x{7650}\x{7652}-\x{7654}\x{7656}-\x{7672}'
. '\x{7674}-\x{7679}\x{767B}-\x{768C}\x{768E}-\x{76A0}\x{76A3}\x{76A4}\x{76A6}'
. '\x{76A7}\x{76A9}-\x{76B2}\x{76B4}\x{76B5}\x{76B7}\x{76B8}\x{76BA}-\x{76C0}'
. '\x{76C2}-\x{76CA}\x{76CD}-\x{76D8}\x{76DA}-\x{76EA}\x{76EC}-\x{76FF}\x{7701}'
. '\x{7703}-\x{770D}\x{770F}-\x{7720}\x{7722}\x{7723}\x{7725}-\x{772A}'
. '\x{772C}-\x{773E}\x{7740}\x{7741}\x{7743}-\x{7763}\x{7765}-\x{7795}'
. '\x{7797}-\x{77A3}\x{77A5}-\x{77BD}\x{77BF}\x{77C0}\x{77C2}-\x{77D1}'
. '\x{77D3}-\x{77DC}\x{77DE}-\x{77E3}\x{77E5}\x{77E7}-\x{77F3}\x{77F6}-\x{7806}'
. '\x{7808}-\x{7823}\x{7825}-\x{7835}\x{7837}-\x{783E}\x{7840}\x{7841}'
. '\x{7843}-\x{7845}\x{7847}-\x{784A}\x{784C}-\x{784E}\x{7850}-\x{7875}'
. '\x{7877}-\x{7887}\x{7889}-\x{78C1}\x{78C3}-\x{78C6}\x{78C8}-\x{78D1}'
. '\x{78D3}-\x{78EF}\x{78F1}-\x{78F7}\x{78F9}-\x{78FF}\x{7901}-\x{7907}'
. '\x{7909}-\x{790C}\x{790E}-\x{7914}\x{7916}-\x{791E}\x{7921}-\x{7931}'
. '\x{7933}-\x{7935}\x{7937}-\x{7958}\x{795A}-\x{796B}\x{796D}\x{796F}-\x{7974}'
. '\x{7977}-\x{7985}\x{7988}-\x{799C}\x{799F}-\x{79A8}\x{79AA}-\x{79BB}'
. '\x{79BD}-\x{79C3}\x{79C5}\x{79C6}\x{79C8}-\x{79CB}\x{79CD}-\x{79D3}\x{79D5}'
. '\x{79D6}\x{79D8}-\x{7A00}\x{7A02}-\x{7A06}\x{7A08}\x{7A0A}-\x{7A2B}'
. '\x{7A2D}-\x{7A35}\x{7A37}\x{7A39}\x{7A3B}-\x{7A4E}\x{7A50}-\x{7A62}'
. '\x{7A65}-\x{7A69}\x{7A6B}-\x{7A6E}\x{7A70}-\x{7A81}\x{7A83}-\x{7A99}'
. '\x{7A9C}-\x{7AB8}\x{7ABA}\x{7ABE}-\x{7AC1}\x{7AC4}\x{7AC5}\x{7AC7}-\x{7AD6}'
. '\x{7AD8}\x{7AD9}\x{7ADB}-\x{7AE8}\x{7AEA}-\x{7AF4}\x{7AF6}-\x{7AFB}'
. '\x{7AFD}-\x{7B06}\x{7B08}-\x{7B1E}\x{7B20}-\x{7B26}\x{7B28}\x{7B2A}-\x{7B41}'
. '\x{7B43}-\x{7B52}\x{7B54}-\x{7B6E}\x{7B70}-\x{7B79}\x{7B7B}-\x{7B85}'
. '\x{7B87}-\x{7B91}\x{7B93}-\x{7BA2}\x{7BA4}\x{7BA6}-\x{7BAF}\x{7BB1}'
. '\x{7BB3}-\x{7BCE}\x{7BD0}-\x{7BF9}\x{7BFB}-\x{7C13}\x{7C15}-\x{7C1A}'
. '\x{7C1C}-\x{7C2D}\x{7C30}-\x{7C4E}\x{7C50}\x{7C51}\x{7C53}\x{7C54}'
. '\x{7C56}-\x{7C5C}\x{7C5E}-\x{7C75}\x{7C77}-\x{7C82}\x{7C84}-\x{7C86}'
. '\x{7C88}-\x{7C92}\x{7C94}-\x{7C99}\x{7C9B}-\x{7CAA}\x{7CAD}-\x{7CD2}'
. '\x{7CD4}-\x{7CD9}\x{7CDC}-\x{7CE0}\x{7CE2}\x{7CE4}\x{7CE7}-\x{7CFB}\x{7CFD}'
. '\x{7CFE}\x{7D00}-\x{7D22}\x{7D24}-\x{7D29}\x{7D2B}\x{7D2C}\x{7D2E}-\x{7D47}'
. '\x{7D49}-\x{7D4C}\x{7D4E}-\x{7D59}\x{7D5B}-\x{7D63}\x{7D65}-\x{7D77}'
. '\x{7D79}-\x{7D81}\x{7D83}-\x{7D94}\x{7D96}\x{7D97}\x{7D99}\x{7D9B}-\x{7DA3}'
. '\x{7DA5}-\x{7DA7}\x{7DA9}-\x{7DCC}\x{7DCE}-\x{7DD2}\x{7DD4}-\x{7DDB}'
. '\x{7DDD}-\x{7DE3}\x{7DE6}-\x{7DEA}\x{7DEC}-\x{7DFC}\x{7E00}-\x{7E17}'
. '\x{7E19}-\x{7E49}\x{7E4C}-\x{7E5A}\x{7E5C}-\x{7E63}\x{7E65}-\x{7E9C}'
. '\x{7E9E}-\x{7F3A}\x{7F3D}-\x{7F40}\x{7F42}-\x{7F45}\x{7F47}-\x{7F58}'
. '\x{7F5A}-\x{7F83}\x{7F85}-\x{7F8F}\x{7F91}-\x{7F96}\x{7F98}\x{7F9A}-\x{7FB3}'
. '\x{7FB5}-\x{7FD5}\x{7FD7}-\x{7FDC}\x{7FDE}-\x{7FE3}\x{7FE5}-\x{8009}'
. '\x{800B}-\x{802E}\x{8030}-\x{803B}\x{803D}-\x{803F}\x{8041}-\x{8065}'
. '\x{8067}-\x{8087}\x{8089}-\x{808D}\x{808F}-\x{8093}\x{8095}-\x{80A5}'
. '\x{80A9}-\x{80AB}\x{80AD}-\x{80B2}\x{80B4}-\x{80B8}\x{80BA}-\x{80DE}'
. '\x{80E0}-\x{8102}\x{8105}-\x{8116}\x{8118}-\x{8132}\x{8136}-\x{815E}'
. '\x{8160}-\x{8183}\x{8185}-\x{818F}\x{8191}-\x{8195}\x{8197}-\x{81CA}'
. '\x{81CC}-\x{81D2}\x{81D4}-\x{81E3}\x{81E5}-\x{81EE}\x{81F1}-\x{8212}'
. '\x{8214}-\x{8216}\x{8218}-\x{8223}\x{8225}-\x{822D}\x{822F}-\x{8240}'
. '\x{8242}-\x{8261}\x{8263}\x{8264}\x{8266}-\x{828B}\x{828D}-\x{82B1}'
. '\x{82B3}-\x{82E1}\x{82E3}-\x{82FB}\x{82FD}-\x{8309}\x{830B}-\x{830F}'
. '\x{8311}-\x{832F}\x{8331}-\x{8354}\x{8356}-\x{839E}\x{83A0}-\x{83B4}'
. '\x{83B6}-\x{83BD}\x{83BF}-\x{83E5}\x{83E7}-\x{83EC}\x{83EE}-\x{8413}\x{8415}'
. '\x{8418}-\x{841E}\x{8421}-\x{8457}\x{8459}-\x{8482}\x{8484}-\x{8494}'
. '\x{8496}-\x{84AC}\x{84AE}-\x{84B6}\x{84B8}-\x{84C2}\x{84C4}-\x{84D9}'
. '\x{84DB}-\x{84EC}\x{84EE}-\x{8504}\x{8506}-\x{850F}\x{8511}-\x{8531}'
. '\x{8534}-\x{854B}\x{854D}-\x{854F}\x{8551}-\x{857E}\x{8580}-\x{8592}'
. '\x{8594}-\x{8596}\x{8598}-\x{85B1}\x{85B3}-\x{85BA}\x{85BC}-\x{85CB}'
. '\x{85CD}-\x{85ED}\x{85EF}-\x{85F2}\x{85F4}-\x{85FB}\x{85FD}-\x{8602}'
. '\x{8604}-\x{860C}\x{860F}\x{8611}-\x{8614}\x{8616}-\x{861C}\x{861E}-\x{8636}'
. '\x{8638}-\x{8656}\x{8658}-\x{8674}\x{8676}-\x{8688}\x{868A}-\x{8691}'
. '\x{8693}-\x{869F}\x{86A1}-\x{86A5}\x{86A7}-\x{86CC}\x{86CE}-\x{86D4}'
. '\x{86D6}-\x{86DF}\x{86E1}-\x{86E6}\x{86E8}-\x{86FC}\x{86FE}-\x{871C}'
. '\x{871E}-\x{872E}\x{8730}-\x{873C}\x{873E}-\x{8744}\x{8746}-\x{874A}'
. '\x{874C}-\x{8770}\x{8772}-\x{877E}\x{8780}-\x{878D}\x{878F}-\x{8798}'
. '\x{879A}-\x{87D9}\x{87DB}-\x{87EF}\x{87F1}-\x{8806}\x{8808}-\x{8811}'
. '\x{8813}-\x{882C}\x{882E}-\x{8839}\x{883B}-\x{8846}\x{8848}-\x{8857}'
. '\x{8859}-\x{885B}\x{885D}\x{885E}\x{8860}-\x{8879}\x{887B}-\x{88B4}'
. '\x{88B6}-\x{88E5}\x{88E7}\x{88E8}\x{88EA}-\x{88EC}\x{88EE}-\x{8902}'
. '\x{8904}-\x{890E}\x{8910}-\x{8923}\x{8925}-\x{894C}\x{894E}-\x{8964}'
. '\x{8966}-\x{8974}\x{8976}-\x{897C}\x{897E}-\x{898C}\x{898E}\x{898F}'
. '\x{8991}-\x{8993}\x{8995}-\x{8998}\x{899A}-\x{89A8}\x{89AA}-\x{89AF}'
. '\x{89B1}-\x{89B3}\x{89B5}-\x{89BA}\x{89BD}-\x{89ED}\x{89EF}-\x{89F4}'
. '\x{89F6}-\x{89F8}\x{89FA}-\x{89FC}\x{89FE}-\x{8A04}\x{8A07}-\x{8A13}'
. '\x{8A15}-\x{8A18}\x{8A1A}-\x{8A1F}\x{8A22}-\x{8A2A}\x{8A2C}-\x{8A32}'
. '\x{8A34}-\x{8A3C}\x{8A3E}-\x{8A4A}\x{8A4C}-\x{8A63}\x{8A65}-\x{8A77}'
. '\x{8A79}-\x{8A7C}\x{8A7E}-\x{8A87}\x{8A89}-\x{8A9E}\x{8AA0}-\x{8AAC}\x{8AAE}'
. '\x{8AB0}-\x{8AB6}\x{8AB8}-\x{8ACF}\x{8AD1}-\x{8AEB}\x{8AED}-\x{8B0B}'
. '\x{8B0D}-\x{8B28}\x{8B2A}-\x{8B31}\x{8B33}-\x{8B37}\x{8B39}-\x{8B3E}'
. '\x{8B40}-\x{8B60}\x{8B63}-\x{8B68}\x{8B6A}-\x{8B71}\x{8B73}\x{8B74}'
. '\x{8B76}-\x{8B7B}\x{8B7D}-\x{8B80}\x{8B82}-\x{8B86}\x{8B88}-\x{8B8C}\x{8B8E}'
. '\x{8B90}-\x{8B9A}\x{8B9C}-\x{8C37}\x{8C39}-\x{8C3F}\x{8C41}-\x{8C43}'
. '\x{8C45}-\x{8C50}\x{8C54}-\x{8C57}\x{8C59}-\x{8C73}\x{8C75}-\x{8C7B}\x{8C7D}'
. '\x{8C7E}\x{8C80}-\x{8C82}\x{8C84}-\x{8C86}\x{8C88}-\x{8C8A}\x{8C8C}\x{8C8D}'
. '\x{8C8F}-\x{8C9A}\x{8C9C}-\x{8CA5}\x{8CA7}-\x{8CCA}\x{8CCC}\x{8CCE}-\x{8CD5}'
. '\x{8CD7}\x{8CD9}-\x{8CE8}\x{8CEA}-\x{8CF6}\x{8CF8}-\x{8D00}\x{8D02}-\x{8D10}'
. '\x{8D13}-\x{8D7B}\x{8D7D}-\x{8DA5}\x{8DA7}-\x{8DBF}\x{8DC1}-\x{8DE4}'
. '\x{8DE6}-\x{8E00}\x{8E02}-\x{8E0A}\x{8E0C}-\x{8E31}\x{8E33}-\x{8E45}'
. '\x{8E47}-\x{8E4E}\x{8E50}-\x{8E6D}\x{8E6F}-\x{8E74}\x{8E76}\x{8E78}'
. '\x{8E7A}-\x{8E98}\x{8E9A}\x{8E9C}-\x{8EA1}\x{8EA3}-\x{8EB2}\x{8EB4}\x{8EB5}'
. '\x{8EB8}-\x{8EC0}\x{8EC2}\x{8EC3}\x{8EC5}-\x{8ED8}\x{8EDA}-\x{8EE1}'
. '\x{8EE4}-\x{8EEF}\x{8EF1}-\x{8F0B}\x{8F0D}\x{8F0E}\x{8F10}-\x{8F18}'
. '\x{8F1A}-\x{8F2C}\x{8F2E}-\x{8F39}\x{8F3B}-\x{8F40}\x{8F42}-\x{8F5B}'
. '\x{8F5D}-\x{8F9C}\x{8F9E}-\x{8FA3}\x{8FA5}-\x{8FB2}\x{8FB4}-\x{8FB9}'
. '\x{8FBB}-\x{8FC2}\x{8FC4}-\x{8FC9}\x{8FCB}-\x{8FE6}\x{8FE8}-\x{900D}'
. '\x{900F}-\x{9029}\x{902B}\x{902D}-\x{9036}\x{9038}\x{903A}-\x{903F}'
. '\x{9041}-\x{9045}\x{9047}-\x{90AA}\x{90AC}-\x{90CB}\x{90CE}-\x{90D1}'
. '\x{90D3}-\x{90F5}\x{90F7}-\x{9109}\x{910B}-\x{913B}\x{913E}-\x{9158}'
. '\x{915A}-\x{917A}\x{917C}-\x{9194}\x{9196}\x{9199}-\x{91A3}\x{91A5}-\x{91A8}'
. '\x{91AA}-\x{91B7}\x{91B9}-\x{91BE}\x{91C0}-\x{91C3}\x{91C5}-\x{91C7}'
. '\x{91C9}-\x{91D5}\x{91D7}-\x{91DF}\x{91E2}-\x{91EE}\x{91F0}-\x{91F5}'
. '\x{91F7}-\x{91FB}\x{91FD}-\x{9212}\x{9214}-\x{921E}\x{9220}\x{9221}'
. '\x{9223}-\x{922B}\x{922D}-\x{9242}\x{9245}-\x{9268}\x{926B}-\x{9270}'
. '\x{9272}-\x{9280}\x{9282}\x{9283}\x{9285}-\x{929D}\x{929F}-\x{92BC}'
. '\x{92BE}-\x{92D3}\x{92D5}-\x{92DA}\x{92DC}-\x{92E1}\x{92E3}-\x{931B}'
. '\x{931D}-\x{932B}\x{932D}-\x{932F}\x{9332}-\x{9361}\x{9363}-\x{9367}\x{9369}'
. '\x{936A}\x{936C}-\x{936E}\x{9370}-\x{9372}\x{9374}-\x{9377}\x{9379}-\x{937E}'
. '\x{9380}\x{9382}-\x{938A}\x{938C}-\x{939B}\x{939D}-\x{939F}\x{93A1}-\x{93AA}'
. '\x{93AC}-\x{93BA}\x{93BC}-\x{93DF}\x{93E1}-\x{93E4}\x{93E6}-\x{93F2}'
. '\x{93F4}-\x{9401}\x{9403}-\x{9416}\x{9418}\x{9419}\x{941B}\x{941D}\x{9420}'
. '\x{9422}\x{9423}\x{9425}-\x{9442}\x{9444}-\x{944D}\x{944F}-\x{9459}'
. '\x{945B}-\x{946B}\x{946D}-\x{947A}\x{947C}-\x{9577}\x{957A}-\x{957D}'
. '\x{957F}-\x{9584}\x{9586}-\x{9596}\x{9598}-\x{959F}\x{95A1}-\x{95B2}'
. '\x{95B5}-\x{95B7}\x{95B9}-\x{95C0}\x{95C2}-\x{95D8}\x{95DA}-\x{95DC}'
. '\x{95DE}-\x{9624}\x{9627}\x{9628}\x{962A}-\x{963D}\x{963F}-\x{9655}'
. '\x{9658}-\x{9664}\x{9666}-\x{9678}\x{967C}-\x{967E}\x{9680}\x{9683}-\x{968B}'
. '\x{968D}-\x{9695}\x{9697}-\x{9699}\x{969B}\x{969C}\x{969E}\x{96A0}-\x{96AA}'
. '\x{96AC}-\x{96AE}\x{96B0}\x{96B1}\x{96B3}\x{96B4}\x{96B6}-\x{96E3}\x{96E5}'
. '\x{96E8}-\x{96FB}\x{96FD}-\x{9713}\x{9715}\x{9716}\x{9718}\x{9719}'
. '\x{971C}-\x{9732}\x{9735}\x{9736}\x{9738}-\x{973F}\x{9742}-\x{974C}'
. '\x{974E}-\x{9756}\x{9758}-\x{9762}\x{9765}-\x{9770}\x{9772}-\x{9774}'
. '\x{9776}-\x{9786}\x{9788}\x{978A}-\x{979A}\x{979C}-\x{97A8}\x{97AA}-\x{97AF}'
. '\x{97B2}-\x{97B4}\x{97B6}-\x{97BD}\x{97BF}\x{97C1}-\x{97D1}\x{97D3}-\x{97FB}'
. '\x{97FD}-\x{981E}\x{9820}-\x{9824}\x{9826}-\x{9829}\x{982B}\x{982D}-\x{9832}'
. '\x{9834}-\x{9839}\x{983B}-\x{983D}\x{983F}-\x{9841}\x{9843}-\x{9846}'
. '\x{9848}-\x{984A}\x{984C}-\x{9855}\x{9857}-\x{9865}\x{9867}\x{9869}-\x{98B6}'
. '\x{98B8}-\x{98C6}\x{98C8}\x{98C9}\x{98CB}-\x{98E0}\x{98E2}\x{98E3}'
. '\x{98E5}-\x{98EB}\x{98ED}\x{98EF}\x{98F0}\x{98F2}-\x{98F7}\x{98F9}\x{98FA}'
. '\x{98FC}-\x{9918}\x{991A}-\x{993A}\x{993C}-\x{9943}\x{9945}-\x{994C}'
. '\x{994E}-\x{9959}\x{995B}\x{995C}\x{995E}-\x{99BE}\x{99C0}-\x{99C4}'
. '\x{99C6}-\x{99DF}\x{99E1}-\x{99E5}\x{99E7}-\x{99EA}\x{99EC}-\x{99F4}'
. '\x{99F6}-\x{9A0F}\x{9A11}\x{9A14}-\x{9A16}\x{9A19}-\x{9A27}\x{9A29}-\x{9A3A}'
. '\x{9A3C}-\x{9A50}\x{9A52}-\x{9A57}\x{9A59}-\x{9A5C}\x{9A5E}-\x{9A62}'
. '\x{9A64}-\x{9AA8}\x{9AAA}-\x{9ABC}\x{9ABE}-\x{9AC7}\x{9AC9}-\x{9AD6}'
. '\x{9AD8}-\x{9ADF}\x{9AE1}-\x{9AE3}\x{9AE5}-\x{9AE7}\x{9AEA}-\x{9AEF}'
. '\x{9AF1}-\x{9AFF}\x{9B01}\x{9B03}-\x{9B08}\x{9B0A}-\x{9B13}\x{9B15}-\x{9B1A}'
. '\x{9B1C}-\x{9B33}\x{9B35}-\x{9B3C}\x{9B3E}\x{9B3F}\x{9B41}-\x{9B4F}'
. '\x{9B51}-\x{9B56}\x{9B58}-\x{9B61}\x{9B63}-\x{9B71}\x{9B73}-\x{9B88}\x{9B8A}'
. '\x{9B8B}\x{9B8D}-\x{9B98}\x{9B9A}-\x{9BC1}\x{9BC3}-\x{9BF5}\x{9BF7}-\x{9BFF}'
. '\x{9C02}\x{9C05}-\x{9C2D}\x{9C2F}-\x{9C41}\x{9C43}-\x{9C4E}\x{9C50}'
. '\x{9C52}-\x{9C60}\x{9C62}\x{9C63}\x{9C65}-\x{9C75}\x{9C77}-\x{9C7A}'
. '\x{9C7C}-\x{9D0B}\x{9D0F}\x{9D10}\x{9D12}-\x{9D26}\x{9D28}\x{9D29}\x{9D2B}'
. '\x{9D2D}-\x{9D34}\x{9D36}-\x{9D3B}\x{9D3D}-\x{9D43}\x{9D45}-\x{9D6C}'
. '\x{9D6E}-\x{9D8E}\x{9D90}-\x{9D94}\x{9D96}-\x{9DAD}\x{9DAF}-\x{9DBC}\x{9DBE}'
. '\x{9DBF}\x{9DC1}-\x{9DC5}\x{9DC7}-\x{9DE9}\x{9DEB}-\x{9DFB}\x{9DFD}-\x{9E0D}'
. '\x{9E0F}-\x{9E15}\x{9E17}-\x{9E1B}\x{9E1D}-\x{9E77}\x{9E79}\x{9E7A}'
. '\x{9E7C}-\x{9E8E}\x{9E91}-\x{9E94}\x{9E96}\x{9E97}\x{9E99}-\x{9E9D}'
. '\x{9E9F}-\x{9EA1}\x{9EA3}-\x{9EAA}\x{9EAD}-\x{9EB0}\x{9EB2}-\x{9EB8}'
. '\x{9EBB}-\x{9EEB}\x{9EED}-\x{9EF0}\x{9EF2}-\x{9F02}\x{9F04}-\x{9F10}\x{9F12}'
. '\x{9F13}\x{9F15}-\x{9F20}\x{9F22}-\x{9F25}\x{9F27}-\x{9F44}\x{9F46}-\x{9F52}'
. '\x{9F54}-\x{9F61}\x{9F63}-\x{9F6C}\x{9F6E}-\x{9FA0}\x{9FA2}\x{9FA4}\x{9FA5}]{1,20}$/iu',
];

View File

@@ -1,176 +0,0 @@
<?php // phpcs:disable PSR12.Files.FileHeader.IncorrectOrder,WebimpressCodingStandard.Arrays.DoubleArrow.SpacesBefore
namespace Laminas\Validator\Hostname;
/**
* Resource file for com and net idn validation
*/
return [
1 => '/^[\x{002d}0-9\x{0400}-\x{052f}]{1,63}$/iu',
2 => '/^[\x{002d}0-9\x{0370}-\x{03ff}]{1,63}$/iu',
3 => '/^[\x{002d}0-9a-z\x{ac00}-\x{d7a3}]{1,17}$/iu',
// @codingStandardsIgnoreStart
4 => '/^[\x{002d}0-9a-z·à-öø-ÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźżž]{1,63}$/iu',
// @codingStandardsIgnoreEnd
5 => '/^[\x{002d}0-9A-Za-z\x{3400}-\x{3401}\x{3404}-\x{3406}\x{340C}\x{3416}\x{341C}'
. '\x{3421}\x{3424}\x{3428}-\x{3429}\x{342B}-\x{342E}\x{3430}-\x{3434}\x{3436}'
. '\x{3438}-\x{343C}\x{343E}\x{3441}-\x{3445}\x{3447}\x{3449}-\x{3451}\x{3453}'
. '\x{3457}-\x{345F}\x{3463}-\x{3467}\x{346E}-\x{3471}\x{3473}-\x{3477}\x{3479}-\x{348E}\x{3491}-\x{3497}'
. '\x{3499}-\x{34A1}\x{34A4}-\x{34AD}\x{34AF}-\x{34B0}\x{34B2}-\x{34BF}\x{34C2}-\x{34C5}\x{34C7}-\x{34CC}'
. '\x{34CE}-\x{34D1}\x{34D3}-\x{34D8}\x{34DA}-\x{34E4}\x{34E7}-\x{34E9}\x{34EC}-\x{34EF}\x{34F1}-\x{34FE}'
. '\x{3500}-\x{3507}\x{350A}-\x{3513}\x{3515}\x{3517}-\x{351A}\x{351C}-\x{351E}\x{3520}-\x{352A}'
. '\x{352C}-\x{3552}\x{3554}-\x{355C}\x{355E}-\x{3567}\x{3569}-\x{3573}\x{3575}-\x{357C}\x{3580}-\x{3588}'
. '\x{358F}-\x{3598}\x{359E}-\x{35AB}\x{35B4}-\x{35CD}\x{35D0}\x{35D3}-\x{35DC}\x{35E2}-\x{35ED}'
. '\x{35F0}-\x{35F6}\x{35FB}-\x{3602}\x{3605}-\x{360E}\x{3610}-\x{3611}\x{3613}-\x{3616}\x{3619}-\x{362D}'
. '\x{362F}-\x{3634}\x{3636}-\x{363B}\x{363F}-\x{3645}\x{3647}-\x{364B}\x{364D}-\x{3653}\x{3655}'
. '\x{3659}-\x{365E}\x{3660}-\x{3665}\x{3667}-\x{367C}\x{367E}\x{3680}-\x{3685}\x{3687}'
. '\x{3689}-\x{3690}\x{3692}-\x{3698}\x{369A}\x{369C}-\x{36AE}\x{36B0}-\x{36BF}\x{36C1}-\x{36C5}'
. '\x{36C9}-\x{36CA}\x{36CD}-\x{36DE}\x{36E1}-\x{36E2}\x{36E5}-\x{36FE}\x{3701}-\x{3713}\x{3715}-\x{371E}'
. '\x{3720}-\x{372C}\x{372E}-\x{3745}\x{3747}-\x{3748}\x{374A}\x{374C}-\x{3759}\x{375B}-\x{3760}'
. '\x{3762}-\x{3767}\x{3769}-\x{3772}\x{3774}-\x{378C}\x{378F}-\x{379C}\x{379F}\x{37A1}-\x{37AD}'
. '\x{37AF}-\x{37B7}\x{37B9}-\x{37C1}\x{37C3}-\x{37C5}\x{37C7}-\x{37D4}\x{37D6}-\x{37E0}\x{37E2}'
. '\x{37E5}-\x{37ED}\x{37EF}-\x{37F6}\x{37F8}-\x{3802}\x{3804}-\x{381D}\x{3820}-\x{3822}\x{3825}-\x{382A}'
. '\x{382D}-\x{382F}\x{3831}-\x{3832}\x{3834}-\x{384C}\x{384E}-\x{3860}\x{3862}-\x{3863}\x{3865}-\x{386B}'
. '\x{386D}-\x{3886}\x{3888}-\x{38A1}\x{38A3}\x{38A5}-\x{38AA}\x{38AC}\x{38AE}-\x{38B0}'
. '\x{38B2}-\x{38B6}\x{38B8}\x{38BA}-\x{38BE}\x{38C0}-\x{38C9}\x{38CB}-\x{38D4}\x{38D8}-\x{38E0}'
. '\x{38E2}-\x{38E6}\x{38EB}-\x{38ED}\x{38EF}-\x{38F2}\x{38F5}-\x{38F7}\x{38FA}-\x{38FF}\x{3901}-\x{392A}'
. '\x{392C}\x{392E}-\x{393B}\x{393E}-\x{3956}\x{395A}-\x{3969}\x{396B}-\x{397A}\x{397C}-\x{3987}'
. '\x{3989}-\x{3998}\x{399A}-\x{39B0}\x{39B2}\x{39B4}-\x{39D0}\x{39D2}-\x{39DA}\x{39DE}-\x{39DF}'
. '\x{39E1}-\x{39EF}\x{39F1}-\x{3A17}\x{3A19}-\x{3A2A}\x{3A2D}-\x{3A40}\x{3A43}-\x{3A4E}\x{3A50}'
. '\x{3A52}-\x{3A5E}\x{3A60}-\x{3A6D}\x{3A6F}-\x{3A77}\x{3A79}-\x{3A82}\x{3A84}-\x{3A85}\x{3A87}-\x{3A89}'
. '\x{3A8B}-\x{3A8F}\x{3A91}-\x{3A93}\x{3A95}-\x{3A96}\x{3A9A}\x{3A9C}-\x{3AA6}\x{3AA8}-\x{3AA9}'
. '\x{3AAB}-\x{3AB1}\x{3AB4}-\x{3ABC}\x{3ABE}-\x{3AC5}\x{3ACA}-\x{3ACB}\x{3ACD}-\x{3AD5}\x{3AD7}-\x{3AE1}'
. '\x{3AE4}-\x{3AE7}\x{3AE9}-\x{3AEC}\x{3AEE}-\x{3AFD}\x{3B01}-\x{3B10}\x{3B12}-\x{3B15}\x{3B17}-\x{3B1E}'
. '\x{3B20}-\x{3B23}\x{3B25}-\x{3B27}\x{3B29}-\x{3B36}\x{3B38}-\x{3B39}\x{3B3B}-\x{3B3C}\x{3B3F}'
. '\x{3B41}-\x{3B44}\x{3B47}-\x{3B4C}\x{3B4E}\x{3B51}-\x{3B55}\x{3B58}-\x{3B62}\x{3B68}-\x{3B72}'
. '\x{3B78}-\x{3B88}\x{3B8B}-\x{3B9F}\x{3BA1}\x{3BA3}-\x{3BBA}\x{3BBC}\x{3BBF}-\x{3BD0}'
. '\x{3BD3}-\x{3BE6}\x{3BEA}-\x{3BFB}\x{3BFE}-\x{3C12}\x{3C14}-\x{3C1B}\x{3C1D}-\x{3C37}\x{3C39}-\x{3C4F}'
. '\x{3C52}\x{3C54}-\x{3C5C}\x{3C5E}-\x{3C68}\x{3C6A}-\x{3C76}\x{3C78}-\x{3C8F}\x{3C91}-\x{3CA8}'
. '\x{3CAA}-\x{3CAD}\x{3CAF}-\x{3CBE}\x{3CC0}-\x{3CC8}\x{3CCA}-\x{3CD3}\x{3CD6}-\x{3CE0}\x{3CE4}-\x{3CEE}'
. '\x{3CF3}-\x{3D0A}\x{3D0E}-\x{3D1E}\x{3D20}-\x{3D21}\x{3D25}-\x{3D38}\x{3D3B}-\x{3D46}\x{3D4A}-\x{3D59}'
. '\x{3D5D}-\x{3D7B}\x{3D7D}-\x{3D81}\x{3D84}-\x{3D88}\x{3D8C}-\x{3D8F}\x{3D91}-\x{3D98}\x{3D9A}-\x{3D9C}'
. '\x{3D9E}-\x{3DA1}\x{3DA3}-\x{3DB0}\x{3DB2}-\x{3DB5}\x{3DB9}-\x{3DBC}\x{3DBE}-\x{3DCB}\x{3DCD}-\x{3DDB}'
. '\x{3DDF}-\x{3DE8}\x{3DEB}-\x{3DF0}\x{3DF3}-\x{3DF9}\x{3DFB}-\x{3DFC}\x{3DFE}-\x{3E05}\x{3E08}-\x{3E33}'
. '\x{3E35}-\x{3E3E}\x{3E40}-\x{3E47}\x{3E49}-\x{3E67}\x{3E6B}-\x{3E6F}\x{3E71}-\x{3E85}\x{3E87}-\x{3E8C}'
. '\x{3E8E}-\x{3E98}\x{3E9A}-\x{3EA1}\x{3EA3}-\x{3EAE}\x{3EB0}-\x{3EB5}\x{3EB7}-\x{3EBA}\x{3EBD}'
. '\x{3EBF}-\x{3EC4}\x{3EC7}-\x{3ECE}\x{3ED1}-\x{3ED7}\x{3ED9}-\x{3EDA}\x{3EDD}-\x{3EE3}\x{3EE7}-\x{3EE8}'
. '\x{3EEB}-\x{3EF2}\x{3EF5}-\x{3EFF}\x{3F01}-\x{3F02}\x{3F04}-\x{3F07}\x{3F09}-\x{3F44}\x{3F46}-\x{3F4E}'
. '\x{3F50}-\x{3F53}\x{3F55}-\x{3F72}\x{3F74}-\x{3F75}\x{3F77}-\x{3F7B}\x{3F7D}-\x{3FB0}\x{3FB6}-\x{3FBF}'
. '\x{3FC1}-\x{3FCF}\x{3FD1}-\x{3FD3}\x{3FD5}-\x{3FDF}\x{3FE1}-\x{400B}\x{400D}-\x{401C}\x{401E}-\x{4024}'
. '\x{4027}-\x{403F}\x{4041}-\x{4060}\x{4062}-\x{4069}\x{406B}-\x{408A}\x{408C}-\x{40A7}\x{40A9}-\x{40B4}'
. '\x{40B6}-\x{40C2}\x{40C7}-\x{40CF}\x{40D1}-\x{40DE}\x{40E0}-\x{40E7}\x{40E9}-\x{40EE}\x{40F0}-\x{40FB}'
. '\x{40FD}-\x{4109}\x{410B}-\x{4115}\x{4118}-\x{411D}\x{411F}-\x{4122}\x{4124}-\x{4133}\x{4136}-\x{4138}'
. '\x{413A}-\x{4148}\x{414A}-\x{4169}\x{416C}-\x{4185}\x{4188}-\x{418B}\x{418D}-\x{41AD}\x{41AF}-\x{41B3}'
. '\x{41B5}-\x{41C3}\x{41C5}-\x{41C9}\x{41CB}-\x{41F2}\x{41F5}-\x{41FE}\x{4200}-\x{4227}\x{422A}-\x{4246}'
. '\x{4248}-\x{4263}\x{4265}-\x{428B}\x{428D}-\x{42A1}\x{42A3}-\x{42C4}\x{42C8}-\x{42DC}\x{42DE}-\x{430A}'
. '\x{430C}-\x{4335}\x{4337}\x{4342}-\x{435F}\x{4361}-\x{439A}\x{439C}-\x{439D}\x{439F}-\x{43A4}'
. '\x{43A6}-\x{43EC}\x{43EF}-\x{4405}\x{4407}-\x{4429}\x{442B}-\x{4455}\x{4457}-\x{4468}\x{446A}-\x{446D}'
. '\x{446F}-\x{4476}\x{4479}-\x{447D}\x{447F}-\x{4486}\x{4488}-\x{4490}\x{4492}-\x{4498}\x{449A}-\x{44AD}'
. '\x{44B0}-\x{44BD}\x{44C1}-\x{44D3}\x{44D6}-\x{44E7}\x{44EA}\x{44EC}-\x{44FA}\x{44FC}-\x{4541}'
. '\x{4543}-\x{454F}\x{4551}-\x{4562}\x{4564}-\x{4575}\x{4577}-\x{45AB}\x{45AD}-\x{45BD}\x{45BF}-\x{45D5}'
. '\x{45D7}-\x{45EC}\x{45EE}-\x{45F2}\x{45F4}-\x{45FA}\x{45FC}-\x{461A}\x{461C}-\x{461D}\x{461F}-\x{4631}'
. '\x{4633}-\x{4649}\x{464C}\x{464E}-\x{4652}\x{4654}-\x{466A}\x{466C}-\x{4675}\x{4677}-\x{467A}'
. '\x{467C}-\x{4694}\x{4696}-\x{46A3}\x{46A5}-\x{46AB}\x{46AD}-\x{46D2}\x{46D4}-\x{4723}\x{4729}-\x{4732}'
. '\x{4734}-\x{4758}\x{475A}\x{475C}-\x{478B}\x{478D}\x{4791}-\x{47B1}\x{47B3}-\x{47F1}'
. '\x{47F3}-\x{480B}\x{480D}-\x{4815}\x{4817}-\x{4839}\x{483B}-\x{4870}\x{4872}-\x{487A}\x{487C}-\x{487F}'
. '\x{4883}-\x{488E}\x{4890}-\x{4896}\x{4899}-\x{48A2}\x{48A4}-\x{48B9}\x{48BB}-\x{48C8}\x{48CA}-\x{48D1}'
. '\x{48D3}-\x{48E5}\x{48E7}-\x{48F2}\x{48F4}-\x{48FF}\x{4901}-\x{4922}\x{4924}-\x{4928}\x{492A}-\x{4931}'
. '\x{4933}-\x{495B}\x{495D}-\x{4978}\x{497A}\x{497D}\x{4982}-\x{4983}\x{4985}-\x{49A8}'
. '\x{49AA}-\x{49AF}\x{49B1}-\x{49B7}\x{49B9}-\x{49BD}\x{49C1}-\x{49C7}\x{49C9}-\x{49CE}\x{49D0}-\x{49E8}'
. '\x{49EA}\x{49EC}\x{49EE}-\x{4A19}\x{4A1B}-\x{4A43}\x{4A45}-\x{4A4D}\x{4A4F}-\x{4A9E}'
. '\x{4AA0}-\x{4AA9}\x{4AAB}-\x{4B4E}\x{4B50}-\x{4B5B}\x{4B5D}-\x{4B69}\x{4B6B}-\x{4BC2}\x{4BC6}-\x{4BE8}'
. '\x{4BEA}-\x{4BFA}\x{4BFC}-\x{4C06}\x{4C08}-\x{4C2D}\x{4C2F}-\x{4C32}\x{4C34}-\x{4C35}\x{4C37}-\x{4C69}'
. '\x{4C6B}-\x{4C73}\x{4C75}-\x{4C86}\x{4C88}-\x{4C97}\x{4C99}-\x{4C9C}\x{4C9F}-\x{4CA3}\x{4CA5}-\x{4CB5}'
. '\x{4CB7}-\x{4CF8}\x{4CFA}-\x{4D27}\x{4D29}-\x{4DAC}\x{4DAE}-\x{4DB1}\x{4DB3}-\x{4DB5}\x{4E00}-\x{4E54}'
. '\x{4E56}-\x{4E89}\x{4E8B}-\x{4EEC}\x{4EEE}-\x{4FAC}\x{4FAE}-\x{503C}\x{503E}-\x{51E5}\x{51E7}-\x{5270}'
. '\x{5272}-\x{56A1}\x{56A3}-\x{5840}\x{5842}-\x{58B5}\x{58B7}-\x{58CB}\x{58CD}-\x{5BC8}\x{5BCA}-\x{5C01}'
. '\x{5C03}-\x{5C25}\x{5C27}-\x{5D5B}\x{5D5D}-\x{5F08}\x{5F0A}-\x{61F3}\x{61F5}-\x{63BA}\x{63BC}-\x{6441}'
. '\x{6443}-\x{657C}\x{657E}-\x{663E}\x{6640}-\x{66FC}\x{66FE}-\x{6728}\x{672A}-\x{6766}\x{6768}-\x{67A8}'
. '\x{67AA}-\x{685B}\x{685D}-\x{685E}\x{6860}-\x{68B9}\x{68BB}-\x{6AC8}\x{6ACA}-\x{6BB0}\x{6BB2}-\x{6C16}'
. '\x{6C18}-\x{6D9B}\x{6D9D}-\x{6E12}\x{6E14}-\x{6E8B}\x{6E8D}-\x{704D}\x{704F}-\x{7113}\x{7115}-\x{713B}'
. '\x{713D}-\x{7154}\x{7156}-\x{729F}\x{72A1}-\x{731E}\x{7320}-\x{7362}\x{7364}-\x{7533}\x{7535}-\x{7551}'
. '\x{7553}-\x{7572}\x{7574}-\x{75E8}\x{75EA}-\x{7679}\x{767B}-\x{783E}\x{7840}-\x{7A62}\x{7A64}-\x{7AC2}'
. '\x{7AC4}-\x{7B06}\x{7B08}-\x{7B79}\x{7B7B}-\x{7BCE}\x{7BD0}-\x{7D99}\x{7D9B}-\x{7E49}\x{7E4C}-\x{8132}'
. '\x{8134}\x{8136}-\x{81D2}\x{81D4}-\x{8216}\x{8218}-\x{822D}\x{822F}-\x{83B4}\x{83B6}-\x{841F}'
. '\x{8421}-\x{86CC}\x{86CE}-\x{874A}\x{874C}-\x{877E}\x{8780}-\x{8A32}\x{8A34}-\x{8B71}\x{8B73}-\x{8B8E}'
. '\x{8B90}-\x{8DE4}\x{8DE6}-\x{8E9A}\x{8E9C}-\x{8EE1}\x{8EE4}-\x{8F0B}\x{8F0D}-\x{8FB9}\x{8FBB}-\x{9038}'
. '\x{903A}-\x{9196}\x{9198}-\x{91A3}\x{91A5}-\x{91B7}\x{91B9}-\x{91C7}\x{91C9}-\x{91E0}\x{91E2}-\x{91FB}'
. '\x{91FD}-\x{922B}\x{922D}-\x{9270}\x{9272}-\x{9420}\x{9422}-\x{9664}\x{9666}-\x{9679}\x{967B}-\x{9770}'
. '\x{9772}-\x{982B}\x{982D}-\x{98ED}\x{98EF}-\x{99C4}\x{99C6}-\x{9A11}\x{9A14}-\x{9A27}\x{9A29}-\x{9D0D}'
. '\x{9D0F}-\x{9D2B}\x{9D2D}-\x{9D8E}\x{9D90}-\x{9DC5}\x{9DC7}-\x{9E77}\x{9E79}-\x{9EB8}\x{9EBB}-\x{9F20}'
. '\x{9F22}-\x{9F61}\x{9F63}-\x{9FA5}\x{FA28}]{1,20}$/iu',
6 => '/^[\x{002d}0-9A-Za-z]{1,63}$/iu',
7 => '/^[\x{00A1}-\x{00FF}]{1,63}$/iu',
8 => '/^[\x{0100}-\x{017f}]{1,63}$/iu',
9 => '/^[\x{0180}-\x{024f}]{1,63}$/iu',
10 => '/^[\x{0250}-\x{02af}]{1,63}$/iu',
11 => '/^[\x{02b0}-\x{02ff}]{1,63}$/iu',
12 => '/^[\x{0300}-\x{036f}]{1,63}$/iu',
13 => '/^[\x{0370}-\x{03ff}]{1,63}$/iu',
14 => '/^[\x{0400}-\x{04ff}]{1,63}$/iu',
15 => '/^[\x{0500}-\x{052f}]{1,63}$/iu',
16 => '/^[\x{0530}-\x{058F}]{1,63}$/iu',
17 => '/^[\x{0590}-\x{05FF}]{1,63}$/iu',
18 => '/^[\x{0600}-\x{06FF}]{1,63}$/iu',
19 => '/^[\x{0700}-\x{074F}]{1,63}$/iu',
20 => '/^[\x{0780}-\x{07BF}]{1,63}$/iu',
21 => '/^[\x{0900}-\x{097F}]{1,63}$/iu',
22 => '/^[\x{0980}-\x{09FF}]{1,63}$/iu',
23 => '/^[\x{0A00}-\x{0A7F}]{1,63}$/iu',
24 => '/^[\x{0A80}-\x{0AFF}]{1,63}$/iu',
25 => '/^[\x{0B00}-\x{0B7F}]{1,63}$/iu',
26 => '/^[\x{0B80}-\x{0BFF}]{1,63}$/iu',
27 => '/^[\x{0C00}-\x{0C7F}]{1,63}$/iu',
28 => '/^[\x{0C80}-\x{0CFF}]{1,63}$/iu',
29 => '/^[\x{0D00}-\x{0D7F}]{1,63}$/iu',
30 => '/^[\x{0D80}-\x{0DFF}]{1,63}$/iu',
31 => '/^[\x{0E00}-\x{0E7F}]{1,63}$/iu',
32 => '/^[\x{0E80}-\x{0EFF}]{1,63}$/iu',
33 => '/^[\x{0F00}-\x{0FFF}]{1,63}$/iu',
34 => '/^[\x{1000}-\x{109F}]{1,63}$/iu',
35 => '/^[\x{10A0}-\x{10FF}]{1,63}$/iu',
36 => '/^[\x{1100}-\x{11FF}]{1,63}$/iu',
37 => '/^[\x{1200}-\x{137F}]{1,63}$/iu',
38 => '/^[\x{13A0}-\x{13FF}]{1,63}$/iu',
39 => '/^[\x{1400}-\x{167F}]{1,63}$/iu',
40 => '/^[\x{1680}-\x{169F}]{1,63}$/iu',
41 => '/^[\x{16A0}-\x{16FF}]{1,63}$/iu',
42 => '/^[\x{1700}-\x{171F}]{1,63}$/iu',
43 => '/^[\x{1720}-\x{173F}]{1,63}$/iu',
44 => '/^[\x{1740}-\x{175F}]{1,63}$/iu',
45 => '/^[\x{1760}-\x{177F}]{1,63}$/iu',
46 => '/^[\x{1780}-\x{17FF}]{1,63}$/iu',
47 => '/^[\x{1800}-\x{18AF}]{1,63}$/iu',
48 => '/^[\x{1E00}-\x{1EFF}]{1,63}$/iu',
49 => '/^[\x{1F00}-\x{1FFF}]{1,63}$/iu',
50 => '/^[\x{2070}-\x{209F}]{1,63}$/iu',
51 => '/^[\x{2100}-\x{214F}]{1,63}$/iu',
52 => '/^[\x{2150}-\x{218F}]{1,63}$/iu',
53 => '/^[\x{2460}-\x{24FF}]{1,63}$/iu',
54 => '/^[\x{2E80}-\x{2EFF}]{1,63}$/iu',
55 => '/^[\x{2F00}-\x{2FDF}]{1,63}$/iu',
56 => '/^[\x{2FF0}-\x{2FFF}]{1,63}$/iu',
57 => '/^[\x{3040}-\x{309F}]{1,63}$/iu',
58 => '/^[\x{30A0}-\x{30FF}]{1,63}$/iu',
59 => '/^[\x{3100}-\x{312F}]{1,63}$/iu',
60 => '/^[\x{3130}-\x{318F}]{1,63}$/iu',
61 => '/^[\x{3190}-\x{319F}]{1,63}$/iu',
62 => '/^[\x{31A0}-\x{31BF}]{1,63}$/iu',
63 => '/^[\x{31F0}-\x{31FF}]{1,63}$/iu',
64 => '/^[\x{3200}-\x{32FF}]{1,63}$/iu',
65 => '/^[\x{3300}-\x{33FF}]{1,63}$/iu',
66 => '/^[\x{3400}-\x{4DBF}]{1,63}$/iu',
67 => '/^[\x{4E00}-\x{9FFF}]{1,63}$/iu',
68 => '/^[\x{A000}-\x{A48F}]{1,63}$/iu',
69 => '/^[\x{A490}-\x{A4CF}]{1,63}$/iu',
70 => '/^[\x{AC00}-\x{D7AF}]{1,63}$/iu',
73 => '/^[\x{F900}-\x{FAFF}]{1,63}$/iu',
74 => '/^[\x{FB00}-\x{FB4F}]{1,63}$/iu',
75 => '/^[\x{FB50}-\x{FDFF}]{1,63}$/iu',
76 => '/^[\x{FE20}-\x{FE2F}]{1,63}$/iu',
77 => '/^[\x{FE70}-\x{FEFF}]{1,63}$/iu',
78 => '/^[\x{FF00}-\x{FFEF}]{1,63}$/iu',
79 => '/^[\x{20000}-\x{2A6DF}]{1,63}$/iu',
80 => '/^[\x{2F800}-\x{2FA1F}]{1,63}$/iu',
];

View File

@@ -1,719 +0,0 @@
<?php // phpcs:disable PSR12.Files.FileHeader.IncorrectOrder
namespace Laminas\Validator\Hostname;
/**
* Resource file for japanese idn validation
*/
return [
1 => '/^[\x{002d}0-9a-z\x{3005}-\x{3007}\x{3041}-\x{3093}\x{309D}\x{309E}'
. '\x{30A1}-\x{30F6}\x{30FC}'
. '\x{30FD}\x{30FE}\x{4E00}\x{4E01}\x{4E03}\x{4E07}\x{4E08}\x{4E09}\x{4E0A}'
. '\x{4E0B}\x{4E0D}\x{4E0E}\x{4E10}\x{4E11}\x{4E14}\x{4E15}\x{4E16}\x{4E17}'
. '\x{4E18}\x{4E19}\x{4E1E}\x{4E21}\x{4E26}\x{4E2A}\x{4E2D}\x{4E31}\x{4E32}'
. '\x{4E36}\x{4E38}\x{4E39}\x{4E3B}\x{4E3C}\x{4E3F}\x{4E42}\x{4E43}\x{4E45}'
. '\x{4E4B}\x{4E4D}\x{4E4E}\x{4E4F}\x{4E55}\x{4E56}\x{4E57}\x{4E58}\x{4E59}'
. '\x{4E5D}\x{4E5E}\x{4E5F}\x{4E62}\x{4E71}\x{4E73}\x{4E7E}\x{4E80}\x{4E82}'
. '\x{4E85}\x{4E86}\x{4E88}\x{4E89}\x{4E8A}\x{4E8B}\x{4E8C}\x{4E8E}\x{4E91}'
. '\x{4E92}\x{4E94}\x{4E95}\x{4E98}\x{4E99}\x{4E9B}\x{4E9C}\x{4E9E}\x{4E9F}'
. '\x{4EA0}\x{4EA1}\x{4EA2}\x{4EA4}\x{4EA5}\x{4EA6}\x{4EA8}\x{4EAB}\x{4EAC}'
. '\x{4EAD}\x{4EAE}\x{4EB0}\x{4EB3}\x{4EB6}\x{4EBA}\x{4EC0}\x{4EC1}\x{4EC2}'
. '\x{4EC4}\x{4EC6}\x{4EC7}\x{4ECA}\x{4ECB}\x{4ECD}\x{4ECE}\x{4ECF}\x{4ED4}'
. '\x{4ED5}\x{4ED6}\x{4ED7}\x{4ED8}\x{4ED9}\x{4EDD}\x{4EDE}\x{4EDF}\x{4EE3}'
. '\x{4EE4}\x{4EE5}\x{4EED}\x{4EEE}\x{4EF0}\x{4EF2}\x{4EF6}\x{4EF7}\x{4EFB}'
. '\x{4F01}\x{4F09}\x{4F0A}\x{4F0D}\x{4F0E}\x{4F0F}\x{4F10}\x{4F11}\x{4F1A}'
. '\x{4F1C}\x{4F1D}\x{4F2F}\x{4F30}\x{4F34}\x{4F36}\x{4F38}\x{4F3A}\x{4F3C}'
. '\x{4F3D}\x{4F43}\x{4F46}\x{4F47}\x{4F4D}\x{4F4E}\x{4F4F}\x{4F50}\x{4F51}'
. '\x{4F53}\x{4F55}\x{4F57}\x{4F59}\x{4F5A}\x{4F5B}\x{4F5C}\x{4F5D}\x{4F5E}'
. '\x{4F69}\x{4F6F}\x{4F70}\x{4F73}\x{4F75}\x{4F76}\x{4F7B}\x{4F7C}\x{4F7F}'
. '\x{4F83}\x{4F86}\x{4F88}\x{4F8B}\x{4F8D}\x{4F8F}\x{4F91}\x{4F96}\x{4F98}'
. '\x{4F9B}\x{4F9D}\x{4FA0}\x{4FA1}\x{4FAB}\x{4FAD}\x{4FAE}\x{4FAF}\x{4FB5}'
. '\x{4FB6}\x{4FBF}\x{4FC2}\x{4FC3}\x{4FC4}\x{4FCA}\x{4FCE}\x{4FD0}\x{4FD1}'
. '\x{4FD4}\x{4FD7}\x{4FD8}\x{4FDA}\x{4FDB}\x{4FDD}\x{4FDF}\x{4FE1}\x{4FE3}'
. '\x{4FE4}\x{4FE5}\x{4FEE}\x{4FEF}\x{4FF3}\x{4FF5}\x{4FF6}\x{4FF8}\x{4FFA}'
. '\x{4FFE}\x{5005}\x{5006}\x{5009}\x{500B}\x{500D}\x{500F}\x{5011}\x{5012}'
. '\x{5014}\x{5016}\x{5019}\x{501A}\x{501F}\x{5021}\x{5023}\x{5024}\x{5025}'
. '\x{5026}\x{5028}\x{5029}\x{502A}\x{502B}\x{502C}\x{502D}\x{5036}\x{5039}'
. '\x{5043}\x{5047}\x{5048}\x{5049}\x{504F}\x{5050}\x{5055}\x{5056}\x{505A}'
. '\x{505C}\x{5065}\x{506C}\x{5072}\x{5074}\x{5075}\x{5076}\x{5078}\x{507D}'
. '\x{5080}\x{5085}\x{508D}\x{5091}\x{5098}\x{5099}\x{509A}\x{50AC}\x{50AD}'
. '\x{50B2}\x{50B3}\x{50B4}\x{50B5}\x{50B7}\x{50BE}\x{50C2}\x{50C5}\x{50C9}'
. '\x{50CA}\x{50CD}\x{50CF}\x{50D1}\x{50D5}\x{50D6}\x{50DA}\x{50DE}\x{50E3}'
. '\x{50E5}\x{50E7}\x{50ED}\x{50EE}\x{50F5}\x{50F9}\x{50FB}\x{5100}\x{5101}'
. '\x{5102}\x{5104}\x{5109}\x{5112}\x{5114}\x{5115}\x{5116}\x{5118}\x{511A}'
. '\x{511F}\x{5121}\x{512A}\x{5132}\x{5137}\x{513A}\x{513B}\x{513C}\x{513F}'
. '\x{5140}\x{5141}\x{5143}\x{5144}\x{5145}\x{5146}\x{5147}\x{5148}\x{5149}'
. '\x{514B}\x{514C}\x{514D}\x{514E}\x{5150}\x{5152}\x{5154}\x{515A}\x{515C}'
. '\x{5162}\x{5165}\x{5168}\x{5169}\x{516A}\x{516B}\x{516C}\x{516D}\x{516E}'
. '\x{5171}\x{5175}\x{5176}\x{5177}\x{5178}\x{517C}\x{5180}\x{5182}\x{5185}'
. '\x{5186}\x{5189}\x{518A}\x{518C}\x{518D}\x{518F}\x{5190}\x{5191}\x{5192}'
. '\x{5193}\x{5195}\x{5196}\x{5197}\x{5199}\x{51A0}\x{51A2}\x{51A4}\x{51A5}'
. '\x{51A6}\x{51A8}\x{51A9}\x{51AA}\x{51AB}\x{51AC}\x{51B0}\x{51B1}\x{51B2}'
. '\x{51B3}\x{51B4}\x{51B5}\x{51B6}\x{51B7}\x{51BD}\x{51C4}\x{51C5}\x{51C6}'
. '\x{51C9}\x{51CB}\x{51CC}\x{51CD}\x{51D6}\x{51DB}\x{51DC}\x{51DD}\x{51E0}'
. '\x{51E1}\x{51E6}\x{51E7}\x{51E9}\x{51EA}\x{51ED}\x{51F0}\x{51F1}\x{51F5}'
. '\x{51F6}\x{51F8}\x{51F9}\x{51FA}\x{51FD}\x{51FE}\x{5200}\x{5203}\x{5204}'
. '\x{5206}\x{5207}\x{5208}\x{520A}\x{520B}\x{520E}\x{5211}\x{5214}\x{5217}'
. '\x{521D}\x{5224}\x{5225}\x{5227}\x{5229}\x{522A}\x{522E}\x{5230}\x{5233}'
. '\x{5236}\x{5237}\x{5238}\x{5239}\x{523A}\x{523B}\x{5243}\x{5244}\x{5247}'
. '\x{524A}\x{524B}\x{524C}\x{524D}\x{524F}\x{5254}\x{5256}\x{525B}\x{525E}'
. '\x{5263}\x{5264}\x{5265}\x{5269}\x{526A}\x{526F}\x{5270}\x{5271}\x{5272}'
. '\x{5273}\x{5274}\x{5275}\x{527D}\x{527F}\x{5283}\x{5287}\x{5288}\x{5289}'
. '\x{528D}\x{5291}\x{5292}\x{5294}\x{529B}\x{529F}\x{52A0}\x{52A3}\x{52A9}'
. '\x{52AA}\x{52AB}\x{52AC}\x{52AD}\x{52B1}\x{52B4}\x{52B5}\x{52B9}\x{52BC}'
. '\x{52BE}\x{52C1}\x{52C3}\x{52C5}\x{52C7}\x{52C9}\x{52CD}\x{52D2}\x{52D5}'
. '\x{52D7}\x{52D8}\x{52D9}\x{52DD}\x{52DE}\x{52DF}\x{52E0}\x{52E2}\x{52E3}'
. '\x{52E4}\x{52E6}\x{52E7}\x{52F2}\x{52F3}\x{52F5}\x{52F8}\x{52F9}\x{52FA}'
. '\x{52FE}\x{52FF}\x{5301}\x{5302}\x{5305}\x{5306}\x{5308}\x{530D}\x{530F}'
. '\x{5310}\x{5315}\x{5316}\x{5317}\x{5319}\x{531A}\x{531D}\x{5320}\x{5321}'
. '\x{5323}\x{532A}\x{532F}\x{5331}\x{5333}\x{5338}\x{5339}\x{533A}\x{533B}'
. '\x{533F}\x{5340}\x{5341}\x{5343}\x{5345}\x{5346}\x{5347}\x{5348}\x{5349}'
. '\x{534A}\x{534D}\x{5351}\x{5352}\x{5353}\x{5354}\x{5357}\x{5358}\x{535A}'
. '\x{535C}\x{535E}\x{5360}\x{5366}\x{5369}\x{536E}\x{536F}\x{5370}\x{5371}'
. '\x{5373}\x{5374}\x{5375}\x{5377}\x{5378}\x{537B}\x{537F}\x{5382}\x{5384}'
. '\x{5396}\x{5398}\x{539A}\x{539F}\x{53A0}\x{53A5}\x{53A6}\x{53A8}\x{53A9}'
. '\x{53AD}\x{53AE}\x{53B0}\x{53B3}\x{53B6}\x{53BB}\x{53C2}\x{53C3}\x{53C8}'
. '\x{53C9}\x{53CA}\x{53CB}\x{53CC}\x{53CD}\x{53CE}\x{53D4}\x{53D6}\x{53D7}'
. '\x{53D9}\x{53DB}\x{53DF}\x{53E1}\x{53E2}\x{53E3}\x{53E4}\x{53E5}\x{53E8}'
. '\x{53E9}\x{53EA}\x{53EB}\x{53EC}\x{53ED}\x{53EE}\x{53EF}\x{53F0}\x{53F1}'
. '\x{53F2}\x{53F3}\x{53F6}\x{53F7}\x{53F8}\x{53FA}\x{5401}\x{5403}\x{5404}'
. '\x{5408}\x{5409}\x{540A}\x{540B}\x{540C}\x{540D}\x{540E}\x{540F}\x{5410}'
. '\x{5411}\x{541B}\x{541D}\x{541F}\x{5420}\x{5426}\x{5429}\x{542B}\x{542C}'
. '\x{542D}\x{542E}\x{5436}\x{5438}\x{5439}\x{543B}\x{543C}\x{543D}\x{543E}'
. '\x{5440}\x{5442}\x{5446}\x{5448}\x{5449}\x{544A}\x{544E}\x{5451}\x{545F}'
. '\x{5468}\x{546A}\x{5470}\x{5471}\x{5473}\x{5475}\x{5476}\x{5477}\x{547B}'
. '\x{547C}\x{547D}\x{5480}\x{5484}\x{5486}\x{548B}\x{548C}\x{548E}\x{548F}'
. '\x{5490}\x{5492}\x{54A2}\x{54A4}\x{54A5}\x{54A8}\x{54AB}\x{54AC}\x{54AF}'
. '\x{54B2}\x{54B3}\x{54B8}\x{54BC}\x{54BD}\x{54BE}\x{54C0}\x{54C1}\x{54C2}'
. '\x{54C4}\x{54C7}\x{54C8}\x{54C9}\x{54D8}\x{54E1}\x{54E2}\x{54E5}\x{54E6}'
. '\x{54E8}\x{54E9}\x{54ED}\x{54EE}\x{54F2}\x{54FA}\x{54FD}\x{5504}\x{5506}'
. '\x{5507}\x{550F}\x{5510}\x{5514}\x{5516}\x{552E}\x{552F}\x{5531}\x{5533}'
. '\x{5538}\x{5539}\x{553E}\x{5540}\x{5544}\x{5545}\x{5546}\x{554C}\x{554F}'
. '\x{5553}\x{5556}\x{5557}\x{555C}\x{555D}\x{5563}\x{557B}\x{557C}\x{557E}'
. '\x{5580}\x{5583}\x{5584}\x{5587}\x{5589}\x{558A}\x{558B}\x{5598}\x{5599}'
. '\x{559A}\x{559C}\x{559D}\x{559E}\x{559F}\x{55A7}\x{55A8}\x{55A9}\x{55AA}'
. '\x{55AB}\x{55AC}\x{55AE}\x{55B0}\x{55B6}\x{55C4}\x{55C5}\x{55C7}\x{55D4}'
. '\x{55DA}\x{55DC}\x{55DF}\x{55E3}\x{55E4}\x{55F7}\x{55F9}\x{55FD}\x{55FE}'
. '\x{5606}\x{5609}\x{5614}\x{5616}\x{5617}\x{5618}\x{561B}\x{5629}\x{562F}'
. '\x{5631}\x{5632}\x{5634}\x{5636}\x{5638}\x{5642}\x{564C}\x{564E}\x{5650}'
. '\x{565B}\x{5664}\x{5668}\x{566A}\x{566B}\x{566C}\x{5674}\x{5678}\x{567A}'
. '\x{5680}\x{5686}\x{5687}\x{568A}\x{568F}\x{5694}\x{56A0}\x{56A2}\x{56A5}'
. '\x{56AE}\x{56B4}\x{56B6}\x{56BC}\x{56C0}\x{56C1}\x{56C2}\x{56C3}\x{56C8}'
. '\x{56CE}\x{56D1}\x{56D3}\x{56D7}\x{56D8}\x{56DA}\x{56DB}\x{56DE}\x{56E0}'
. '\x{56E3}\x{56EE}\x{56F0}\x{56F2}\x{56F3}\x{56F9}\x{56FA}\x{56FD}\x{56FF}'
. '\x{5700}\x{5703}\x{5704}\x{5708}\x{5709}\x{570B}\x{570D}\x{570F}\x{5712}'
. '\x{5713}\x{5716}\x{5718}\x{571C}\x{571F}\x{5726}\x{5727}\x{5728}\x{572D}'
. '\x{5730}\x{5737}\x{5738}\x{573B}\x{5740}\x{5742}\x{5747}\x{574A}\x{574E}'
. '\x{574F}\x{5750}\x{5751}\x{5761}\x{5764}\x{5766}\x{5769}\x{576A}\x{577F}'
. '\x{5782}\x{5788}\x{5789}\x{578B}\x{5793}\x{57A0}\x{57A2}\x{57A3}\x{57A4}'
. '\x{57AA}\x{57B0}\x{57B3}\x{57C0}\x{57C3}\x{57C6}\x{57CB}\x{57CE}\x{57D2}'
. '\x{57D3}\x{57D4}\x{57D6}\x{57DC}\x{57DF}\x{57E0}\x{57E3}\x{57F4}\x{57F7}'
. '\x{57F9}\x{57FA}\x{57FC}\x{5800}\x{5802}\x{5805}\x{5806}\x{580A}\x{580B}'
. '\x{5815}\x{5819}\x{581D}\x{5821}\x{5824}\x{582A}\x{582F}\x{5830}\x{5831}'
. '\x{5834}\x{5835}\x{583A}\x{583D}\x{5840}\x{5841}\x{584A}\x{584B}\x{5851}'
. '\x{5852}\x{5854}\x{5857}\x{5858}\x{5859}\x{585A}\x{585E}\x{5862}\x{5869}'
. '\x{586B}\x{5870}\x{5872}\x{5875}\x{5879}\x{587E}\x{5883}\x{5885}\x{5893}'
. '\x{5897}\x{589C}\x{589F}\x{58A8}\x{58AB}\x{58AE}\x{58B3}\x{58B8}\x{58B9}'
. '\x{58BA}\x{58BB}\x{58BE}\x{58C1}\x{58C5}\x{58C7}\x{58CA}\x{58CC}\x{58D1}'
. '\x{58D3}\x{58D5}\x{58D7}\x{58D8}\x{58D9}\x{58DC}\x{58DE}\x{58DF}\x{58E4}'
. '\x{58E5}\x{58EB}\x{58EC}\x{58EE}\x{58EF}\x{58F0}\x{58F1}\x{58F2}\x{58F7}'
. '\x{58F9}\x{58FA}\x{58FB}\x{58FC}\x{58FD}\x{5902}\x{5909}\x{590A}\x{590F}'
. '\x{5910}\x{5915}\x{5916}\x{5918}\x{5919}\x{591A}\x{591B}\x{591C}\x{5922}'
. '\x{5925}\x{5927}\x{5929}\x{592A}\x{592B}\x{592C}\x{592D}\x{592E}\x{5931}'
. '\x{5932}\x{5937}\x{5938}\x{593E}\x{5944}\x{5947}\x{5948}\x{5949}\x{594E}'
. '\x{594F}\x{5950}\x{5951}\x{5954}\x{5955}\x{5957}\x{5958}\x{595A}\x{5960}'
. '\x{5962}\x{5965}\x{5967}\x{5968}\x{5969}\x{596A}\x{596C}\x{596E}\x{5973}'
. '\x{5974}\x{5978}\x{597D}\x{5981}\x{5982}\x{5983}\x{5984}\x{598A}\x{598D}'
. '\x{5993}\x{5996}\x{5999}\x{599B}\x{599D}\x{59A3}\x{59A5}\x{59A8}\x{59AC}'
. '\x{59B2}\x{59B9}\x{59BB}\x{59BE}\x{59C6}\x{59C9}\x{59CB}\x{59D0}\x{59D1}'
. '\x{59D3}\x{59D4}\x{59D9}\x{59DA}\x{59DC}\x{59E5}\x{59E6}\x{59E8}\x{59EA}'
. '\x{59EB}\x{59F6}\x{59FB}\x{59FF}\x{5A01}\x{5A03}\x{5A09}\x{5A11}\x{5A18}'
. '\x{5A1A}\x{5A1C}\x{5A1F}\x{5A20}\x{5A25}\x{5A29}\x{5A2F}\x{5A35}\x{5A36}'
. '\x{5A3C}\x{5A40}\x{5A41}\x{5A46}\x{5A49}\x{5A5A}\x{5A62}\x{5A66}\x{5A6A}'
. '\x{5A6C}\x{5A7F}\x{5A92}\x{5A9A}\x{5A9B}\x{5ABC}\x{5ABD}\x{5ABE}\x{5AC1}'
. '\x{5AC2}\x{5AC9}\x{5ACB}\x{5ACC}\x{5AD0}\x{5AD6}\x{5AD7}\x{5AE1}\x{5AE3}'
. '\x{5AE6}\x{5AE9}\x{5AFA}\x{5AFB}\x{5B09}\x{5B0B}\x{5B0C}\x{5B16}\x{5B22}'
. '\x{5B2A}\x{5B2C}\x{5B30}\x{5B32}\x{5B36}\x{5B3E}\x{5B40}\x{5B43}\x{5B45}'
. '\x{5B50}\x{5B51}\x{5B54}\x{5B55}\x{5B57}\x{5B58}\x{5B5A}\x{5B5B}\x{5B5C}'
. '\x{5B5D}\x{5B5F}\x{5B63}\x{5B64}\x{5B65}\x{5B66}\x{5B69}\x{5B6B}\x{5B70}'
. '\x{5B71}\x{5B73}\x{5B75}\x{5B78}\x{5B7A}\x{5B80}\x{5B83}\x{5B85}\x{5B87}'
. '\x{5B88}\x{5B89}\x{5B8B}\x{5B8C}\x{5B8D}\x{5B8F}\x{5B95}\x{5B97}\x{5B98}'
. '\x{5B99}\x{5B9A}\x{5B9B}\x{5B9C}\x{5B9D}\x{5B9F}\x{5BA2}\x{5BA3}\x{5BA4}'
. '\x{5BA5}\x{5BA6}\x{5BAE}\x{5BB0}\x{5BB3}\x{5BB4}\x{5BB5}\x{5BB6}\x{5BB8}'
. '\x{5BB9}\x{5BBF}\x{5BC2}\x{5BC3}\x{5BC4}\x{5BC5}\x{5BC6}\x{5BC7}\x{5BC9}'
. '\x{5BCC}\x{5BD0}\x{5BD2}\x{5BD3}\x{5BD4}\x{5BDB}\x{5BDD}\x{5BDE}\x{5BDF}'
. '\x{5BE1}\x{5BE2}\x{5BE4}\x{5BE5}\x{5BE6}\x{5BE7}\x{5BE8}\x{5BE9}\x{5BEB}'
. '\x{5BEE}\x{5BF0}\x{5BF3}\x{5BF5}\x{5BF6}\x{5BF8}\x{5BFA}\x{5BFE}\x{5BFF}'
. '\x{5C01}\x{5C02}\x{5C04}\x{5C05}\x{5C06}\x{5C07}\x{5C08}\x{5C09}\x{5C0A}'
. '\x{5C0B}\x{5C0D}\x{5C0E}\x{5C0F}\x{5C11}\x{5C13}\x{5C16}\x{5C1A}\x{5C20}'
. '\x{5C22}\x{5C24}\x{5C28}\x{5C2D}\x{5C31}\x{5C38}\x{5C39}\x{5C3A}\x{5C3B}'
. '\x{5C3C}\x{5C3D}\x{5C3E}\x{5C3F}\x{5C40}\x{5C41}\x{5C45}\x{5C46}\x{5C48}'
. '\x{5C4A}\x{5C4B}\x{5C4D}\x{5C4E}\x{5C4F}\x{5C50}\x{5C51}\x{5C53}\x{5C55}'
. '\x{5C5E}\x{5C60}\x{5C61}\x{5C64}\x{5C65}\x{5C6C}\x{5C6E}\x{5C6F}\x{5C71}'
. '\x{5C76}\x{5C79}\x{5C8C}\x{5C90}\x{5C91}\x{5C94}\x{5CA1}\x{5CA8}\x{5CA9}'
. '\x{5CAB}\x{5CAC}\x{5CB1}\x{5CB3}\x{5CB6}\x{5CB7}\x{5CB8}\x{5CBB}\x{5CBC}'
. '\x{5CBE}\x{5CC5}\x{5CC7}\x{5CD9}\x{5CE0}\x{5CE1}\x{5CE8}\x{5CE9}\x{5CEA}'
. '\x{5CED}\x{5CEF}\x{5CF0}\x{5CF6}\x{5CFA}\x{5CFB}\x{5CFD}\x{5D07}\x{5D0B}'
. '\x{5D0E}\x{5D11}\x{5D14}\x{5D15}\x{5D16}\x{5D17}\x{5D18}\x{5D19}\x{5D1A}'
. '\x{5D1B}\x{5D1F}\x{5D22}\x{5D29}\x{5D4B}\x{5D4C}\x{5D4E}\x{5D50}\x{5D52}'
. '\x{5D5C}\x{5D69}\x{5D6C}\x{5D6F}\x{5D73}\x{5D76}\x{5D82}\x{5D84}\x{5D87}'
. '\x{5D8B}\x{5D8C}\x{5D90}\x{5D9D}\x{5DA2}\x{5DAC}\x{5DAE}\x{5DB7}\x{5DBA}'
. '\x{5DBC}\x{5DBD}\x{5DC9}\x{5DCC}\x{5DCD}\x{5DD2}\x{5DD3}\x{5DD6}\x{5DDB}'
. '\x{5DDD}\x{5DDE}\x{5DE1}\x{5DE3}\x{5DE5}\x{5DE6}\x{5DE7}\x{5DE8}\x{5DEB}'
. '\x{5DEE}\x{5DF1}\x{5DF2}\x{5DF3}\x{5DF4}\x{5DF5}\x{5DF7}\x{5DFB}\x{5DFD}'
. '\x{5DFE}\x{5E02}\x{5E03}\x{5E06}\x{5E0B}\x{5E0C}\x{5E11}\x{5E16}\x{5E19}'
. '\x{5E1A}\x{5E1B}\x{5E1D}\x{5E25}\x{5E2B}\x{5E2D}\x{5E2F}\x{5E30}\x{5E33}'
. '\x{5E36}\x{5E37}\x{5E38}\x{5E3D}\x{5E40}\x{5E43}\x{5E44}\x{5E45}\x{5E47}'
. '\x{5E4C}\x{5E4E}\x{5E54}\x{5E55}\x{5E57}\x{5E5F}\x{5E61}\x{5E62}\x{5E63}'
. '\x{5E64}\x{5E72}\x{5E73}\x{5E74}\x{5E75}\x{5E76}\x{5E78}\x{5E79}\x{5E7A}'
. '\x{5E7B}\x{5E7C}\x{5E7D}\x{5E7E}\x{5E7F}\x{5E81}\x{5E83}\x{5E84}\x{5E87}'
. '\x{5E8A}\x{5E8F}\x{5E95}\x{5E96}\x{5E97}\x{5E9A}\x{5E9C}\x{5EA0}\x{5EA6}'
. '\x{5EA7}\x{5EAB}\x{5EAD}\x{5EB5}\x{5EB6}\x{5EB7}\x{5EB8}\x{5EC1}\x{5EC2}'
. '\x{5EC3}\x{5EC8}\x{5EC9}\x{5ECA}\x{5ECF}\x{5ED0}\x{5ED3}\x{5ED6}\x{5EDA}'
. '\x{5EDB}\x{5EDD}\x{5EDF}\x{5EE0}\x{5EE1}\x{5EE2}\x{5EE3}\x{5EE8}\x{5EE9}'
. '\x{5EEC}\x{5EF0}\x{5EF1}\x{5EF3}\x{5EF4}\x{5EF6}\x{5EF7}\x{5EF8}\x{5EFA}'
. '\x{5EFB}\x{5EFC}\x{5EFE}\x{5EFF}\x{5F01}\x{5F03}\x{5F04}\x{5F09}\x{5F0A}'
. '\x{5F0B}\x{5F0C}\x{5F0D}\x{5F0F}\x{5F10}\x{5F11}\x{5F13}\x{5F14}\x{5F15}'
. '\x{5F16}\x{5F17}\x{5F18}\x{5F1B}\x{5F1F}\x{5F25}\x{5F26}\x{5F27}\x{5F29}'
. '\x{5F2D}\x{5F2F}\x{5F31}\x{5F35}\x{5F37}\x{5F38}\x{5F3C}\x{5F3E}\x{5F41}'
. '\x{5F48}\x{5F4A}\x{5F4C}\x{5F4E}\x{5F51}\x{5F53}\x{5F56}\x{5F57}\x{5F59}'
. '\x{5F5C}\x{5F5D}\x{5F61}\x{5F62}\x{5F66}\x{5F69}\x{5F6A}\x{5F6B}\x{5F6C}'
. '\x{5F6D}\x{5F70}\x{5F71}\x{5F73}\x{5F77}\x{5F79}\x{5F7C}\x{5F7F}\x{5F80}'
. '\x{5F81}\x{5F82}\x{5F83}\x{5F84}\x{5F85}\x{5F87}\x{5F88}\x{5F8A}\x{5F8B}'
. '\x{5F8C}\x{5F90}\x{5F91}\x{5F92}\x{5F93}\x{5F97}\x{5F98}\x{5F99}\x{5F9E}'
. '\x{5FA0}\x{5FA1}\x{5FA8}\x{5FA9}\x{5FAA}\x{5FAD}\x{5FAE}\x{5FB3}\x{5FB4}'
. '\x{5FB9}\x{5FBC}\x{5FBD}\x{5FC3}\x{5FC5}\x{5FCC}\x{5FCD}\x{5FD6}\x{5FD7}'
. '\x{5FD8}\x{5FD9}\x{5FDC}\x{5FDD}\x{5FE0}\x{5FE4}\x{5FEB}\x{5FF0}\x{5FF1}'
. '\x{5FF5}\x{5FF8}\x{5FFB}\x{5FFD}\x{5FFF}\x{600E}\x{600F}\x{6010}\x{6012}'
. '\x{6015}\x{6016}\x{6019}\x{601B}\x{601C}\x{601D}\x{6020}\x{6021}\x{6025}'
. '\x{6026}\x{6027}\x{6028}\x{6029}\x{602A}\x{602B}\x{602F}\x{6031}\x{603A}'
. '\x{6041}\x{6042}\x{6043}\x{6046}\x{604A}\x{604B}\x{604D}\x{6050}\x{6052}'
. '\x{6055}\x{6059}\x{605A}\x{605F}\x{6060}\x{6062}\x{6063}\x{6064}\x{6065}'
. '\x{6068}\x{6069}\x{606A}\x{606B}\x{606C}\x{606D}\x{606F}\x{6070}\x{6075}'
. '\x{6077}\x{6081}\x{6083}\x{6084}\x{6089}\x{608B}\x{608C}\x{608D}\x{6092}'
. '\x{6094}\x{6096}\x{6097}\x{609A}\x{609B}\x{609F}\x{60A0}\x{60A3}\x{60A6}'
. '\x{60A7}\x{60A9}\x{60AA}\x{60B2}\x{60B3}\x{60B4}\x{60B5}\x{60B6}\x{60B8}'
. '\x{60BC}\x{60BD}\x{60C5}\x{60C6}\x{60C7}\x{60D1}\x{60D3}\x{60D8}\x{60DA}'
. '\x{60DC}\x{60DF}\x{60E0}\x{60E1}\x{60E3}\x{60E7}\x{60E8}\x{60F0}\x{60F1}'
. '\x{60F3}\x{60F4}\x{60F6}\x{60F7}\x{60F9}\x{60FA}\x{60FB}\x{6100}\x{6101}'
. '\x{6103}\x{6106}\x{6108}\x{6109}\x{610D}\x{610E}\x{610F}\x{6115}\x{611A}'
. '\x{611B}\x{611F}\x{6121}\x{6127}\x{6128}\x{612C}\x{6134}\x{613C}\x{613D}'
. '\x{613E}\x{613F}\x{6142}\x{6144}\x{6147}\x{6148}\x{614A}\x{614B}\x{614C}'
. '\x{614D}\x{614E}\x{6153}\x{6155}\x{6158}\x{6159}\x{615A}\x{615D}\x{615F}'
. '\x{6162}\x{6163}\x{6165}\x{6167}\x{6168}\x{616B}\x{616E}\x{616F}\x{6170}'
. '\x{6171}\x{6173}\x{6174}\x{6175}\x{6176}\x{6177}\x{617E}\x{6182}\x{6187}'
. '\x{618A}\x{618E}\x{6190}\x{6191}\x{6194}\x{6196}\x{6199}\x{619A}\x{61A4}'
. '\x{61A7}\x{61A9}\x{61AB}\x{61AC}\x{61AE}\x{61B2}\x{61B6}\x{61BA}\x{61BE}'
. '\x{61C3}\x{61C6}\x{61C7}\x{61C8}\x{61C9}\x{61CA}\x{61CB}\x{61CC}\x{61CD}'
. '\x{61D0}\x{61E3}\x{61E6}\x{61F2}\x{61F4}\x{61F6}\x{61F7}\x{61F8}\x{61FA}'
. '\x{61FC}\x{61FD}\x{61FE}\x{61FF}\x{6200}\x{6208}\x{6209}\x{620A}\x{620C}'
. '\x{620D}\x{620E}\x{6210}\x{6211}\x{6212}\x{6214}\x{6216}\x{621A}\x{621B}'
. '\x{621D}\x{621E}\x{621F}\x{6221}\x{6226}\x{622A}\x{622E}\x{622F}\x{6230}'
. '\x{6232}\x{6233}\x{6234}\x{6238}\x{623B}\x{623F}\x{6240}\x{6241}\x{6247}'
. '\x{6248}\x{6249}\x{624B}\x{624D}\x{624E}\x{6253}\x{6255}\x{6258}\x{625B}'
. '\x{625E}\x{6260}\x{6263}\x{6268}\x{626E}\x{6271}\x{6276}\x{6279}\x{627C}'
. '\x{627E}\x{627F}\x{6280}\x{6282}\x{6283}\x{6284}\x{6289}\x{628A}\x{6291}'
. '\x{6292}\x{6293}\x{6294}\x{6295}\x{6296}\x{6297}\x{6298}\x{629B}\x{629C}'
. '\x{629E}\x{62AB}\x{62AC}\x{62B1}\x{62B5}\x{62B9}\x{62BB}\x{62BC}\x{62BD}'
. '\x{62C2}\x{62C5}\x{62C6}\x{62C7}\x{62C8}\x{62C9}\x{62CA}\x{62CC}\x{62CD}'
. '\x{62CF}\x{62D0}\x{62D1}\x{62D2}\x{62D3}\x{62D4}\x{62D7}\x{62D8}\x{62D9}'
. '\x{62DB}\x{62DC}\x{62DD}\x{62E0}\x{62E1}\x{62EC}\x{62ED}\x{62EE}\x{62EF}'
. '\x{62F1}\x{62F3}\x{62F5}\x{62F6}\x{62F7}\x{62FE}\x{62FF}\x{6301}\x{6302}'
. '\x{6307}\x{6308}\x{6309}\x{630C}\x{6311}\x{6319}\x{631F}\x{6327}\x{6328}'
. '\x{632B}\x{632F}\x{633A}\x{633D}\x{633E}\x{633F}\x{6349}\x{634C}\x{634D}'
. '\x{634F}\x{6350}\x{6355}\x{6357}\x{635C}\x{6367}\x{6368}\x{6369}\x{636B}'
. '\x{636E}\x{6372}\x{6376}\x{6377}\x{637A}\x{637B}\x{6380}\x{6383}\x{6388}'
. '\x{6389}\x{638C}\x{638E}\x{638F}\x{6392}\x{6396}\x{6398}\x{639B}\x{639F}'
. '\x{63A0}\x{63A1}\x{63A2}\x{63A3}\x{63A5}\x{63A7}\x{63A8}\x{63A9}\x{63AA}'
. '\x{63AB}\x{63AC}\x{63B2}\x{63B4}\x{63B5}\x{63BB}\x{63BE}\x{63C0}\x{63C3}'
. '\x{63C4}\x{63C6}\x{63C9}\x{63CF}\x{63D0}\x{63D2}\x{63D6}\x{63DA}\x{63DB}'
. '\x{63E1}\x{63E3}\x{63E9}\x{63EE}\x{63F4}\x{63F6}\x{63FA}\x{6406}\x{640D}'
. '\x{640F}\x{6413}\x{6416}\x{6417}\x{641C}\x{6426}\x{6428}\x{642C}\x{642D}'
. '\x{6434}\x{6436}\x{643A}\x{643E}\x{6442}\x{644E}\x{6458}\x{6467}\x{6469}'
. '\x{646F}\x{6476}\x{6478}\x{647A}\x{6483}\x{6488}\x{6492}\x{6493}\x{6495}'
. '\x{649A}\x{649E}\x{64A4}\x{64A5}\x{64A9}\x{64AB}\x{64AD}\x{64AE}\x{64B0}'
. '\x{64B2}\x{64B9}\x{64BB}\x{64BC}\x{64C1}\x{64C2}\x{64C5}\x{64C7}\x{64CD}'
. '\x{64D2}\x{64D4}\x{64D8}\x{64DA}\x{64E0}\x{64E1}\x{64E2}\x{64E3}\x{64E6}'
. '\x{64E7}\x{64EC}\x{64EF}\x{64F1}\x{64F2}\x{64F4}\x{64F6}\x{64FA}\x{64FD}'
. '\x{64FE}\x{6500}\x{6505}\x{6518}\x{651C}\x{651D}\x{6523}\x{6524}\x{652A}'
. '\x{652B}\x{652C}\x{652F}\x{6534}\x{6535}\x{6536}\x{6537}\x{6538}\x{6539}'
. '\x{653B}\x{653E}\x{653F}\x{6545}\x{6548}\x{654D}\x{654F}\x{6551}\x{6555}'
. '\x{6556}\x{6557}\x{6558}\x{6559}\x{655D}\x{655E}\x{6562}\x{6563}\x{6566}'
. '\x{656C}\x{6570}\x{6572}\x{6574}\x{6575}\x{6577}\x{6578}\x{6582}\x{6583}'
. '\x{6587}\x{6588}\x{6589}\x{658C}\x{658E}\x{6590}\x{6591}\x{6597}\x{6599}'
. '\x{659B}\x{659C}\x{659F}\x{65A1}\x{65A4}\x{65A5}\x{65A7}\x{65AB}\x{65AC}'
. '\x{65AD}\x{65AF}\x{65B0}\x{65B7}\x{65B9}\x{65BC}\x{65BD}\x{65C1}\x{65C3}'
. '\x{65C4}\x{65C5}\x{65C6}\x{65CB}\x{65CC}\x{65CF}\x{65D2}\x{65D7}\x{65D9}'
. '\x{65DB}\x{65E0}\x{65E1}\x{65E2}\x{65E5}\x{65E6}\x{65E7}\x{65E8}\x{65E9}'
. '\x{65EC}\x{65ED}\x{65F1}\x{65FA}\x{65FB}\x{6602}\x{6603}\x{6606}\x{6607}'
. '\x{660A}\x{660C}\x{660E}\x{660F}\x{6613}\x{6614}\x{661C}\x{661F}\x{6620}'
. '\x{6625}\x{6627}\x{6628}\x{662D}\x{662F}\x{6634}\x{6635}\x{6636}\x{663C}'
. '\x{663F}\x{6641}\x{6642}\x{6643}\x{6644}\x{6649}\x{664B}\x{664F}\x{6652}'
. '\x{665D}\x{665E}\x{665F}\x{6662}\x{6664}\x{6666}\x{6667}\x{6668}\x{6669}'
. '\x{666E}\x{666F}\x{6670}\x{6674}\x{6676}\x{667A}\x{6681}\x{6683}\x{6684}'
. '\x{6687}\x{6688}\x{6689}\x{668E}\x{6691}\x{6696}\x{6697}\x{6698}\x{669D}'
. '\x{66A2}\x{66A6}\x{66AB}\x{66AE}\x{66B4}\x{66B8}\x{66B9}\x{66BC}\x{66BE}'
. '\x{66C1}\x{66C4}\x{66C7}\x{66C9}\x{66D6}\x{66D9}\x{66DA}\x{66DC}\x{66DD}'
. '\x{66E0}\x{66E6}\x{66E9}\x{66F0}\x{66F2}\x{66F3}\x{66F4}\x{66F5}\x{66F7}'
. '\x{66F8}\x{66F9}\x{66FC}\x{66FD}\x{66FE}\x{66FF}\x{6700}\x{6703}\x{6708}'
. '\x{6709}\x{670B}\x{670D}\x{670F}\x{6714}\x{6715}\x{6716}\x{6717}\x{671B}'
. '\x{671D}\x{671E}\x{671F}\x{6726}\x{6727}\x{6728}\x{672A}\x{672B}\x{672C}'
. '\x{672D}\x{672E}\x{6731}\x{6734}\x{6736}\x{6737}\x{6738}\x{673A}\x{673D}'
. '\x{673F}\x{6741}\x{6746}\x{6749}\x{674E}\x{674F}\x{6750}\x{6751}\x{6753}'
. '\x{6756}\x{6759}\x{675C}\x{675E}\x{675F}\x{6760}\x{6761}\x{6762}\x{6763}'
. '\x{6764}\x{6765}\x{676A}\x{676D}\x{676F}\x{6770}\x{6771}\x{6772}\x{6773}'
. '\x{6775}\x{6777}\x{677C}\x{677E}\x{677F}\x{6785}\x{6787}\x{6789}\x{678B}'
. '\x{678C}\x{6790}\x{6795}\x{6797}\x{679A}\x{679C}\x{679D}\x{67A0}\x{67A1}'
. '\x{67A2}\x{67A6}\x{67A9}\x{67AF}\x{67B3}\x{67B4}\x{67B6}\x{67B7}\x{67B8}'
. '\x{67B9}\x{67C1}\x{67C4}\x{67C6}\x{67CA}\x{67CE}\x{67CF}\x{67D0}\x{67D1}'
. '\x{67D3}\x{67D4}\x{67D8}\x{67DA}\x{67DD}\x{67DE}\x{67E2}\x{67E4}\x{67E7}'
. '\x{67E9}\x{67EC}\x{67EE}\x{67EF}\x{67F1}\x{67F3}\x{67F4}\x{67F5}\x{67FB}'
. '\x{67FE}\x{67FF}\x{6802}\x{6803}\x{6804}\x{6813}\x{6816}\x{6817}\x{681E}'
. '\x{6821}\x{6822}\x{6829}\x{682A}\x{682B}\x{6832}\x{6834}\x{6838}\x{6839}'
. '\x{683C}\x{683D}\x{6840}\x{6841}\x{6842}\x{6843}\x{6846}\x{6848}\x{684D}'
. '\x{684E}\x{6850}\x{6851}\x{6853}\x{6854}\x{6859}\x{685C}\x{685D}\x{685F}'
. '\x{6863}\x{6867}\x{6874}\x{6876}\x{6877}\x{687E}\x{687F}\x{6881}\x{6883}'
. '\x{6885}\x{688D}\x{688F}\x{6893}\x{6894}\x{6897}\x{689B}\x{689D}\x{689F}'
. '\x{68A0}\x{68A2}\x{68A6}\x{68A7}\x{68A8}\x{68AD}\x{68AF}\x{68B0}\x{68B1}'
. '\x{68B3}\x{68B5}\x{68B6}\x{68B9}\x{68BA}\x{68BC}\x{68C4}\x{68C6}\x{68C9}'
. '\x{68CA}\x{68CB}\x{68CD}\x{68D2}\x{68D4}\x{68D5}\x{68D7}\x{68D8}\x{68DA}'
. '\x{68DF}\x{68E0}\x{68E1}\x{68E3}\x{68E7}\x{68EE}\x{68EF}\x{68F2}\x{68F9}'
. '\x{68FA}\x{6900}\x{6901}\x{6904}\x{6905}\x{6908}\x{690B}\x{690C}\x{690D}'
. '\x{690E}\x{690F}\x{6912}\x{6919}\x{691A}\x{691B}\x{691C}\x{6921}\x{6922}'
. '\x{6923}\x{6925}\x{6926}\x{6928}\x{692A}\x{6930}\x{6934}\x{6936}\x{6939}'
. '\x{693D}\x{693F}\x{694A}\x{6953}\x{6954}\x{6955}\x{6959}\x{695A}\x{695C}'
. '\x{695D}\x{695E}\x{6960}\x{6961}\x{6962}\x{696A}\x{696B}\x{696D}\x{696E}'
. '\x{696F}\x{6973}\x{6974}\x{6975}\x{6977}\x{6978}\x{6979}\x{697C}\x{697D}'
. '\x{697E}\x{6981}\x{6982}\x{698A}\x{698E}\x{6991}\x{6994}\x{6995}\x{699B}'
. '\x{699C}\x{69A0}\x{69A7}\x{69AE}\x{69B1}\x{69B2}\x{69B4}\x{69BB}\x{69BE}'
. '\x{69BF}\x{69C1}\x{69C3}\x{69C7}\x{69CA}\x{69CB}\x{69CC}\x{69CD}\x{69CE}'
. '\x{69D0}\x{69D3}\x{69D8}\x{69D9}\x{69DD}\x{69DE}\x{69E7}\x{69E8}\x{69EB}'
. '\x{69ED}\x{69F2}\x{69F9}\x{69FB}\x{69FD}\x{69FF}\x{6A02}\x{6A05}\x{6A0A}'
. '\x{6A0B}\x{6A0C}\x{6A12}\x{6A13}\x{6A14}\x{6A17}\x{6A19}\x{6A1B}\x{6A1E}'
. '\x{6A1F}\x{6A21}\x{6A22}\x{6A23}\x{6A29}\x{6A2A}\x{6A2B}\x{6A2E}\x{6A35}'
. '\x{6A36}\x{6A38}\x{6A39}\x{6A3A}\x{6A3D}\x{6A44}\x{6A47}\x{6A48}\x{6A4B}'
. '\x{6A58}\x{6A59}\x{6A5F}\x{6A61}\x{6A62}\x{6A66}\x{6A72}\x{6A78}\x{6A7F}'
. '\x{6A80}\x{6A84}\x{6A8D}\x{6A8E}\x{6A90}\x{6A97}\x{6A9C}\x{6AA0}\x{6AA2}'
. '\x{6AA3}\x{6AAA}\x{6AAC}\x{6AAE}\x{6AB3}\x{6AB8}\x{6ABB}\x{6AC1}\x{6AC2}'
. '\x{6AC3}\x{6AD1}\x{6AD3}\x{6ADA}\x{6ADB}\x{6ADE}\x{6ADF}\x{6AE8}\x{6AEA}'
. '\x{6AFA}\x{6AFB}\x{6B04}\x{6B05}\x{6B0A}\x{6B12}\x{6B16}\x{6B1D}\x{6B1F}'
. '\x{6B20}\x{6B21}\x{6B23}\x{6B27}\x{6B32}\x{6B37}\x{6B38}\x{6B39}\x{6B3A}'
. '\x{6B3D}\x{6B3E}\x{6B43}\x{6B47}\x{6B49}\x{6B4C}\x{6B4E}\x{6B50}\x{6B53}'
. '\x{6B54}\x{6B59}\x{6B5B}\x{6B5F}\x{6B61}\x{6B62}\x{6B63}\x{6B64}\x{6B66}'
. '\x{6B69}\x{6B6A}\x{6B6F}\x{6B73}\x{6B74}\x{6B78}\x{6B79}\x{6B7B}\x{6B7F}'
. '\x{6B80}\x{6B83}\x{6B84}\x{6B86}\x{6B89}\x{6B8A}\x{6B8B}\x{6B8D}\x{6B95}'
. '\x{6B96}\x{6B98}\x{6B9E}\x{6BA4}\x{6BAA}\x{6BAB}\x{6BAF}\x{6BB1}\x{6BB2}'
. '\x{6BB3}\x{6BB4}\x{6BB5}\x{6BB7}\x{6BBA}\x{6BBB}\x{6BBC}\x{6BBF}\x{6BC0}'
. '\x{6BC5}\x{6BC6}\x{6BCB}\x{6BCD}\x{6BCE}\x{6BD2}\x{6BD3}\x{6BD4}\x{6BD8}'
. '\x{6BDB}\x{6BDF}\x{6BEB}\x{6BEC}\x{6BEF}\x{6BF3}\x{6C08}\x{6C0F}\x{6C11}'
. '\x{6C13}\x{6C14}\x{6C17}\x{6C1B}\x{6C23}\x{6C24}\x{6C34}\x{6C37}\x{6C38}'
. '\x{6C3E}\x{6C40}\x{6C41}\x{6C42}\x{6C4E}\x{6C50}\x{6C55}\x{6C57}\x{6C5A}'
. '\x{6C5D}\x{6C5E}\x{6C5F}\x{6C60}\x{6C62}\x{6C68}\x{6C6A}\x{6C70}\x{6C72}'
. '\x{6C73}\x{6C7A}\x{6C7D}\x{6C7E}\x{6C81}\x{6C82}\x{6C83}\x{6C88}\x{6C8C}'
. '\x{6C8D}\x{6C90}\x{6C92}\x{6C93}\x{6C96}\x{6C99}\x{6C9A}\x{6C9B}\x{6CA1}'
. '\x{6CA2}\x{6CAB}\x{6CAE}\x{6CB1}\x{6CB3}\x{6CB8}\x{6CB9}\x{6CBA}\x{6CBB}'
. '\x{6CBC}\x{6CBD}\x{6CBE}\x{6CBF}\x{6CC1}\x{6CC4}\x{6CC5}\x{6CC9}\x{6CCA}'
. '\x{6CCC}\x{6CD3}\x{6CD5}\x{6CD7}\x{6CD9}\x{6CDB}\x{6CDD}\x{6CE1}\x{6CE2}'
. '\x{6CE3}\x{6CE5}\x{6CE8}\x{6CEA}\x{6CEF}\x{6CF0}\x{6CF1}\x{6CF3}\x{6D0B}'
. '\x{6D0C}\x{6D12}\x{6D17}\x{6D19}\x{6D1B}\x{6D1E}\x{6D1F}\x{6D25}\x{6D29}'
. '\x{6D2A}\x{6D2B}\x{6D32}\x{6D33}\x{6D35}\x{6D36}\x{6D38}\x{6D3B}\x{6D3D}'
. '\x{6D3E}\x{6D41}\x{6D44}\x{6D45}\x{6D59}\x{6D5A}\x{6D5C}\x{6D63}\x{6D64}'
. '\x{6D66}\x{6D69}\x{6D6A}\x{6D6C}\x{6D6E}\x{6D74}\x{6D77}\x{6D78}\x{6D79}'
. '\x{6D85}\x{6D88}\x{6D8C}\x{6D8E}\x{6D93}\x{6D95}\x{6D99}\x{6D9B}\x{6D9C}'
. '\x{6DAF}\x{6DB2}\x{6DB5}\x{6DB8}\x{6DBC}\x{6DC0}\x{6DC5}\x{6DC6}\x{6DC7}'
. '\x{6DCB}\x{6DCC}\x{6DD1}\x{6DD2}\x{6DD5}\x{6DD8}\x{6DD9}\x{6DDE}\x{6DE1}'
. '\x{6DE4}\x{6DE6}\x{6DE8}\x{6DEA}\x{6DEB}\x{6DEC}\x{6DEE}\x{6DF1}\x{6DF3}'
. '\x{6DF5}\x{6DF7}\x{6DF9}\x{6DFA}\x{6DFB}\x{6E05}\x{6E07}\x{6E08}\x{6E09}'
. '\x{6E0A}\x{6E0B}\x{6E13}\x{6E15}\x{6E19}\x{6E1A}\x{6E1B}\x{6E1D}\x{6E1F}'
. '\x{6E20}\x{6E21}\x{6E23}\x{6E24}\x{6E25}\x{6E26}\x{6E29}\x{6E2B}\x{6E2C}'
. '\x{6E2D}\x{6E2E}\x{6E2F}\x{6E38}\x{6E3A}\x{6E3E}\x{6E43}\x{6E4A}\x{6E4D}'
. '\x{6E4E}\x{6E56}\x{6E58}\x{6E5B}\x{6E5F}\x{6E67}\x{6E6B}\x{6E6E}\x{6E6F}'
. '\x{6E72}\x{6E76}\x{6E7E}\x{6E7F}\x{6E80}\x{6E82}\x{6E8C}\x{6E8F}\x{6E90}'
. '\x{6E96}\x{6E98}\x{6E9C}\x{6E9D}\x{6E9F}\x{6EA2}\x{6EA5}\x{6EAA}\x{6EAF}'
. '\x{6EB2}\x{6EB6}\x{6EB7}\x{6EBA}\x{6EBD}\x{6EC2}\x{6EC4}\x{6EC5}\x{6EC9}'
. '\x{6ECB}\x{6ECC}\x{6ED1}\x{6ED3}\x{6ED4}\x{6ED5}\x{6EDD}\x{6EDE}\x{6EEC}'
. '\x{6EEF}\x{6EF2}\x{6EF4}\x{6EF7}\x{6EF8}\x{6EFE}\x{6EFF}\x{6F01}\x{6F02}'
. '\x{6F06}\x{6F09}\x{6F0F}\x{6F11}\x{6F13}\x{6F14}\x{6F15}\x{6F20}\x{6F22}'
. '\x{6F23}\x{6F2B}\x{6F2C}\x{6F31}\x{6F32}\x{6F38}\x{6F3E}\x{6F3F}\x{6F41}'
. '\x{6F45}\x{6F54}\x{6F58}\x{6F5B}\x{6F5C}\x{6F5F}\x{6F64}\x{6F66}\x{6F6D}'
. '\x{6F6E}\x{6F6F}\x{6F70}\x{6F74}\x{6F78}\x{6F7A}\x{6F7C}\x{6F80}\x{6F81}'
. '\x{6F82}\x{6F84}\x{6F86}\x{6F8E}\x{6F91}\x{6F97}\x{6FA1}\x{6FA3}\x{6FA4}'
. '\x{6FAA}\x{6FB1}\x{6FB3}\x{6FB9}\x{6FC0}\x{6FC1}\x{6FC2}\x{6FC3}\x{6FC6}'
. '\x{6FD4}\x{6FD5}\x{6FD8}\x{6FDB}\x{6FDF}\x{6FE0}\x{6FE1}\x{6FE4}\x{6FEB}'
. '\x{6FEC}\x{6FEE}\x{6FEF}\x{6FF1}\x{6FF3}\x{6FF6}\x{6FFA}\x{6FFE}\x{7001}'
. '\x{7009}\x{700B}\x{700F}\x{7011}\x{7015}\x{7018}\x{701A}\x{701B}\x{701D}'
. '\x{701E}\x{701F}\x{7026}\x{7027}\x{702C}\x{7030}\x{7032}\x{703E}\x{704C}'
. '\x{7051}\x{7058}\x{7063}\x{706B}\x{706F}\x{7070}\x{7078}\x{707C}\x{707D}'
. '\x{7089}\x{708A}\x{708E}\x{7092}\x{7099}\x{70AC}\x{70AD}\x{70AE}\x{70AF}'
. '\x{70B3}\x{70B8}\x{70B9}\x{70BA}\x{70C8}\x{70CB}\x{70CF}\x{70D9}\x{70DD}'
. '\x{70DF}\x{70F1}\x{70F9}\x{70FD}\x{7109}\x{7114}\x{7119}\x{711A}\x{711C}'
. '\x{7121}\x{7126}\x{7136}\x{713C}\x{7149}\x{714C}\x{714E}\x{7155}\x{7156}'
. '\x{7159}\x{7162}\x{7164}\x{7165}\x{7166}\x{7167}\x{7169}\x{716C}\x{716E}'
. '\x{717D}\x{7184}\x{7188}\x{718A}\x{718F}\x{7194}\x{7195}\x{7199}\x{719F}'
. '\x{71A8}\x{71AC}\x{71B1}\x{71B9}\x{71BE}\x{71C3}\x{71C8}\x{71C9}\x{71CE}'
. '\x{71D0}\x{71D2}\x{71D4}\x{71D5}\x{71D7}\x{71DF}\x{71E0}\x{71E5}\x{71E6}'
. '\x{71E7}\x{71EC}\x{71ED}\x{71EE}\x{71F5}\x{71F9}\x{71FB}\x{71FC}\x{71FF}'
. '\x{7206}\x{720D}\x{7210}\x{721B}\x{7228}\x{722A}\x{722C}\x{722D}\x{7230}'
. '\x{7232}\x{7235}\x{7236}\x{723A}\x{723B}\x{723C}\x{723D}\x{723E}\x{723F}'
. '\x{7240}\x{7246}\x{7247}\x{7248}\x{724B}\x{724C}\x{7252}\x{7258}\x{7259}'
. '\x{725B}\x{725D}\x{725F}\x{7261}\x{7262}\x{7267}\x{7269}\x{7272}\x{7274}'
. '\x{7279}\x{727D}\x{727E}\x{7280}\x{7281}\x{7282}\x{7287}\x{7292}\x{7296}'
. '\x{72A0}\x{72A2}\x{72A7}\x{72AC}\x{72AF}\x{72B2}\x{72B6}\x{72B9}\x{72C2}'
. '\x{72C3}\x{72C4}\x{72C6}\x{72CE}\x{72D0}\x{72D2}\x{72D7}\x{72D9}\x{72DB}'
. '\x{72E0}\x{72E1}\x{72E2}\x{72E9}\x{72EC}\x{72ED}\x{72F7}\x{72F8}\x{72F9}'
. '\x{72FC}\x{72FD}\x{730A}\x{7316}\x{7317}\x{731B}\x{731C}\x{731D}\x{731F}'
. '\x{7325}\x{7329}\x{732A}\x{732B}\x{732E}\x{732F}\x{7334}\x{7336}\x{7337}'
. '\x{733E}\x{733F}\x{7344}\x{7345}\x{734E}\x{734F}\x{7357}\x{7363}\x{7368}'
. '\x{736A}\x{7370}\x{7372}\x{7375}\x{7378}\x{737A}\x{737B}\x{7384}\x{7387}'
. '\x{7389}\x{738B}\x{7396}\x{73A9}\x{73B2}\x{73B3}\x{73BB}\x{73C0}\x{73C2}'
. '\x{73C8}\x{73CA}\x{73CD}\x{73CE}\x{73DE}\x{73E0}\x{73E5}\x{73EA}\x{73ED}'
. '\x{73EE}\x{73F1}\x{73F8}\x{73FE}\x{7403}\x{7405}\x{7406}\x{7409}\x{7422}'
. '\x{7425}\x{7432}\x{7433}\x{7434}\x{7435}\x{7436}\x{743A}\x{743F}\x{7441}'
. '\x{7455}\x{7459}\x{745A}\x{745B}\x{745C}\x{745E}\x{745F}\x{7460}\x{7463}'
. '\x{7464}\x{7469}\x{746A}\x{746F}\x{7470}\x{7473}\x{7476}\x{747E}\x{7483}'
. '\x{748B}\x{749E}\x{74A2}\x{74A7}\x{74B0}\x{74BD}\x{74CA}\x{74CF}\x{74D4}'
. '\x{74DC}\x{74E0}\x{74E2}\x{74E3}\x{74E6}\x{74E7}\x{74E9}\x{74EE}\x{74F0}'
. '\x{74F1}\x{74F2}\x{74F6}\x{74F7}\x{74F8}\x{7503}\x{7504}\x{7505}\x{750C}'
. '\x{750D}\x{750E}\x{7511}\x{7513}\x{7515}\x{7518}\x{751A}\x{751C}\x{751E}'
. '\x{751F}\x{7523}\x{7525}\x{7526}\x{7528}\x{752B}\x{752C}\x{7530}\x{7531}'
. '\x{7532}\x{7533}\x{7537}\x{7538}\x{753A}\x{753B}\x{753C}\x{7544}\x{7546}'
. '\x{7549}\x{754A}\x{754B}\x{754C}\x{754D}\x{754F}\x{7551}\x{7554}\x{7559}'
. '\x{755A}\x{755B}\x{755C}\x{755D}\x{7560}\x{7562}\x{7564}\x{7565}\x{7566}'
. '\x{7567}\x{7569}\x{756A}\x{756B}\x{756D}\x{7570}\x{7573}\x{7574}\x{7576}'
. '\x{7577}\x{7578}\x{757F}\x{7582}\x{7586}\x{7587}\x{7589}\x{758A}\x{758B}'
. '\x{758E}\x{758F}\x{7591}\x{7594}\x{759A}\x{759D}\x{75A3}\x{75A5}\x{75AB}'
. '\x{75B1}\x{75B2}\x{75B3}\x{75B5}\x{75B8}\x{75B9}\x{75BC}\x{75BD}\x{75BE}'
. '\x{75C2}\x{75C3}\x{75C5}\x{75C7}\x{75CA}\x{75CD}\x{75D2}\x{75D4}\x{75D5}'
. '\x{75D8}\x{75D9}\x{75DB}\x{75DE}\x{75E2}\x{75E3}\x{75E9}\x{75F0}\x{75F2}'
. '\x{75F3}\x{75F4}\x{75FA}\x{75FC}\x{75FE}\x{75FF}\x{7601}\x{7609}\x{760B}'
. '\x{760D}\x{761F}\x{7620}\x{7621}\x{7622}\x{7624}\x{7627}\x{7630}\x{7634}'
. '\x{763B}\x{7642}\x{7646}\x{7647}\x{7648}\x{764C}\x{7652}\x{7656}\x{7658}'
. '\x{765C}\x{7661}\x{7662}\x{7667}\x{7668}\x{7669}\x{766A}\x{766C}\x{7670}'
. '\x{7672}\x{7676}\x{7678}\x{767A}\x{767B}\x{767C}\x{767D}\x{767E}\x{7680}'
. '\x{7683}\x{7684}\x{7686}\x{7687}\x{7688}\x{768B}\x{768E}\x{7690}\x{7693}'
. '\x{7696}\x{7699}\x{769A}\x{76AE}\x{76B0}\x{76B4}\x{76B7}\x{76B8}\x{76B9}'
. '\x{76BA}\x{76BF}\x{76C2}\x{76C3}\x{76C6}\x{76C8}\x{76CA}\x{76CD}\x{76D2}'
. '\x{76D6}\x{76D7}\x{76DB}\x{76DC}\x{76DE}\x{76DF}\x{76E1}\x{76E3}\x{76E4}'
. '\x{76E5}\x{76E7}\x{76EA}\x{76EE}\x{76F2}\x{76F4}\x{76F8}\x{76FB}\x{76FE}'
. '\x{7701}\x{7704}\x{7707}\x{7708}\x{7709}\x{770B}\x{770C}\x{771B}\x{771E}'
. '\x{771F}\x{7720}\x{7724}\x{7725}\x{7726}\x{7729}\x{7737}\x{7738}\x{773A}'
. '\x{773C}\x{7740}\x{7747}\x{775A}\x{775B}\x{7761}\x{7763}\x{7765}\x{7766}'
. '\x{7768}\x{776B}\x{7779}\x{777E}\x{777F}\x{778B}\x{778E}\x{7791}\x{779E}'
. '\x{77A0}\x{77A5}\x{77AC}\x{77AD}\x{77B0}\x{77B3}\x{77B6}\x{77B9}\x{77BB}'
. '\x{77BC}\x{77BD}\x{77BF}\x{77C7}\x{77CD}\x{77D7}\x{77DA}\x{77DB}\x{77DC}'
. '\x{77E2}\x{77E3}\x{77E5}\x{77E7}\x{77E9}\x{77ED}\x{77EE}\x{77EF}\x{77F3}'
. '\x{77FC}\x{7802}\x{780C}\x{7812}\x{7814}\x{7815}\x{7820}\x{7825}\x{7826}'
. '\x{7827}\x{7832}\x{7834}\x{783A}\x{783F}\x{7845}\x{785D}\x{786B}\x{786C}'
. '\x{786F}\x{7872}\x{7874}\x{787C}\x{7881}\x{7886}\x{7887}\x{788C}\x{788D}'
. '\x{788E}\x{7891}\x{7893}\x{7895}\x{7897}\x{789A}\x{78A3}\x{78A7}\x{78A9}'
. '\x{78AA}\x{78AF}\x{78B5}\x{78BA}\x{78BC}\x{78BE}\x{78C1}\x{78C5}\x{78C6}'
. '\x{78CA}\x{78CB}\x{78D0}\x{78D1}\x{78D4}\x{78DA}\x{78E7}\x{78E8}\x{78EC}'
. '\x{78EF}\x{78F4}\x{78FD}\x{7901}\x{7907}\x{790E}\x{7911}\x{7912}\x{7919}'
. '\x{7926}\x{792A}\x{792B}\x{792C}\x{793A}\x{793C}\x{793E}\x{7940}\x{7941}'
. '\x{7947}\x{7948}\x{7949}\x{7950}\x{7953}\x{7955}\x{7956}\x{7957}\x{795A}'
. '\x{795D}\x{795E}\x{795F}\x{7960}\x{7962}\x{7965}\x{7968}\x{796D}\x{7977}'
. '\x{797A}\x{797F}\x{7980}\x{7981}\x{7984}\x{7985}\x{798A}\x{798D}\x{798E}'
. '\x{798F}\x{799D}\x{79A6}\x{79A7}\x{79AA}\x{79AE}\x{79B0}\x{79B3}\x{79B9}'
. '\x{79BA}\x{79BD}\x{79BE}\x{79BF}\x{79C0}\x{79C1}\x{79C9}\x{79CB}\x{79D1}'
. '\x{79D2}\x{79D5}\x{79D8}\x{79DF}\x{79E1}\x{79E3}\x{79E4}\x{79E6}\x{79E7}'
. '\x{79E9}\x{79EC}\x{79F0}\x{79FB}\x{7A00}\x{7A08}\x{7A0B}\x{7A0D}\x{7A0E}'
. '\x{7A14}\x{7A17}\x{7A18}\x{7A19}\x{7A1A}\x{7A1C}\x{7A1F}\x{7A20}\x{7A2E}'
. '\x{7A31}\x{7A32}\x{7A37}\x{7A3B}\x{7A3C}\x{7A3D}\x{7A3E}\x{7A3F}\x{7A40}'
. '\x{7A42}\x{7A43}\x{7A46}\x{7A49}\x{7A4D}\x{7A4E}\x{7A4F}\x{7A50}\x{7A57}'
. '\x{7A61}\x{7A62}\x{7A63}\x{7A69}\x{7A6B}\x{7A70}\x{7A74}\x{7A76}\x{7A79}'
. '\x{7A7A}\x{7A7D}\x{7A7F}\x{7A81}\x{7A83}\x{7A84}\x{7A88}\x{7A92}\x{7A93}'
. '\x{7A95}\x{7A96}\x{7A97}\x{7A98}\x{7A9F}\x{7AA9}\x{7AAA}\x{7AAE}\x{7AAF}'
. '\x{7AB0}\x{7AB6}\x{7ABA}\x{7ABF}\x{7AC3}\x{7AC4}\x{7AC5}\x{7AC7}\x{7AC8}'
. '\x{7ACA}\x{7ACB}\x{7ACD}\x{7ACF}\x{7AD2}\x{7AD3}\x{7AD5}\x{7AD9}\x{7ADA}'
. '\x{7ADC}\x{7ADD}\x{7ADF}\x{7AE0}\x{7AE1}\x{7AE2}\x{7AE3}\x{7AE5}\x{7AE6}'
. '\x{7AEA}\x{7AED}\x{7AEF}\x{7AF0}\x{7AF6}\x{7AF8}\x{7AF9}\x{7AFA}\x{7AFF}'
. '\x{7B02}\x{7B04}\x{7B06}\x{7B08}\x{7B0A}\x{7B0B}\x{7B0F}\x{7B11}\x{7B18}'
. '\x{7B19}\x{7B1B}\x{7B1E}\x{7B20}\x{7B25}\x{7B26}\x{7B28}\x{7B2C}\x{7B33}'
. '\x{7B35}\x{7B36}\x{7B39}\x{7B45}\x{7B46}\x{7B48}\x{7B49}\x{7B4B}\x{7B4C}'
. '\x{7B4D}\x{7B4F}\x{7B50}\x{7B51}\x{7B52}\x{7B54}\x{7B56}\x{7B5D}\x{7B65}'
. '\x{7B67}\x{7B6C}\x{7B6E}\x{7B70}\x{7B71}\x{7B74}\x{7B75}\x{7B7A}\x{7B86}'
. '\x{7B87}\x{7B8B}\x{7B8D}\x{7B8F}\x{7B92}\x{7B94}\x{7B95}\x{7B97}\x{7B98}'
. '\x{7B99}\x{7B9A}\x{7B9C}\x{7B9D}\x{7B9F}\x{7BA1}\x{7BAA}\x{7BAD}\x{7BB1}'
. '\x{7BB4}\x{7BB8}\x{7BC0}\x{7BC1}\x{7BC4}\x{7BC6}\x{7BC7}\x{7BC9}\x{7BCB}'
. '\x{7BCC}\x{7BCF}\x{7BDD}\x{7BE0}\x{7BE4}\x{7BE5}\x{7BE6}\x{7BE9}\x{7BED}'
. '\x{7BF3}\x{7BF6}\x{7BF7}\x{7C00}\x{7C07}\x{7C0D}\x{7C11}\x{7C12}\x{7C13}'
. '\x{7C14}\x{7C17}\x{7C1F}\x{7C21}\x{7C23}\x{7C27}\x{7C2A}\x{7C2B}\x{7C37}'
. '\x{7C38}\x{7C3D}\x{7C3E}\x{7C3F}\x{7C40}\x{7C43}\x{7C4C}\x{7C4D}\x{7C4F}'
. '\x{7C50}\x{7C54}\x{7C56}\x{7C58}\x{7C5F}\x{7C60}\x{7C64}\x{7C65}\x{7C6C}'
. '\x{7C73}\x{7C75}\x{7C7E}\x{7C81}\x{7C82}\x{7C83}\x{7C89}\x{7C8B}\x{7C8D}'
. '\x{7C90}\x{7C92}\x{7C95}\x{7C97}\x{7C98}\x{7C9B}\x{7C9F}\x{7CA1}\x{7CA2}'
. '\x{7CA4}\x{7CA5}\x{7CA7}\x{7CA8}\x{7CAB}\x{7CAD}\x{7CAE}\x{7CB1}\x{7CB2}'
. '\x{7CB3}\x{7CB9}\x{7CBD}\x{7CBE}\x{7CC0}\x{7CC2}\x{7CC5}\x{7CCA}\x{7CCE}'
. '\x{7CD2}\x{7CD6}\x{7CD8}\x{7CDC}\x{7CDE}\x{7CDF}\x{7CE0}\x{7CE2}\x{7CE7}'
. '\x{7CEF}\x{7CF2}\x{7CF4}\x{7CF6}\x{7CF8}\x{7CFA}\x{7CFB}\x{7CFE}\x{7D00}'
. '\x{7D02}\x{7D04}\x{7D05}\x{7D06}\x{7D0A}\x{7D0B}\x{7D0D}\x{7D10}\x{7D14}'
. '\x{7D15}\x{7D17}\x{7D18}\x{7D19}\x{7D1A}\x{7D1B}\x{7D1C}\x{7D20}\x{7D21}'
. '\x{7D22}\x{7D2B}\x{7D2C}\x{7D2E}\x{7D2F}\x{7D30}\x{7D32}\x{7D33}\x{7D35}'
. '\x{7D39}\x{7D3A}\x{7D3F}\x{7D42}\x{7D43}\x{7D44}\x{7D45}\x{7D46}\x{7D4B}'
. '\x{7D4C}\x{7D4E}\x{7D4F}\x{7D50}\x{7D56}\x{7D5B}\x{7D5E}\x{7D61}\x{7D62}'
. '\x{7D63}\x{7D66}\x{7D68}\x{7D6E}\x{7D71}\x{7D72}\x{7D73}\x{7D75}\x{7D76}'
. '\x{7D79}\x{7D7D}\x{7D89}\x{7D8F}\x{7D93}\x{7D99}\x{7D9A}\x{7D9B}\x{7D9C}'
. '\x{7D9F}\x{7DA2}\x{7DA3}\x{7DAB}\x{7DAC}\x{7DAD}\x{7DAE}\x{7DAF}\x{7DB0}'
. '\x{7DB1}\x{7DB2}\x{7DB4}\x{7DB5}\x{7DB8}\x{7DBA}\x{7DBB}\x{7DBD}\x{7DBE}'
. '\x{7DBF}\x{7DC7}\x{7DCA}\x{7DCB}\x{7DCF}\x{7DD1}\x{7DD2}\x{7DD5}\x{7DD8}'
. '\x{7DDA}\x{7DDC}\x{7DDD}\x{7DDE}\x{7DE0}\x{7DE1}\x{7DE4}\x{7DE8}\x{7DE9}'
. '\x{7DEC}\x{7DEF}\x{7DF2}\x{7DF4}\x{7DFB}\x{7E01}\x{7E04}\x{7E05}\x{7E09}'
. '\x{7E0A}\x{7E0B}\x{7E12}\x{7E1B}\x{7E1E}\x{7E1F}\x{7E21}\x{7E22}\x{7E23}'
. '\x{7E26}\x{7E2B}\x{7E2E}\x{7E31}\x{7E32}\x{7E35}\x{7E37}\x{7E39}\x{7E3A}'
. '\x{7E3B}\x{7E3D}\x{7E3E}\x{7E41}\x{7E43}\x{7E46}\x{7E4A}\x{7E4B}\x{7E4D}'
. '\x{7E54}\x{7E55}\x{7E56}\x{7E59}\x{7E5A}\x{7E5D}\x{7E5E}\x{7E66}\x{7E67}'
. '\x{7E69}\x{7E6A}\x{7E6D}\x{7E70}\x{7E79}\x{7E7B}\x{7E7C}\x{7E7D}\x{7E7F}'
. '\x{7E82}\x{7E83}\x{7E88}\x{7E89}\x{7E8C}\x{7E8E}\x{7E8F}\x{7E90}\x{7E92}'
. '\x{7E93}\x{7E94}\x{7E96}\x{7E9B}\x{7E9C}\x{7F36}\x{7F38}\x{7F3A}\x{7F45}'
. '\x{7F4C}\x{7F4D}\x{7F4E}\x{7F50}\x{7F51}\x{7F54}\x{7F55}\x{7F58}\x{7F5F}'
. '\x{7F60}\x{7F67}\x{7F68}\x{7F69}\x{7F6A}\x{7F6B}\x{7F6E}\x{7F70}\x{7F72}'
. '\x{7F75}\x{7F77}\x{7F78}\x{7F79}\x{7F82}\x{7F83}\x{7F85}\x{7F86}\x{7F87}'
. '\x{7F88}\x{7F8A}\x{7F8C}\x{7F8E}\x{7F94}\x{7F9A}\x{7F9D}\x{7F9E}\x{7FA3}'
. '\x{7FA4}\x{7FA8}\x{7FA9}\x{7FAE}\x{7FAF}\x{7FB2}\x{7FB6}\x{7FB8}\x{7FB9}'
. '\x{7FBD}\x{7FC1}\x{7FC5}\x{7FC6}\x{7FCA}\x{7FCC}\x{7FD2}\x{7FD4}\x{7FD5}'
. '\x{7FE0}\x{7FE1}\x{7FE6}\x{7FE9}\x{7FEB}\x{7FF0}\x{7FF3}\x{7FF9}\x{7FFB}'
. '\x{7FFC}\x{8000}\x{8001}\x{8003}\x{8004}\x{8005}\x{8006}\x{800B}\x{800C}'
. '\x{8010}\x{8012}\x{8015}\x{8017}\x{8018}\x{8019}\x{801C}\x{8021}\x{8028}'
. '\x{8033}\x{8036}\x{803B}\x{803D}\x{803F}\x{8046}\x{804A}\x{8052}\x{8056}'
. '\x{8058}\x{805A}\x{805E}\x{805F}\x{8061}\x{8062}\x{8068}\x{806F}\x{8070}'
. '\x{8072}\x{8073}\x{8074}\x{8076}\x{8077}\x{8079}\x{807D}\x{807E}\x{807F}'
. '\x{8084}\x{8085}\x{8086}\x{8087}\x{8089}\x{808B}\x{808C}\x{8093}\x{8096}'
. '\x{8098}\x{809A}\x{809B}\x{809D}\x{80A1}\x{80A2}\x{80A5}\x{80A9}\x{80AA}'
. '\x{80AC}\x{80AD}\x{80AF}\x{80B1}\x{80B2}\x{80B4}\x{80BA}\x{80C3}\x{80C4}'
. '\x{80C6}\x{80CC}\x{80CE}\x{80D6}\x{80D9}\x{80DA}\x{80DB}\x{80DD}\x{80DE}'
. '\x{80E1}\x{80E4}\x{80E5}\x{80EF}\x{80F1}\x{80F4}\x{80F8}\x{80FC}\x{80FD}'
. '\x{8102}\x{8105}\x{8106}\x{8107}\x{8108}\x{8109}\x{810A}\x{811A}\x{811B}'
. '\x{8123}\x{8129}\x{812F}\x{8131}\x{8133}\x{8139}\x{813E}\x{8146}\x{814B}'
. '\x{814E}\x{8150}\x{8151}\x{8153}\x{8154}\x{8155}\x{815F}\x{8165}\x{8166}'
. '\x{816B}\x{816E}\x{8170}\x{8171}\x{8174}\x{8178}\x{8179}\x{817A}\x{817F}'
. '\x{8180}\x{8182}\x{8183}\x{8188}\x{818A}\x{818F}\x{8193}\x{8195}\x{819A}'
. '\x{819C}\x{819D}\x{81A0}\x{81A3}\x{81A4}\x{81A8}\x{81A9}\x{81B0}\x{81B3}'
. '\x{81B5}\x{81B8}\x{81BA}\x{81BD}\x{81BE}\x{81BF}\x{81C0}\x{81C2}\x{81C6}'
. '\x{81C8}\x{81C9}\x{81CD}\x{81D1}\x{81D3}\x{81D8}\x{81D9}\x{81DA}\x{81DF}'
. '\x{81E0}\x{81E3}\x{81E5}\x{81E7}\x{81E8}\x{81EA}\x{81ED}\x{81F3}\x{81F4}'
. '\x{81FA}\x{81FB}\x{81FC}\x{81FE}\x{8201}\x{8202}\x{8205}\x{8207}\x{8208}'
. '\x{8209}\x{820A}\x{820C}\x{820D}\x{820E}\x{8210}\x{8212}\x{8216}\x{8217}'
. '\x{8218}\x{821B}\x{821C}\x{821E}\x{821F}\x{8229}\x{822A}\x{822B}\x{822C}'
. '\x{822E}\x{8233}\x{8235}\x{8236}\x{8237}\x{8238}\x{8239}\x{8240}\x{8247}'
. '\x{8258}\x{8259}\x{825A}\x{825D}\x{825F}\x{8262}\x{8264}\x{8266}\x{8268}'
. '\x{826A}\x{826B}\x{826E}\x{826F}\x{8271}\x{8272}\x{8276}\x{8277}\x{8278}'
. '\x{827E}\x{828B}\x{828D}\x{8292}\x{8299}\x{829D}\x{829F}\x{82A5}\x{82A6}'
. '\x{82AB}\x{82AC}\x{82AD}\x{82AF}\x{82B1}\x{82B3}\x{82B8}\x{82B9}\x{82BB}'
. '\x{82BD}\x{82C5}\x{82D1}\x{82D2}\x{82D3}\x{82D4}\x{82D7}\x{82D9}\x{82DB}'
. '\x{82DC}\x{82DE}\x{82DF}\x{82E1}\x{82E3}\x{82E5}\x{82E6}\x{82E7}\x{82EB}'
. '\x{82F1}\x{82F3}\x{82F4}\x{82F9}\x{82FA}\x{82FB}\x{8302}\x{8303}\x{8304}'
. '\x{8305}\x{8306}\x{8309}\x{830E}\x{8316}\x{8317}\x{8318}\x{831C}\x{8323}'
. '\x{8328}\x{832B}\x{832F}\x{8331}\x{8332}\x{8334}\x{8335}\x{8336}\x{8338}'
. '\x{8339}\x{8340}\x{8345}\x{8349}\x{834A}\x{834F}\x{8350}\x{8352}\x{8358}'
. '\x{8373}\x{8375}\x{8377}\x{837B}\x{837C}\x{8385}\x{8387}\x{8389}\x{838A}'
. '\x{838E}\x{8393}\x{8396}\x{839A}\x{839E}\x{839F}\x{83A0}\x{83A2}\x{83A8}'
. '\x{83AA}\x{83AB}\x{83B1}\x{83B5}\x{83BD}\x{83C1}\x{83C5}\x{83CA}\x{83CC}'
. '\x{83CE}\x{83D3}\x{83D6}\x{83D8}\x{83DC}\x{83DF}\x{83E0}\x{83E9}\x{83EB}'
. '\x{83EF}\x{83F0}\x{83F1}\x{83F2}\x{83F4}\x{83F7}\x{83FB}\x{83FD}\x{8403}'
. '\x{8404}\x{8407}\x{840B}\x{840C}\x{840D}\x{840E}\x{8413}\x{8420}\x{8422}'
. '\x{8429}\x{842A}\x{842C}\x{8431}\x{8435}\x{8438}\x{843C}\x{843D}\x{8446}'
. '\x{8449}\x{844E}\x{8457}\x{845B}\x{8461}\x{8462}\x{8463}\x{8466}\x{8469}'
. '\x{846B}\x{846C}\x{846D}\x{846E}\x{846F}\x{8471}\x{8475}\x{8477}\x{8479}'
. '\x{847A}\x{8482}\x{8484}\x{848B}\x{8490}\x{8494}\x{8499}\x{849C}\x{849F}'
. '\x{84A1}\x{84AD}\x{84B2}\x{84B8}\x{84B9}\x{84BB}\x{84BC}\x{84BF}\x{84C1}'
. '\x{84C4}\x{84C6}\x{84C9}\x{84CA}\x{84CB}\x{84CD}\x{84D0}\x{84D1}\x{84D6}'
. '\x{84D9}\x{84DA}\x{84EC}\x{84EE}\x{84F4}\x{84FC}\x{84FF}\x{8500}\x{8506}'
. '\x{8511}\x{8513}\x{8514}\x{8515}\x{8517}\x{8518}\x{851A}\x{851F}\x{8521}'
. '\x{8526}\x{852C}\x{852D}\x{8535}\x{853D}\x{8540}\x{8541}\x{8543}\x{8548}'
. '\x{8549}\x{854A}\x{854B}\x{854E}\x{8555}\x{8557}\x{8558}\x{855A}\x{8563}'
. '\x{8568}\x{8569}\x{856A}\x{856D}\x{8577}\x{857E}\x{8580}\x{8584}\x{8587}'
. '\x{8588}\x{858A}\x{8590}\x{8591}\x{8594}\x{8597}\x{8599}\x{859B}\x{859C}'
. '\x{85A4}\x{85A6}\x{85A8}\x{85A9}\x{85AA}\x{85AB}\x{85AC}\x{85AE}\x{85AF}'
. '\x{85B9}\x{85BA}\x{85C1}\x{85C9}\x{85CD}\x{85CF}\x{85D0}\x{85D5}\x{85DC}'
. '\x{85DD}\x{85E4}\x{85E5}\x{85E9}\x{85EA}\x{85F7}\x{85F9}\x{85FA}\x{85FB}'
. '\x{85FE}\x{8602}\x{8606}\x{8607}\x{860A}\x{860B}\x{8613}\x{8616}\x{8617}'
. '\x{861A}\x{8622}\x{862D}\x{862F}\x{8630}\x{863F}\x{864D}\x{864E}\x{8650}'
. '\x{8654}\x{8655}\x{865A}\x{865C}\x{865E}\x{865F}\x{8667}\x{866B}\x{8671}'
. '\x{8679}\x{867B}\x{868A}\x{868B}\x{868C}\x{8693}\x{8695}\x{86A3}\x{86A4}'
. '\x{86A9}\x{86AA}\x{86AB}\x{86AF}\x{86B0}\x{86B6}\x{86C4}\x{86C6}\x{86C7}'
. '\x{86C9}\x{86CB}\x{86CD}\x{86CE}\x{86D4}\x{86D9}\x{86DB}\x{86DE}\x{86DF}'
. '\x{86E4}\x{86E9}\x{86EC}\x{86ED}\x{86EE}\x{86EF}\x{86F8}\x{86F9}\x{86FB}'
. '\x{86FE}\x{8700}\x{8702}\x{8703}\x{8706}\x{8708}\x{8709}\x{870A}\x{870D}'
. '\x{8711}\x{8712}\x{8718}\x{871A}\x{871C}\x{8725}\x{8729}\x{8734}\x{8737}'
. '\x{873B}\x{873F}\x{8749}\x{874B}\x{874C}\x{874E}\x{8753}\x{8755}\x{8757}'
. '\x{8759}\x{875F}\x{8760}\x{8763}\x{8766}\x{8768}\x{876A}\x{876E}\x{8774}'
. '\x{8776}\x{8778}\x{877F}\x{8782}\x{878D}\x{879F}\x{87A2}\x{87AB}\x{87AF}'
. '\x{87B3}\x{87BA}\x{87BB}\x{87BD}\x{87C0}\x{87C4}\x{87C6}\x{87C7}\x{87CB}'
. '\x{87D0}\x{87D2}\x{87E0}\x{87EF}\x{87F2}\x{87F6}\x{87F7}\x{87F9}\x{87FB}'
. '\x{87FE}\x{8805}\x{880D}\x{880E}\x{880F}\x{8811}\x{8815}\x{8816}\x{8821}'
. '\x{8822}\x{8823}\x{8827}\x{8831}\x{8836}\x{8839}\x{883B}\x{8840}\x{8842}'
. '\x{8844}\x{8846}\x{884C}\x{884D}\x{8852}\x{8853}\x{8857}\x{8859}\x{885B}'
. '\x{885D}\x{885E}\x{8861}\x{8862}\x{8863}\x{8868}\x{886B}\x{8870}\x{8872}'
. '\x{8875}\x{8877}\x{887D}\x{887E}\x{887F}\x{8881}\x{8882}\x{8888}\x{888B}'
. '\x{888D}\x{8892}\x{8896}\x{8897}\x{8899}\x{889E}\x{88A2}\x{88A4}\x{88AB}'
. '\x{88AE}\x{88B0}\x{88B1}\x{88B4}\x{88B5}\x{88B7}\x{88BF}\x{88C1}\x{88C2}'
. '\x{88C3}\x{88C4}\x{88C5}\x{88CF}\x{88D4}\x{88D5}\x{88D8}\x{88D9}\x{88DC}'
. '\x{88DD}\x{88DF}\x{88E1}\x{88E8}\x{88F2}\x{88F3}\x{88F4}\x{88F8}\x{88F9}'
. '\x{88FC}\x{88FD}\x{88FE}\x{8902}\x{8904}\x{8907}\x{890A}\x{890C}\x{8910}'
. '\x{8912}\x{8913}\x{891D}\x{891E}\x{8925}\x{892A}\x{892B}\x{8936}\x{8938}'
. '\x{893B}\x{8941}\x{8943}\x{8944}\x{894C}\x{894D}\x{8956}\x{895E}\x{895F}'
. '\x{8960}\x{8964}\x{8966}\x{896A}\x{896D}\x{896F}\x{8972}\x{8974}\x{8977}'
. '\x{897E}\x{897F}\x{8981}\x{8983}\x{8986}\x{8987}\x{8988}\x{898A}\x{898B}'
. '\x{898F}\x{8993}\x{8996}\x{8997}\x{8998}\x{899A}\x{89A1}\x{89A6}\x{89A7}'
. '\x{89A9}\x{89AA}\x{89AC}\x{89AF}\x{89B2}\x{89B3}\x{89BA}\x{89BD}\x{89BF}'
. '\x{89C0}\x{89D2}\x{89DA}\x{89DC}\x{89DD}\x{89E3}\x{89E6}\x{89E7}\x{89F4}'
. '\x{89F8}\x{8A00}\x{8A02}\x{8A03}\x{8A08}\x{8A0A}\x{8A0C}\x{8A0E}\x{8A10}'
. '\x{8A13}\x{8A16}\x{8A17}\x{8A18}\x{8A1B}\x{8A1D}\x{8A1F}\x{8A23}\x{8A25}'
. '\x{8A2A}\x{8A2D}\x{8A31}\x{8A33}\x{8A34}\x{8A36}\x{8A3A}\x{8A3B}\x{8A3C}'
. '\x{8A41}\x{8A46}\x{8A48}\x{8A50}\x{8A51}\x{8A52}\x{8A54}\x{8A55}\x{8A5B}'
. '\x{8A5E}\x{8A60}\x{8A62}\x{8A63}\x{8A66}\x{8A69}\x{8A6B}\x{8A6C}\x{8A6D}'
. '\x{8A6E}\x{8A70}\x{8A71}\x{8A72}\x{8A73}\x{8A7C}\x{8A82}\x{8A84}\x{8A85}'
. '\x{8A87}\x{8A89}\x{8A8C}\x{8A8D}\x{8A91}\x{8A93}\x{8A95}\x{8A98}\x{8A9A}'
. '\x{8A9E}\x{8AA0}\x{8AA1}\x{8AA3}\x{8AA4}\x{8AA5}\x{8AA6}\x{8AA8}\x{8AAC}'
. '\x{8AAD}\x{8AB0}\x{8AB2}\x{8AB9}\x{8ABC}\x{8ABF}\x{8AC2}\x{8AC4}\x{8AC7}'
. '\x{8ACB}\x{8ACC}\x{8ACD}\x{8ACF}\x{8AD2}\x{8AD6}\x{8ADA}\x{8ADB}\x{8ADC}'
. '\x{8ADE}\x{8AE0}\x{8AE1}\x{8AE2}\x{8AE4}\x{8AE6}\x{8AE7}\x{8AEB}\x{8AED}'
. '\x{8AEE}\x{8AF1}\x{8AF3}\x{8AF7}\x{8AF8}\x{8AFA}\x{8AFE}\x{8B00}\x{8B01}'
. '\x{8B02}\x{8B04}\x{8B07}\x{8B0C}\x{8B0E}\x{8B10}\x{8B14}\x{8B16}\x{8B17}'
. '\x{8B19}\x{8B1A}\x{8B1B}\x{8B1D}\x{8B20}\x{8B21}\x{8B26}\x{8B28}\x{8B2B}'
. '\x{8B2C}\x{8B33}\x{8B39}\x{8B3E}\x{8B41}\x{8B49}\x{8B4C}\x{8B4E}\x{8B4F}'
. '\x{8B56}\x{8B58}\x{8B5A}\x{8B5B}\x{8B5C}\x{8B5F}\x{8B66}\x{8B6B}\x{8B6C}'
. '\x{8B6F}\x{8B70}\x{8B71}\x{8B72}\x{8B74}\x{8B77}\x{8B7D}\x{8B80}\x{8B83}'
. '\x{8B8A}\x{8B8C}\x{8B8E}\x{8B90}\x{8B92}\x{8B93}\x{8B96}\x{8B99}\x{8B9A}'
. '\x{8C37}\x{8C3A}\x{8C3F}\x{8C41}\x{8C46}\x{8C48}\x{8C4A}\x{8C4C}\x{8C4E}'
. '\x{8C50}\x{8C55}\x{8C5A}\x{8C61}\x{8C62}\x{8C6A}\x{8C6B}\x{8C6C}\x{8C78}'
. '\x{8C79}\x{8C7A}\x{8C7C}\x{8C82}\x{8C85}\x{8C89}\x{8C8A}\x{8C8C}\x{8C8D}'
. '\x{8C8E}\x{8C94}\x{8C98}\x{8C9D}\x{8C9E}\x{8CA0}\x{8CA1}\x{8CA2}\x{8CA7}'
. '\x{8CA8}\x{8CA9}\x{8CAA}\x{8CAB}\x{8CAC}\x{8CAD}\x{8CAE}\x{8CAF}\x{8CB0}'
. '\x{8CB2}\x{8CB3}\x{8CB4}\x{8CB6}\x{8CB7}\x{8CB8}\x{8CBB}\x{8CBC}\x{8CBD}'
. '\x{8CBF}\x{8CC0}\x{8CC1}\x{8CC2}\x{8CC3}\x{8CC4}\x{8CC7}\x{8CC8}\x{8CCA}'
. '\x{8CCD}\x{8CCE}\x{8CD1}\x{8CD3}\x{8CDA}\x{8CDB}\x{8CDC}\x{8CDE}\x{8CE0}'
. '\x{8CE2}\x{8CE3}\x{8CE4}\x{8CE6}\x{8CEA}\x{8CED}\x{8CFA}\x{8CFB}\x{8CFC}'
. '\x{8CFD}\x{8D04}\x{8D05}\x{8D07}\x{8D08}\x{8D0A}\x{8D0B}\x{8D0D}\x{8D0F}'
. '\x{8D10}\x{8D13}\x{8D14}\x{8D16}\x{8D64}\x{8D66}\x{8D67}\x{8D6B}\x{8D6D}'
. '\x{8D70}\x{8D71}\x{8D73}\x{8D74}\x{8D77}\x{8D81}\x{8D85}\x{8D8A}\x{8D99}'
. '\x{8DA3}\x{8DA8}\x{8DB3}\x{8DBA}\x{8DBE}\x{8DC2}\x{8DCB}\x{8DCC}\x{8DCF}'
. '\x{8DD6}\x{8DDA}\x{8DDB}\x{8DDD}\x{8DDF}\x{8DE1}\x{8DE3}\x{8DE8}\x{8DEA}'
. '\x{8DEB}\x{8DEF}\x{8DF3}\x{8DF5}\x{8DFC}\x{8DFF}\x{8E08}\x{8E09}\x{8E0A}'
. '\x{8E0F}\x{8E10}\x{8E1D}\x{8E1E}\x{8E1F}\x{8E2A}\x{8E30}\x{8E34}\x{8E35}'
. '\x{8E42}\x{8E44}\x{8E47}\x{8E48}\x{8E49}\x{8E4A}\x{8E4C}\x{8E50}\x{8E55}'
. '\x{8E59}\x{8E5F}\x{8E60}\x{8E63}\x{8E64}\x{8E72}\x{8E74}\x{8E76}\x{8E7C}'
. '\x{8E81}\x{8E84}\x{8E85}\x{8E87}\x{8E8A}\x{8E8B}\x{8E8D}\x{8E91}\x{8E93}'
. '\x{8E94}\x{8E99}\x{8EA1}\x{8EAA}\x{8EAB}\x{8EAC}\x{8EAF}\x{8EB0}\x{8EB1}'
. '\x{8EBE}\x{8EC5}\x{8EC6}\x{8EC8}\x{8ECA}\x{8ECB}\x{8ECC}\x{8ECD}\x{8ED2}'
. '\x{8EDB}\x{8EDF}\x{8EE2}\x{8EE3}\x{8EEB}\x{8EF8}\x{8EFB}\x{8EFC}\x{8EFD}'
. '\x{8EFE}\x{8F03}\x{8F05}\x{8F09}\x{8F0A}\x{8F0C}\x{8F12}\x{8F13}\x{8F14}'
. '\x{8F15}\x{8F19}\x{8F1B}\x{8F1C}\x{8F1D}\x{8F1F}\x{8F26}\x{8F29}\x{8F2A}'
. '\x{8F2F}\x{8F33}\x{8F38}\x{8F39}\x{8F3B}\x{8F3E}\x{8F3F}\x{8F42}\x{8F44}'
. '\x{8F45}\x{8F46}\x{8F49}\x{8F4C}\x{8F4D}\x{8F4E}\x{8F57}\x{8F5C}\x{8F5F}'
. '\x{8F61}\x{8F62}\x{8F63}\x{8F64}\x{8F9B}\x{8F9C}\x{8F9E}\x{8F9F}\x{8FA3}'
. '\x{8FA7}\x{8FA8}\x{8FAD}\x{8FAE}\x{8FAF}\x{8FB0}\x{8FB1}\x{8FB2}\x{8FB7}'
. '\x{8FBA}\x{8FBB}\x{8FBC}\x{8FBF}\x{8FC2}\x{8FC4}\x{8FC5}\x{8FCE}\x{8FD1}'
. '\x{8FD4}\x{8FDA}\x{8FE2}\x{8FE5}\x{8FE6}\x{8FE9}\x{8FEA}\x{8FEB}\x{8FED}'
. '\x{8FEF}\x{8FF0}\x{8FF4}\x{8FF7}\x{8FF8}\x{8FF9}\x{8FFA}\x{8FFD}\x{9000}'
. '\x{9001}\x{9003}\x{9005}\x{9006}\x{900B}\x{900D}\x{900E}\x{900F}\x{9010}'
. '\x{9011}\x{9013}\x{9014}\x{9015}\x{9016}\x{9017}\x{9019}\x{901A}\x{901D}'
. '\x{901E}\x{901F}\x{9020}\x{9021}\x{9022}\x{9023}\x{9027}\x{902E}\x{9031}'
. '\x{9032}\x{9035}\x{9036}\x{9038}\x{9039}\x{903C}\x{903E}\x{9041}\x{9042}'
. '\x{9045}\x{9047}\x{9049}\x{904A}\x{904B}\x{904D}\x{904E}\x{904F}\x{9050}'
. '\x{9051}\x{9052}\x{9053}\x{9054}\x{9055}\x{9056}\x{9058}\x{9059}\x{905C}'
. '\x{905E}\x{9060}\x{9061}\x{9063}\x{9065}\x{9068}\x{9069}\x{906D}\x{906E}'
. '\x{906F}\x{9072}\x{9075}\x{9076}\x{9077}\x{9078}\x{907A}\x{907C}\x{907D}'
. '\x{907F}\x{9080}\x{9081}\x{9082}\x{9083}\x{9084}\x{9087}\x{9089}\x{908A}'
. '\x{908F}\x{9091}\x{90A3}\x{90A6}\x{90A8}\x{90AA}\x{90AF}\x{90B1}\x{90B5}'
. '\x{90B8}\x{90C1}\x{90CA}\x{90CE}\x{90DB}\x{90E1}\x{90E2}\x{90E4}\x{90E8}'
. '\x{90ED}\x{90F5}\x{90F7}\x{90FD}\x{9102}\x{9112}\x{9119}\x{912D}\x{9130}'
. '\x{9132}\x{9149}\x{914A}\x{914B}\x{914C}\x{914D}\x{914E}\x{9152}\x{9154}'
. '\x{9156}\x{9158}\x{9162}\x{9163}\x{9165}\x{9169}\x{916A}\x{916C}\x{9172}'
. '\x{9173}\x{9175}\x{9177}\x{9178}\x{9182}\x{9187}\x{9189}\x{918B}\x{918D}'
. '\x{9190}\x{9192}\x{9197}\x{919C}\x{91A2}\x{91A4}\x{91AA}\x{91AB}\x{91AF}'
. '\x{91B4}\x{91B5}\x{91B8}\x{91BA}\x{91C0}\x{91C1}\x{91C6}\x{91C7}\x{91C8}'
. '\x{91C9}\x{91CB}\x{91CC}\x{91CD}\x{91CE}\x{91CF}\x{91D0}\x{91D1}\x{91D6}'
. '\x{91D8}\x{91DB}\x{91DC}\x{91DD}\x{91DF}\x{91E1}\x{91E3}\x{91E6}\x{91E7}'
. '\x{91F5}\x{91F6}\x{91FC}\x{91FF}\x{920D}\x{920E}\x{9211}\x{9214}\x{9215}'
. '\x{921E}\x{9229}\x{922C}\x{9234}\x{9237}\x{923F}\x{9244}\x{9245}\x{9248}'
. '\x{9249}\x{924B}\x{9250}\x{9257}\x{925A}\x{925B}\x{925E}\x{9262}\x{9264}'
. '\x{9266}\x{9271}\x{927E}\x{9280}\x{9283}\x{9285}\x{9291}\x{9293}\x{9295}'
. '\x{9296}\x{9298}\x{929A}\x{929B}\x{929C}\x{92AD}\x{92B7}\x{92B9}\x{92CF}'
. '\x{92D2}\x{92E4}\x{92E9}\x{92EA}\x{92ED}\x{92F2}\x{92F3}\x{92F8}\x{92FA}'
. '\x{92FC}\x{9306}\x{930F}\x{9310}\x{9318}\x{9319}\x{931A}\x{9320}\x{9322}'
. '\x{9323}\x{9326}\x{9328}\x{932B}\x{932C}\x{932E}\x{932F}\x{9332}\x{9335}'
. '\x{933A}\x{933B}\x{9344}\x{934B}\x{934D}\x{9354}\x{9356}\x{935B}\x{935C}'
. '\x{9360}\x{936C}\x{936E}\x{9375}\x{937C}\x{937E}\x{938C}\x{9394}\x{9396}'
. '\x{9397}\x{939A}\x{93A7}\x{93AC}\x{93AD}\x{93AE}\x{93B0}\x{93B9}\x{93C3}'
. '\x{93C8}\x{93D0}\x{93D1}\x{93D6}\x{93D7}\x{93D8}\x{93DD}\x{93E1}\x{93E4}'
. '\x{93E5}\x{93E8}\x{9403}\x{9407}\x{9410}\x{9413}\x{9414}\x{9418}\x{9419}'
. '\x{941A}\x{9421}\x{942B}\x{9435}\x{9436}\x{9438}\x{943A}\x{9441}\x{9444}'
. '\x{9451}\x{9452}\x{9453}\x{945A}\x{945B}\x{945E}\x{9460}\x{9462}\x{946A}'
. '\x{9470}\x{9475}\x{9477}\x{947C}\x{947D}\x{947E}\x{947F}\x{9481}\x{9577}'
. '\x{9580}\x{9582}\x{9583}\x{9587}\x{9589}\x{958A}\x{958B}\x{958F}\x{9591}'
. '\x{9593}\x{9594}\x{9596}\x{9598}\x{9599}\x{95A0}\x{95A2}\x{95A3}\x{95A4}'
. '\x{95A5}\x{95A7}\x{95A8}\x{95AD}\x{95B2}\x{95B9}\x{95BB}\x{95BC}\x{95BE}'
. '\x{95C3}\x{95C7}\x{95CA}\x{95CC}\x{95CD}\x{95D4}\x{95D5}\x{95D6}\x{95D8}'
. '\x{95DC}\x{95E1}\x{95E2}\x{95E5}\x{961C}\x{9621}\x{9628}\x{962A}\x{962E}'
. '\x{962F}\x{9632}\x{963B}\x{963F}\x{9640}\x{9642}\x{9644}\x{964B}\x{964C}'
. '\x{964D}\x{964F}\x{9650}\x{965B}\x{965C}\x{965D}\x{965E}\x{965F}\x{9662}'
. '\x{9663}\x{9664}\x{9665}\x{9666}\x{966A}\x{966C}\x{9670}\x{9672}\x{9673}'
. '\x{9675}\x{9676}\x{9677}\x{9678}\x{967A}\x{967D}\x{9685}\x{9686}\x{9688}'
. '\x{968A}\x{968B}\x{968D}\x{968E}\x{968F}\x{9694}\x{9695}\x{9697}\x{9698}'
. '\x{9699}\x{969B}\x{969C}\x{96A0}\x{96A3}\x{96A7}\x{96A8}\x{96AA}\x{96B0}'
. '\x{96B1}\x{96B2}\x{96B4}\x{96B6}\x{96B7}\x{96B8}\x{96B9}\x{96BB}\x{96BC}'
. '\x{96C0}\x{96C1}\x{96C4}\x{96C5}\x{96C6}\x{96C7}\x{96C9}\x{96CB}\x{96CC}'
. '\x{96CD}\x{96CE}\x{96D1}\x{96D5}\x{96D6}\x{96D9}\x{96DB}\x{96DC}\x{96E2}'
. '\x{96E3}\x{96E8}\x{96EA}\x{96EB}\x{96F0}\x{96F2}\x{96F6}\x{96F7}\x{96F9}'
. '\x{96FB}\x{9700}\x{9704}\x{9706}\x{9707}\x{9708}\x{970A}\x{970D}\x{970E}'
. '\x{970F}\x{9711}\x{9713}\x{9716}\x{9719}\x{971C}\x{971E}\x{9724}\x{9727}'
. '\x{972A}\x{9730}\x{9732}\x{9738}\x{9739}\x{973D}\x{973E}\x{9742}\x{9744}'
. '\x{9746}\x{9748}\x{9749}\x{9752}\x{9756}\x{9759}\x{975C}\x{975E}\x{9760}'
. '\x{9761}\x{9762}\x{9764}\x{9766}\x{9768}\x{9769}\x{976B}\x{976D}\x{9771}'
. '\x{9774}\x{9779}\x{977A}\x{977C}\x{9781}\x{9784}\x{9785}\x{9786}\x{978B}'
. '\x{978D}\x{978F}\x{9790}\x{9798}\x{979C}\x{97A0}\x{97A3}\x{97A6}\x{97A8}'
. '\x{97AB}\x{97AD}\x{97B3}\x{97B4}\x{97C3}\x{97C6}\x{97C8}\x{97CB}\x{97D3}'
. '\x{97DC}\x{97ED}\x{97EE}\x{97F2}\x{97F3}\x{97F5}\x{97F6}\x{97FB}\x{97FF}'
. '\x{9801}\x{9802}\x{9803}\x{9805}\x{9806}\x{9808}\x{980C}\x{980F}\x{9810}'
. '\x{9811}\x{9812}\x{9813}\x{9817}\x{9818}\x{981A}\x{9821}\x{9824}\x{982C}'
. '\x{982D}\x{9834}\x{9837}\x{9838}\x{983B}\x{983C}\x{983D}\x{9846}\x{984B}'
. '\x{984C}\x{984D}\x{984E}\x{984F}\x{9854}\x{9855}\x{9858}\x{985B}\x{985E}'
. '\x{9867}\x{986B}\x{986F}\x{9870}\x{9871}\x{9873}\x{9874}\x{98A8}\x{98AA}'
. '\x{98AF}\x{98B1}\x{98B6}\x{98C3}\x{98C4}\x{98C6}\x{98DB}\x{98DC}\x{98DF}'
. '\x{98E2}\x{98E9}\x{98EB}\x{98ED}\x{98EE}\x{98EF}\x{98F2}\x{98F4}\x{98FC}'
. '\x{98FD}\x{98FE}\x{9903}\x{9905}\x{9909}\x{990A}\x{990C}\x{9910}\x{9912}'
. '\x{9913}\x{9914}\x{9918}\x{991D}\x{991E}\x{9920}\x{9921}\x{9924}\x{9928}'
. '\x{992C}\x{992E}\x{993D}\x{993E}\x{9942}\x{9945}\x{9949}\x{994B}\x{994C}'
. '\x{9950}\x{9951}\x{9952}\x{9955}\x{9957}\x{9996}\x{9997}\x{9998}\x{9999}'
. '\x{99A5}\x{99A8}\x{99AC}\x{99AD}\x{99AE}\x{99B3}\x{99B4}\x{99BC}\x{99C1}'
. '\x{99C4}\x{99C5}\x{99C6}\x{99C8}\x{99D0}\x{99D1}\x{99D2}\x{99D5}\x{99D8}'
. '\x{99DB}\x{99DD}\x{99DF}\x{99E2}\x{99ED}\x{99EE}\x{99F1}\x{99F2}\x{99F8}'
. '\x{99FB}\x{99FF}\x{9A01}\x{9A05}\x{9A0E}\x{9A0F}\x{9A12}\x{9A13}\x{9A19}'
. '\x{9A28}\x{9A2B}\x{9A30}\x{9A37}\x{9A3E}\x{9A40}\x{9A42}\x{9A43}\x{9A45}'
. '\x{9A4D}\x{9A55}\x{9A57}\x{9A5A}\x{9A5B}\x{9A5F}\x{9A62}\x{9A64}\x{9A65}'
. '\x{9A69}\x{9A6A}\x{9A6B}\x{9AA8}\x{9AAD}\x{9AB0}\x{9AB8}\x{9ABC}\x{9AC0}'
. '\x{9AC4}\x{9ACF}\x{9AD1}\x{9AD3}\x{9AD4}\x{9AD8}\x{9ADE}\x{9ADF}\x{9AE2}'
. '\x{9AE3}\x{9AE6}\x{9AEA}\x{9AEB}\x{9AED}\x{9AEE}\x{9AEF}\x{9AF1}\x{9AF4}'
. '\x{9AF7}\x{9AFB}\x{9B06}\x{9B18}\x{9B1A}\x{9B1F}\x{9B22}\x{9B23}\x{9B25}'
. '\x{9B27}\x{9B28}\x{9B29}\x{9B2A}\x{9B2E}\x{9B2F}\x{9B31}\x{9B32}\x{9B3B}'
. '\x{9B3C}\x{9B41}\x{9B42}\x{9B43}\x{9B44}\x{9B45}\x{9B4D}\x{9B4E}\x{9B4F}'
. '\x{9B51}\x{9B54}\x{9B58}\x{9B5A}\x{9B6F}\x{9B74}\x{9B83}\x{9B8E}\x{9B91}'
. '\x{9B92}\x{9B93}\x{9B96}\x{9B97}\x{9B9F}\x{9BA0}\x{9BA8}\x{9BAA}\x{9BAB}'
. '\x{9BAD}\x{9BAE}\x{9BB4}\x{9BB9}\x{9BC0}\x{9BC6}\x{9BC9}\x{9BCA}\x{9BCF}'
. '\x{9BD1}\x{9BD2}\x{9BD4}\x{9BD6}\x{9BDB}\x{9BE1}\x{9BE2}\x{9BE3}\x{9BE4}'
. '\x{9BE8}\x{9BF0}\x{9BF1}\x{9BF2}\x{9BF5}\x{9C04}\x{9C06}\x{9C08}\x{9C09}'
. '\x{9C0A}\x{9C0C}\x{9C0D}\x{9C10}\x{9C12}\x{9C13}\x{9C14}\x{9C15}\x{9C1B}'
. '\x{9C21}\x{9C24}\x{9C25}\x{9C2D}\x{9C2E}\x{9C2F}\x{9C30}\x{9C32}\x{9C39}'
. '\x{9C3A}\x{9C3B}\x{9C3E}\x{9C46}\x{9C47}\x{9C48}\x{9C52}\x{9C57}\x{9C5A}'
. '\x{9C60}\x{9C67}\x{9C76}\x{9C78}\x{9CE5}\x{9CE7}\x{9CE9}\x{9CEB}\x{9CEC}'
. '\x{9CF0}\x{9CF3}\x{9CF4}\x{9CF6}\x{9D03}\x{9D06}\x{9D07}\x{9D08}\x{9D09}'
. '\x{9D0E}\x{9D12}\x{9D15}\x{9D1B}\x{9D1F}\x{9D23}\x{9D26}\x{9D28}\x{9D2A}'
. '\x{9D2B}\x{9D2C}\x{9D3B}\x{9D3E}\x{9D3F}\x{9D41}\x{9D44}\x{9D46}\x{9D48}'
. '\x{9D50}\x{9D51}\x{9D59}\x{9D5C}\x{9D5D}\x{9D5E}\x{9D60}\x{9D61}\x{9D64}'
. '\x{9D6C}\x{9D6F}\x{9D72}\x{9D7A}\x{9D87}\x{9D89}\x{9D8F}\x{9D9A}\x{9DA4}'
. '\x{9DA9}\x{9DAB}\x{9DAF}\x{9DB2}\x{9DB4}\x{9DB8}\x{9DBA}\x{9DBB}\x{9DC1}'
. '\x{9DC2}\x{9DC4}\x{9DC6}\x{9DCF}\x{9DD3}\x{9DD9}\x{9DE6}\x{9DED}\x{9DEF}'
. '\x{9DF2}\x{9DF8}\x{9DF9}\x{9DFA}\x{9DFD}\x{9E1A}\x{9E1B}\x{9E1E}\x{9E75}'
. '\x{9E78}\x{9E79}\x{9E7D}\x{9E7F}\x{9E81}\x{9E88}\x{9E8B}\x{9E8C}\x{9E91}'
. '\x{9E92}\x{9E93}\x{9E95}\x{9E97}\x{9E9D}\x{9E9F}\x{9EA5}\x{9EA6}\x{9EA9}'
. '\x{9EAA}\x{9EAD}\x{9EB8}\x{9EB9}\x{9EBA}\x{9EBB}\x{9EBC}\x{9EBE}\x{9EBF}'
. '\x{9EC4}\x{9ECC}\x{9ECD}\x{9ECE}\x{9ECF}\x{9ED0}\x{9ED2}\x{9ED4}\x{9ED8}'
. '\x{9ED9}\x{9EDB}\x{9EDC}\x{9EDD}\x{9EDE}\x{9EE0}\x{9EE5}\x{9EE8}\x{9EEF}'
. '\x{9EF4}\x{9EF6}\x{9EF7}\x{9EF9}\x{9EFB}\x{9EFC}\x{9EFD}\x{9F07}\x{9F08}'
. '\x{9F0E}\x{9F13}\x{9F15}\x{9F20}\x{9F21}\x{9F2C}\x{9F3B}\x{9F3E}\x{9F4A}'
. '\x{9F4B}\x{9F4E}\x{9F4F}\x{9F52}\x{9F54}\x{9F5F}\x{9F60}\x{9F61}\x{9F62}'
. '\x{9F63}\x{9F66}\x{9F67}\x{9F6A}\x{9F6C}\x{9F72}\x{9F76}\x{9F77}\x{9F8D}'
. '\x{9F95}\x{9F9C}\x{9F9D}\x{9FA0}]{1,15}$/iu',
];

View File

@@ -1,374 +0,0 @@
<?php
namespace Laminas\Validator;
use Laminas\Stdlib\ArrayUtils;
use Traversable;
use function array_key_exists;
use function in_array;
use function intval;
use function is_string;
use function preg_match;
use function str_replace;
use function strlen;
use function strtoupper;
use function substr;
/**
* Validates IBAN Numbers (International Bank Account Numbers)
*
* @final
*/
class Iban extends AbstractValidator
{
public const NOTSUPPORTED = 'ibanNotSupported';
public const SEPANOTSUPPORTED = 'ibanSepaNotSupported';
public const FALSEFORMAT = 'ibanFalseFormat';
public const CHECKFAILED = 'ibanCheckFailed';
/**
* Validation failure message template definitions
*
* @var array<string, string>
*/
protected $messageTemplates = [
self::NOTSUPPORTED => 'Unknown country within the IBAN',
self::SEPANOTSUPPORTED => 'Countries outside the Single Euro Payments Area (SEPA) are not supported',
self::FALSEFORMAT => 'The input has a false IBAN format',
self::CHECKFAILED => 'The input has failed the IBAN check',
];
/**
* Optional country code by ISO 3166-1
*
* @var string|null
*/
protected $countryCode;
/**
* Optionally allow IBAN codes from non-SEPA countries. Defaults to true
*
* @var bool
*/
protected $allowNonSepa = true;
/**
* The SEPA country codes
*
* @var string[] ISO 3166-1 codes
*/
protected static $sepaCountries = [
'AT',
'BE',
'BG',
'CY',
'CZ',
'DK',
'FO',
'GL',
'EE',
'FI',
'FR',
'DE',
'GI',
'GR',
'HU',
'IS',
'IE',
'IT',
'LV',
'LI',
'LT',
'LU',
'MT',
'MC',
'NL',
'NO',
'PL',
'PT',
'RO',
'SK',
'SI',
'ES',
'SE',
'CH',
'GB',
'SM',
'HR',
];
/**
* IBAN regexes by country code
*
* @var array
*/
protected static $ibanRegex = [
'AD' => 'AD[0-9]{2}[0-9]{4}[0-9]{4}[A-Z0-9]{12}',
'AE' => 'AE[0-9]{2}[0-9]{3}[0-9]{16}',
'AL' => 'AL[0-9]{2}[0-9]{8}[A-Z0-9]{16}',
'AT' => 'AT[0-9]{2}[0-9]{5}[0-9]{11}',
'AZ' => 'AZ[0-9]{2}[A-Z]{4}[A-Z0-9]{20}',
'BA' => 'BA[0-9]{2}[0-9]{3}[0-9]{3}[0-9]{8}[0-9]{2}',
'BE' => 'BE[0-9]{2}[0-9]{3}[0-9]{7}[0-9]{2}',
'BG' => 'BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}',
'BH' => 'BH[0-9]{2}[A-Z]{4}[A-Z0-9]{14}',
'BR' => 'BR[0-9]{2}[0-9]{8}[0-9]{5}[0-9]{10}[A-Z][A-Z0-9]',
'BY' => 'BY[0-9]{2}[A-Z0-9]{4}[0-9]{4}[A-Z0-9]{16}',
'CH' => 'CH[0-9]{2}[0-9]{5}[A-Z0-9]{12}',
'CR' => 'CR[0-9]{2}[0-9]{3}[0-9]{14}',
'CY' => 'CY[0-9]{2}[0-9]{3}[0-9]{5}[A-Z0-9]{16}',
'CZ' => 'CZ[0-9]{2}[0-9]{20}',
'DE' => 'DE[0-9]{2}[0-9]{8}[0-9]{10}',
'DO' => 'DO[0-9]{2}[A-Z0-9]{4}[0-9]{20}',
'DK' => 'DK[0-9]{2}[0-9]{14}',
'EE' => 'EE[0-9]{2}[0-9]{2}[0-9]{2}[0-9]{11}[0-9]{1}',
'ES' => 'ES[0-9]{2}[0-9]{4}[0-9]{4}[0-9]{1}[0-9]{1}[0-9]{10}',
'FI' => 'FI[0-9]{2}[0-9]{6}[0-9]{7}[0-9]{1}',
'FO' => 'FO[0-9]{2}[0-9]{4}[0-9]{9}[0-9]{1}',
'FR' => 'FR[0-9]{2}[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}',
'GB' => 'GB[0-9]{2}[A-Z]{4}[0-9]{6}[0-9]{8}',
'GE' => 'GE[0-9]{2}[A-Z]{2}[0-9]{16}',
'GI' => 'GI[0-9]{2}[A-Z]{4}[A-Z0-9]{15}',
'GL' => 'GL[0-9]{2}[0-9]{4}[0-9]{9}[0-9]{1}',
'GR' => 'GR[0-9]{2}[0-9]{3}[0-9]{4}[A-Z0-9]{16}',
'GT' => 'GT[0-9]{2}[A-Z0-9]{4}[A-Z0-9]{20}',
'HR' => 'HR[0-9]{2}[0-9]{7}[0-9]{10}',
'HU' => 'HU[0-9]{2}[0-9]{3}[0-9]{4}[0-9]{1}[0-9]{15}[0-9]{1}',
'IE' => 'IE[0-9]{2}[A-Z]{4}[0-9]{6}[0-9]{8}',
'IL' => 'IL[0-9]{2}[0-9]{3}[0-9]{3}[0-9]{13}',
'IS' => 'IS[0-9]{2}[0-9]{4}[0-9]{2}[0-9]{6}[0-9]{10}',
'IT' => 'IT[0-9]{2}[A-Z]{1}[0-9]{5}[0-9]{5}[A-Z0-9]{12}',
'KW' => 'KW[0-9]{2}[A-Z]{4}[0-9]{22}',
'KZ' => 'KZ[0-9]{2}[0-9]{3}[A-Z0-9]{13}',
'LB' => 'LB[0-9]{2}[0-9]{4}[A-Z0-9]{20}',
'LI' => 'LI[0-9]{2}[0-9]{5}[A-Z0-9]{12}',
'LT' => 'LT[0-9]{2}[0-9]{5}[0-9]{11}',
'LU' => 'LU[0-9]{2}[0-9]{3}[A-Z0-9]{13}',
'LV' => 'LV[0-9]{2}[A-Z]{4}[A-Z0-9]{13}',
'MC' => 'MC[0-9]{2}[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}',
'MD' => 'MD[0-9]{2}[A-Z0-9]{20}',
'ME' => 'ME[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}',
'MK' => 'MK[0-9]{2}[0-9]{3}[A-Z0-9]{10}[0-9]{2}',
'MR' => 'MR13[0-9]{5}[0-9]{5}[0-9]{11}[0-9]{2}',
'MT' => 'MT[0-9]{2}[A-Z]{4}[0-9]{5}[A-Z0-9]{18}',
'MU' => 'MU[0-9]{2}[A-Z]{4}[0-9]{2}[0-9]{2}[0-9]{12}[0-9]{3}[A-Z]{3}',
'NL' => 'NL[0-9]{2}[A-Z]{4}[0-9]{10}',
'NO' => 'NO[0-9]{2}[0-9]{4}[0-9]{6}[0-9]{1}',
'UA' => 'UA[0-9]{2}[0-9]{6}[0-9]{19}',
'PK' => 'PK[0-9]{2}[A-Z]{4}[A-Z0-9]{16}',
'PL' => 'PL[0-9]{2}[0-9]{8}[0-9]{16}',
'PS' => 'PS[0-9]{2}[A-Z]{4}[A-Z0-9]{21}',
'PT' => 'PT[0-9]{2}[0-9]{4}[0-9]{4}[0-9]{11}[0-9]{2}',
'RO' => 'RO[0-9]{2}[A-Z]{4}[A-Z0-9]{16}',
'RS' => 'RS[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}',
'SA' => 'SA[0-9]{2}[0-9]{2}[A-Z0-9]{18}',
'SE' => 'SE[0-9]{2}[0-9]{3}[0-9]{16}[0-9]{1}',
'SI' => 'SI[0-9]{2}[0-9]{5}[0-9]{8}[0-9]{2}',
'SK' => 'SK[0-9]{2}[0-9]{4}[0-9]{6}[0-9]{10}',
'SM' => 'SM[0-9]{2}[A-Z]{1}[0-9]{5}[0-9]{5}[A-Z0-9]{12}',
'TN' => 'TN59[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}',
'TR' => 'TR[0-9]{2}[0-9]{5}[A-Z0-9]{1}[A-Z0-9]{16}',
'VG' => 'VG[0-9]{2}[A-Z]{4}[0-9]{16}',
];
/**
* Sets validator options
*
* @param array|Traversable $options OPTIONAL
*/
public function __construct($options = [])
{
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
}
if (array_key_exists('country_code', $options)) {
$this->setCountryCode($options['country_code']);
}
if (array_key_exists('allow_non_sepa', $options)) {
$this->setAllowNonSepa($options['allow_non_sepa']);
}
parent::__construct($options);
}
/**
* Returns the optional country code by ISO 3166-1
*
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @return string|null
*/
public function getCountryCode()
{
return $this->countryCode;
}
/**
* Sets an optional country code by ISO 3166-1
*
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @param string|null $countryCode
* @return $this provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function setCountryCode($countryCode = null)
{
if ($countryCode !== null) {
$countryCode = (string) $countryCode;
if (! isset(static::$ibanRegex[$countryCode])) {
throw new Exception\InvalidArgumentException(
"Country code '{$countryCode}' invalid by ISO 3166-1 or not supported"
);
}
}
$this->countryCode = $countryCode;
return $this;
}
/**
* Returns the optional allow non-sepa countries setting
*
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @return bool
*/
public function allowNonSepa()
{
return $this->allowNonSepa;
}
/**
* Sets the optional allow non-sepa countries setting
*
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @param bool $allowNonSepa
* @return $this provides a fluent interface
*/
public function setAllowNonSepa($allowNonSepa)
{
$this->allowNonSepa = (bool) $allowNonSepa;
return $this;
}
/**
* Returns true if $value is a valid IBAN
*
* @param string $value
* @return bool
*/
public function isValid($value)
{
if (! is_string($value)) {
$this->error(self::FALSEFORMAT);
return false;
}
$value = str_replace(' ', '', strtoupper($value));
$this->setValue($value);
$countryCode = $this->getCountryCode();
if ($countryCode === null) {
$countryCode = substr($value, 0, 2);
}
if (! array_key_exists($countryCode, static::$ibanRegex)) {
$this->setValue($countryCode);
$this->error(self::NOTSUPPORTED);
return false;
}
if (! $this->allowNonSepa && ! in_array($countryCode, static::$sepaCountries)) {
$this->setValue($countryCode);
$this->error(self::SEPANOTSUPPORTED);
return false;
}
if (! preg_match('/^' . static::$ibanRegex[$countryCode] . '$/', $value)) {
$this->error(self::FALSEFORMAT);
return false;
}
$format = substr($value, 4) . substr($value, 0, 4);
$format = str_replace(
[
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
],
[
'10',
'11',
'12',
'13',
'14',
'15',
'16',
'17',
'18',
'19',
'20',
'21',
'22',
'23',
'24',
'25',
'26',
'27',
'28',
'29',
'30',
'31',
'32',
'33',
'34',
'35',
],
$format
);
$temp = intval(substr($format, 0, 1));
$len = strlen($format);
for ($x = 1; $x < $len; ++$x) {
$temp *= 10;
$temp += intval(substr($format, $x, 1));
$temp %= 97;
}
if ($temp !== 1) {
$this->error(self::CHECKFAILED);
return false;
}
return true;
}
}

View File

@@ -1,231 +0,0 @@
<?php
namespace Laminas\Validator;
use ArrayAccess;
use Laminas\Stdlib\ArrayUtils;
use Traversable;
use function array_key_exists;
use function get_debug_type;
use function is_array;
use function is_int;
use function is_string;
use function key;
use function sprintf;
use function var_export;
/** @final */
class Identical extends AbstractValidator
{
/**
* Error codes
*
* @const string
*/
public const NOT_SAME = 'notSame';
public const MISSING_TOKEN = 'missingToken';
/**
* Error messages
*
* @var array
*/
protected $messageTemplates = [
self::NOT_SAME => 'The two given tokens do not match',
self::MISSING_TOKEN => 'No token was provided to match against',
];
/** @var array */
protected $messageVariables = [
'token' => 'tokenString',
];
/**
* Original token against which to validate
*
* @var null|string
*/
protected $tokenString;
/** @var null|string */
protected $token;
/** @var bool */
protected $strict = true;
/** @var bool */
protected $literal = false;
/**
* Sets validator options
*
* @param mixed $token
*/
public function __construct($token = null)
{
if ($token instanceof Traversable) {
$token = ArrayUtils::iteratorToArray($token);
}
if (is_array($token) && array_key_exists('token', $token)) {
if (array_key_exists('strict', $token)) {
$this->setStrict($token['strict']);
}
if (array_key_exists('literal', $token)) {
$this->setLiteral($token['literal']);
}
$this->setToken($token['token']);
} elseif (null !== $token) {
$this->setToken($token);
}
parent::__construct(is_array($token) ? $token : null);
}
/**
* Retrieve token
*
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @return mixed
*/
public function getToken()
{
return $this->token;
}
/**
* Set token against which to compare
*
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @return $this
*/
public function setToken(mixed $token)
{
$this->tokenString = is_array($token) ? var_export($token, true) : (string) $token;
$this->token = $token;
return $this;
}
/**
* Returns the strict parameter
*
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @return bool
*/
public function getStrict()
{
return $this->strict;
}
/**
* Sets the strict parameter
*
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @param bool $strict
* @return $this
*/
public function setStrict($strict)
{
$this->strict = (bool) $strict;
return $this;
}
/**
* Returns the literal parameter
*
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @return bool
*/
public function getLiteral()
{
return $this->literal;
}
/**
* Sets the literal parameter
*
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @param bool $literal
* @return $this
*/
public function setLiteral($literal)
{
$this->literal = (bool) $literal;
return $this;
}
/**
* Returns true if and only if a token has been set and the provided value
* matches that token.
*
* @param mixed $value
* @param null|array|ArrayAccess $context
* @throws Exception\InvalidArgumentException If context is not array or ArrayObject.
* @return bool
*/
public function isValid($value, $context = null)
{
$this->setValue($value);
$token = $this->getToken();
if (! $this->getLiteral() && $context !== null) {
if (! is_array($context) && ! $context instanceof ArrayAccess) {
throw new Exception\InvalidArgumentException(sprintf(
'Context passed to %s must be array, ArrayObject or null; received "%s"',
__METHOD__,
get_debug_type($context)
));
}
if (is_array($token)) {
while (is_array($token)) {
$key = key($token);
if (! isset($context[$key])) {
break;
}
$context = $context[$key];
$token = $token[$key];
}
}
// if $token is an array it means the above loop didn't went all the way down to the leaf,
// so the $token structure doesn't match the $context structure
if (
is_array($token)
|| (! is_int($token) && ! is_string($token))
|| ! isset($context[$token])
) {
$token = $this->getToken();
} else {
$token = $context[$token];
}
}
if ($token === null) {
$this->error(self::MISSING_TOKEN);
return false;
}
$strict = $this->getStrict();
if (
($strict && ($value !== $token))
// phpcs:ignore SlevomatCodingStandard.Operators.DisallowEqualOperators.DisallowedNotEqualOperator
|| (! $strict && ($value != $token))
) {
$this->error(self::NOT_SAME);
return false;
}
return true;
}
}

View File

@@ -1,266 +0,0 @@
<?php
namespace Laminas\Validator;
use RecursiveArrayIterator;
use RecursiveIteratorIterator;
use function in_array;
use function is_bool;
use function is_float;
use function is_int;
use function is_string;
/** @final */
class InArray extends AbstractValidator
{
public const NOT_IN_ARRAY = 'notInArray';
// Type of Strict check
/**
* standard in_array strict checking value and type
*/
public const COMPARE_STRICT = 1;
/**
* Non strict check but prevents "asdf" == 0 returning TRUE causing false/positive.
* This is the most secure option for non-strict checks and replaces strict = false
* This will only be effective when the input is a string
*/
public const COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY = 0;
/**
* Standard non-strict check where "asdf" == 0 returns TRUE
* This will be wanted when comparing "0" against int 0
*/
public const COMPARE_NOT_STRICT = -1;
/** @var array<string, string> */
protected $messageTemplates = [
self::NOT_IN_ARRAY => 'The input was not found in the haystack',
];
/**
* Haystack of possible values
*
* @var array
*/
protected $haystack;
/**
* Type of strict check to be used. Due to "foo" == 0 === TRUE with in_array when strict = false,
* an option has been added to prevent this. When $strict = 0/false, the most
* secure non-strict check is implemented. if $strict = -1, the default in_array non-strict
* behaviour is used
*
* @var int
*/
protected $strict = self::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY;
/**
* Whether a recursive search should be done
*
* @var bool
*/
protected $recursive = false;
/**
* Returns the haystack option
*
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @return mixed
* @throws Exception\RuntimeException If haystack option is not set.
*/
public function getHaystack()
{
if ($this->haystack === null) {
throw new Exception\RuntimeException('haystack option is mandatory');
}
return $this->haystack;
}
/**
* Sets the haystack option
*
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @param mixed $haystack
* @return $this Provides a fluent interface
*/
public function setHaystack(array $haystack)
{
$this->haystack = $haystack;
return $this;
}
/**
* Returns the strict option
*
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @return bool|int
*/
public function getStrict()
{
// To keep BC with new strict modes
if (
$this->strict === self::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY
|| $this->strict === self::COMPARE_STRICT
) {
return (bool) $this->strict;
}
return $this->strict;
}
/**
* Sets the strict option mode
* InArray::COMPARE_STRICT
* InArray::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY
* InArray::COMPARE_NOT_STRICT
*
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @param int|bool $strict
* @return $this Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function setStrict($strict)
{
if (is_bool($strict)) {
$strict = $strict ? self::COMPARE_STRICT : self::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY;
}
$checkTypes = [
self::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY, // 0
self::COMPARE_STRICT, // 1
self::COMPARE_NOT_STRICT, // -1
];
// validate strict value
if (! in_array($strict, $checkTypes)) {
throw new Exception\InvalidArgumentException('Strict option must be one of the COMPARE_ constants');
}
$this->strict = $strict;
return $this;
}
/**
* Returns the recursive option
*
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @return bool
*/
public function getRecursive()
{
return $this->recursive;
}
/**
* Sets the recursive option
*
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @param bool $recursive
* @return $this Provides a fluent interface
*/
public function setRecursive($recursive)
{
$this->recursive = (bool) $recursive;
return $this;
}
/**
* Returns true if and only if $value is contained in the haystack option. If the strict
* option is true, then the type of $value is also checked.
*
* @param mixed $value
* See {@link http://php.net/manual/function.in-array.php#104501}
* @return bool
*/
public function isValid($value)
{
// we create a copy of the haystack in case we need to modify it
$haystack = $this->getHaystack();
// if the input is a string or float, and vulnerability protection is on
// we type cast the input to a string
if (
self::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY === $this->strict
&& (is_int($value) || is_float($value))
) {
$value = (string) $value;
}
$this->setValue($value);
if ($this->getRecursive()) {
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($haystack));
foreach ($iterator as $element) {
if (self::COMPARE_STRICT === $this->strict) {
if ($element === $value) {
return true;
}
continue;
}
// add protection to prevent string to int vuln's
$el = $element;
if (
self::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY === $this->strict
&& is_string($value) && (is_int($el) || is_float($el))
) {
$el = (string) $el;
}
// phpcs:ignore SlevomatCodingStandard.Operators.DisallowEqualOperators.DisallowedEqualOperator
if ($el == $value) {
return true;
}
}
$this->error(self::NOT_IN_ARRAY);
return false;
}
/**
* If the check is not strict, then, to prevent "asdf" being converted to 0
* and returning a false positive if 0 is in haystack, we type cast
* the haystack to strings. To prevent "56asdf" == 56 === TRUE we also
* type cast values like 56 to strings as well.
*
* This occurs only if the input is a string and a haystack member is an int
*/
if (
self::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY === $this->strict
&& is_string($value)
) {
foreach ($haystack as &$h) {
if (is_int($h) || is_float($h)) {
$h = (string) $h;
}
}
if (in_array($value, $haystack, (bool) $this->strict)) {
return true;
}
$this->error(self::NOT_IN_ARRAY);
return false;
}
if (in_array($value, $haystack, self::COMPARE_STRICT === $this->strict)) {
return true;
}
if (self::COMPARE_NOT_STRICT === $this->strict) {
return true;
}
$this->error(self::NOT_IN_ARRAY);
return false;
}
}

View File

@@ -1,198 +0,0 @@
<?php
namespace Laminas\Validator;
use Traversable;
use function bindec;
use function hexdec;
use function ip2long;
use function is_string;
use function long2ip;
use function preg_match;
use function str_contains;
use function strlen;
use function strpos;
use function strrpos;
use function substr;
use function substr_count;
/** @final */
class Ip extends AbstractValidator
{
public const INVALID = 'ipInvalid';
public const NOT_IP_ADDRESS = 'notIpAddress';
/** @var array */
protected $messageTemplates = [
self::INVALID => 'Invalid type given. String expected',
self::NOT_IP_ADDRESS => 'The input does not appear to be a valid IP address',
];
/**
* Internal options
*
* @var array
*/
protected $options = [
'allowipv4' => true, // Enable IPv4 Validation
'allowipv6' => true, // Enable IPv6 Validation
'allowipvfuture' => false, // Enable IPvFuture Validation
'allowliteral' => true, // Enable IPs in literal format (only IPv6 and IPvFuture)
];
/**
* Sets the options for this validator
*
* @param array|Traversable $options
* @throws Exception\InvalidArgumentException If there is any kind of IP allowed or $options is not an array
* or Traversable.
* @return AbstractValidator
*/
public function setOptions($options = [])
{
parent::setOptions($options);
if (! $this->options['allowipv4'] && ! $this->options['allowipv6'] && ! $this->options['allowipvfuture']) {
throw new Exception\InvalidArgumentException('Nothing to validate. Check your options');
}
return $this;
}
/**
* Returns true if and only if $value is a valid IP address
*
* @param mixed $value
* @return bool
*/
public function isValid($value)
{
if (! is_string($value)) {
$this->error(self::INVALID);
return false;
}
$this->setValue($value);
if ($this->options['allowipv4'] && $this->validateIPv4($value)) {
return true;
} else {
if ((bool) $this->options['allowliteral']) {
static $regex = '/^\[(.*)\]$/';
if ((bool) preg_match($regex, $value, $matches)) {
$value = $matches[1];
}
}
$isValidV6Address = $this->validateIPv6($value);
$isValidV6Address = $isValidV6Address !== false && $isValidV6Address !== 0;
if (
($this->options['allowipv6'] && $isValidV6Address) ||
($this->options['allowipvfuture'] && $this->validateIPvFuture($value))
) {
return true;
}
}
$this->error(self::NOT_IP_ADDRESS);
return false;
}
/**
* Validates an IPv4 address
*
* @param string $value
* @return bool
*/
protected function validateIPv4($value)
{
if (preg_match('/^([01]{8}\.){3}[01]{8}\z/i', $value)) {
// binary format 00000000.00000000.00000000.00000000
$value = bindec(substr($value, 0, 8)) . '.' . bindec(substr($value, 9, 8)) . '.'
. bindec(substr($value, 18, 8)) . '.' . bindec(substr($value, 27, 8));
} elseif (preg_match('/^([0-9]{3}\.){3}[0-9]{3}\z/i', $value)) {
// octet format 777.777.777.777
$value = (int) substr($value, 0, 3) . '.' . (int) substr($value, 4, 3) . '.'
. (int) substr($value, 8, 3) . '.' . (int) substr($value, 12, 3);
} elseif (preg_match('/^([0-9a-f]{2}\.){3}[0-9a-f]{2}\z/i', $value)) {
// hex format ff.ff.ff.ff
$value = hexdec(substr($value, 0, 2)) . '.' . hexdec(substr($value, 3, 2)) . '.'
. hexdec(substr($value, 6, 2)) . '.' . hexdec(substr($value, 9, 2));
}
$ip2long = ip2long($value);
if ($ip2long === false) {
return false;
}
return $value === long2ip($ip2long);
}
/**
* Validates an IPv6 address
*
* @param string $value Value to check against
* @return bool|int True when $value is a valid ipv6 address False otherwise
*/
protected function validateIPv6($value)
{
if (strlen($value) < 3) {
return $value === '::';
}
if (strpos($value, '.') !== false) {
$lastcolon = strrpos($value, ':');
if (! ($lastcolon !== false && $this->validateIPv4(substr($value, $lastcolon + 1)))) {
return false;
}
$value = substr($value, 0, $lastcolon) . ':0:0';
}
if (! str_contains($value, '::')) {
return preg_match('/\A(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}\z/i', $value);
}
$colonCount = substr_count($value, ':');
if ($colonCount < 8) {
return preg_match('/\A(?::|(?:[a-f0-9]{1,4}:)+):(?:(?:[a-f0-9]{1,4}:)*[a-f0-9]{1,4})?\z/i', $value);
}
// special case with ending or starting double colon
if ($colonCount === 8) {
return preg_match('/\A(?:::)?(?:[a-f0-9]{1,4}:){6}[a-f0-9]{1,4}(?:::)?\z/i', $value);
}
return false;
}
/**
* Validates an IPvFuture address.
*
* IPvFuture is loosely defined in the Section 3.2.2 of RFC 3986
*
* @param string $value Value to check against
* @return bool True when $value is a valid IPvFuture address
* False otherwise
*/
protected function validateIPvFuture($value)
{
/*
* ABNF:
* IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / ","
* / ";" / "="
*/
static $regex = '/^v([[:xdigit:]]+)\.[[:alnum:]\-\._~!\$&\'\(\)\*\+,;=:]+$/';
$result = (bool) preg_match($regex, $value, $matches);
/*
* "As such, implementations must not provide the version flag for the
* existing IPv4 and IPv6 literal address forms described below."
*/
return $result && $matches[1] !== '4' && $matches[1] !== '6';
}
}

View File

@@ -1,40 +0,0 @@
<?php
declare(strict_types=1);
namespace Laminas\Validator;
use function get_debug_type;
use function is_array;
final class IsArray extends AbstractValidator
{
public const NOT_ARRAY = 'NotArray';
/** @var array<non-empty-string, non-empty-string> */
protected $messageTemplates = [
self::NOT_ARRAY => 'Expected an array value but %type% provided',
];
/** @var array<string, string> */
protected $messageVariables = [
'type' => 'type',
];
protected ?string $type = null;
/** @var array<never, never> */
protected $options = [];
public function isValid(mixed $value): bool
{
if (is_array($value)) {
return true;
}
$this->type = get_debug_type($value);
$this->error(self::NOT_ARRAY);
return false;
}
}

View File

@@ -1,223 +0,0 @@
<?php
namespace Laminas\Validator;
use Laminas\Stdlib\ArrayUtils;
use Traversable;
use function count;
use function is_countable;
use function is_numeric;
/**
* Validate that a value is countable and the count meets expectations.
*
* The validator has five specific behaviors:
*
* - You can determine if a value is countable only
* - You can test if the value is an exact count
* - You can test if the value is greater than a minimum count value
* - You can test if the value is greater than a maximum count value
* - You can test if the value is between the minimum and maximum count values
*
* When creating the instance or calling `setOptions()`, if you specify a
* "count" option, specifying either "min" or "max" leads to an inconsistent
* state and, as such will raise an Exception\InvalidArgumentException.
*
* @psalm-type Options = array{
* count: int|null,
* min: int|null,
* max: int|null,
* }
* @psalm-type OptionsArgument = array{
* count?: int|null,
* min?: int|null,
* max?: int|null,
* }&array<string, mixed>
* @property Options&array<string, mixed> $options Required to stop Psalm getting confused about the declaration
* on AbstractValidator
* @final
*/
class IsCountable extends AbstractValidator
{
public const NOT_COUNTABLE = 'notCountable';
public const NOT_EQUALS = 'notEquals';
public const GREATER_THAN = 'greaterThan';
public const LESS_THAN = 'lessThan';
/**
* Validation failure message template definitions
*
* @var array<string, string>
*/
protected $messageTemplates = [
self::NOT_COUNTABLE => 'The input must be an array or an instance of \\Countable',
self::NOT_EQUALS => "The input count must equal '%count%'",
self::GREATER_THAN => "The input count must be less than '%max%', inclusively",
self::LESS_THAN => "The input count must be greater than '%min%', inclusively",
];
/**
* Additional variables available for validation failure messages
*
* @var array<string, array{options: string}>
*/
protected $messageVariables = [
'count' => ['options' => 'count'],
'min' => ['options' => 'min'],
'max' => ['options' => 'max'],
];
/** @psalm-var Options */
protected $options = [
'count' => null,
'min' => null,
'max' => null,
];
/**
* @param OptionsArgument|iterable<string, mixed> $options
* @return $this Provides fluid interface
*/
public function setOptions($options = [])
{
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
}
/** @psalm-var Options $options */
if (isset($options['count'])) {
$this->setCount($options['count']);
}
if (isset($options['min'])) {
$this->setMin($options['min']);
}
if (isset($options['max'])) {
$this->setMax($options['max']);
}
unset($options['count'], $options['min'], $options['max']);
parent::setOptions($options);
return $this;
}
/**
* Returns true if and only if $value is countable (and the count validates against optional values).
*
* @param mixed $value
* @return bool
*/
public function isValid($value)
{
if (! is_countable($value)) {
$this->error(self::NOT_COUNTABLE);
return false;
}
$count = count($value);
if (is_numeric($this->getCount())) {
if ($count !== $this->getCount()) {
$this->error(self::NOT_EQUALS);
return false;
}
return true;
}
if (is_numeric($this->getMax()) && $count > $this->getMax()) {
$this->error(self::GREATER_THAN);
return false;
}
if (is_numeric($this->getMin()) && $count < $this->getMin()) {
$this->error(self::LESS_THAN);
return false;
}
return true;
}
/**
* Returns the count option
*
* @deprecated Since 2.61.0 All option getters and setters will be removed in 3.0
*
* @return int|null
*/
public function getCount()
{
return $this->options['count'];
}
/**
* Returns the min option
*
* @deprecated Since 2.61.0 All option getters and setters will be removed in 3.0
*
* @return int|null
*/
public function getMin()
{
return $this->options['min'];
}
/**
* Returns the max option
*
* @deprecated Since 2.61.0 All option getters and setters will be removed in 3.0
*
* @return int|null
*/
public function getMax()
{
return $this->options['max'];
}
/**
* @throws Exception\InvalidArgumentException If either a min or max option
* was previously set.
*/
private function setCount(int $value): void
{
if (isset($this->options['min']) || isset($this->options['max'])) {
throw new Exception\InvalidArgumentException(
'Cannot set count; conflicts with either a min or max option previously set'
);
}
$this->options['count'] = $value;
}
/**
* @throws Exception\InvalidArgumentException If either a count or max option
* was previously set.
*/
private function setMin(int $value): void
{
if (isset($this->options['count'])) {
throw new Exception\InvalidArgumentException(
'Cannot set count; conflicts with either a count option previously set'
);
}
$this->options['min'] = $value;
}
/**
* @throws Exception\InvalidArgumentException If either a count or min option
* was previously set.
*/
private function setMax(int $value): void
{
if (isset($this->options['count'])) {
throw new Exception\InvalidArgumentException(
'Cannot set count; conflicts with either a count option previously set'
);
}
$this->options['max'] = $value;
}
}

View File

@@ -1,108 +0,0 @@
<?php
namespace Laminas\Validator;
use Traversable;
use function array_key_exists;
use function array_shift;
use function func_get_args;
use function is_array;
use function iterator_to_array;
/** @final */
class IsInstanceOf extends AbstractValidator
{
public const NOT_INSTANCE_OF = 'notInstanceOf';
/**
* Validation failure message template definitions
*
* @var array
*/
protected $messageTemplates = [
self::NOT_INSTANCE_OF => "The input is not an instance of '%className%'",
];
/**
* Additional variables available for validation failure messages
*
* @var array
*/
protected $messageVariables = [
'className' => 'className',
];
/** @var string */
protected $className;
/**
* Sets validator options
*
* @param array|Traversable $options
* @throws Exception\InvalidArgumentException
*/
public function __construct($options = null)
{
if ($options instanceof Traversable) {
$options = iterator_to_array($options);
}
// If argument is not an array, consider first argument as class name
if (! is_array($options)) {
$options = func_get_args();
$tmpOptions = [];
$tmpOptions['className'] = array_shift($options);
$options = $tmpOptions;
}
if (! array_key_exists('className', $options)) {
throw new Exception\InvalidArgumentException('Missing option "className"');
}
parent::__construct($options);
}
/**
* Get class name
*
* @deprecated Since 2.61.0 All option setters and getters will be removed in v3.0
*
* @return string
*/
public function getClassName()
{
return $this->className;
}
/**
* Set class name
*
* @deprecated Since 2.61.0 All option setters and getters will be removed in v3.0
*
* @param string $className
* @return $this
*/
public function setClassName($className)
{
$this->className = $className;
return $this;
}
/**
* Returns true if $value is instance of $this->className
*
* @param mixed $value
* @return bool
*/
public function isValid($value)
{
if ($value instanceof $this->className) {
return true;
}
$this->error(self::NOT_INSTANCE_OF);
return false;
}
}

View File

@@ -1,160 +0,0 @@
<?php
declare(strict_types=1);
namespace Laminas\Validator;
use JsonException;
use function gettype;
use function is_float;
use function is_int;
use function is_numeric;
use function is_string;
use function json_decode;
use function str_starts_with;
use const JSON_ERROR_DEPTH;
use const JSON_THROW_ON_ERROR;
/**
* @psalm-type CustomOptions = array{
* allow: int-mask-of<self::ALLOW_*>,
* maxDepth: positive-int,
* }
* @psalm-import-type AbstractOptions from AbstractValidator
* @psalm-type Options = AbstractOptions|CustomOptions
*/
final class IsJsonString extends AbstractValidator
{
public const ERROR_NOT_STRING = 'errorNotString';
public const ERROR_TYPE_NOT_ALLOWED = 'errorTypeNotAllowed';
public const ERROR_MAX_DEPTH_EXCEEDED = 'errorMaxDepthExceeded';
public const ERROR_INVALID_JSON = 'errorInvalidJson';
public const ALLOW_INT = 0b0000001;
public const ALLOW_FLOAT = 0b0000010;
public const ALLOW_BOOL = 0b0000100;
public const ALLOW_ARRAY = 0b0001000;
public const ALLOW_OBJECT = 0b0010000;
public const ALLOW_ALL = 0b0011111;
/** @var array<self::ERROR_*, non-empty-string> */
protected $messageTemplates = [
self::ERROR_NOT_STRING => 'Expected a string but %type% was received',
self::ERROR_TYPE_NOT_ALLOWED => 'Received a JSON %type% but this type is not acceptable',
self::ERROR_MAX_DEPTH_EXCEEDED => 'The decoded JSON payload exceeds the allowed depth of %maxDepth%',
self::ERROR_INVALID_JSON => 'An invalid JSON payload was received',
];
/** @var array<string, string> */
protected $messageVariables = [
'type' => 'type',
'maxDepth' => 'maxDepth',
];
protected ?string $type = null;
/** @var int-mask-of<self::ALLOW_*> */
protected int $allow = self::ALLOW_ALL;
/** @var positive-int */
protected int $maxDepth = 512;
/**
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @param int-mask-of<self::ALLOW_*> $type
*/
public function setAllow(int $type): void
{
$this->allow = $type;
}
/**
* @deprecated Since 2.61.0 - All option setters and getters will be removed in 3.0
*
* @param positive-int $maxDepth
*/
public function setMaxDepth(int $maxDepth): void
{
$this->maxDepth = $maxDepth;
}
public function isValid(mixed $value): bool
{
if (! is_string($value)) {
$this->error(self::ERROR_NOT_STRING);
$this->type = gettype($value);
return false;
}
if (is_numeric($value)) {
/** @psalm-var mixed $value */
$value = json_decode($value);
if (is_int($value) && ! $this->isAllowed(self::ALLOW_INT)) {
$this->error(self::ERROR_TYPE_NOT_ALLOWED);
$this->type = 'int';
return false;
}
if (is_float($value) && ! $this->isAllowed(self::ALLOW_FLOAT)) {
$this->error(self::ERROR_TYPE_NOT_ALLOWED);
$this->type = 'float';
return false;
}
return true;
}
if ($value === 'true' || $value === 'false') {
if (! $this->isAllowed(self::ALLOW_BOOL)) {
$this->error(self::ERROR_TYPE_NOT_ALLOWED);
$this->type = 'boolean';
return false;
}
return true;
}
if (str_starts_with($value, '[') && ! $this->isAllowed(self::ALLOW_ARRAY)) {
$this->error(self::ERROR_TYPE_NOT_ALLOWED);
$this->type = 'array';
return false;
}
if (str_starts_with($value, '{') && ! $this->isAllowed(self::ALLOW_OBJECT)) {
$this->error(self::ERROR_TYPE_NOT_ALLOWED);
$this->type = 'object';
return false;
}
try {
/** @psalm-suppress UnusedFunctionCall */
json_decode($value, true, $this->maxDepth, JSON_THROW_ON_ERROR);
return true;
} catch (JsonException $e) {
if ($e->getCode() === JSON_ERROR_DEPTH) {
$this->error(self::ERROR_MAX_DEPTH_EXCEEDED);
return false;
}
$this->error(self::ERROR_INVALID_JSON);
return false;
}
}
/** @param self::ALLOW_* $flag */
private function isAllowed(int $flag): bool
{
return ($this->allow & $flag) === $flag;
}
}

Some files were not shown because too many files have changed in this diff Show More