|
| 1 | +--TEST-- |
| 2 | +Test binary operands exposing the same behavior at compile as at run time |
| 3 | +--INI-- |
| 4 | +memory_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 | + |
| 87 | +function 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 | + |
| 103 | +function 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++; try { "; |
| 112 | + try { |
| 113 | + $result = makeParam($cmp()); |
| 114 | + $line .= "if (" . ($result === "(NAN)" ? "!is_nan($compare)" : "$compare !== $result") . ") { $error } } catch (Error \$e) { $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 .= "$compare; $error } catch (Error \$e) { if (\$e->getMessage() !== $msg) { $error } }"; |
| 121 | + } |
| 122 | + return $line; |
| 123 | +} |
| 124 | + |
| 125 | +$filename = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'compare_binary_operands_temp.php'; |
| 126 | +$file = fopen($filename, "w"); |
| 127 | + |
| 128 | +fwrite($file, "<?php\n"); |
| 129 | + |
| 130 | +foreach ($input as $left) { |
| 131 | + foreach ($input as $right) { |
| 132 | + foreach ($operands as $operand) { |
| 133 | + fwrite($file, prepareLine($left, $right, function() use ($left, $right, $operand) { return eval("return @(\$left $operand \$right);"); }, $operand) . "\n"); |
| 134 | + } |
| 135 | + } |
| 136 | +} |
| 137 | + |
| 138 | +fclose($file); |
| 139 | + |
| 140 | +include $filename; |
| 141 | + |
| 142 | +if($c === 0) { |
| 143 | + echo "Completely failed\n"; |
| 144 | +} else { |
| 145 | + echo "Failed: $f\n"; |
| 146 | +} |
| 147 | +?> |
| 148 | +===DONE=== |
| 149 | +--CLEAN-- |
| 150 | +<?php |
| 151 | +$fl = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'compare_binary_operands_temp.php'; |
| 152 | +@unlink($fl); |
| 153 | +?> |
| 154 | +--EXPECTF-- |
| 155 | +Failed: 0 |
| 156 | +===DONE=== |
0 commit comments