1--TEST-- 2Test binary operands exposing the same behavior at compile as at run time 3--INI-- 4memory_limit=256M 5--SKIPIF-- 6<?php 7if (getenv("SKIP_SLOW_TESTS")) die('skip slow test'); 8?> 9--FILE-- 10<?php 11error_reporting(E_ALL ^ E_DEPRECATED); 12 13$binaryOperators = [ 14 "==", 15 "!=", 16 "===", 17 "!==", 18 "<", 19 "<=", 20 ">", 21 ">=", 22 "<=>", 23 "+", 24 "-", 25 "*", 26 "/", 27 "%", 28 "**", 29 ".", 30 "|", 31 "&", 32 "^", 33 "or", 34 "and", 35 "xor", 36 "||", 37 "&&", 38]; 39$unaryOperators = [ 40 "~", 41 "-", 42 "+", 43 "!", 44]; 45 46$input = [ 47 0, 48 0.0, 49 1, 50 2, 51 -1, 52 2.0, 53 2.1, 54 -2.0, 55 -2.1, 56 PHP_INT_MAX, 57 PHP_INT_MIN, 58 PHP_INT_MAX * 2, 59 PHP_INT_MIN * 2, 60 INF, 61 NAN, 62 [], 63 [1, 2], 64 [1, 2, 3], 65 [1 => 2, 0 => 1], 66 [1, 'a' => 2], 67 [1, 4], 68 [1, 'a'], 69 [1, 2 => 2], 70 [1, [ 2 ]], 71 null, 72 false, 73 true, 74 "", 75 " ", 76 "banana", 77 "Banana", 78 "banan", 79 "0", 80 "200", 81 "20", 82 "20a", 83 " \t\n\r\v\f20", 84 "20 ", 85 "2e1", 86 "2e150", 87 "9179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368", 88 "-9179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368", 89 "0.1", 90 "-0.1", 91 "1e-1", 92 "-20", 93 "-20.0", 94 "0x14", 95 (string) PHP_INT_MAX * 2, 96 (string) PHP_INT_MIN * 2, 97]; 98 99function makeParam($param) { 100 if ($param === PHP_INT_MIN) { 101 return "PHP_INT_MIN"; 102 } 103 if ($param === PHP_INT_MAX) { 104 return "PHP_INT_MAX"; 105 } 106 if (is_string($param)) { 107 return '"' . strtr($param, ["\t" => '\t', "\n" => '\n', "\r" => '\r', "\v" => '\v', "\f" => '\f', '$' => '\$', '"' => '\"']) . '"'; 108 } 109 return "(" . str_replace("\n", "", var_export($param, true)) . ")"; 110} 111 112$c = 0; 113$f = 0; 114 115function prepareBinaryLine($op1, $op2, $cmp, $operator) { 116 $op1_p = makeParam($op1); 117 $op2_p = makeParam($op2); 118 119 $error = "echo '" . addcslashes("$op1_p $operator $op2_p", "\\'") . '\', "\n"; $f++;'; 120 121 $compare = "@($op1_p $operator $op2_p)"; 122 $line = "\$c++; "; 123 try { 124 $result = makeParam($cmp()); 125 $line .= "if (" . ($result === "(NAN)" ? "!is_nan($compare)" : "$compare !== $result") . ") { $error }"; 126 } catch (Throwable $e) { 127 $msg = makeParam($e->getMessage()); 128 $line .= "try { $compare; $error } catch (Error \$e) { if (\$e->getMessage() !== $msg) { $error } }"; 129 } 130 return $line; 131} 132function prepareUnaryLine($op, $cmp, $operator) { 133 $op_p = makeParam($op); 134 135 $error = "echo '" . addcslashes("$operator $op_p", "\\'") . '\', "\n"; $f++;'; 136 137 $compare = "@($operator $op_p)"; 138 $line = "\$c++; "; 139 try { 140 $result = makeParam($cmp()); 141 $line .= "if (" . ($result === "(NAN)" ? "!is_nan($compare)" : "$compare !== $result") . ") { $error }"; 142 } catch (Throwable $e) { 143 $msg = makeParam($e->getMessage()); 144 $line .= "try { $compare; $error } catch (Error \$e) { if (\$e->getMessage() !== $msg) { $error } }"; 145 } 146 return $line; 147} 148 149$filename = __DIR__ . DIRECTORY_SEPARATOR . 'compare_binary_operands_temp.php'; 150$file = fopen($filename, "w"); 151 152fwrite($file, "<?php\n"); 153 154foreach ($input as $left) { 155 foreach ($input as $right) { 156 foreach ($binaryOperators as $operator) { 157 $line = prepareBinaryLine($left, $right, function() use ($left, $right, $operator) { 158 return eval("return @(\$left $operator \$right);"); 159 }, $operator); 160 fwrite($file, $line . "\n"); 161 } 162 } 163} 164foreach ($input as $right) { 165 foreach ($unaryOperators as $operator) { 166 $line = prepareUnaryLine($right, function() use ($right, $operator) { 167 return eval("return @($operator \$right);"); 168 }, $operator); 169 fwrite($file, $line . "\n"); 170 } 171} 172 173fclose($file); 174 175include $filename; 176 177if($c === 0) { 178 echo "Completely failed\n"; 179} else { 180 echo "Failed: $f\n"; 181} 182?> 183--CLEAN-- 184<?php 185$fl = __DIR__ . DIRECTORY_SEPARATOR . 'compare_binary_operands_temp.php'; 186@unlink($fl); 187?> 188--EXPECT-- 189Failed: 0 190