Make array_pad's $length warning less confusing#10149
Conversation
Girgias
left a comment
There was a problem hiding this comment.
Not exactly sure of the wording, but this is definitely an improvement (also removes a duplicate computation).
10df271 to
f70ce66
Compare
Actually this can happen due to undefined behavior, when the result of abs() can not be represented in the return type. With ZEND_ABS(), and assuming two's complement, this happens with pad_size=INTMAX_MIN only. If sizeof(intmax_t) > sizeof(zend_long), the conversion is implementation defined as well. We could check that pad_size > LONG_MIN before calling ZEND_ABS(). We should add a test with length=PHP_INT_MIN. |
Right. My compiler actually optimizes away the check because of the UB. So on my system the old code didn't actually perform the
I can take a look at testing this soon-ish. |
f70ce66 to
88a98fa
Compare
|
I removed the arbitrary limit, and perform the check first on |
That looks reasonable, but I wonder why that 1048576 limit had been chosen. It has been introduced by 4b343a0, but the commit message is not helpful. |
|
Found the original commit: 7e8039e, and I think a related internals post: https://marc.info/?l=php-internals&m=104919385614541&w=2, but no details about the crash or the fix, except that it's an arbitrarily chosen limit. The implementation of array_pad back then has nothing in common with today's. |
|
From reading the code of array_pad, it seems safe as long as Also, |
|
@nielsdos could you adjust I will merge after that. |
The error message was wrong; it *is* possible to use a larger length. Furthermore, there is an arbitrary restriction on the new array's length. Fix both by checking the length against HT_MAX_SIZE.
88a98fa to
56f3ef4
Compare
Thank you, I've rebased and updated the test. |
|
Thank you! |
|
Thank you for the merge! |
|
Indeed! I've just added an UPGRADING entry |
|
Thank you! |
The error message was wrong; it is possible to use a larger length. The error message should be clear it's about how much padding is required.
Valid example with length greater than 1048576:
If we were to remove the
- 1in the above code snippet such that the required padding length becomes too large, it would be especially confusing for developers using thearray_padfunction.This patch also removes a redundant check on pad_size_abs: it can never be negative since it is the absolute value of pad_size.EDIT: I changed the code to check the new array length instead of having an arbtrary limit. This also simplifies the error message.
Note: I targeted the master branch because I'm not sure how much confusion is considered a bug.