Skip to content

Commit

Permalink
Make numeric operations on resources, arrays and objects type errors
Browse files Browse the repository at this point in the history
  • Loading branch information
nikic committed May 5, 2020
1 parent 31fb6a0 commit 5bc1e22
Show file tree
Hide file tree
Showing 24 changed files with 1,816 additions and 187 deletions.
9 changes: 8 additions & 1 deletion UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,14 @@ PHP 8.0 UPGRADE NOTES
. Disabled functions are now treated exactly like non-existent functions.
Calling a disabled function will report it as unknown, and redefining a
disabled function is now possible.
. data: wrappers are no longer writable, what matches the documented behavior.
. data: stream wrappers are no longer writable, which matches the documented
behavior.
. The arithmetic and bitwise operators
+, -, *, /, **, %, <<, >>, &, |, ^, ~, ++, --
will now consistently throw a TypeError when one of the operands is an
array, resource or non-overloaded object. The only exception to this is the
array + array merge operation, which remains supported.
RFC: https://wiki.php.net/rfc/arithmetic_operator_type_checks

- COM:
. Removed the ability to import case-insensitive constants from type
Expand Down
4 changes: 0 additions & 4 deletions Zend/tests/add_003.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,8 @@ var_dump($c);
echo "Done\n";
?>
--EXPECTF--
Notice: Object of class stdClass could not be converted to number in %sadd_003.php on line %d

Exception: Unsupported operand types: object + array

Notice: Object of class stdClass could not be converted to number in %s on line %d

Fatal error: Uncaught TypeError: Unsupported operand types: object + array in %s:%d
Stack trace:
#0 {main}
Expand Down
17 changes: 7 additions & 10 deletions Zend/tests/bug54305.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,11 @@ class TestClass {
abstract class AbstractClass {
}
$methodWithArgs = new ReflectionMethod('TestClass', 'methodWithArgs');
echo $methodWithArgs++;
?>
--EXPECTF--
Method [ <user> public method methodWithArgs ] {
@@ %sbug54305.php %d - %d

- Parameters [2] {
Parameter #0 [ <required> $a ]
Parameter #1 [ <required> $b ]
}
try {
echo $methodWithArgs++;
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
?>
--EXPECT--
Cannot increment object
5 changes: 1 addition & 4 deletions Zend/tests/bug73337.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,5 @@ Bug #73337 (try/catch not working with two exceptions inside a same operation)
class d { function __destruct() { throw new Exception; } }
try { new d + new d; } catch (Exception $e) { print "Exception properly caught\n"; }
?>
--EXPECTF--
Notice: Object of class d could not be converted to number in %sbug73337.php on line 3

Notice: Object of class d could not be converted to number in %sbug73337.php on line 3
--EXPECT--
Exception properly caught
66 changes: 33 additions & 33 deletions Zend/tests/compound_assign_failure.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -34,167 +34,167 @@ try {

$x = new stdClass;
try { $x += 1; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = 1;
try { $x += new stdClass; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = "foo";
try { $x += new stdClass; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = new stdClass;
try { $x -= 1; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = 1;
try { $x -= new stdClass; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = "foo";
try { $x -= new stdClass; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = new stdClass;
try { $x *= 1; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = 1;
try { $x *= new stdClass; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = "foo";
try { $x *= new stdClass; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = new stdClass;
try { $x /= 1; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = 1;
try { $x /= new stdClass; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = "foo";
try { $x /= new stdClass; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = new stdClass;
try { $x %= 1; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = 1;
try { $x %= new stdClass; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = "foo";
try { $x %= new stdClass; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = new stdClass;
try { $x **= 1; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = 1;
try { $x **= new stdClass; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = "foo";
try { $x **= new stdClass; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = new stdClass;
try { $x ^= 1; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = 1;
try { $x ^= new stdClass; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = "foo";
try { $x ^= new stdClass; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = new stdClass;
try { $x &= 1; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = 1;
try { $x &= new stdClass; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = "foo";
try { $x &= new stdClass; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = new stdClass;
try { $x |= 1; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = 1;
try { $x |= new stdClass; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = "foo";
try { $x |= new stdClass; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = new stdClass;
try { $x <<= 1; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = 1;
try { $x <<= new stdClass; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = "foo";
try { $x <<= new stdClass; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = new stdClass;
try { $x >>= 1; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = 1;
try { $x >>= new stdClass; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

$x = "foo";
try { $x >>= new stdClass; }
catch (Exception $e) {}
catch (Throwable $e) {}
var_dump($x);

?>
Expand Down
9 changes: 8 additions & 1 deletion Zend/tests/decrement_001.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,18 @@ $a = array(
);

foreach ($a as $var) {
$var--;
try {
$var--;
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
var_dump($var);
}

echo "Done\n";
?>
--EXPECTF--
Cannot decrement array
array(3) {
[0]=>
int(1)
Expand All @@ -51,8 +56,10 @@ float(1.5)
NULL
bool(true)
bool(false)
Cannot decrement object
object(stdClass)#%d (0) {
}
Cannot decrement array
array(0) {
}
float(-2147483649)
Expand Down
13 changes: 10 additions & 3 deletions Zend/tests/decrement_001_64bit.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,18 @@ $a = array(
);

foreach ($a as $var) {
$var--;
try {
$var--;
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
var_dump($var);
}

echo "Done\n";
?>
--EXPECTF--
--EXPECT--
Cannot decrement array
array(3) {
[0]=>
int(1)
Expand All @@ -51,8 +56,10 @@ float(1.5)
NULL
bool(true)
bool(false)
object(stdClass)#%d (0) {
Cannot decrement object
object(stdClass)#1 (0) {
}
Cannot decrement array
array(0) {
}
float(-9.223372036854776E+18)
Expand Down
Loading

0 comments on commit 5bc1e22

Please sign in to comment.