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