ID:               43541
 User updated by:  [EMAIL PROTECTED]
 Reported By:      [EMAIL PROTECTED]
 Status:           Open
 Bug Type:         Arrays related
 Operating System: irrelevant
 PHP Version:      5.3CVS-2007-12-09 (CVS)
 New Comment:

Fixed tests and reduced patch. I still think the initial implementation
was wrong, but fixing it breaks long-established behaviour :\

Patch and tests sent to [EMAIL PROTECTED]

http://news.php.net/php.internals/33887


Previous Comments:
------------------------------------------------------------------------

[2007-12-09 01:03:45] [EMAIL PROTECTED]

Forgot to post patch. (Is there no way to upload files?)

Index: ext/standard/array.c
===================================================================
RCS file: /repository/php-src/ext/standard/array.c,v
retrieving revision 1.308.2.21.2.37.2.11
diff -u -r1.308.2.21.2.37.2.11 array.c
--- ext/standard/array.c        5 Dec 2007 19:55:31
-0000   1.308.2.21.2.37.2.11
+++ ext/standard/array.c        8 Dec 2007 23:10:28 -0000
@@ -2101,17 +2101,16 @@
        zval     *input,                /* Input array */
                        **entry;                /* An array entry */
        long     offset,                /* Offset to get elements from */
-                        length;                /* How many elements to get */
+                        length = 0;    /* How many elements to get */
        zend_bool preserve_keys = 0; /* Whether to preserve keys while
copying to the new array or not */
        int              num_in,                /* Number of elements in the 
input array */
                         pos;                   /* Current position in the 
array */
-       zval    *length_param;
        char *string_key;
        uint string_key_len;
        ulong num_key;
        HashPosition hpos;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "al|zb", &input,
&offset, &length_param, &preserve_keys) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "al|lb", &input,
&offset, &length, &preserve_keys) == FAILURE) {
                return;
        }
 
@@ -2119,9 +2118,7 @@
        num_in = zend_hash_num_elements(Z_ARRVAL_P(input));
 
        /* We want all entries from offset to the end if length is not passed
or is null */
-       if (ZEND_NUM_ARGS() >= 3 && Z_TYPE_P(length_param) != IS_NULL) {
-               length = Z_LVAL_P(length_param);
-       } else {
+       if (!ZEND_NUM_ARGS() >= 3 || length == IS_NULL) {
                length = num_in;
        }

------------------------------------------------------------------------

[2007-12-09 01:01:54] [EMAIL PROTECTED]

Description:
------------
If the length argument fed to array_slice() isn't of PHP type integer,
array_slice() fails silently.

This was broken during Jani's major backporting session from CVS HEAD
on Nov 2nd (i.e. it looks like HEAD's broken this way too). In the 5_2
branch there's a less clean API but the Z_LVAL_P is explicitly converted
to long.

http://cvs.php.net/viewvc.cgi/php-src/ext/standard/array.c?r1=1.308.2.21.2.37.2.5&r2=1.308.2.21.2.37.2.6&pathrev=PHP_5_3

I've a trivial fix for it that involves making the zval length
parameter  a long. It's impossible to tell from the test suite whether
this breaks anything that wasn't broken before (looking at how it's
used, I can't see how it could.) Patch should apply cleanly to HEAD
also, apart from the length initialization (already exists in HEAD but
not in 5_3).


Reproduce code:
---------------
Basic, but illustrates the problem:

<?php

$arr = array(1, 2, 3, 4, 5, 6);

var_dump(array_slice($arr, 0, (float)2));
var_dump(array_slice($arr, 0, (int)2));

?>


Expected result:
----------------
array(2) {
  [0]=>
  int(1)
  [1]=>
  int(2)
}
array(2) {
  [0]=>
  int(1)
  [1]=>
  int(2)
}


Actual result:
--------------
array(0) {
}
array(2) {
  [0]=>
  int(1)
  [1]=>
  int(2)
}


------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=43541&edit=1

Reply via email to