shell bypass 403
<?php declare(strict_types=1); namespace BenMorel\GsmCharsetConverter; /** * Converts GSM 03.38 strings to and from UTF-8. */ class Converter { /** * @var array */ private $utf8ToGsm; /** * @var array */ private $utf8ToGsmWithTranslit; /** * Converter constructor. */ public function __construct() { // Flip the GSM to UTF-8 dictionary to create the UTF-8 to GSM dictionary; // Convert all values to strings as the array keys for digits are converted to int by PHP. $this->utf8ToGsm = array_map(static function($value) { return (string) $value; }, array_flip(Charset::GSM_TO_UTF8)); // Create the base dictionary + transliteration $this->utf8ToGsmWithTranslit = $this->utf8ToGsm; foreach (Charset::TRANSLITERATE as $from => $to) { // Transliterate character by character, as the output string may contain several chars $to = $this->splitUtf8String($to); $to = array_map(function(string $char) : string { return $this->utf8ToGsm[$char]; }, $to); $this->utf8ToGsmWithTranslit[$from] = implode('', $to); } } /** * Converts a GSM 03.38 string to UTF-8. * * The input string must be a valid, unpacked 7-bit GSM charset string: the leading bit must be zero in every byte. * * @param string $string The GSM charset string to convert. If the string is not a valid GSM charset string, * an exception is thrown. * * @return string * * @throws \InvalidArgumentException If an error occurs. */ public function convertGsmToUtf8(string $string) : string { $result = ''; $length = strlen($string); $dictionary = Charset::GSM_TO_UTF8; for ($i = 0; $i < $length; $i++) { $char = $string[$i]; if ($char === "\x1B") { if ($i + 1 === $length) { throw new \InvalidArgumentException( 'The input string is not valid GSM 03.38: ' . 'it contains an ESC char at the end of the string.' ); } $char .= $string[++$i]; } if (! isset($dictionary[$char])) { throw new \InvalidArgumentException( 'The input string is not valid GSM 03.38: ' . 'char ' . strtoupper(bin2hex($char)) . ' is unknown.' ); } $result .= $dictionary[$char]; } return $result; } /** * Converts a UTF-8 string to GSM 03.38. * * The output is an unpacked 7-bit GSM charset string: the leading bit is zero in every byte. * * @param string $string The UTF-8 string to convert. If the string is not valid UTF-8, an exception * is thrown. * @param bool $translit Whether to transliterate, i.e. replace incompatible characters with similar, * compatible characters when possible. * @param string|null $replaceChars Zero or more UTF-8 characters to replace unknown chars with. You can typically * use an empty string, a blank space or a question mark. The string must only * contain characters compatible with the GSM charset, or an exception is thrown. * If this parameter is omitted or null, and the string to convert contains any * character that cannot be replaced, an exception is thrown. * * @return string * * @throws \InvalidArgumentException If an error occurs. */ public function convertUtf8ToGsm(string $string, bool $translit, ?string $replaceChars = null) : string { $dictionary = $translit ? $this->utf8ToGsmWithTranslit : $this->utf8ToGsm; // Convert the replacement string to GSM 03.38 if ($replaceChars !== null) { $chars = $this->splitUtf8String($replaceChars); $replaceChars = ''; foreach ($chars as $char) { if (! isset($this->utf8ToGsm[$char])) { throw new \InvalidArgumentException( 'Replacement string must contain only GSM 03.38 compatible chars.' ); } $replaceChars .= $this->utf8ToGsm[$char]; } } $result = ''; $chars = $this->splitUtf8String($string); foreach ($chars as $char) { if (isset($dictionary[$char])) { $result .= $dictionary[$char]; } elseif ($replaceChars !== null) { $result .= $replaceChars; } else { throw new \InvalidArgumentException( 'UTF-8 character ' . strtoupper(bin2hex($char)) . ' cannot be converted, ' . 'and no replacement string has been provided.' ); } } return $result; } /** * Cleans up the given UTF-8 string, to make it contain only chars compatible with the GSM 03.38 charset. * * This is useful if your SMS gateway accepts UTF-8, but provides no way to force the GSM charset, and you want to * avoid the extra charge of getting your SMS sent as UCS-2 and split into several parts. * * This is just a convenience method for convertUtf8ToGsm() -> convertGsmToUtf8(). * * @param string $string The UTF-8 string to convert. If the string is not valid UTF-8, an exception * is thrown. * @param bool $translit Whether to transliterate, i.e. replace incompatible characters with similar, * compatible characters when possible. * @param string|null $replaceChars Zero or more UTF-8 characters to replace unknown chars with. You can typically * use an empty string, a blank space or a question mark. The string must only * contain characters compatible with the GSM charset, or an exception is thrown. * If this parameter is omitted or null, and the string to convert contains any * character that cannot be replaced, an exception is thrown. * * @return string * * @throws \InvalidArgumentException If an error occurs. */ public function cleanUpUtf8String(string $string, bool $translit, ?string $replaceChars = null) : string { return $this->convertGsmToUtf8( $this->convertUtf8ToGsm($string, $translit, $replaceChars) ); } /** * @param string $string * * @return array * * @throws \InvalidArgumentException */ private function splitUtf8String(string $string) : array { if (! mb_check_encoding($string, 'UTF-8')) { throw new \InvalidArgumentException('The input string is not valid UTF-8.'); } return preg_split('//u', $string, -1, PREG_SPLIT_NO_EMPTY); } }