1--TEST-- 2Check that strings are marked as valid UTF-8 3--EXTENSIONS-- 4zend_test 5--FILE-- 6<?php 7echo "Empty strings:\n"; 8$s = ""; 9var_dump(zend_test_is_string_marked_as_valid_utf8($s)); 10 11echo "Known strings:\n"; 12$s = "c"; 13var_dump(zend_test_is_string_marked_as_valid_utf8($s)); 14 15echo "Integer cast to string:\n"; 16$i = 2563; 17$s = (string) $i; 18var_dump($s); 19var_dump(zend_test_is_string_marked_as_valid_utf8($s)); 20 21echo "Float cast to string:\n"; 22$f = 26.7; 23$s = (string) $f; 24var_dump($s); 25var_dump(zend_test_is_string_marked_as_valid_utf8($s)); 26$f = 2e100; 27$s = (string) $f; 28var_dump($s); 29var_dump(zend_test_is_string_marked_as_valid_utf8($s)); 30 31echo "Concatenation known valid UTF-8 strings in variables:\n"; 32$s1 = "f"; 33$s2 = "o"; 34$s = $s1 . $s2; 35var_dump($s); 36var_dump(zend_test_is_string_marked_as_valid_utf8($s)); 37 38echo "Multiple concatenation known valid UTF-8 strings in variables:\n"; 39$s1 = "f"; 40$s2 = "o"; 41$s = $s1 . $s2 . $s2; 42var_dump($s); 43var_dump(zend_test_is_string_marked_as_valid_utf8($s)); 44 45echo "Concatenation known valid UTF-8 in assignment:\n"; 46$s = "f" . "o"; 47var_dump($s); 48var_dump(zend_test_is_string_marked_as_valid_utf8($s)); 49 50// The "foo" string matches with a "Foo" class which is registered by the zend_test extension. 51// That class name does not have the "valid UTF-8" flag because class names in general 52// don't have to be UTF-8. As the "foo" string here goes through the interning logic, 53// the string gets replaced by the "foo" string from the class, which does 54// not have the "valid UTF-8" flag. We therefore choose a different test case: "fxo". 55// The previous "foo" test case works because it is not interned. 56echo "Multiple concatenation known valid UTF-8 in assignment:\n"; 57$s = "f" . "o" . "o"; 58var_dump($s); 59var_dump(zend_test_is_string_marked_as_valid_utf8($s)); 60$s = "f" . "x" . "o"; 61var_dump($s); 62var_dump(zend_test_is_string_marked_as_valid_utf8($s)); 63 64echo "Concatenation known valid UTF-8 string with empty string in variables:\n"; 65$s1 = "f"; 66$s2 = ""; 67$s = $s1 . $s2; 68var_dump(zend_test_is_string_marked_as_valid_utf8($s)); 69$s1 = "f"; 70$s2 = ""; 71$s = $s2 . $s1; 72var_dump(zend_test_is_string_marked_as_valid_utf8($s)); 73 74echo "Concatenation known valid UTF-8 string with empty string in assignment:\n"; 75$s = "f" . ""; 76var_dump(zend_test_is_string_marked_as_valid_utf8($s)); 77$s = "" . "f"; 78var_dump(zend_test_is_string_marked_as_valid_utf8($s)); 79 80echo "Concatenation in loop:\n"; 81const COPY_TIMES = 10_000; 82$string = "a"; 83 84$string_concat = $string; 85for ($i = 1; $i < COPY_TIMES; $i++) { 86 $string_concat = $string_concat . $string; 87} 88var_dump(zend_test_is_string_marked_as_valid_utf8($string_concat)); 89 90echo "Concatenation in loop (compound assignment):\n"; 91$string = "a"; 92 93$string_concat = $string; 94for ($i = 1; $i < COPY_TIMES; $i++) { 95 $string_concat .= $string; 96} 97var_dump(zend_test_is_string_marked_as_valid_utf8($string_concat)); 98 99echo "Concatenation of objects:\n"; 100class ToString { 101 public function __toString() : string{ 102 return "z"; 103 } 104} 105$o = new ToString(); 106$s = $o . $o; 107var_dump($s); 108var_dump(zend_test_is_string_marked_as_valid_utf8($s)); 109 110echo "Rope concat:\n"; 111$foo = 'f'; 112$bar = 'b'; 113$baz = 'a'; 114$rope = "$foo$bar$baz"; 115var_dump(zend_test_is_string_marked_as_valid_utf8($rope)); 116 117echo "str_repeat:\n"; 118$string = "a"; 119$string_concat = str_repeat($string, 100); 120var_dump(zend_test_is_string_marked_as_valid_utf8($string_concat)); 121$string = "\xff"; 122$string_concat = str_repeat($string, 100); 123var_dump(zend_test_is_string_marked_as_valid_utf8($string_concat)); 124 125echo "implode:\n"; 126$arr = ['a', 'b']; 127$string_concat = implode('', $arr); 128var_dump(zend_test_is_string_marked_as_valid_utf8($string_concat)); 129$string_concat = implode('|', $arr); 130var_dump(zend_test_is_string_marked_as_valid_utf8($string_concat)); 131$string_concat = implode('', ['c', ...$arr]); 132var_dump(zend_test_is_string_marked_as_valid_utf8($string_concat)); 133$string_concat = implode('', [...$arr, 'c']); 134var_dump(zend_test_is_string_marked_as_valid_utf8($string_concat)); 135$string_concat = implode('', ["\xff", ...$arr]); 136var_dump(zend_test_is_string_marked_as_valid_utf8($string_concat)); 137$string_concat = implode('', [...$arr, "\xff"]); 138var_dump(zend_test_is_string_marked_as_valid_utf8($string_concat)); 139$string_concat = implode("\xff", $arr); 140var_dump(zend_test_is_string_marked_as_valid_utf8($string_concat)); 141$string_concat = implode('', []); 142var_dump(zend_test_is_string_marked_as_valid_utf8($string_concat)); 143$string_concat = implode("\xff", []); 144var_dump(zend_test_is_string_marked_as_valid_utf8($string_concat)); 145$string_concat = implode('', ['a']); 146var_dump(zend_test_is_string_marked_as_valid_utf8($string_concat)); 147$string_concat = implode("\xff", ['a']); 148var_dump(zend_test_is_string_marked_as_valid_utf8($string_concat)); 149$string_concat = implode('', [1, 1.0, 'a']); 150var_dump(zend_test_is_string_marked_as_valid_utf8($string_concat)); 151 152?> 153--EXPECT-- 154Empty strings: 155bool(true) 156Known strings: 157bool(true) 158Integer cast to string: 159string(4) "2563" 160bool(true) 161Float cast to string: 162string(4) "26.7" 163bool(true) 164string(8) "2.0E+100" 165bool(true) 166Concatenation known valid UTF-8 strings in variables: 167string(2) "fo" 168bool(true) 169Multiple concatenation known valid UTF-8 strings in variables: 170string(3) "foo" 171bool(true) 172Concatenation known valid UTF-8 in assignment: 173string(2) "fo" 174bool(true) 175Multiple concatenation known valid UTF-8 in assignment: 176string(3) "foo" 177bool(false) 178string(3) "fxo" 179bool(true) 180Concatenation known valid UTF-8 string with empty string in variables: 181bool(true) 182bool(true) 183Concatenation known valid UTF-8 string with empty string in assignment: 184bool(true) 185bool(true) 186Concatenation in loop: 187bool(true) 188Concatenation in loop (compound assignment): 189bool(true) 190Concatenation of objects: 191string(2) "zz" 192bool(true) 193Rope concat: 194bool(true) 195str_repeat: 196bool(true) 197bool(false) 198implode: 199bool(true) 200bool(true) 201bool(true) 202bool(true) 203bool(false) 204bool(false) 205bool(false) 206bool(true) 207bool(true) 208bool(true) 209bool(true) 210bool(true) 211