Update Composer, update everything

This commit is contained in:
Oliver Davies 2018-11-23 12:29:20 +00:00
parent ea3e94409f
commit dda5c284b6
19527 changed files with 1135420 additions and 351004 deletions

View file

@ -23,7 +23,7 @@ class Color {
// Hash prefix is optional.
$hex = ltrim($hex, '#');
// Must be either RGB or RRGGBB.
$length = Unicode::strlen($hex);
$length = mb_strlen($hex);
$valid = $valid && ($length === 3 || $length === 6);
// Must be a valid hex value.
$valid = $valid && ctype_xdigit($hex);
@ -94,4 +94,28 @@ class Color {
return '#' . str_pad(dechex($out), 6, 0, STR_PAD_LEFT);
}
/**
* Normalize the hex color length to 6 characters for comparison.
*
* @param string $hex
* The hex color to normalize.
*
* @return string
* The 6 character hex color.
*/
public static function normalizeHexLength($hex) {
// Ignore '#' prefixes.
$hex = ltrim($hex, '#');
if (strlen($hex) === 3) {
$hex[5] = $hex[2];
$hex[4] = $hex[2];
$hex[3] = $hex[1];
$hex[2] = $hex[1];
$hex[1] = $hex[0];
}
return '#' . $hex;
}
}

View file

