mirror of
https://github.com/php/php-src.git
synced 2024-09-21 09:57:23 +00:00
- MFH:
. Fix comparision edgecases involving objects (Tony, Marcus) . Use ZVAL_LONG() where appropriate
This commit is contained in:
parent
d5811fc08a
commit
fa57959f47
@ -1273,8 +1273,7 @@ ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_
|
||||
convert_to_double(&op1_copy);
|
||||
convert_to_double(&op2_copy);
|
||||
|
||||
result->value.lval = ZEND_NORMALIZE_BOOL(op1_copy.value.dval-op2_copy.value.dval);
|
||||
result->type = IS_LONG;
|
||||
ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL(op1_copy)-Z_DVAL(op2_copy)));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
@ -1301,18 +1300,21 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
{
|
||||
zval op1_copy, op2_copy;
|
||||
zval *op1_free, *op2_free;
|
||||
int op1_obj = op1->type == IS_OBJECT;
|
||||
int op2_obj = op2->type == IS_OBJECT;
|
||||
|
||||
int op1_obj = Z_TYPE_P(op1) == IS_OBJECT;
|
||||
int op2_obj = Z_TYPE_P(op2) == IS_OBJECT;
|
||||
|
||||
if (op1_obj) {
|
||||
if (Z_OBJ_HT_P(op1)->get) {
|
||||
if (Z_TYPE_P(op2) == IS_NULL) {
|
||||
ZVAL_LONG(result, 1);
|
||||
return SUCCESS;
|
||||
} else if (Z_OBJ_HT_P(op1)->get) {
|
||||
op1 = op1_free = Z_OBJ_HT_P(op1)->get(op1 TSRMLS_CC);
|
||||
} else if (!op2_obj && Z_OBJ_HT_P(op1)->cast_object) {
|
||||
ALLOC_INIT_ZVAL(op1_free);
|
||||
if (Z_OBJ_HT_P(op1)->cast_object(op1, op1_free, Z_TYPE_P(op2) TSRMLS_CC) == FAILURE) {
|
||||
op2_free = NULL;
|
||||
ZVAL_BOOL(result, 0);
|
||||
COMPARE_RETURN_AND_FREE(FAILURE);
|
||||
ZVAL_LONG(result, 1);
|
||||
COMPARE_RETURN_AND_FREE(SUCCESS);
|
||||
}
|
||||
op1 = op1_free;
|
||||
} else {
|
||||
@ -1322,13 +1324,17 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
op1_free = NULL;
|
||||
}
|
||||
if (op2_obj) {
|
||||
if (Z_OBJ_HT_P(op2)->get) {
|
||||
if (Z_TYPE_P(op1) == IS_NULL) {
|
||||
op2_free = NULL;
|
||||
ZVAL_LONG(result, -1);
|
||||
COMPARE_RETURN_AND_FREE(SUCCESS);
|
||||
} else if (Z_OBJ_HT_P(op2)->get) {
|
||||
op2 = op2_free = Z_OBJ_HT_P(op2)->get(op2 TSRMLS_CC);
|
||||
} else if (!op1_obj && Z_OBJ_HT_P(op2)->cast_object) {
|
||||
ALLOC_INIT_ZVAL(op2_free);
|
||||
if (Z_OBJ_HT_P(op2)->cast_object(op2, op2_free, Z_TYPE_P(op1) TSRMLS_CC) == FAILURE) {
|
||||
ZVAL_BOOL(result, 0);
|
||||
COMPARE_RETURN_AND_FREE(FAILURE);
|
||||
ZVAL_LONG(result, -1);
|
||||
COMPARE_RETURN_AND_FREE(SUCCESS);
|
||||
}
|
||||
op2 = op2_free;
|
||||
} else {
|
||||
@ -1338,15 +1344,13 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
op2_free = NULL;
|
||||
}
|
||||
|
||||
if ((op1->type == IS_NULL && op2->type == IS_STRING)
|
||||
|| (op2->type == IS_NULL && op1->type == IS_STRING)) {
|
||||
if (op1->type == IS_NULL) {
|
||||
result->type = IS_LONG;
|
||||
result->value.lval = zend_binary_strcmp("", 0, op2->value.str.val, op2->value.str.len);
|
||||
if ((Z_TYPE_P(op1) == IS_NULL && Z_TYPE_P(op2) == IS_STRING)
|
||||
|| (Z_TYPE_P(op2) == IS_NULL && Z_TYPE_P(op1) == IS_STRING)) {
|
||||
if (Z_TYPE_P(op1) == IS_NULL) {
|
||||
ZVAL_LONG(result, zend_binary_strcmp("", 0, Z_STRVAL_P(op2), Z_STRLEN_P(op2)));
|
||||
COMPARE_RETURN_AND_FREE(SUCCESS);
|
||||
} else {
|
||||
result->type = IS_LONG;
|
||||
result->value.lval = zend_binary_strcmp(op1->value.str.val, op1->value.str.len, "", 0);
|
||||
ZVAL_LONG(result, zend_binary_strcmp(Z_STRVAL_P(op1), Z_STRLEN_P(op1), "", 0));
|
||||
COMPARE_RETURN_AND_FREE(SUCCESS);
|
||||
}
|
||||
}
|
||||
@ -1356,16 +1360,15 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
COMPARE_RETURN_AND_FREE(SUCCESS);
|
||||
}
|
||||
|
||||
if (op1->type == IS_BOOL || op2->type == IS_BOOL
|
||||
|| op1->type == IS_NULL || op2->type == IS_NULL) {
|
||||
if (Z_TYPE_P(op1) == IS_BOOL || Z_TYPE_P(op2) == IS_BOOL
|
||||
|| Z_TYPE_P(op1) == IS_NULL || Z_TYPE_P(op2) == IS_NULL) {
|
||||
zendi_convert_to_boolean(op1, op1_copy, result);
|
||||
zendi_convert_to_boolean(op2, op2_copy, result);
|
||||
result->type = IS_LONG;
|
||||
result->value.lval = ZEND_NORMALIZE_BOOL(op1->value.lval-op2->value.lval);
|
||||
ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2)));
|
||||
COMPARE_RETURN_AND_FREE(SUCCESS);
|
||||
}
|
||||
|
||||
if (op1->type==IS_OBJECT && op2->type==IS_OBJECT) {
|
||||
if (Z_TYPE_P(op1)==IS_OBJECT && Z_TYPE_P(op2)==IS_OBJECT) {
|
||||
/* If the handlers array is not identical, fall through
|
||||
* and perform get() or cast() if implemented
|
||||
*/
|
||||
@ -1378,41 +1381,35 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
zendi_convert_scalar_to_number(op1, op1_copy, result);
|
||||
zendi_convert_scalar_to_number(op2, op2_copy, result);
|
||||
|
||||
if (op1->type == IS_LONG && op2->type == IS_LONG) {
|
||||
result->type = IS_LONG;
|
||||
result->value.lval = op1->value.lval>op2->value.lval?1:(op1->value.lval<op2->value.lval?-1:0);
|
||||
if (Z_TYPE_P(op1) == IS_LONG && Z_TYPE_P(op2) == IS_LONG) {
|
||||
ZVAL_LONG(result, Z_LVAL_P(op1)>Z_LVAL_P(op2)?1:(Z_LVAL_P(op1)<Z_LVAL_P(op2)?-1:0));
|
||||
COMPARE_RETURN_AND_FREE(SUCCESS);
|
||||
}
|
||||
if ((op1->type == IS_DOUBLE || op1->type == IS_LONG)
|
||||
&& (op2->type == IS_DOUBLE || op2->type == IS_LONG)) {
|
||||
result->value.dval = (op1->type == IS_LONG ? (double) op1->value.lval : op1->value.dval) - (op2->type == IS_LONG ? (double) op2->value.lval : op2->value.dval);
|
||||
result->value.lval = ZEND_NORMALIZE_BOOL(result->value.dval);
|
||||
result->type = IS_LONG;
|
||||
if ((Z_TYPE_P(op1) == IS_DOUBLE || Z_TYPE_P(op1) == IS_LONG)
|
||||
&& (Z_TYPE_P(op2) == IS_DOUBLE || Z_TYPE_P(op2) == IS_LONG)) {
|
||||
Z_DVAL_P(result) = (Z_TYPE_P(op1) == IS_LONG ? (double) Z_LVAL_P(op1) : Z_DVAL_P(op1)) - (Z_TYPE_P(op2) == IS_LONG ? (double) Z_LVAL_P(op2) : Z_DVAL_P(op2));
|
||||
ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
|
||||
COMPARE_RETURN_AND_FREE(SUCCESS);
|
||||
}
|
||||
if (op1->type==IS_ARRAY && op2->type==IS_ARRAY) {
|
||||
if (Z_TYPE_P(op1)==IS_ARRAY && Z_TYPE_P(op2)==IS_ARRAY) {
|
||||
zend_compare_arrays(result, op1, op2 TSRMLS_CC);
|
||||
COMPARE_RETURN_AND_FREE(SUCCESS);
|
||||
}
|
||||
|
||||
if (op1->type==IS_ARRAY) {
|
||||
result->value.lval = 1;
|
||||
result->type = IS_LONG;
|
||||
if (Z_TYPE_P(op1)==IS_ARRAY) {
|
||||
ZVAL_LONG(result, 1);
|
||||
COMPARE_RETURN_AND_FREE(SUCCESS);
|
||||
}
|
||||
if (op2->type==IS_ARRAY) {
|
||||
result->value.lval = -1;
|
||||
result->type = IS_LONG;
|
||||
if (Z_TYPE_P(op2)==IS_ARRAY) {
|
||||
ZVAL_LONG(result, -1);
|
||||
COMPARE_RETURN_AND_FREE(SUCCESS);
|
||||
}
|
||||
if (op1->type==IS_OBJECT) {
|
||||
result->value.lval = 1;
|
||||
result->type = IS_LONG;
|
||||
if (Z_TYPE_P(op1)==IS_OBJECT) {
|
||||
ZVAL_LONG(result, 1);
|
||||
COMPARE_RETURN_AND_FREE(SUCCESS);
|
||||
}
|
||||
if (op2->type==IS_OBJECT) {
|
||||
result->value.lval = -1;
|
||||
result->type = IS_LONG;
|
||||
if (Z_TYPE_P(op2)==IS_OBJECT) {
|
||||
ZVAL_LONG(result, -1);
|
||||
COMPARE_RETURN_AND_FREE(SUCCESS);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user