]> granicus.if.org Git - php/commitdiff
- Fix comparison of objects
authorZeev Suraski <zeev@php.net>
Mon, 10 May 2004 14:56:21 +0000 (14:56 +0000)
committerZeev Suraski <zeev@php.net>
Mon, 10 May 2004 14:56:21 +0000 (14:56 +0000)
- Clarify convert_object_to_type()

Zend/zend_operators.c

index 1df4af3f880d1b53fe13640b31ca2e535c1065dc..96217df5b15df6cc68a9ec0fc158939e5b9c701b 100644 (file)
@@ -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)) {