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$operands = [ 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 35$input = [ 36 0, 37 1, 38 2, 39 -1, 40 2.0, 41 2.1, 42 -2.0, 43 -2.1, 44 PHP_INT_MAX, 45 PHP_INT_MIN, 46 PHP_INT_MAX * 2, 47 PHP_INT_MIN * 2, 48 INF, 49 NAN, 50 [], 51 [1, 2], 52 [1, 2, 3], 53 [1 => 2, 0 => 1], 54 [1, 'a' => 2], 55 [1, 4], 56 [1, 'a'], 57 [1, 2 => 2], 58 [1, [ 2 ]], 59 null, 60 false, 61 true, 62 "", 63 " ", 64 "banana", 65 "Banana", 66 "banan", 67 "0", 68 "200", 69 "20", 70 "20a", 71 " \t\n\r\v\f20", 72 "20 ", 73 "2e1", 74 "2e150", 75 "9179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368", 76 "-9179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368", 77 "0.1", 78 "-0.1", 79 "1e-1", 80 "-20", 81 "-20.0", 82 "0x14", 83 (string) PHP_INT_MAX * 2, 84 (string) PHP_INT_MIN * 2, 85]; 86 87function makeParam($param) { 88 if ($param === PHP_INT_MIN) { 89 return "PHP_INT_MIN"; 90 } 91 if ($param === PHP_INT_MAX) { 92 return "PHP_INT_MAX"; 93 } 94 if (is_string($param)) { 95 return '"' . strtr($param, ["\t" => '\t', "\n" => '\n', "\r" => '\r', "\v" => '\v', "\f" => '\f', '$' => '\$', '"' => '\"']) . '"'; 96 } 97 return "(" . str_replace("\n", "", var_export($param, true)) . ")"; 98} 99 100$c = 0; 101$f = 0; 102 103function prepareLine($op1, $op2, $cmp, $operator) { 104 105 $op1_p = makeParam($op1); 106 $op2_p = makeParam($op2); 107 108 $error = "echo '" . addcslashes("$op1_p $operator $op2_p", "\\'") . '\', "\n"; $f++;'; 109 110 $compare = "@($op1_p $operator $op2_p)"; 111 $line = "\$c++; "; 112 try { 113 $result = makeParam($cmp()); 114 $line .= "if (" . ($result === "(NAN)" ? "!is_nan($compare)" : "$compare !== $result") . ") { $error }"; 115 } catch (Error $e) { 116 if (get_class($e) == "Error") { 117 return "// exempt $op1_p $operator $op2_p from checking, it generates a compile time error"; 118 } 119 $msg = makeParam($e->getMessage()); 120 $line .= "try { $compare; $error } catch (Error \$e) { if (\$e->getMessage() !== $msg) { $error } }"; 121 } 122 return $line; 123} 124 125$filename = __DIR__ . DIRECTORY_SEPARATOR . 'compare_binary_operands_temp.php'; 126$file = fopen($filename, "w"); 127 128fwrite($file, "<?php\n"); 129 130foreach ($input as $left) { 131 foreach ($input as $right) { 132 foreach ($operands as $operand) { 133 $line = prepareLine($left, $right, function() use ($left, $right, $operand) { 134 return eval("return @(\$left $operand \$right);"); 135 }, $operand); 136 fwrite($file, $line . "\n"); 137 } 138 } 139} 140 141fclose($file); 142 143include $filename; 144 145if($c === 0) { 146 echo "Completely failed\n"; 147} else { 148 echo "Failed: $f\n"; 149} 150?> 151===DONE=== 152--CLEAN-- 153<?php 154$fl = __DIR__ . DIRECTORY_SEPARATOR . 'compare_binary_operands_temp.php'; 155@unlink($fl); 156?> 157--EXPECT-- 158Failed: 0 159===DONE=== 160