Skip to content

Commit

Permalink
Merge branch 'MDL-73433-master' of https://github.com/marinaglancy/mo…
Browse files Browse the repository at this point in the history
  • Loading branch information
junpataleta committed Oct 4, 2022
2 parents 2b6a955 + 8ba4e5a commit 28a4c55
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 12 deletions.
35 changes: 23 additions & 12 deletions lib/classes/text.php
Expand Up @@ -94,7 +94,7 @@ public static function reset_caches() {
* @return string normalised lowercase charset name
*/
public static function parse_charset($charset) {
$charset = strtolower($charset);
$charset = strtolower($charset ?? '');

if ($charset === 'utf8' or $charset === 'utf-8') {
return 'utf-8';
Expand Down Expand Up @@ -181,9 +181,9 @@ public static function substr($text, $start, $len=null, $charset='utf-8') {

// Check whether the charset is supported by mbstring. CP1250 is not supported. Fall back to iconv.
if (self::is_charset_supported($charset)) {
$result = mb_substr($text, $start, $len, $charset);
$result = mb_substr($text ?? '', $start, $len, $charset);
} else {
$result = iconv_substr($text, $start, $len, $charset);
$result = (string)iconv_substr($text ?? '', $start, $len, $charset);
}

return $result;
Expand All @@ -199,7 +199,7 @@ public static function substr($text, $start, $len=null, $charset='utf-8') {
* @since Moodle 3.1
*/
public static function str_max_bytes($string, $bytes) {
return mb_strcut($string, 0, $bytes, 'UTF-8');
return mb_strcut($string ?? '', 0, $bytes, 'UTF-8');
}

/**
Expand All @@ -213,6 +213,10 @@ public static function str_max_bytes($string, $bytes) {
* @since Moodle 2.4.6, 2.5.2, 2.6
*/
public static function strrchr($haystack, $needle, $part = false) {
if (is_null($haystack)) {
// Compatibility with behavior in PHP before version 8.1.
return false;
}
return mb_strrchr($haystack, $needle, $part, 'UTF-8');
}

Expand All @@ -227,10 +231,10 @@ public static function strlen($text, $charset='utf-8') {
$charset = self::parse_charset($charset);

if (self::is_charset_supported($charset)) {
return mb_strlen($text, $charset);
return mb_strlen($text ?? '', $charset);
}

return iconv_strlen($text, $charset);
return iconv_strlen($text ?? '', $charset);
}

/**
Expand All @@ -245,7 +249,7 @@ public static function strtolower($text, $charset='utf-8') {

// Confirm mbstring can handle the charset.
if (self::is_charset_supported($charset)) {
return mb_strtolower($text, $charset);
return mb_strtolower($text ?? '', $charset);
}

// The mbstring extension cannot handle the charset. Convert to UTF-8.
Expand All @@ -267,7 +271,7 @@ public static function strtoupper($text, $charset='utf-8') {

// Confirm mbstring can handle the charset.
if (self::is_charset_supported($charset)) {
return mb_strtoupper($text, $charset);
return mb_strtoupper($text ?? '', $charset);
}

// The mbstring extension cannot handle the charset. Convert to UTF-8.
Expand All @@ -287,7 +291,7 @@ public static function strtoupper($text, $charset='utf-8') {
* @return int the numeric position of the first occurrence of needle in haystack.
*/
public static function strpos($haystack, $needle, $offset=0) {
return mb_strpos($haystack, $needle, $offset, 'UTF-8');
return mb_strpos($haystack ?? '', $needle, $offset, 'UTF-8');
}

/**
Expand All @@ -299,7 +303,11 @@ public static function strpos($haystack, $needle, $offset=0) {
* @return int the numeric position of the last occurrence of needle in haystack
*/
public static function strrpos($haystack, $needle) {
return mb_strrpos($haystack, $needle, null, 'UTF-8');
if (is_null($haystack)) {
// Compatibility with behavior in PHP before version 8.1.
return false;
}
return mb_strrpos($haystack, $needle, 0, 'UTF-8');
}

/**
Expand All @@ -310,7 +318,7 @@ public static function strrpos($haystack, $needle) {
* @return string the reversed multi byte string
*/
public static function strrev($str) {
preg_match_all('/./us', $str, $ar);
preg_match_all('/./us', $str ?? '', $ar);
return join('', array_reverse($ar[0]));
}

Expand Down Expand Up @@ -513,7 +521,7 @@ public static function utf8_to_entities($str, $dec=false, $nonnum=false) {
$str = self::entities_to_utf8($str, true);
}

$result = mb_strtolower(mb_encode_numericentity($str, [0xa0, 0xffff, 0, 0xffff], 'UTF-8', true));
$result = mb_strtolower(mb_encode_numericentity($str ?? '', [0xa0, 0xffff, 0, 0xffff], 'UTF-8', true));

// We cannot use the decimal equivalent of the above call due to the unit test and our allowance for
// entities to be entered within the provided $str. Refer to the correspond unit test for examples.
Expand All @@ -536,6 +544,9 @@ public static function utf8_to_entities($str, $dec=false, $nonnum=false) {
* @return string
*/
public static function trim_utf8_bom($str) {
if (is_null($str)) {
return null;
}
$bom = self::UTF8_BOM;
if (strpos($str, $bom) === 0) {
return substr($str, strlen($bom));
Expand Down
62 changes: 62 additions & 0 deletions lib/tests/text_test.php
Expand Up @@ -106,6 +106,9 @@ public function test_convert() {
$utf8 = "A æ Übérmensch på høyeste nivå! И я люблю PHP! есть. アクセシビリティ. fi";
$this->assertSame("A ae Ubermensch pa hoyeste niva! I a lublu PHP! est'. akuseshibiriti. fi",
core_text::convert($utf8, 'utf-8', 'ascii'));

// Check that null argument is allowed.
$this->assertSame('', core_text::convert(null, 'utf-8', 'ascii'));
}

/**
Expand Down Expand Up @@ -150,6 +153,12 @@ public function test_substr() {
$str = pack("H*", "bcf2cce5d6d0cec4"); // GB18030
$s = pack("H*", "cce5"); // GB18030
$this->assertSame($s, core_text::substr($str, 1, 1, 'GB18030'));

// Check that null argument is allowed.
$this->assertSame('', core_text::substr(null, 1, 1));
$this->assertSame('', core_text::substr(null, 1));
$this->assertSame('', core_text::substr(null, 1, 1, 'cp1250'));
$this->assertSame('', core_text::substr(null, 1, null, 'cp1250'));
}

/**
Expand Down Expand Up @@ -191,6 +200,10 @@ public function test_strlen() {
$this->assertSame(1, core_text::strlen($str, 'GB18030'));
$str = pack("H*", "bcf2cce5d6d0cec4"); // GB18030
$this->assertSame(4, core_text::strlen($str, 'GB18030'));

// Check that null argument is allowed.
$this->assertSame(0, core_text::strlen(null));
$this->assertSame(0, core_text::strlen(null, 'cp1250'));
}

/**
Expand Down Expand Up @@ -243,6 +256,9 @@ public function test_str_max_bytes() {
$conv = core_text::str_max_bytes($str, 0);
$this->assertEquals(0, strlen($conv));
$this->assertSame('', $conv);

// Check that null argument is allowed.
$this->assertSame('', core_text::str_max_bytes(null, 1));
}

/**
Expand Down Expand Up @@ -281,6 +297,10 @@ public function test_strtolower() {

$str = 1309528800;
$this->assertSame((string)$str, core_text::strtolower($str));

// Check that null argument is allowed.
$this->assertSame('', core_text::strtolower(null));
$this->assertSame('', core_text::strtolower(null, 'cp1250'));
}

/**
Expand Down Expand Up @@ -316,6 +336,10 @@ public function test_strtoupper() {

$str = pack("H*", "bcf2cce5d6d0cec4"); // GB18030
$this->assertSame($str, core_text::strtoupper($str, 'GB18030'));

// Check that null argument is allowed.
$this->assertSame('', core_text::strtoupper(null));
$this->assertSame('', core_text::strtoupper(null, 'cp1250'));
}

/**
Expand All @@ -338,6 +362,9 @@ public function test_strrev() {
// Reverse it twice to be doubly sure.
$this->assertSame($after, core_text::strrev(core_text::strrev($after)));
}

// Check that null argument is allowed.
$this->assertSame('', core_text::strrev(null));
}

/**
Expand All @@ -348,6 +375,9 @@ public function test_strrev() {
public function test_strpos() {
$str = "Žluťoučký koníček";
$this->assertSame(10, core_text::strpos($str, 'koníč'));

// Check that null argument is allowed.
$this->assertSame(false, core_text::strpos(null, 'a'));
}

/**
Expand All @@ -358,6 +388,9 @@ public function test_strpos() {
public function test_strrpos() {
$str = "Žluťoučký koníček";
$this->assertSame(11, core_text::strrpos($str, 'o'));

// Check that null argument is allowed.
$this->assertSame(false, core_text::strrpos(null, 'o'));
}

/**
Expand All @@ -382,6 +415,10 @@ public function test_specialtoascii() {

$utf8 = 'キャンパス Αλφαβητικός Κατάλογος Лорем ипсум долор сит амет';
$this->assertSame('kyanpasu Alphabetikos Katalogos Lorem ipsum dolor sit amet', core_text::specialtoascii($utf8));

// Check that null argument is allowed.
$this->assertSame('', core_text::specialtoascii(null));
$this->assertSame('', core_text::specialtoascii(null, 'ascii'));
}

/**
Expand Down Expand Up @@ -423,6 +460,9 @@ public function test_encode_mimeheader() {
=?utf-8?B?0Ywg0LLQuNC90LTQvtGD0Lci?=";
$this->assertSame($encodedlongstr, $mailer->encodeHeader($longstr));
$this->assertSame('"' . $encodedlongstr . '"', $mailer->encodeHeader($longstr, 'phrase'));

// Check that null argument is allowed.
$this->assertSame('', core_text::encode_mimeheader(null));
}

/**
Expand All @@ -433,6 +473,9 @@ public function test_encode_mimeheader() {
public function test_entities_to_utf8() {
$str = "Žluťoučký koníček©"&<>§«";
$this->assertSame("Žluťoučký koníček©\"&<>§«", core_text::entities_to_utf8($str));

// Check that null argument is allowed.
$this->assertSame('', core_text::entities_to_utf8(null));
}

/**
Expand All @@ -448,6 +491,10 @@ public function test_utf8_to_entities() {
$str = "&#381;luťoučký kon&iacute;ček&copy;&quot;&amp;&lt;&gt;&sect;&laquo;";
$this->assertSame("&#x17d;lu&#x165;ou&#x10d;k&#xfd; kon&#xed;&#x10d;ek&#xa9;\"&<>&#xa7;&#xab;", core_text::utf8_to_entities($str, false, true));
$this->assertSame("&#381;lu&#357;ou&#269;k&#253; kon&#237;&#269;ek&#169;\"&<>&#167;&#171;", core_text::utf8_to_entities($str, true, true));

// Check that null argument is allowed.
$this->assertSame('', core_text::utf8_to_entities(null));
$this->assertSame('', core_text::utf8_to_entities(null, true));
}

/**
Expand All @@ -459,6 +506,9 @@ public function test_trim_utf8_bom() {
$bom = "\xef\xbb\xbf";
$str = "Žluťoučký koníček";
$this->assertSame($str.$bom, core_text::trim_utf8_bom($bom.$str.$bom));

// Check that null argument is allowed.
$this->assertSame(null, core_text::trim_utf8_bom(null));
}

/**
Expand All @@ -482,6 +532,9 @@ public function test_remove_unicode_non_characters() {
// If you only have a non-character, you get empty string.
$example = html_entity_decode('&#xfffe;');
$this->assertSame('', core_text::remove_unicode_non_characters($example));

// Check that null argument is allowed.
$this->assertSame(null, core_text::trim_utf8_bom(null));
}

/**
Expand Down Expand Up @@ -517,6 +570,9 @@ public function test_utf8ord() {
$this->assertSame(0x0439, core_text::utf8ord('й'));
$this->assertSame(0x2FA1F, core_text::utf8ord('𯨟'));
$this->assertSame(381, core_text::utf8ord('Ž'));

// Check that null argument is allowed.
$this->assertSame(ord(''), core_text::utf8ord(null));
}

/**
Expand All @@ -527,6 +583,9 @@ public function test_utf8ord() {
public function test_strtotitle() {
$str = "žluťoučký koníček";
$this->assertSame("Žluťoučký Koníček", core_text::strtotitle($str));

// Check that null argument is allowed.
$this->assertSame(null, core_text::strtotitle(null));
}

/**
Expand All @@ -540,6 +599,9 @@ public function test_strrchr() {
$this->assertSame('Žluťoučký ', core_text::strrchr($str, 'koní', true));
$this->assertFalse(core_text::strrchr($str, 'A'));
$this->assertFalse(core_text::strrchr($str, 'ç', true));

// Check that null argument is allowed.
$this->assertSame(false, core_text::strrchr(null, 'o'));
}

/**
Expand Down

0 comments on commit 28a4c55

Please sign in to comment.