Hi Stas,

I just spent most of two evenings looking at this one - so much for an easy fix. Read on...

the code is

if (ZEND_NUM_ARGS() >= 3 && Z_TYPE_P(length_param) != IS_NULL) {
length = Z_LVAL_P(length_param);
} else {
length = num_in;
}

and afaik should be

I think in fact it should just parse it as long and not as zval - what would be any reason to parse it as zval and then convert to long anyway?

The problem is that this function's always been wrong, so it doesn't really care what you throw at it - it just does a silent conversion to long if you get it wrong. If you turn the parameter into a long now, there's a good chance of breaking a lot of code out there - not least because at present if you give array_slice() a length of 0, that's what it (sanely or otherwise) takes it to mean. If you fix it, it will see 0 as meaning 'everything to the end of the array'. So one of the tests at present is:

var_dump(array_slice($sub_array, 0, 0));

and the expectation is for that to always return:

array(0) {
}

Unfortunately this is far from new behaviour.

As far as the original float issue goes: What's been happening up to now is that anything fed in as the third argument gets converted to a long, and now it doesn't. Should be easy enough to sort out you'd think, but when you try to do:

/* 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;
}

all of a sudden the fourth parameter, preserve_keys, doesn't throw zend_parse_parameter() warnings any more, regardless of the type you give it. (You tell me...)

There's also the issue of what to do about inappropriate vs appropriate input types, since we can't rely on zend_parse_parameters() to psychically know that this particular zval is really a loose long kind of thing... so I tried:

if (ZEND_NUM_ARGS() >= 3 && Z_TYPE_P(length_param) > IS_DOUBLE) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "integer expected in parameter 3, %s given", zend_zval_type_name(length_param));
}

This actually doesn't seem to harm anything, but I bet Dmitry'd say otherwise (it probably slows the function right down).

So - not as straightforward as it looks, whatever way you look at it. Maybe we should just revert to the old, messy but mostly working code for array_slice()?

- Steph

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to