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:
Adding this for the sake of completeness, just in case there's a
decision taken to dump the zval.
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 10 Dec 2007 20:31:35 -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 (length == 0) {
length = num_in;
}
Previous Comments:
------------------------------------------------------------------------
[2007-12-09 23:40:08] [EMAIL PROTECTED]
It's just not my day.
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 9 Dec 2007 23:07:13 -0000
@@ -2120,6 +2120,7 @@
/* 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) {
+ convert_to_long_ex(&length_param);
length = Z_LVAL_P(length_param);
} else {
length = num_in;
------------------------------------------------------------------------
[2007-12-09 23:35:55] [EMAIL PROTECTED]
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
------------------------------------------------------------------------
[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