Re: Sorting Bug / Wrong behavior?
| From: | Marcus Boerger | Date: | Tue, 27 Jul 2004 19:45:59 +0000 |
| Subject: | Re: Sorting Bug / Wrong behavior? | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-11620@lists.php.net to get a copy of this message | ||
Hello John,
Tuesday, July 27, 2004, 9:48:28 PM, you wrote:
> Consider the following:
> <?php $a = array('a', 'b', 'c', 'a'=>0,
> 'b'=>1, 'c'=>2);
> sort($a);
> print_r($a);
?>>
> This produces a bogus output:
> Array
> (
> [0] => a
> [1] => b
> [2] => 0
> [3] => c
> [4] => 1
> [5] => 2
> )
> Notice how 0 and c are switched incorrectly. Attached is a patch to
> zend_operators.c that fixes it.
The current order simply makes no sense at all.ŽThe following though would:
0 a b c 1 2 // zero dirst, then strings then numbers
a b c 0 1 2 // strings first, then numbers
0 1 2 a b c // numbers first, then strings
and btw, john you forgot the patch, it is attached here.
The one provided does the 2nd which means we only ensured
0 is treated un the same way other numbers are.
Best regards,
Marcus mailto:helly@php.net
Index: Zend/zend_operators.c =================================================================== RCS file: /repository/ZendEngine2/zend_operators.c,v retrieving revision 1.194 diff -u -p -d -r1.194 zend_operators.c --- Zend/zend_operators.c 19 Jul 2004 07:19:02 -0000 1.194 +++ Zend/zend_operators.c 27 Jul 2004 16:24:17 -0000 @@ -1251,6 +1251,9 @@ static inline void zend_free_obj_get_res zend_free_obj_get_result(op2, free_op2); \ return retval; +#define CHECK_SPECIAL(op1, op2) \ + (op1->type == IS_LONG && !op1->value.lval && op2->type == IS_STRING) + ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) { zval op1_copy, op2_copy; @@ -1303,6 +1306,16 @@ ZEND_API int compare_function(zval *resu } } + if (CHECK_SPECIAL(op1, op2)) { + result->type = IS_LONG; + result->value.lval = 1; + COMPARE_RETURN_AND_FREE(SUCCESS); + } else if (CHECK_SPECIAL(op2, op1)) { + result->type = IS_LONG; + result->value.lval = -1; + COMPARE_RETURN_AND_FREE(SUCCESS); + } + zendi_convert_scalar_to_number(op1, op1_copy, result); zendi_convert_scalar_to_number(op2, op2_copy, result);
Index: Zend/zend_operators.c =================================================================== RCS file: /repository/ZendEngine2/zend_operators.c,v retrieving revision 1.194 diff -u -p -d -r1.194 zend_operators.c --- Zend/zend_operators.c 19 Jul 2004 07:19:02 -0000 1.194 +++ Zend/zend_operators.c 27 Jul 2004 16:24:17 -0000 @@ -1251,6 +1251,9 @@ static inline void zend_free_obj_get_res zend_free_obj_get_result(op2, free_op2); \ return retval; +#define CHECK_SPECIAL(op1, op2) \ + (op1->type == IS_LONG && !op1->value.lval && op2->type == IS_STRING) + ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) { zval op1_copy, op2_copy; @@ -1303,6 +1306,16 @@ ZEND_API int compare_function(zval *resu } } + if (CHECK_SPECIAL(op1, op2)) { + result->type = IS_LONG; + result->value.lval = 1; + COMPARE_RETURN_AND_FREE(SUCCESS); + } else if (CHECK_SPECIAL(op2, op1)) { + result->type = IS_LONG; + result->value.lval = -1; + COMPARE_RETURN_AND_FREE(SUCCESS); + } + zendi_convert_scalar_to_number(op1, op1_copy, result); zendi_convert_scalar_to_number(op2, op2_copy, result);