public function validate($target) { if (!is_string($target)) { throw new InvalidDataTypeException("Target is not a string, and cannot be validated according to string length!"); } $len = UTF8::strlen($target, $this->encoding); if ($len < $this->minLength) { throw new StringTooShortException("Length of target is too short, min = " . $this->minLength); } elseif ($len > $this->maxLength) { if (!$this->chopDown) { throw new StringTooLongException("Length of target is too long, max = " . $this->maxLength); } else { $target = UTF8::substr($target, 0, $this->maxLength, $this->encoding); } } return $target; }
/** * @param string $str payload * * @return int length of payload in bytes */ public function _determineLength($str) { return UTF8::strlen($str, '8bit'); }
/** * Helper function for BLOCKQUOTE body conversion. * * @param string $text HTML content */ protected function convertBlockquotes(&$text) { if (preg_match_all('/<\\/*blockquote[^>]*>/i', $text, $matches, PREG_OFFSET_CAPTURE)) { // init $start = 0; $taglen = 0; $level = 0; $diff = 0; // convert preg offsets from bytes to characters foreach ($matches[0] as $index => $m) { $matches[0][$index][1] = UTF8::strlen(substr($text, 0, $m[1])); } foreach ($matches[0] as $m) { if ($m[0][0] == '<' && $m[0][1] == '/') { $level--; if ($level < 0) { // malformed HTML: go to next blockquote $level = 0; } elseif ($level > 0) { // skip inner blockquote } else { $end = $m[1]; $len = $end - $taglen - $start; // get blockquote content $body = UTF8::substr($text, $start + $taglen - $diff, $len); // set text width $pWidth = $this->options['width']; if ($this->options['width'] > 0) { $this->options['width'] -= 2; } // convert blockquote content $this->converter($body); // add citation markers $body = preg_replace('/((^|\\n)>*)/', '\\1> ', UTF8::trim($body)); // create PRE block $body = '<pre>' . UTF8::htmlspecialchars($body) . '</pre>'; // re-set text width $this->options['width'] = $pWidth; // replace content $text = UTF8::substr($text, 0, $start - $diff) . $body . UTF8::substr($text, $end + UTF8::strlen($m[0]) - $diff); $diff += $len + $taglen + UTF8::strlen($m[0]) - UTF8::strlen($body); unset($body); } } else { if ($level == 0) { $start = $m[1]; $taglen = UTF8::strlen($m[0]); } $level++; } } } }
/** * Get random bytes * * @ref https://github.com/paragonie/random_compat/ * * @param int $length Output length * * @return string|false false on error */ public static function get_random_bytes($length) { if (!$length || !ctype_digit((string) $length)) { return false; } else { $length = (int) $length; } if (function_exists('random_bytes') && self::is_php('7.0')) { /** * PHP 7 -> http://php.net/manual/de/function.random-bytes.php */ try { $return = random_bytes($length); } catch (\Exception $e) { $return = false; } return $return; } else { /** * PHP 5.2.0 - 5.6.x way to implement random_bytes() * * // WARNING: Unfortunately, none of the following PRNGs is guaranteed to exist ... * * In order of preference: * 1. PHP-Module: "mcrypt" via mcrypt_create_iv() * 2. Linux / BSD: "/dev/urandom" via fread() * 3. Windows: \COM('CAPICOM.Utilities.1')->GetRandom() * 4. PHP+OpenSSL: openssl_random_pseudo_bytes() */ /** * 1. PHP-Module */ if (extension_loaded('mcrypt') && defined(MCRYPT_DEV_URANDOM) === true) { $output = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM); if ($output !== false && UTF8::strlen($output, '8bit') === $length) { return $output; } } /** * 2. Linux / BSD */ if (!ini_get('open_basedir') && is_readable('/dev/urandom')) { $fp = fopen('/dev/urandom', 'rb'); if (!empty($fp)) { $st = fstat($fp); // In C, this would be: (stat_mode & S_IFMT) !== S_IFCHR if (($st['mode'] & 0170000) !== 020000) { fclose($fp); $fp = false; } unset($st); } } if (isset($fp) && $fp !== false) { /** * stream_set_read_buffer() / stream_set_chunk_size does not exist in HHVM * * If we don't set the stream's read buffer to 0, PHP will * internally buffer 8192 bytes, which can waste entropy * * stream_set_read_buffer returns 0 on success */ if (function_exists('stream_set_chunk_size')) { stream_set_chunk_size($fp, $length); } if (function_exists('stream_set_read_buffer')) { stream_set_read_buffer($fp, $length); } $remaining = $length; $buf = ''; do { $read = fread($fp, $remaining); // We cannot safely read from the file, so exit the do-while loop. if ($read === false) { $buf = false; break; } // Decrease the number of bytes returned from remaining. $remaining -= UTF8::strlen($read, '8bit'); $buf .= $read; } while ($remaining > 0); fclose($fp); if ($buf !== false) { if (UTF8::strlen($buf, '8bit') === $length) { return $buf; } } } /* * 3. Windows * * PHP can be used to access COM objects on Windows platforms * * --- * * PROBLEM: you see this error-message: * com_exception thrown with message * "Failed to create COM object `CAPICOM.Utilities.1': Ungültige Syntax * * SOLUTION: register the dll: * regsvr32 c:\windows\capicom.dll * * --- * * @ref http://php.net/manual/en/ref.com.php */ if (extension_loaded('com_dotnet') && class_exists('COM') === true) { // init $buf = ''; /** @noinspection PhpUndefinedClassInspection */ $util = new \COM('CAPICOM.Utilities.1'); /** * Let's not let it loop forever. If we run N times and fail to * get N bytes of random data, then CAPICOM has failed us. */ $execCount = 0; do { /** @noinspection PhpUndefinedMethodInspection */ $buf .= base64_decode($util->GetRandom($length, 0)); if (UTF8::strlen($buf, '8bit') >= $length) { return UTF8::substr($buf, 0, $length); } ++$execCount; } while ($execCount < $length); } /** * 4. PHP + OpenSSL * * fallback to "openssl_random_pseudo_bytes()" */ if (function_exists('openssl_random_pseudo_bytes')) { $output = openssl_random_pseudo_bytes($length, $strong); if ($output !== false && $strong === true) { if (UTF8::strlen($output, '8bit') === $length) { return $output; } } } return false; } }
/** * @param mixed $variable * @param KintVariableData $variableData */ private static function _parse_string(&$variable, KintVariableData $variableData) { $variableData->type = 'string'; $encoding = self::_detectEncoding($variable); if ($encoding) { $variableData->type .= ' [' . $encoding . ']'; } $variableData->size = UTF8::strlen($variable); if (Kint::enabled() !== Kint::MODE_RICH) { $variableData->value = '"' . self::escape($variable, $encoding) . '"'; return; } if (!self::$_placeFullStringInValue) { $strippedString = preg_replace('[\\s+]', ' ', $variable); if (Kint::$maxStrLength && $variableData->size > Kint::$maxStrLength) { $tmpStrippedString = self::_substr($strippedString, 0, Kint::$maxStrLength, $encoding); // encode and truncate $variableData->value = '"' . self::escape($tmpStrippedString, $encoding) . '…"'; $variableData->extendedValue = self::escape($variable, $encoding); return; } elseif ($variable !== $strippedString) { // omit no data from display $variableData->value = '"' . self::escape($variable, $encoding) . '"'; $variableData->extendedValue = self::escape($variable, $encoding); return; } } $variableData->value = '"' . self::escape($variable, $encoding) . '"'; }
function minMaxLength($minLength, $maxLength) { return $this->ifOk(function ($x) use($minLength, $maxLength) { if (UTF8::strlen($x) > $maxLength) { return Result::error('The input is too long. Maximum is ' . $maxLength . ' characters.'); } elseif (UTF8::strlen($x) < $minLength) { return Result::error('The input is too short. Minimum is ' . $minLength . ' characters.'); } else { return Result::ok($x); } }); }
/** * Gets the substring after the last occurrence of a separator. * If no match is found returns new empty Stringy object. * * @param string $separator * * @return Stringy */ public function afterLast($separator) { $offset = $this->indexOfLast($separator); if ($offset === false) { return static::create('', $this->encoding); } return static::create(UTF8::substr($this->str, $offset + UTF8::strlen($separator, $this->encoding), null, $this->encoding), $this->encoding); }
/** * Return the index of begin/end delimiters. * * @param string $begin befin delimiter * @param string $end end delimiter * * @return integer position index */ protected function getDelimitersIndex($begin, $end) { $string = $this->input; $nbegin = 0; $nend = 0; $position = 0; $sbrac = false; $dbrac = false; for ($i = 0, $length = UTF8::strlen($string); $i < $length; ++$i) { if ('"' === $string[$i]) { $dbrac = !$dbrac; } elseif ('\'' === $string[$i]) { $sbrac = !$sbrac; } if (!$sbrac && !$dbrac && $begin === $string[$i]) { ++$nbegin; } elseif (!$sbrac && !$dbrac && $end === $string[$i]) { if (++$nend === $nbegin) { $position = $i; break; } } } return $position; }
})->ifOk(function ($output) { return json_encode(['data' => $output]); }); }); # Generate a CSV file for a TableView # See http://stackoverflow.com/questions/217424/create-a-csv-file-for-a-user-in-php $klein->respond('GET', '/csv', function ($req, $res) use($parser, $stringifier) { $res->header('X-Frame-Options', 'DENY'); $page = $parser->parseJade($_GET['form']); $view = new CSVView($page->getView($_GET['view'])); header("Content-type: text/csv; charset=utf-8"); header("Content-Disposition: attachment; filename=formulaic-" . time() . ".csv"); ob_start(); $view->makeView($view->query(1))->render()->save('php://output'); $result = ob_get_clean(); return $result; }); # Get the details of a particular table entry. $klein->respond('GET', '/details', function ($req, $res) use($parser, $stringifier) { $page = $parser->parseJade($_GET['form']); $view = new DetailsView(); $view->setPage($page); $stringifier->writeResponse(new PageWrapper($view->makeView($view->query($_GET))), $res); }); # See https://github.com/chriso/klein.php/wiki/Sub-Directory-Installation $config = Config::get(); $request = \Klein\Request::createFromGlobals(); $uri = $request->server()->get('REQUEST_URI'); $request->server()->set('REQUEST_URI', UTF8::substr($uri, UTF8::strlen($config['app-path']))); # Route! $klein->dispatch($request);
/** * Chops down a string according to given max length, all characters beyond $maxLength is removed. * * This function is UTF8 compatible * * @param $str * @param $maxLength * @param bool $lengthUnitInByte * * @return string * */ public static function stringChopdown($str, $maxLength, $lengthUnitInByte = false) { if ($lengthUnitInByte) { return substr($str, 0, $maxLength); } $str = UTF8::to_utf8($str); $len = UTF8::strlen($str); if ($len <= $maxLength) { return $str; } return UTF8::substr($str, 0, $maxLength); }
function getForm($name) { if (is_string($name) && !preg_match('/[^A-za-z0-9_-]/', $name) && UTF8::strlen($name) > 0) { return 'forms/' . $name . '.jade'; } else { throw new Exception('Invalid form name!'); } }
/** * Return first and last position of text * * @param string The parent text of the text to be formatted * @param string The text to be formatted * @return string */ protected function getTextPosition($context, $text) { $pos = UTF8::strpos($context, $text); return [$pos, $pos + UTF8::strlen($text)]; }