diff options
Diffstat (limited to 'vendor/thecodingmachine/safe/lib')
8 files changed, 653 insertions, 0 deletions
diff --git a/vendor/thecodingmachine/safe/lib/DateTime.php b/vendor/thecodingmachine/safe/lib/DateTime.php new file mode 100644 index 000000000..581ef35c0 --- /dev/null +++ b/vendor/thecodingmachine/safe/lib/DateTime.php @@ -0,0 +1,81 @@ +<?php + +namespace Safe; + +use DateInterval; +use DateTimeInterface; +use DateTimeZone; +use Safe\Exceptions\DatetimeException; + +/** this class implements a safe version of the Datetime class */ +class DateTime extends \DateTime +{ + //switch from regular datetime to safe version + private static function createFromRegular(\DateTime $datetime): self + { + return new self($datetime->format('Y-m-d H:i:s.u'), $datetime->getTimezone()); + } + + /** + * @param string $format + * @param string $time + * @param DateTimeZone|null $timezone + * @throws DatetimeException + */ + public static function createFromFormat($format, $time, $timezone = null): self + { + $datetime = parent::createFromFormat($format, $time, $timezone); + if ($datetime === false) { + throw DatetimeException::createFromPhpError(); + } + return self::createFromRegular($datetime); + } + + /** + * @param DateTimeInterface $datetime2 The date to compare to. + * @param boolean $absolute [optional] Whether to return absolute difference. + * @return DateInterval The DateInterval object representing the difference between the two dates. + * @throws DatetimeException + */ + public function diff($datetime2, $absolute = false): DateInterval + { + /** @var \DateInterval|false $result */ + $result = parent::diff($datetime2, $absolute); + if ($result === false) { + throw DatetimeException::createFromPhpError(); + } + return $result; + } + + /** + * @param string $modify A date/time string. Valid formats are explained in <a href="https://secure.php.net/manual/en/datetime.formats.php">Date and Time Formats</a>. + * @return DateTime Returns the DateTime object for method chaining. + * @throws DatetimeException + */ + public function modify($modify): self + { + /** @var DateTime|false $result */ + $result = parent::modify($modify); + if ($result === false) { + throw DatetimeException::createFromPhpError(); + } + return $result; + } + + /** + * @param int $year + * @param int $month + * @param int $day + * @return DateTime + * @throws DatetimeException + */ + public function setDate($year, $month, $day): self + { + /** @var DateTime|false $result */ + $result = parent::setDate($year, $month, $day); + if ($result === false) { + throw DatetimeException::createFromPhpError(); + } + return $result; + } +} diff --git a/vendor/thecodingmachine/safe/lib/DateTimeImmutable.php b/vendor/thecodingmachine/safe/lib/DateTimeImmutable.php new file mode 100644 index 000000000..114ec3a3d --- /dev/null +++ b/vendor/thecodingmachine/safe/lib/DateTimeImmutable.php @@ -0,0 +1,262 @@ +<?php + +namespace Safe; + +use DateInterval; +use DateTime; +use DateTimeInterface; +use DateTimeZone; +use Safe\Exceptions\DatetimeException; + +/** + * This class is used to implement a safe version of the DatetimeImmutable class. + * While it technically overloads \DateTimeImmutable for typehint compatibility, + * it is actually used as a wrapper of \DateTimeImmutable, mostly to be able to overwrite functions like getTimestamp() while still being able to edit milliseconds via setTime(). + */ +class DateTimeImmutable extends \DateTimeImmutable +{ + /** + * @var \DateTimeImmutable + */ + private $innerDateTime; + + /** + * DateTimeImmutable constructor. + * @param string $time + * @param DateTimeZone|null $timezone + * @throws \Exception + */ + public function __construct($time = 'now', $timezone = null) + { + parent::__construct($time, $timezone); + $this->innerDateTime = new parent($time, $timezone); + } + + //switch between regular datetime and safe version + public static function createFromRegular(\DateTimeImmutable $datetime): self + { + $safeDatetime = new self($datetime->format('Y-m-d H:i:s.u'), $datetime->getTimezone()); //we need to also update the wrapper to not break the operators '<' and '>' + $safeDatetime->innerDateTime = $datetime; //to make sure we don't lose information because of the format(). + return $safeDatetime; + } + + //usefull if you need to switch back to regular DateTimeImmutable (for example when using DatePeriod) + public function getInnerDateTime(): \DateTimeImmutable + { + return $this->innerDateTime; + } + + ///////////////////////////////////////////////////////////////////////////// + // overload functions with false errors + + /** + * @param string $format + * @param string $time + * @param DateTimeZone|null $timezone + * @throws DatetimeException + */ + public static function createFromFormat($format, $time, $timezone = null): self + { + $datetime = parent::createFromFormat($format, $time, $timezone); + if ($datetime === false) { + throw DatetimeException::createFromPhpError(); + } + return self::createFromRegular($datetime); + } + + /** + * @param string $format + * @return string + * @throws DatetimeException + */ + public function format($format): string + { + /** @var string|false $result */ + $result = $this->innerDateTime->format($format); + if ($result === false) { + throw DatetimeException::createFromPhpError(); + } + return $result; + } + + /** + * @param DateTimeInterface $datetime2 + * @param bool $absolute + * @return DateInterval + * @throws DatetimeException + */ + public function diff($datetime2, $absolute = false): DateInterval + { + /** @var \DateInterval|false $result */ + $result = $this->innerDateTime->diff($datetime2, $absolute); + if ($result === false) { + throw DatetimeException::createFromPhpError(); + } + return $result; + } + + /** + * @param string $modify + * @return DateTimeImmutable + * @throws DatetimeException + */ + public function modify($modify): self + { + /** @var \DateTimeImmutable|false $result */ + $result = $this->innerDateTime->modify($modify); + if ($result === false) { + throw DatetimeException::createFromPhpError(); + } + return self::createFromRegular($result); //we have to recreate a safe datetime because modify create a new instance of \DateTimeImmutable + } + + /** + * @param int $year + * @param int $month + * @param int $day + * @return DateTimeImmutable + * @throws DatetimeException + */ + public function setDate($year, $month, $day): self + { + /** @var \DateTimeImmutable|false $result */ + $result = $this->innerDateTime->setDate($year, $month, $day); + if ($result === false) { + throw DatetimeException::createFromPhpError(); + } + return self::createFromRegular($result); //we have to recreate a safe datetime because modify create a new instance of \DateTimeImmutable + } + + /** + * @param int $year + * @param int $week + * @param int $day + * @return DateTimeImmutable + * @throws DatetimeException + */ + public function setISODate($year, $week, $day = 1): self + { + /** @var \DateTimeImmutable|false $result */ + $result = $this->innerDateTime->setISODate($year, $week, $day); + if ($result === false) { + throw DatetimeException::createFromPhpError(); + } + return self::createFromRegular($result); //we have to recreate a safe datetime because modify create a new instance of \DateTimeImmutable + } + + /** + * @param int $hour + * @param int $minute + * @param int $second + * @param int $microseconds + * @return DateTimeImmutable + * @throws DatetimeException + */ + public function setTime($hour, $minute, $second = 0, $microseconds = 0): self + { + /** @var \DateTimeImmutable|false $result */ + $result = $this->innerDateTime->setTime($hour, $minute, $second, $microseconds); + if ($result === false) { + throw DatetimeException::createFromPhpError(); + } + return self::createFromRegular($result); + } + + /** + * @param int $unixtimestamp + * @return DateTimeImmutable + * @throws DatetimeException + */ + public function setTimestamp($unixtimestamp): self + { + /** @var \DateTimeImmutable|false $result */ + $result = $this->innerDateTime->setTimestamp($unixtimestamp); + if ($result === false) { + throw DatetimeException::createFromPhpError(); + } + return self::createFromRegular($result); + } + + /** + * @param DateTimeZone $timezone + * @return DateTimeImmutable + * @throws DatetimeException + */ + public function setTimezone($timezone): self + { + /** @var \DateTimeImmutable|false $result */ + $result = $this->innerDateTime->setTimezone($timezone); + if ($result === false) { + throw DatetimeException::createFromPhpError(); + } + return self::createFromRegular($result); + } + + /** + * @param DateInterval $interval + * @return DateTimeImmutable + * @throws DatetimeException + */ + public function sub($interval): self + { + /** @var \DateTimeImmutable|false $result */ + $result = $this->innerDateTime->sub($interval); + if ($result === false) { + throw DatetimeException::createFromPhpError(); + } + return self::createFromRegular($result); + } + + /** + * @throws DatetimeException + */ + public function getOffset(): int + { + /** @var int|false $result */ + $result = $this->innerDateTime->getOffset(); + if ($result === false) { + throw DatetimeException::createFromPhpError(); + } + return $result; + } + + ////////////////////////////////////////////////////////////////////////////////////////// + //overload getters to use the inner datetime immutable instead of itself + + /** + * @param DateInterval $interval + * @return DateTimeImmutable + */ + public function add($interval): self + { + return self::createFromRegular($this->innerDateTime->add($interval)); + } + + /** + * @param DateTime $dateTime + * @return DateTimeImmutable + */ + public static function createFromMutable($dateTime): self + { + return self::createFromRegular(parent::createFromMutable($dateTime)); + } + + /** + * @param mixed[] $array + * @return DateTimeImmutable + */ + public static function __set_state($array): self + { + return self::createFromRegular(parent::__set_state($array)); + } + + public function getTimezone(): DateTimeZone + { + return $this->innerDateTime->getTimezone(); + } + + public function getTimestamp(): int + { + return $this->innerDateTime->getTimestamp(); + } +} diff --git a/vendor/thecodingmachine/safe/lib/Exceptions/CurlException.php b/vendor/thecodingmachine/safe/lib/Exceptions/CurlException.php new file mode 100644 index 000000000..2814066b0 --- /dev/null +++ b/vendor/thecodingmachine/safe/lib/Exceptions/CurlException.php @@ -0,0 +1,15 @@ +<?php + + +namespace Safe\Exceptions; + +class CurlException extends \Exception implements SafeExceptionInterface +{ + /** + * @param resource $ch + */ + public static function createFromCurlResource($ch): self + { + return new self(\curl_error($ch), \curl_errno($ch)); + } +} diff --git a/vendor/thecodingmachine/safe/lib/Exceptions/JsonException.php b/vendor/thecodingmachine/safe/lib/Exceptions/JsonException.php new file mode 100644 index 000000000..4300d29e9 --- /dev/null +++ b/vendor/thecodingmachine/safe/lib/Exceptions/JsonException.php @@ -0,0 +1,12 @@ +<?php + + +namespace Safe\Exceptions; + +class JsonException extends \Exception implements SafeExceptionInterface +{ + public static function createFromPhpError(): self + { + return new self(\json_last_error_msg(), \json_last_error()); + } +} diff --git a/vendor/thecodingmachine/safe/lib/Exceptions/OpensslException.php b/vendor/thecodingmachine/safe/lib/Exceptions/OpensslException.php new file mode 100644 index 000000000..5f424af2d --- /dev/null +++ b/vendor/thecodingmachine/safe/lib/Exceptions/OpensslException.php @@ -0,0 +1,12 @@ +<?php + + +namespace Safe\Exceptions; + +class OpensslException extends \Exception implements SafeExceptionInterface +{ + public static function createFromPhpError(): self + { + return new self(\openssl_error_string() ?: '', 0); + } +} diff --git a/vendor/thecodingmachine/safe/lib/Exceptions/PcreException.php b/vendor/thecodingmachine/safe/lib/Exceptions/PcreException.php new file mode 100644 index 000000000..ee6367ef6 --- /dev/null +++ b/vendor/thecodingmachine/safe/lib/Exceptions/PcreException.php @@ -0,0 +1,21 @@ +<?php + + +namespace Safe\Exceptions; + +class PcreException extends \Exception implements SafeExceptionInterface +{ + public static function createFromPhpError(): self + { + $errorMap = [ + PREG_INTERNAL_ERROR => 'PREG_INTERNAL_ERROR: Internal error', + PREG_BACKTRACK_LIMIT_ERROR => 'PREG_BACKTRACK_LIMIT_ERROR: Backtrack limit reached', + PREG_RECURSION_LIMIT_ERROR => 'PREG_RECURSION_LIMIT_ERROR: Recursion limit reached', + PREG_BAD_UTF8_ERROR => 'PREG_BAD_UTF8_ERROR: Invalid UTF8 character', + PREG_BAD_UTF8_OFFSET_ERROR => 'PREG_BAD_UTF8_OFFSET_ERROR', + PREG_JIT_STACKLIMIT_ERROR => 'PREG_JIT_STACKLIMIT_ERROR', + ]; + $errMsg = $errorMap[preg_last_error()] ?? 'Unknown PCRE error: '.preg_last_error(); + return new self($errMsg, \preg_last_error()); + } +} diff --git a/vendor/thecodingmachine/safe/lib/Exceptions/SafeExceptionInterface.php b/vendor/thecodingmachine/safe/lib/Exceptions/SafeExceptionInterface.php new file mode 100644 index 000000000..fbea6ad25 --- /dev/null +++ b/vendor/thecodingmachine/safe/lib/Exceptions/SafeExceptionInterface.php @@ -0,0 +1,9 @@ +<?php + + +namespace Safe\Exceptions; + +interface SafeExceptionInterface extends \Throwable +{ + +} diff --git a/vendor/thecodingmachine/safe/lib/special_cases.php b/vendor/thecodingmachine/safe/lib/special_cases.php new file mode 100644 index 000000000..d18e2118b --- /dev/null +++ b/vendor/thecodingmachine/safe/lib/special_cases.php @@ -0,0 +1,241 @@ +<?php +/** + * This file contains all the functions that could not be dealt with automatically using the code generator. + * If you add a function in this list, do not forget to add it in the generator/config/specialCasesFunctions.php + * + */ + +namespace Safe; + +use Safe\Exceptions\SocketsException; +use const PREG_NO_ERROR; +use Safe\Exceptions\ApcException; +use Safe\Exceptions\ApcuException; +use Safe\Exceptions\JsonException; +use Safe\Exceptions\OpensslException; +use Safe\Exceptions\PcreException; + +/** + * Wrapper for json_decode that throws when an error occurs. + * + * @param string $json JSON data to parse + * @param bool $assoc When true, returned objects will be converted + * into associative arrays. + * @param int $depth User specified recursion depth. + * @param int $options Bitmask of JSON decode options. + * + * @return mixed + * @throws JsonException if the JSON cannot be decoded. + * @link http://www.php.net/manual/en/function.json-decode.php + */ +function json_decode(string $json, bool $assoc = false, int $depth = 512, int $options = 0) +{ + $data = \json_decode($json, $assoc, $depth, $options); + if (JSON_ERROR_NONE !== json_last_error()) { + throw JsonException::createFromPhpError(); + } + return $data; +} + + +/** + * Fetchs a stored variable from the cache. + * + * @param mixed $key The key used to store the value (with + * apc_store). If an array is passed then each + * element is fetched and returned. + * @return mixed The stored variable or array of variables on success; FALSE on failure + * @throws ApcException + * + */ +function apc_fetch($key) +{ + error_clear_last(); + $result = \apc_fetch($key, $success); + if ($success === false) { + throw ApcException::createFromPhpError(); + } + return $result; +} + +/** + * Fetchs an entry from the cache. + * + * @param string|string[] $key The key used to store the value (with + * apcu_store). If an array is passed then each + * element is fetched and returned. + * @return mixed The stored variable or array of variables on success + * @throws ApcuException + * + */ +function apcu_fetch($key) +{ + error_clear_last(); + $result = \apcu_fetch($key, $success); + if ($success === false) { + throw ApcuException::createFromPhpError(); + } + return $result; +} + +/** + * Searches subject for matches to + * pattern and replaces them with + * replacement. + * + * @param mixed $pattern The pattern to search for. It can be either a string or an array with + * strings. + * + * Several PCRE modifiers + * are also available. + * @param mixed $replacement The string or an array with strings to replace. If this parameter is a + * string and the pattern parameter is an array, + * all patterns will be replaced by that string. If both + * pattern and replacement + * parameters are arrays, each pattern will be + * replaced by the replacement counterpart. If + * there are fewer elements in the replacement + * array than in the pattern array, any extra + * patterns will be replaced by an empty string. + * + * replacement may contain references of the form + * \\n or + * $n, with the latter form + * being the preferred one. Every such reference will be replaced by the text + * captured by the n'th parenthesized pattern. + * n can be from 0 to 99, and + * \\0 or $0 refers to the text matched + * by the whole pattern. Opening parentheses are counted from left to right + * (starting from 1) to obtain the number of the capturing subpattern. + * To use backslash in replacement, it must be doubled + * ("\\\\" PHP string). + * + * When working with a replacement pattern where a backreference is + * immediately followed by another number (i.e.: placing a literal number + * immediately after a matched pattern), you cannot use the familiar + * \\1 notation for your backreference. + * \\11, for example, would confuse + * preg_replace since it does not know whether you + * want the \\1 backreference followed by a literal + * 1, or the \\11 backreference + * followed by nothing. In this case the solution is to use + * ${1}1. This creates an isolated + * $1 backreference, leaving the 1 + * as a literal. + * + * When using the deprecated e modifier, this function escapes + * some characters (namely ', ", + * \ and NULL) in the strings that replace the + * backreferences. This is done to ensure that no syntax errors arise + * from backreference usage with either single or double quotes (e.g. + * 'strlen(\'$1\')+strlen("$2")'). Make sure you are + * aware of PHP's string + * syntax to know exactly how the interpreted string will look. + * @param string|array|string[] $subject The string or an array with strings to search and replace. + * + * If subject is an array, then the search and + * replace is performed on every entry of subject, + * and the return value is an array as well. + * @param int $limit The maximum possible replacements for each pattern in each + * subject string. Defaults to + * -1 (no limit). + * @param int $count If specified, this variable will be filled with the number of + * replacements done. + * @return string|array|string[] preg_replace returns an array if the + * subject parameter is an array, or a string + * otherwise. + * + * If matches are found, the new subject will + * be returned, otherwise subject will be + * returned unchanged. + * + * @throws PcreException + * + */ +function preg_replace($pattern, $replacement, $subject, int $limit = -1, int &$count = null) +{ + error_clear_last(); + $result = \preg_replace($pattern, $replacement, $subject, $limit, $count); + if (preg_last_error() !== PREG_NO_ERROR || $result === null) { + throw PcreException::createFromPhpError(); + } + return $result; +} + +/** + * @param resource|null $dir_handle + * @return string|false + * @deprecated + * This function is only in safe because the php documentation is wrong + */ +function readdir($dir_handle = null) +{ + if ($dir_handle !== null) { + $result = \readdir($dir_handle); + } else { + $result = \readdir(); + } + return $result; +} + +/** + * Encrypts given data with given method and key, returns a raw + * or base64 encoded string + * + * @param string $data The plaintext message data to be encrypted. + * @param string $method The cipher method. For a list of available cipher methods, use openssl_get_cipher_methods. + * @param string $key The key. + * @param int $options options is a bitwise disjunction of the flags + * OPENSSL_RAW_DATA and + * OPENSSL_ZERO_PADDING. + * @param string $iv A non-NULL Initialization Vector. + * @param string $tag The authentication tag passed by reference when using AEAD cipher mode (GCM or CCM). + * @param string $aad Additional authentication data. + * @param int $tag_length The length of the authentication tag. Its value can be between 4 and 16 for GCM mode. + * @return string Returns the encrypted string. + * @throws OpensslException + * + */ +function openssl_encrypt(string $data, string $method, string $key, int $options = 0, string $iv = "", string &$tag = "", string $aad = "", int $tag_length = 16): string +{ + error_clear_last(); + // The $tag parameter is handled in a weird way by openssl_encrypt. It cannot be provided unless encoding is AEAD + if (func_num_args() <= 5) { + $result = \openssl_encrypt($data, $method, $key, $options, $iv); + } else { + $result = \openssl_encrypt($data, $method, $key, $options, $iv, $tag, $aad, $tag_length); + } + if ($result === false) { + throw OpensslException::createFromPhpError(); + } + return $result; +} + +/** + * The function socket_write writes to the + * socket from the given + * buffer. + * + * @param resource $socket + * @param string $buffer The buffer to be written. + * @param int $length The optional parameter length can specify an + * alternate length of bytes written to the socket. If this length is + * greater than the buffer length, it is silently truncated to the length + * of the buffer. + * @return int Returns the number of bytes successfully written to the socket. + * The error code can be retrieved with + * socket_last_error. This code may be passed to + * socket_strerror to get a textual explanation of the + * error. + * @throws SocketsException + * + */ +function socket_write($socket, string $buffer, int $length = 0): int +{ + error_clear_last(); + $result = $length === 0 ? \socket_write($socket, $buffer) : \socket_write($socket, $buffer, $length); + if ($result === false) { + throw SocketsException::createFromPhpError(); + } + return $result; +} |