@@ -1965,7 +1965,7 @@ static void ZEND_FASTCALL convert_compare_result_to_long(zval *result) /* {{{ */
1965
1965
}
1966
1966
/* }}} */
1967
1967
1968
- static int compare_long_to_string (zend_long lval , zend_string * str ) /* {{{ */
1968
+ static int compare_long_to_string (zend_long lval , zend_string * str , zend_bool equality_only ) /* {{{ */
1969
1969
{
1970
1970
zend_long str_lval ;
1971
1971
double str_dval ;
@@ -1994,7 +1994,10 @@ static int compare_long_to_string(zend_long lval, zend_string *str) /* {{{ */
1994
1994
str_cmp_result = ZEND_NORMALIZE_BOOL (str_cmp_result );
1995
1995
zend_string_release (lval_as_str );
1996
1996
1997
- if (str_cmp_result != num_cmp_result ) {
1997
+ /* Don't report a warning if we're using == and the comparison changed between 1/-1. */
1998
+ zend_bool cmp_result_changed_observably = str_cmp_result != num_cmp_result &&
1999
+ (!equality_only || str_cmp_result == 0 || num_cmp_result == 0 );
2000
+ if (cmp_result_changed_observably ) {
1998
2001
zend_error (E_WARNING ,
1999
2002
"Result of comparison between " ZEND_LONG_FMT " and \"%s\" will change (%d to %d)" ,
2000
2003
lval , ZSTR_VAL (str ), num_cmp_result , str_cmp_result );
@@ -2005,7 +2008,7 @@ static int compare_long_to_string(zend_long lval, zend_string *str) /* {{{ */
2005
2008
}
2006
2009
/* }}} */
2007
2010
2008
- static int compare_double_to_string (double dval , zend_string * str ) /* {{{ */
2011
+ static int compare_double_to_string (double dval , zend_string * str , zend_bool equality_only ) /* {{{ */
2009
2012
{
2010
2013
zend_long str_lval ;
2011
2014
double str_dval ;
@@ -2037,7 +2040,10 @@ static int compare_double_to_string(double dval, zend_string *str) /* {{{ */
2037
2040
str_cmp_result = ZEND_NORMALIZE_BOOL (str_cmp_result );
2038
2041
zend_string_release (dval_as_str );
2039
2042
2040
- if (str_cmp_result != num_cmp_result ) {
2043
+ /* Don't report a warning if we're using == and the comparison changed between 1/-1. */
2044
+ zend_bool cmp_result_changed_observably = str_cmp_result != num_cmp_result &&
2045
+ (!equality_only || str_cmp_result == 0 || num_cmp_result == 0 );
2046
+ if (cmp_result_changed_observably ) {
2041
2047
zend_error (E_WARNING ,
2042
2048
"Result of comparison between %G and \"%s\" will change (%d to %d)" ,
2043
2049
dval , ZSTR_VAL (str ), num_cmp_result , str_cmp_result );
@@ -2048,7 +2054,7 @@ static int compare_double_to_string(double dval, zend_string *str) /* {{{ */
2048
2054
}
2049
2055
/* }}} */
2050
2056
2051
- ZEND_API int ZEND_FASTCALL compare_function (zval * result , zval * op1 , zval * op2 ) /* {{{ */
2057
+ ZEND_API int ZEND_FASTCALL compare_function_ex (zval * result , zval * op1 , zval * op2 , zend_bool equality_only ) /* {{{ */
2052
2058
{
2053
2059
int ret ;
2054
2060
int converted = 0 ;
@@ -2081,7 +2087,7 @@ ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2)
2081
2087
return SUCCESS ;
2082
2088
2083
2089
case TYPE_PAIR (IS_ARRAY , IS_ARRAY ):
2084
- ZVAL_LONG (result , zend_compare_arrays (op1 , op2 ));
2090
+ ZVAL_LONG (result , zend_compare_arrays_ex (op1 , op2 , equality_only ));
2085
2091
return SUCCESS ;
2086
2092
2087
2093
case TYPE_PAIR (IS_NULL , IS_NULL ):
@@ -2117,11 +2123,11 @@ ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2)
2117
2123
return SUCCESS ;
2118
2124
2119
2125
case TYPE_PAIR (IS_LONG , IS_STRING ):
2120
- ZVAL_LONG (result , compare_long_to_string (Z_LVAL_P (op1 ), Z_STR_P (op2 )));
2126
+ ZVAL_LONG (result , compare_long_to_string (Z_LVAL_P (op1 ), Z_STR_P (op2 ), equality_only ));
2121
2127
return SUCCESS ;
2122
2128
2123
2129
case TYPE_PAIR (IS_STRING , IS_LONG ):
2124
- ZVAL_LONG (result , - compare_long_to_string (Z_LVAL_P (op2 ), Z_STR_P (op1 )));
2130
+ ZVAL_LONG (result , - compare_long_to_string (Z_LVAL_P (op2 ), Z_STR_P (op1 ), equality_only ));
2125
2131
return SUCCESS ;
2126
2132
2127
2133
case TYPE_PAIR (IS_DOUBLE , IS_STRING ):
@@ -2130,7 +2136,7 @@ ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2)
2130
2136
return SUCCESS ;
2131
2137
}
2132
2138
2133
- ZVAL_LONG (result , compare_double_to_string (Z_DVAL_P (op1 ), Z_STR_P (op2 )));
2139
+ ZVAL_LONG (result , compare_double_to_string (Z_DVAL_P (op1 ), Z_STR_P (op2 ), equality_only ));
2134
2140
return SUCCESS ;
2135
2141
2136
2142
case TYPE_PAIR (IS_STRING , IS_DOUBLE ):
@@ -2139,8 +2145,8 @@ ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2)
2139
2145
return SUCCESS ;
2140
2146
}
2141
2147
2142
- ZVAL_LONG (result , - compare_double_to_string (Z_DVAL_P (op2 ), Z_STR_P (op1 )));
2143
- return SUCCESS ;
2148
+ ZVAL_LONG (result , - compare_double_to_string (Z_DVAL_P (op2 ), Z_STR_P (op1 ), equality_only ));
2149
+ return SUCCESS ;
2144
2150
2145
2151
case TYPE_PAIR (IS_OBJECT , IS_NULL ):
2146
2152
ZVAL_LONG (result , 1 );
@@ -2188,7 +2194,7 @@ return SUCCESS;
2188
2194
if (Z_OBJ_HT_P (op1 )-> get ) {
2189
2195
zval rv ;
2190
2196
op_free = Z_OBJ_HT_P (op1 )-> get (op1 , & rv );
2191
- ret = compare_function (result , op_free , op2 );
2197
+ ret = compare_function_ex (result , op_free , op2 , equality_only );
2192
2198
zend_free_obj_get_result (op_free );
2193
2199
return ret ;
2194
2200
} else if (Z_TYPE_P (op2 ) != IS_OBJECT && Z_OBJ_HT_P (op1 )-> cast_object ) {
@@ -2198,7 +2204,7 @@ return SUCCESS;
2198
2204
zend_free_obj_get_result (& tmp_free );
2199
2205
return SUCCESS ;
2200
2206
}
2201
- ret = compare_function (result , & tmp_free , op2 );
2207
+ ret = compare_function_ex (result , & tmp_free , op2 , equality_only );
2202
2208
zend_free_obj_get_result (& tmp_free );
2203
2209
return ret ;
2204
2210
}
@@ -2207,7 +2213,7 @@ return SUCCESS;
2207
2213
if (Z_OBJ_HT_P (op2 )-> get ) {
2208
2214
zval rv ;
2209
2215
op_free = Z_OBJ_HT_P (op2 )-> get (op2 , & rv );
2210
- ret = compare_function (result , op1 , op_free );
2216
+ ret = compare_function_ex (result , op1 , op_free , equality_only );
2211
2217
zend_free_obj_get_result (op_free );
2212
2218
return ret ;
2213
2219
} else if (Z_TYPE_P (op1 ) != IS_OBJECT && Z_OBJ_HT_P (op2 )-> cast_object ) {
@@ -2217,7 +2223,7 @@ return SUCCESS;
2217
2223
zend_free_obj_get_result (& tmp_free );
2218
2224
return SUCCESS ;
2219
2225
}
2220
- ret = compare_function (result , op1 , & tmp_free );
2226
+ ret = compare_function_ex (result , op1 , & tmp_free , equality_only );
2221
2227
zend_free_obj_get_result (& tmp_free );
2222
2228
return ret ;
2223
2229
} else if (Z_TYPE_P (op1 ) == IS_OBJECT ) {
@@ -2268,6 +2274,12 @@ return SUCCESS;
2268
2274
}
2269
2275
/* }}} */
2270
2276
2277
+ ZEND_API int ZEND_FASTCALL compare_function (zval * result , zval * op1 , zval * op2 ) /* {{{ */
2278
+ {
2279
+ return compare_function_ex (result , op1 , op2 , 0 );
2280
+ }
2281
+ /* }}} */
2282
+
2271
2283
static int hash_zval_identical_function (zval * z1 , zval * z2 ) /* {{{ */
2272
2284
{
2273
2285
zval result ;
@@ -2331,7 +2343,7 @@ ZEND_API int ZEND_FASTCALL is_not_identical_function(zval *result, zval *op1, zv
2331
2343
2332
2344
ZEND_API int ZEND_FASTCALL is_equal_function (zval * result , zval * op1 , zval * op2 ) /* {{{ */
2333
2345
{
2334
- if (compare_function (result , op1 , op2 ) == FAILURE ) {
2346
+ if (compare_function_ex (result , op1 , op2 , 1 ) == FAILURE ) {
2335
2347
return FAILURE ;
2336
2348
}
2337
2349
ZVAL_BOOL (result , (Z_LVAL_P (result ) == 0 ));
@@ -2341,7 +2353,7 @@ ZEND_API int ZEND_FASTCALL is_equal_function(zval *result, zval *op1, zval *op2)
2341
2353
2342
2354
ZEND_API int ZEND_FASTCALL is_not_equal_function (zval * result , zval * op1 , zval * op2 ) /* {{{ */
2343
2355
{
2344
- if (compare_function (result , op1 , op2 ) == FAILURE ) {
2356
+ if (compare_function_ex (result , op1 , op2 , 1 ) == FAILURE ) {
2345
2357
return FAILURE ;
2346
2358
}
2347
2359
ZVAL_BOOL (result , (Z_LVAL_P (result ) != 0 ));
@@ -3048,15 +3060,44 @@ static int hash_zval_compare_function(zval *z1, zval *z2) /* {{{ */
3048
3060
}
3049
3061
/* }}} */
3050
3062
3063
+ static int hash_zval_compare_function_equality (zval * z1 , zval * z2 ) /* {{{ */
3064
+ {
3065
+ zval result ;
3066
+
3067
+ if (compare_function_ex (& result , z1 , z2 , 1 )== FAILURE ) {
3068
+ return 1 ;
3069
+ }
3070
+ return Z_LVAL (result );
3071
+ }
3072
+ /* }}} */
3073
+
3074
+ ZEND_API int ZEND_FASTCALL zend_compare_symbol_tables_ex (HashTable * ht1 , HashTable * ht2 , zend_bool equality_only ) /* {{{ */
3075
+ {
3076
+ if (ht1 == ht2 ) {
3077
+ return 0 ;
3078
+ }
3079
+ return zend_hash_compare (ht1 , ht2 ,
3080
+ equality_only
3081
+ ? (compare_func_t ) hash_zval_compare_function_equality
3082
+ : (compare_func_t ) hash_zval_compare_function , 0 );
3083
+ }
3084
+ /* }}} */
3085
+
3051
3086
ZEND_API int ZEND_FASTCALL zend_compare_symbol_tables (HashTable * ht1 , HashTable * ht2 ) /* {{{ */
3052
3087
{
3053
- return ht1 == ht2 ? 0 : zend_hash_compare (ht1 , ht2 , (compare_func_t ) hash_zval_compare_function , 0 );
3088
+ return zend_compare_symbol_tables_ex (ht1 , ht2 , 0 );
3089
+ }
3090
+ /* }}} */
3091
+
3092
+ ZEND_API int ZEND_FASTCALL zend_compare_arrays_ex (zval * a1 , zval * a2 , zend_bool equality_only ) /* {{{ */
3093
+ {
3094
+ return zend_compare_symbol_tables_ex (Z_ARRVAL_P (a1 ), Z_ARRVAL_P (a2 ), equality_only );
3054
3095
}
3055
3096
/* }}} */
3056
3097
3057
3098
ZEND_API int ZEND_FASTCALL zend_compare_arrays (zval * a1 , zval * a2 ) /* {{{ */
3058
3099
{
3059
- return zend_compare_symbol_tables (Z_ARRVAL_P (a1 ), Z_ARRVAL_P (a2 ));
3100
+ return zend_compare_symbol_tables_ex (Z_ARRVAL_P (a1 ), Z_ARRVAL_P (a2 ), 0 );
3060
3101
}
3061
3102
/* }}} */
3062
3103
0 commit comments