iliaa Tue Feb 5 16:01:22 2008 UTC
Modified files: (Branch: PHP_5_2)
/php-src/ext/standard array.c
/php-src NEWS
Log:
MFB: Fixed bug #44046 (crash inside array_slice() function with an invalid
by-ref offset).
http://cvs.php.net/viewvc.cgi/php-src/ext/standard/array.c?r1=1.308.2.21.2.48&r2=1.308.2.21.2.49&diff_format=u
Index: php-src/ext/standard/array.c
diff -u php-src/ext/standard/array.c:1.308.2.21.2.48
php-src/ext/standard/array.c:1.308.2.21.2.49
--- php-src/ext/standard/array.c:1.308.2.21.2.48 Tue Jan 29 10:44:53 2008
+++ php-src/ext/standard/array.c Tue Feb 5 16:01:21 2008
@@ -21,7 +21,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: array.c,v 1.308.2.21.2.48 2008/01/29 10:44:53 dmitry Exp $ */
+/* $Id: array.c,v 1.308.2.21.2.49 2008/02/05 16:01:21 iliaa Exp $ */
#include "php.h"
#include "php_ini.h"
@@ -2201,103 +2201,79 @@
Returns elements specified by offset and length */
PHP_FUNCTION(array_slice)
{
- zval **input, /* Input array */
- **offset, /* Offset to get elements from */
- **length, /* How many elements to get */
- **entry, /* An array entry */
- **z_preserve_keys; /* Whether to preserve keys while copying
to the new array or not */
- int offset_val, /* Value of the offset argument */
- length_val, /* Value of the length argument */
- num_in, /* Number of elements in the input
array */
- pos, /* Current position in the array */
- argc; /* Number of function arguments */
-
+ zval *input, /* Input array */
+ **entry; /* An array entry */
+ long offset, /* Offset to get elements from */
+ length = NULL; /* 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 */
char *string_key;
uint string_key_len;
ulong num_key;
HashPosition hpos;
- zend_bool preserve_keys = 0;
- /* Get the arguments and do error-checking */
- argc = ZEND_NUM_ARGS();
- if (argc < 2 || argc > 4 || zend_get_parameters_ex(argc, &input,
&offset, &length, &z_preserve_keys)) {
- WRONG_PARAM_COUNT;
- }
-
- if (Z_TYPE_PP(input) != IS_ARRAY) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "The first argument
should be an array");
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "al|lb", &input,
&offset, &length, &preserve_keys) == FAILURE) {
return;
}
-
- /* Make sure offset and length are integers and assume
- we want all entries from offset to the end if length
- is not passed */
- convert_to_long_ex(offset);
- offset_val = Z_LVAL_PP(offset);
- if (argc >= 3 && Z_TYPE_PP(length) != IS_NULL) {
- convert_to_long_ex(length);
- length_val = Z_LVAL_PP(length);
- } else {
- length_val = zend_hash_num_elements(Z_ARRVAL_PP(input));
- }
- if (ZEND_NUM_ARGS() > 3) {
- convert_to_boolean_ex(z_preserve_keys);
- preserve_keys = Z_BVAL_PP(z_preserve_keys);
+ /* Get number of entries in the input hash */
+ 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 (length == NULL) {
+ length = num_in;
}
-
+
/* Initialize returned array */
array_init(return_value);
-
- /* Get number of entries in the input hash */
- num_in = zend_hash_num_elements(Z_ARRVAL_PP(input));
-
+
/* Clamp the offset.. */
- if (offset_val > num_in)
+ if (offset > num_in) {
return;
- else if (offset_val < 0 && (offset_val = (num_in + offset_val)) < 0)
- offset_val = 0;
-
+ } else if (offset < 0 && (offset = (num_in + offset)) < 0) {
+ offset = 0;
+ }
+
/* ..and the length */
- if (length_val < 0) {
- length_val = num_in - offset_val + length_val;
- } else if (((unsigned)offset_val + (unsigned)length_val) >
(unsigned)num_in) {
- length_val = num_in - offset_val;
+ if (length < 0) {
+ length = num_in - offset + length;
+ } else if (((unsigned) offset + (unsigned) length) > (unsigned) num_in)
{
+ length = num_in - offset;
}
-
- if (length_val == 0)
+
+ if (length == 0) {
return;
-
+ }
+
/* Start at the beginning and go until we hit offset */
pos = 0;
- zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(input), &hpos);
- while (pos < offset_val &&
zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&entry, &hpos) ==
SUCCESS) {
+ zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &hpos);
+ while (pos < offset && zend_hash_get_current_data_ex(Z_ARRVAL_P(input),
(void **)&entry, &hpos) == SUCCESS) {
pos++;
- zend_hash_move_forward_ex(Z_ARRVAL_PP(input), &hpos);
+ zend_hash_move_forward_ex(Z_ARRVAL_P(input), &hpos);
}
-
+
/* Copy elements from input array to the one that's returned */
- while (pos < offset_val+length_val &&
zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&entry, &hpos) ==
SUCCESS) {
-
- (*entry)->refcount++;
+ while (pos < offset + length &&
zend_hash_get_current_data_ex(Z_ARRVAL_P(input), (void **)&entry, &hpos) ==
SUCCESS) {
- switch (zend_hash_get_current_key_ex(Z_ARRVAL_PP(input),
&string_key, &string_key_len, &num_key, 0, &hpos)) {
+ zval_add_ref(entry);
+
+ switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(input),
&string_key, &string_key_len, &num_key, 0, &hpos)) {
case HASH_KEY_IS_STRING:
- zend_hash_update(Z_ARRVAL_P(return_value),
string_key, string_key_len,
- entry,
sizeof(zval *), NULL);
+ zend_hash_update(Z_ARRVAL_P(return_value),
string_key, string_key_len, entry, sizeof(zval *), NULL);
break;
-
+
case HASH_KEY_IS_LONG:
- if (preserve_keys)
-
zend_hash_index_update(Z_ARRVAL_P(return_value), num_key,
-
entry, sizeof(zval *), NULL);
- else
-
zend_hash_next_index_insert(Z_ARRVAL_P(return_value),
-
entry, sizeof(zval *), NULL);
+ if (preserve_keys) {
+
zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry, sizeof(zval
*), NULL);
+ } else {
+
zend_hash_next_index_insert(Z_ARRVAL_P(return_value), entry, sizeof(zval *),
NULL);
+ }
break;
}
pos++;
- zend_hash_move_forward_ex(Z_ARRVAL_PP(input), &hpos);
+ zend_hash_move_forward_ex(Z_ARRVAL_P(input), &hpos);
}
}
/* }}} */
http://cvs.php.net/viewvc.cgi/php-src/NEWS?r1=1.2027.2.547.2.1073&r2=1.2027.2.547.2.1074&diff_format=u
Index: php-src/NEWS
diff -u php-src/NEWS:1.2027.2.547.2.1073 php-src/NEWS:1.2027.2.547.2.1074
--- php-src/NEWS:1.2027.2.547.2.1073 Mon Feb 4 21:31:52 2008
+++ php-src/NEWS Tue Feb 5 16:01:21 2008
@@ -9,6 +9,8 @@
which to group by data is specified. (Ilia)
- Upgraded PCRE to version 7.6 (Nuno)
+- Fixed bug #44046 (crash inside array_slice() function with an invalid
+ by-ref offset). (Ilia)
- Fixed bug #44028 (crash inside stream_socket_enable_crypto() when enabling
encryption without crypto type). (Ilia)
- Fixed bug #43954 (Memory leak when sending the same HTTP status code
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php