Skip to content

Commit 3b0c83b

Browse files
committed
Remove the intrinsic __equals check during comparison
1 parent e890a1c commit 3b0c83b

File tree

3 files changed

+95
-33
lines changed

3 files changed

+95
-33
lines changed
Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
--TEST--
2-
__equals: Equal objects automatically have the same ordering
2+
__equals: Should not be called for comparisons.
33
--FILE--
44
<?php
55
class A
66
{
77
public function __equals($other)
88
{
9-
return $other % 2 == 0;
9+
return 0;
1010
}
1111

1212
public function __compareTo($other)
@@ -15,10 +15,12 @@ class A
1515
}
1616
}
1717

18-
var_dump(new A <=> 1);
19-
var_dump(new A <=> 2);
18+
$a = new A();
19+
20+
var_dump($a <=> 1);
21+
var_dump($a <=> $a);
2022

2123
?>
2224
--EXPECTF--
2325
int(1)
24-
int(0)
26+
int(1)
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
--TEST--
2+
__equals: Disallow comparison, but allow equality checks
3+
--FILE--
4+
<?php
5+
6+
class Comparable
7+
{
8+
private $value;
9+
10+
public function __construct($value)
11+
{
12+
$this->value = $value;
13+
}
14+
15+
public function __compareTo($other)
16+
{
17+
throw new Exception("This object does not support comparison");
18+
}
19+
20+
public function __equals($other)
21+
{
22+
return $other instanceof self && $this->value === $other->value;
23+
}
24+
}
25+
26+
27+
/**
28+
*
29+
*/
30+
var_dump(new Comparable(1) == new Comparable(2));
31+
32+
/**
33+
*
34+
*/
35+
var_dump(new Comparable(2) == new Comparable(2));
36+
37+
/**
38+
*
39+
*/
40+
try {
41+
new Comparable(2) <= new Comparable(2);
42+
} catch (Exception $e) {
43+
var_dump($e->getMessage());
44+
}
45+
46+
/**
47+
*
48+
*/
49+
try {
50+
new Comparable(1) > new Comparable(2);
51+
} catch (Exception $e) {
52+
var_dump($e->getMessage());
53+
}
54+
55+
?>
56+
--EXPECTF--
57+
bool(false)
58+
bool(true)
59+
string(39) "This object does not support comparison"
60+
string(39) "This object does not support comparison"

Zend/zend_operators.c

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2038,14 +2038,14 @@ ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2)
20382038
return SUCCESS;
20392039

20402040
case TYPE_PAIR(IS_OBJECT, IS_NULL):
2041-
if (Z_OBJ_HANDLER_P(op1, equals)) {
2042-
if (Z_OBJ_HANDLER_P(op1, equals)(result, op1, op2) == SUCCESS) {
2043-
if (i_zend_is_true(result)) {
2044-
ZVAL_LONG(result, 0);
2045-
return SUCCESS;
2046-
}
2047-
}
2048-
}
2041+
// if (Z_OBJ_HANDLER_P(op1, equals)) {
2042+
// if (Z_OBJ_HANDLER_P(op1, equals)(result, op1, op2) == SUCCESS) {
2043+
// if (i_zend_is_true(result)) {
2044+
// ZVAL_LONG(result, 0);
2045+
// return SUCCESS;
2046+
// }
2047+
// }
2048+
// }
20492049

20502050
if (Z_OBJ_HANDLER_P(op1, compare)) {
20512051
if (Z_OBJ_HANDLER_P(op1, compare)(result, op1, op2) == SUCCESS) {
@@ -2058,14 +2058,14 @@ ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2)
20582058
return SUCCESS;
20592059

20602060
case TYPE_PAIR(IS_NULL, IS_OBJECT):
2061-
if (Z_OBJ_HANDLER_P(op2, equals)) {
2062-
if (Z_OBJ_HANDLER_P(op2, equals)(result, op2, op1) == SUCCESS) {
2063-
if (i_zend_is_true(result)) {
2064-
ZVAL_LONG(result, 0);
2065-
return SUCCESS;
2066-
}
2067-
}
2068-
}
2061+
// if (Z_OBJ_HANDLER_P(op2, equals)) {
2062+
// if (Z_OBJ_HANDLER_P(op2, equals)(result, op2, op1) == SUCCESS) {
2063+
// if (i_zend_is_true(result)) {
2064+
// ZVAL_LONG(result, 0);
2065+
// return SUCCESS;
2066+
// }
2067+
// }
2068+
// }
20692069

20702070
if (Z_OBJ_HANDLER_P(op2, compare)) {
20712071
if (Z_OBJ_HANDLER_P(op2, compare)(result, op2, op1) == SUCCESS) {
@@ -2088,12 +2088,12 @@ ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2)
20882088
}
20892089

20902090
if (Z_TYPE_P(op1) == IS_OBJECT) {
2091-
if (Z_OBJ_HANDLER_P(op1, equals) && Z_OBJ_HANDLER_P(op1, equals)(result, op1, op2) == SUCCESS) {
2092-
if (i_zend_is_true(result)) {
2093-
ZVAL_LONG(result, 0);
2094-
return SUCCESS;
2095-
}
2096-
}
2091+
// if (Z_OBJ_HANDLER_P(op1, equals) && Z_OBJ_HANDLER_P(op1, equals)(result, op1, op2) == SUCCESS) {
2092+
// if (i_zend_is_true(result)) {
2093+
// ZVAL_LONG(result, 0);
2094+
// return SUCCESS;
2095+
// }
2096+
// }
20972097

20982098
if (Z_OBJ_HANDLER_P(op1, compare) && Z_OBJ_HANDLER_P(op1, compare)(result, op1, op2) == SUCCESS) {
20992099
convert_compare_result_to_long(result);
@@ -2102,12 +2102,12 @@ ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2)
21022102
}
21032103

21042104
if (Z_TYPE_P(op2) == IS_OBJECT) {
2105-
if (Z_OBJ_HANDLER_P(op2, equals) && Z_OBJ_HANDLER_P(op2, equals)(result, op2, op1) == SUCCESS) {
2106-
if (i_zend_is_true(result)) {
2107-
ZVAL_LONG(result, 0);
2108-
return SUCCESS;
2109-
}
2110-
}
2105+
// if (Z_OBJ_HANDLER_P(op2, equals) && Z_OBJ_HANDLER_P(op2, equals)(result, op2, op1) == SUCCESS) {
2106+
// if (i_zend_is_true(result)) {
2107+
// ZVAL_LONG(result, 0);
2108+
// return SUCCESS;
2109+
// }
2110+
// }
21112111

21122112
if (Z_OBJ_HANDLER_P(op2, compare) && Z_OBJ_HANDLER_P(op2, compare)(result, op2, op1) == SUCCESS) {
21132113
convert_compare_result_to_long(result);

0 commit comments

Comments
 (0)