@ -71,7 +71,7 @@ class Html {
public static function getClass($class) {
$class = (string) $class;
if (!isset(static::$classes[$class])) {
static::$classes[$class] = static::cleanCssIdentifier(Unicode::strtolower($class));
static::$classes[$class] = static::cleanCssIdentifier(mb_strtolower($class));
}
return static::$classes[$class];
}
@ -79,9 +79,10 @@ class Html {
/**
* Prepares a string for use as a CSS identifier (element, class, or ID name).
*
* http://www.w3.org/TR/CSS21/syndata.html#characters shows the syntax for
* valid CSS identifiers (including element names, classes, and IDs in
* selectors.)
* Link below shows the syntax for valid CSS identifiers (including element
* names, classes, and IDs in selectors).
*
* @see http://www.w3.org/TR/CSS21/syndata.html#characters
*
* @param string $identifier
* The identifier to clean.
@ -124,7 +125,7 @@ class Html {
// Identifiers cannot start with a digit, two hyphens, or a hyphen followed by a digit.
$identifier = preg_replace([
'/^[0-9]/',
'/^(-[0-9])|^(--)/'
'/^(-[0-9])|^(--)/',
], ['_', '__'], $identifier);
return $identifier;
}
@ -215,7 +216,7 @@ class Html {
* @see self::getUniqueId()
*/
public static function getId($id) {
$id = str_replace([' ', '_', '[', ']'], ['-', '-', '-', ''], Unicode::strtolower($id));
$id = str_replace([' ', '_', '[', ']'], ['-', '-', '-', ''], mb_strtolower($id));
// As defined in http://www.w3.org/TR/html4/types.html#type-name, HTML IDs can
// only contain letters, digits ([0-9]), hyphens ("-"), underscores ("_"),
@ -451,9 +452,9 @@ EOD;
* The updated (X)HTML snippet.
*/
public static function transformRootRelativeUrlsToAbsolute($html, $scheme_and_host) {
assert('empty(array_diff(array_keys(parse_url($scheme_and_host)), ["scheme", "host", "port"]))', '$scheme_and_host contains scheme, host and port at most.');
assert('isset(parse_url($scheme_and_host)["scheme"])', '$scheme_and_host is absolute and hence has a scheme.');
assert('isset(parse_url($scheme_and_host)["host"])', '$base_url is absolute and hence has a host.');
assert(empty(array_diff(array_keys(parse_url($scheme_and_host)), ["scheme", "host", "port"])), '$scheme_and_host contains scheme, host and port at most.');
assert(isset(parse_url($scheme_and_host)["scheme"]), '$scheme_and_host is absolute and hence has a scheme.');
assert(isset(parse_url($scheme_and_host)["host"]), '$base_url is absolute and hence has a host.');
$html_dom = Html::load($html);
$xpath = new \DOMXpath($html_dom);

View file

@ -69,7 +69,7 @@ class NestedArray {
public static function &getValue(array &$array, array $parents, &$key_exists = NULL) {
$ref = &$array;
foreach ($parents as $parent) {
if (is_array($ref) && array_key_exists($parent, $ref)) {
if (is_array($ref) && (isset($ref[$parent]) || array_key_exists($parent, $ref))) {
$ref = &$ref[$parent];
}
else {
@ -219,7 +219,7 @@ class NestedArray {
public static function unsetValue(array &$array, array $parents, &$key_existed = NULL) {
$unset_key = array_pop($parents);
$ref = &self::getValue($array, $parents, $key_existed);
if ($key_existed && is_array($ref) && array_key_exists($unset_key, $ref)) {
if ($key_existed && is_array($ref) && (isset($ref[$unset_key]) || array_key_exists($unset_key, $ref))) {
$key_existed = TRUE;
unset($ref[$unset_key]);
}
@ -328,7 +328,7 @@ class NestedArray {
// Renumber integer keys as array_merge_recursive() does unless
// $preserve_integer_keys is set to TRUE. Note that PHP automatically
// converts array keys that are integer strings (e.g., '1') to integers.
if (is_integer($key) && !$preserve_integer_keys) {
if (is_int($key) && !$preserve_integer_keys) {
$result[] = $value;
}
// Recurse when both values are arrays.

View file

@ -50,7 +50,7 @@ class Number {
// can't be represented with single precision floats are acceptable. The
// fractional part of a float has 24 bits. That means remainders smaller than
// $step * 2^-24 are acceptable.
$computed_acceptable_error = (double)($step / pow(2.0, 24));
$computed_acceptable_error = (double) ($step / pow(2.0, 24));
return $computed_acceptable_error >= $remainder || $remainder >= ($step - $computed_acceptable_error);
}

View file

@ -143,7 +143,9 @@ class Random {
$vowels = ["a", "e", "i", "o", "u"];
$cons = ["b", "c", "d", "g", "h", "j", "k", "l", "m", "n", "p", "r", "s", "t", "u", "v", "w", "tr",
"cr", "br", "fr", "th", "dr", "ch", "ph", "wr", "st", "sp", "sw", "pr", "sl", "cl", "sh"];
"cr", "br", "fr", "th", "dr", "ch", "ph", "wr", "st", "sp", "sw", "pr",
"sl", "cl", "sh",
];
$num_vowels = count($vowels);
$num_cons = count($cons);
@ -219,7 +221,8 @@ class Random {
"utrum", "uxor", "valde", "valetudo", "validus", "vel", "velit",
"veniam", "venio", "vereor", "vero", "verto", "vicis", "vindico",
"virtus", "voco", "volutpat", "vulpes", "vulputate", "wisi", "ymo",
"zelus"];
"zelus",
];
$dictionary_flipped = array_flip($dictionary);
$greeking = '';
@ -256,7 +259,6 @@ class Random {
return $output;
}
/**
* Create a placeholder image.
*

View file

@ -13,6 +13,8 @@ use Drupal\Component\Render\MarkupInterface;
* @link sanitization sanitization functions @endlink or the @link theme_render theme and render systems @endlink
* so that the output can can be themed, escaped, and altered properly.
*
* @see https://www.drupal.org/node/2549395
*
* @see TwigExtension::escapeFilter()
* @see twig_render_template()
* @see sanitization
@ -34,8 +36,11 @@ class SafeMarkup {
* @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0.
* Instead, you should just check if a variable is an instance of
* \Drupal\Component\Render\MarkupInterface.
*
* @see https://www.drupal.org/node/2549395
*/
public static function isSafe($string, $strategy = 'html') {
@trigger_error('SafeMarkup::isSafe() is scheduled for removal in Drupal 9.0.0. Instead, you should just check if a variable is an instance of \Drupal\Component\Render\MarkupInterface. See https://www.drupal.org/node/2549395.', E_USER_DEPRECATED);
return $string instanceof MarkupInterface;
}
@ -58,9 +63,11 @@ class SafeMarkup {
* possible, \Drupal\Component\Utility\Html::escape() can be used in places
* where explicit escaping is needed.
*
* @see https://www.drupal.org/node/2549395
* @see drupal_validate_utf8()
*/
public static function checkPlain($text) {
@trigger_error('SafeMarkup::checkPlain() is scheduled for removal in Drupal 9.0.0. Rely on Twig\'s auto-escaping feature, or use the @link theme_render #plain_text @endlink key when constructing a render array that contains plain text in order to use the renderer\'s auto-escaping feature. If neither of these are possible, \Drupal\Component\Utility\Html::escape() can be used in places where explicit escaping is needed. See https://www.drupal.org/node/2549395.', E_USER_DEPRECATED);
return new HtmlEscapedText($text);
}
@ -84,8 +91,11 @@ class SafeMarkup {
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
* Use \Drupal\Component\Render\FormattableMarkup.
*
* @see https://www.drupal.org/node/2549395
*/
public static function format($string, array $args) {
@trigger_error('SafeMarkup::format() is scheduled for removal in Drupal 9.0.0. Use \Drupal\Component\Render\FormattableMarkup. See https://www.drupal.org/node/2549395.', E_USER_DEPRECATED);
return new FormattableMarkup($string, $args);
}

View file

@ -20,7 +20,7 @@ class Timer {
* @param $name
* The name of the timer.
*/
static public function start($name) {
public static function start($name) {
static::$timers[$name]['start'] = microtime(TRUE);
static::$timers[$name]['count'] = isset(static::$timers[$name]['count']) ? ++static::$timers[$name]['count'] : 1;
}
@ -34,7 +34,7 @@ class Timer {
* @return int
* The current timer value in ms.
*/
static public function read($name) {
public static function read($name) {
if (isset(static::$timers[$name]['start'])) {
$stop = microtime(TRUE);
$diff = round(($stop - static::$timers[$name]['start']) * 1000, 2);
@ -57,7 +57,7 @@ class Timer {
* A timer array. The array contains the number of times the timer has been
* started and stopped (count) and the accumulated timer value in ms (time).
*/
static public function stop($name) {
public static function stop($name) {
if (isset(static::$timers[$name]['start'])) {
$stop = microtime(TRUE);
$diff = round(($stop - static::$timers[$name]['start']) * 1000, 2);

View file

@ -87,13 +87,6 @@ EOD;
*/
const STATUS_ERROR = -1;
/**
* Holds the multibyte capabilities of the current environment.
*
* @var int
*/
protected static $status = 0;
/**
* Gets the current status of unicode/multibyte support on this environment.
*
@ -107,7 +100,13 @@ EOD;
* An error occurred. No unicode support.
*/
public static function getStatus() {
return static::$status;
switch (static::check()) {
case 'mb_strlen':
return Unicode::STATUS_SINGLEBYTE;
case '':
return Unicode::STATUS_MULTIBYTE;
}
return Unicode::STATUS_ERROR;
}
/**
@ -123,12 +122,16 @@ EOD;
*
* @param int $status
* The new status of multibyte support.
*
* @deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. In
* Drupal 9 there will be no way to set the status and in Drupal 8 this
* ability has been removed because mb_*() functions are supplied using
* Symfony's polyfill.
*
* @see https://www.drupal.org/node/2850048
*/
public static function setStatus($status) {
if (!in_array($status, [static::STATUS_SINGLEBYTE, static::STATUS_MULTIBYTE, static::STATUS_ERROR])) {
throw new \InvalidArgumentException('Invalid status value for unicode support.');
}
static::$status = $status;
@trigger_error('\Drupal\Component\Utility\Unicode::setStatus() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. In Drupal 9 there will be no way to set the status and in Drupal 8 this ability has been removed because mb_*() functions are supplied using Symfony\'s polyfill. See https://www.drupal.org/node/2850048.', E_USER_DEPRECATED);
}
/**
@ -143,38 +146,33 @@ EOD;
* Otherwise, an empty string.
*/
public static function check() {
// Set appropriate configuration.
mb_internal_encoding('utf-8');
mb_language('uni');
// Check for mbstring extension.
if (!function_exists('mb_strlen')) {
static::$status = static::STATUS_SINGLEBYTE;
if (!extension_loaded('mbstring')) {
return 'mb_strlen';
}
// Check mbstring configuration.
if (ini_get('mbstring.func_overload') != 0) {
static::$status = static::STATUS_ERROR;
return 'mbstring.func_overload';
}
if (ini_get('mbstring.encoding_translation') != 0) {
static::$status = static::STATUS_ERROR;
return 'mbstring.encoding_translation';
}
// mbstring.http_input and mbstring.http_output are deprecated and empty by
// default in PHP 5.6.
if (version_compare(PHP_VERSION, '5.6.0') == -1) {
if (ini_get('mbstring.http_input') != 'pass') {
static::$status = static::STATUS_ERROR;
return 'mbstring.http_input';
}
if (ini_get('mbstring.http_output') != 'pass') {
static::$status = static::STATUS_ERROR;
return 'mbstring.http_output';
}
}
// Set appropriate configuration.
mb_internal_encoding('utf-8');
mb_language('uni');
static::$status = static::STATUS_MULTIBYTE;
return '';
}
@ -224,17 +222,7 @@ EOD;
* Converted data or FALSE.
*/
public static function convertToUtf8($data, $encoding) {
if (function_exists('iconv')) {
return @iconv($encoding, 'utf-8', $data);
}
elseif (function_exists('mb_convert_encoding')) {
return @mb_convert_encoding($data, 'utf-8', $encoding);
}
elseif (function_exists('recode_string')) {
return @recode_string($encoding . '..utf-8', $data);
}
// Cannot convert.
return FALSE;
return @iconv($encoding, 'utf-8', $data);
}
/**
@ -264,7 +252,9 @@ EOD;
return substr($string, 0, $len);
}
// Scan backwards to beginning of the byte sequence.
while (--$len >= 0 && ord($string[$len]) >= 0x80 && ord($string[$len]) < 0xC0);
// @todo Make the code more readable in https://www.drupal.org/node/2911497.
while (--$len >= 0 && ord($string[$len]) >= 0x80 && ord($string[$len]) < 0xC0) {
}
return substr($string, 0, $len);
}
@ -279,15 +269,15 @@ EOD;
*
* @return int
* The length of the string.
*
* @deprecated in Drupal 8.6.0, will be removed before Drupal 9.0.0. Use
* mb_strlen() instead.
*
* @see https://www.drupal.org/node/2850048
*/
public static function strlen($text) {
if (static::getStatus() == static::STATUS_MULTIBYTE) {
return mb_strlen($text);
}
else {
// Do not count UTF-8 continuation bytes.
return strlen(preg_replace("/[\x80-\xBF]/", '', $text));
}
@trigger_error('\Drupal\Component\Utility\Unicode::strlen() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_strlen() instead. See https://www.drupal.org/node/2850048.', E_USER_DEPRECATED);
return mb_strlen($text);
}
/**
@ -298,18 +288,15 @@ EOD;
*
* @return string
* The string in uppercase.
*
* @deprecated in Drupal 8.6.0, will be removed before Drupal 9.0.0. Use
* mb_strtoupper() instead.
*
* @see https://www.drupal.org/node/2850048
*/
public static function strtoupper($text) {
if (static::getStatus() == static::STATUS_MULTIBYTE) {
return mb_strtoupper($text);
}
else {
// Use C-locale for ASCII-only uppercase.
$text = strtoupper($text);
// Case flip Latin-1 accented letters.
$text = preg_replace_callback('/\xC3[\xA0-\xB6\xB8-\xBE]/', '\Drupal\Component\Utility\Unicode::caseFlip', $text);
return $text;
}
@trigger_error('\Drupal\Component\Utility\Unicode::strtoupper() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_strtoupper() instead. See https://www.drupal.org/node/2850048.', E_USER_DEPRECATED);
return mb_strtoupper($text);
}
/**
@ -320,18 +307,15 @@ EOD;
*
* @return string
* The string in lowercase.
*
* @deprecated in Drupal 8.6.0, will be removed before Drupal 9.0.0. Use
* mb_strtolower() instead.
*
* @see https://www.drupal.org/node/2850048
*/
public static function strtolower($text) {
if (static::getStatus() == static::STATUS_MULTIBYTE) {
return mb_strtolower($text);
}
else {
// Use C-locale for ASCII-only lowercase.
$text = strtolower($text);
// Case flip Latin-1 accented letters.
$text = preg_replace_callback('/\xC3[\x80-\x96\x98-\x9E]/', '\Drupal\Component\Utility\Unicode::caseFlip', $text);
return $text;
}
@trigger_error('\Drupal\Component\Utility\Unicode::strtolower() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_strtolower() instead. See https://www.drupal.org/node/2850048.', E_USER_DEPRECATED);
return mb_strtolower($text);
}
/**
@ -344,7 +328,7 @@ EOD;
* The string with the first character as uppercase.
*/
public static function ucfirst($text) {
return static::strtoupper(static::substr($text, 0, 1)) . static::substr($text, 1);
return mb_strtoupper(mb_substr($text, 0, 1)) . mb_substr($text, 1);
}
/**
@ -360,7 +344,7 @@ EOD;
*/
public static function lcfirst($text) {
// Note: no mbstring equivalent!
return static::strtolower(static::substr($text, 0, 1)) . static::substr($text, 1);
return mb_strtolower(mb_substr($text, 0, 1)) . mb_substr($text, 1);
}
/**
@ -376,8 +360,8 @@ EOD;
*/
public static function ucwords($text) {
$regex = '/(^|[' . static::PREG_CLASS_WORD_BOUNDARY . '])([^' . static::PREG_CLASS_WORD_BOUNDARY . '])/u';
return preg_replace_callback($regex, function(array $matches) {
return $matches[1] . Unicode::strtoupper($matches[2]);
return preg_replace_callback($regex, function (array $matches) {
return $matches[1] . mb_strtoupper($matches[2]);
}, $text);
}
@ -397,92 +381,15 @@ EOD;
*
* @return string
* The shortened string.
*
* @deprecated in Drupal 8.6.0, will be removed before Drupal 9.0.0. Use
* mb_substr() instead.
*
* @see https://www.drupal.org/node/2850048
*/
public static function substr($text, $start, $length = NULL) {
if (static::getStatus() == static::STATUS_MULTIBYTE) {
return $length === NULL ? mb_substr($text, $start) : mb_substr($text, $start, $length);
}
else {
$strlen = strlen($text);
// Find the starting byte offset.
$bytes = 0;
if ($start > 0) {
// Count all the characters except continuation bytes from the start
// until we have found $start characters or the end of the string.
$bytes = -1; $chars = -1;
while ($bytes < $strlen - 1 && $chars < $start) {
$bytes++;
$c = ord($text[$bytes]);
if ($c < 0x80 || $c >= 0xC0) {
$chars++;
}
}
}
elseif ($start < 0) {
// Count all the characters except continuation bytes from the end
// until we have found abs($start) characters.
$start = abs($start);
$bytes = $strlen; $chars = 0;
while ($bytes > 0 && $chars < $start) {
$bytes--;
$c = ord($text[$bytes]);
if ($c < 0x80 || $c >= 0xC0) {
$chars++;
}
}
}
$istart = $bytes;
// Find the ending byte offset.
if ($length === NULL) {
$iend = $strlen;
}
elseif ($length > 0) {
// Count all the characters except continuation bytes from the starting
// index until we have found $length characters or reached the end of
// the string, then backtrace one byte.
$iend = $istart - 1;
$chars = -1;
$last_real = FALSE;
while ($iend < $strlen - 1 && $chars < $length) {
$iend++;
$c = ord($text[$iend]);
$last_real = FALSE;
if ($c < 0x80 || $c >= 0xC0) {
$chars++;
$last_real = TRUE;
}
}
// Backtrace one byte if the last character we found was a real
// character and we don't need it.
if ($last_real && $chars >= $length) {
$iend--;
}
}
elseif ($length < 0) {
// Count all the characters except continuation bytes from the end
// until we have found abs($start) characters, then backtrace one byte.
$length = abs($length);
$iend = $strlen; $chars = 0;
while ($iend > 0 && $chars < $length) {
$iend--;
$c = ord($text[$iend]);
if ($c < 0x80 || $c >= 0xC0) {
$chars++;
}
}
// Backtrace one byte if we are not at the beginning of the string.
if ($iend > 0) {
$iend--;
}
}
else {
// $length == 0, return an empty string.
return '';
}
return substr($text, $istart, max(0, $iend - $istart + 1));
}
@trigger_error('\Drupal\Component\Utility\Unicode::substr() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_substr() instead. See https://www.drupal.org/node/2850048.', E_USER_DEPRECATED);
return mb_substr($text, $start, $length);
}
/**
@ -524,15 +431,15 @@ EOD;
$max_length = max($max_length, 0);
$min_wordsafe_length = max($min_wordsafe_length, 0);
if (static::strlen($string) <= $max_length) {
if (mb_strlen($string) <= $max_length) {
// No truncation needed, so don't add ellipsis, just return.
return $string;
}
if ($add_ellipsis) {
// Truncate ellipsis in case $max_length is small.
$ellipsis = static::substr('…', 0, $max_length);
$max_length -= static::strlen($ellipsis);
$ellipsis = mb_substr('…', 0, $max_length);
$max_length -= mb_strlen($ellipsis);
$max_length = max($max_length, 0);
}
@ -546,16 +453,16 @@ EOD;
// Find the last word boundary, if there is one within $min_wordsafe_length
// to $max_length characters. preg_match() is always greedy, so it will
// find the longest string possible.
$found = preg_match('/^(.{' . $min_wordsafe_length . ',' . $max_length . '})[' . Unicode::PREG_CLASS_WORD_BOUNDARY . ']/u', $string, $matches);
$found = preg_match('/^(.{' . $min_wordsafe_length . ',' . $max_length . '})[' . Unicode::PREG_CLASS_WORD_BOUNDARY . ']/us', $string, $matches);
if ($found) {
$string = $matches[1];
}
else {
$string = static::substr($string, 0, $max_length);
$string = mb_substr($string, 0, $max_length);
}
}
else {
$string = static::substr($string, 0, $max_length);
$string = mb_substr($string, 0, $max_length);
}
if ($add_ellipsis) {
@ -580,8 +487,8 @@ EOD;
* Returns < 0 if $str1 is less than $str2; > 0 if $str1 is greater than
* $str2, and 0 if they are equal.
*/
public static function strcasecmp($str1 , $str2) {
return strcmp(static::strtoupper($str1), static::strtoupper($str2));
public static function strcasecmp($str1, $str2) {
return strcmp(mb_strtoupper($str1), mb_strtoupper($str2));
}
/**
@ -601,18 +508,24 @@ EOD;
*
* @param string $string
* The header to encode.
* @param bool $shorten
* If TRUE, only return the first chunk of a multi-chunk encoded string.
*
* @return string
* The mime-encoded header.
*/
public static function mimeHeaderEncode($string) {
public static function mimeHeaderEncode($string, $shorten = FALSE) {
if (preg_match('/[^\x20-\x7E]/', $string)) {
$chunk_size = 47; // floor((75 - strlen("=?UTF-8?B??=")) * 0.75);
// floor((75 - strlen("=?UTF-8?B??=")) * 0.75);
$chunk_size = 47;
$len = strlen($string);
$output = '';
while ($len > 0) {
$chunk = static::truncateBytes($string, $chunk_size);
$output .= ' =?UTF-8?B?' . base64_encode($chunk) . "?=\n";
if ($shorten) {
break;
}
$c = strlen($chunk);
$string = substr($string, $c);
$len -= $c;
@ -707,18 +620,15 @@ EOD;
* The position where $needle occurs in $haystack, always relative to the
* beginning (independent of $offset), or FALSE if not found. Note that
* a return value of 0 is not the same as FALSE.
*
* @deprecated in Drupal 8.6.0, will be removed before Drupal 9.0.0. Use
* mb_strpos() instead.
*
* @see https://www.drupal.org/node/2850048
*/
public static function strpos($haystack, $needle, $offset = 0) {
if (static::getStatus() == static::STATUS_MULTIBYTE) {
return mb_strpos($haystack, $needle, $offset);
}
else {
// Remove Unicode continuation characters, to be compatible with
// Unicode::strlen() and Unicode::substr().
$haystack = preg_replace("/[\x80-\xBF]/", '', $haystack);
$needle = preg_replace("/[\x80-\xBF]/", '', $needle);
return strpos($haystack, $needle, $offset);
}
@trigger_error('\Drupal\Component\Utility\Unicode::strpos() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_strpos() instead. See https://www.drupal.org/node/2850048.', E_USER_DEPRECATED);
return mb_strpos($haystack, $needle, $offset);
}
}

View file

@ -19,7 +19,7 @@ class UrlHelper {
/**
* Parses an array into a valid, rawurlencoded query string.
*
* rawurlencode() is RFC3986 compliant, and as a consequence RFC3987
* Function rawurlencode() is RFC3986 compliant, and as a consequence RFC3987
* compliant. The latter defines the required format of "URLs" in HTML5.
* urlencode() is almost the same as rawurlencode(), except that it encodes
* spaces as "+" instead of "%20". This makes its result non compliant to
@ -148,6 +148,11 @@ class UrlHelper {
$scheme_delimiter_position = strpos($url, '://');
$query_delimiter_position = strpos($url, '?');
if ($scheme_delimiter_position !== FALSE && ($query_delimiter_position === FALSE || $scheme_delimiter_position < $query_delimiter_position)) {
// Split off the fragment, if any.
if (strpos($url, '#') !== FALSE) {
list($url, $options['fragment']) = explode('#', $url, 2);
}
// Split off everything before the query string into 'path'.
$parts = explode('?', $url);
@ -158,12 +163,7 @@ class UrlHelper {
}
// If there is a query string, transform it into keyed query parameters.
if (isset($parts[1])) {
$query_parts = explode('#', $parts[1]);
parse_str($query_parts[0], $options['query']);
// Take over the fragment, if there is any.
if (isset($query_parts[1])) {
$options['fragment'] = $query_parts[1];
}
parse_str($parts[1], $options['query']);
}
}
// Internal URLs.
@ -248,6 +248,16 @@ class UrlHelper {
* Exception thrown when a either $url or $bath_url are not fully qualified.
*/
public static function externalIsLocal($url, $base_url) {
// Some browsers treat \ as / so normalize to forward slashes.
$url = str_replace('\\', '/', $url);
// Leading control characters may be ignored or mishandled by browsers, so
// assume such a path may lead to an non-local location. The \p{C} character
// class matches all UTF-8 control, unassigned, and private characters.
if (preg_match('/^\p{C}/u', $url) !== 0) {
return FALSE;
}
$url_parts = parse_url($url);
$base_parts = parse_url($base_url);

View file

@ -3,11 +3,13 @@
"description": "Mostly static utility classes for string, xss, array, image, and other commonly needed manipulations.",
"keywords": ["drupal"],
"homepage": "https://www.drupal.org/project/drupal",
"license": "GPL-2.0+",
"license": "GPL-2.0-or-later",
"require": {
"php": ">=5.5.9",
"paragonie/random_compat": "^1.0|^2.0",
"drupal/core-render": "~8.2"
"drupal/core-render": "^8.2",
"symfony/polyfill-iconv": "~1.0",
"symfony/polyfill-mbstring": "~1.0"
},
"autoload": {
"psr-4": {