summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZeev Suraski <zeev@php.net>2004-05-10 14:56:21 +0000
committerZeev Suraski <zeev@php.net>2004-05-10 14:56:21 +0000
commit428e722d882699787234228270601649fddb0bbb (patch)
tree0546f2e04859aba899eb7193bd4dd8e8e19e6170
parentdbe02eff78edcc08b8c17bcbaacfb9a35b84cdd7 (diff)
downloadphp-git-428e722d882699787234228270601649fddb0bbb.tar.gz
- Fix comparison of objects
- Clarify convert_object_to_type()
-rw-r--r--Zend/zend_operators.c68
1 files changed, 48 insertions, 20 deletions
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index 1df4af3f88..96217df5b1 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -175,6 +175,9 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC)
(holder) = (*(op)); \
zval_copy_ctor(&(holder)); \
convert_to_long_base(&(holder), 10); \
+ if ((holder).type == IS_LONG) { \
+ (op) = &(holder); \
+ } \
break; \
} \
}
@@ -262,7 +265,6 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC)
if (Z_OBJ_HT_P(op)->cast_object) { \
if (Z_OBJ_HT_P(op)->cast_object(op, op, ctype, 1 TSRMLS_CC) == SUCCESS) { \
op->type = ctype; \
- return; \
} \
} else { \
if(Z_OBJ_HT_P(op)->get) { \
@@ -273,7 +275,6 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC)
*op = *newop; \
FREE_ZVAL(newop); \
conv_func(op); \
- return; \
} \
} \
}
@@ -322,7 +323,11 @@ ZEND_API void convert_to_long_base(zval *op, int base)
TSRMLS_FETCH();
convert_object_to_type(op, IS_LONG, convert_to_long);
-
+
+ if (op->type == IS_LONG) {
+ return;
+ }
+
if (EG(ze1_compatibility_mode)) {
HashTable *ht = Z_OBJPROP_P(op);
if (ht) {
@@ -330,8 +335,11 @@ ZEND_API void convert_to_long_base(zval *op, int base)
}
zval_dtor(op);
ZVAL_LONG(op, retval);
+ return;
+ } else {
+ /* we cannot convert it to long */
+ return;
}
- break;
}
default:
zend_error(E_WARNING, "Cannot convert to ordinal value");
@@ -383,6 +391,10 @@ ZEND_API void convert_to_double(zval *op)
convert_object_to_type(op, IS_DOUBLE, convert_to_double);
+ if (op->type == IS_DOUBLE) {
+ return;
+ }
+
if (EG(ze1_compatibility_mode)) {
HashTable *ht = Z_OBJPROP_P(op);
if (ht) {
@@ -467,6 +479,10 @@ ZEND_API void convert_to_boolean(zval *op)
TSRMLS_FETCH();
convert_object_to_type(op, IS_BOOL, convert_to_double);
+
+ if (op->type == IS_BOOL) {
+ return;
+ }
if (EG(ze1_compatibility_mode)) {
HashTable *ht = Z_OBJPROP_P(op);
@@ -542,6 +558,10 @@ ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC)
convert_object_to_type(op, IS_STRING, convert_to_string);
+ if (op->type == IS_STRING) {
+ return;
+ }
+
zend_error(E_NOTICE, "Object of class %s to string conversion", Z_OBJCE_P(op)->name);
zval_dtor(op);
op->value.str.val = estrndup_rel("Object", sizeof("Object")-1);
@@ -608,6 +628,10 @@ ZEND_API void convert_to_array(zval *op)
}
} else {
convert_object_to_type(op, IS_ARRAY, convert_to_array);
+
+ if (op->type == IS_ARRAY) {
+ return;
+ }
}
zval_dtor(op);
op->type = IS_ARRAY;
@@ -1276,6 +1300,16 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
COMPARE_RETURN_AND_FREE(SUCCESS);
}
+ if (op1->type==IS_OBJECT && op2->type==IS_OBJECT) {
+ /* If the handlers array is not identical, fall through
+ * and perform get() or cast() if implemented
+ */
+ if (Z_OBJ_HT_P(op1) == Z_OBJ_HT_P(op2)) {
+ zend_compare_objects(result, op1, op2 TSRMLS_CC);
+ COMPARE_RETURN_AND_FREE(SUCCESS);
+ }
+ }
+
zendi_convert_scalar_to_number(op1, op1_copy, result);
zendi_convert_scalar_to_number(op2, op2_copy, result);
@@ -1296,11 +1330,6 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
COMPARE_RETURN_AND_FREE(SUCCESS);
}
- if (op1->type==IS_OBJECT && op2->type==IS_OBJECT) {
- zend_compare_objects(result, op1, op2 TSRMLS_CC);
- COMPARE_RETURN_AND_FREE(SUCCESS);
- }
-
if (op1->type==IS_ARRAY) {
result->value.lval = 1;
result->type = IS_LONG;
@@ -1379,8 +1408,16 @@ ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
}
break;
case IS_OBJECT:
- if (Z_OBJ_HT_P(op1) == Z_OBJ_HT_P(op2) && Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2)) {
- result->value.lval = 1;
+ if (Z_OBJ_HT_P(op1) == Z_OBJ_HT_P(op2)) {
+ if (EG(ze1_compatibility_mode)) {
+ zend_compare_objects(result, op1, op2 TSRMLS_CC);
+ /* comparison returns 0 in case of equality and
+ * 1 in case of ineqaulity, we need to reverse it
+ */
+ result->value.lval = !result->value.lval;
+ } else {
+ result->value.lval = (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2));
+ }
} else {
result->value.lval = 0;
}
@@ -1884,15 +1921,6 @@ ZEND_API void zend_compare_arrays(zval *result, zval *a1, zval *a2 TSRMLS_DC)
ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2 TSRMLS_DC)
{
result->type = IS_LONG;
- if (Z_OBJ_HT_P(o1) != Z_OBJ_HT_P(o2)) {
- result->value.lval = 1; /* Comparing objects of different types is pretty much meaningless */
- return;
- }
-
- if (EG(ze1_compatibility_mode) && Z_OBJPROP_P(o1) && Z_OBJPROP_P(o2)) {
- zend_compare_symbol_tables(result, Z_OBJPROP_P(o1), Z_OBJPROP_P(o2) TSRMLS_CC);
- return;
- }
if (Z_OBJ_HT_P(o1)->compare_objects == NULL) {
if (Z_OBJ_HANDLE_P(o1) == Z_OBJ_HANDLE_P(o2)) {