Bug #74351 [Opn->Ana]: array_u* functions are not variadic (as reported by reflection)

[email protected]
Newsgroups php.bugs
Message-ID <[email protected]>
Edit report at https://bugs.php.net/bug.php?id=74351&edit=1

 ID:                 74351
 Updated by:         [email protected]
 Reported by:        fabien dot villepinte at gmail dot com
-Summary:            Wrong reflection on variadic array functions
+Summary:            array_u* functions are not variadic (as reported by
                     reflection)
-Status:             Open
+Status:             Analyzed
 Type:               Bug
-Package:            Reflection related
+Package:            Arrays related
-PHP Version:        Irrelevant
+PHP Version:        7.1.3
 Block user comment: N
 Private report:     N

 New Comment:

Reflection is working correctly: those functions are not actually defined internally as being variadic.

https://github.com/php/php-src/blob/PHP-7.1.3/ext/standard/basic_functions.c#L534
It's C but the assorted ZEND_BEGIN_ARG_INFOs are fairly self-explanatory. Note the use of ZEND_ARG_INFO for regular parameters and ZEND_ARG_VARIADIC_INFO for variadic parameters.

The problem is that they all take a final callback parameter (or two) after the varargs list, and that doesn't fit the rules for how variadics work. What PHP did is akin to the PHP <5.6 style of using func_get_args(), and like a corresponding userland implementation the parameters will not be considered variadic.

I'll move this to Analyzed but I'm not sure whether it can/should be fixed.


Previous Comments:
------------------------------------------------------------------------
[2017-03-31 18:15:08] fabien dot villepinte at gmail dot com

Description:
------------
The following functions are variadic but ReflectionFunction::isVariadic and ReflectionParameter::isVariadic return false :
array_diff_uassoc
array_diff_ukey
array_intersect_uassoc
array_intersect_ukey
array_udiff
array_udiff_assoc
array_udiff_uassoc
array_uintersect
array_uintersect_assoc
array_uintersect_uassoc

The test script looks more complicated than necessary because I wanted to highlight the differencies with HHVM (see : https://3v4l.org/clKBH ).

Test script:
---------------
<?php

$functions = [
    'array_diff_uassoc',
    'array_diff_ukey',
    'array_intersect_uassoc',
    'array_intersect_ukey',
    'array_udiff',
    'array_udiff_assoc',
    'array_udiff_uassoc',
    'array_uintersect',
    'array_uintersect_assoc',
    'array_uintersect_uassoc',
];

foreach ($functions as $func) {
    $reflFunc = new ReflectionFunction($func);
    $nbParams = $reflFunc->getNumberOfParameters();
    $nbRequiredParams = $reflFunc->getNumberOfRequiredParameters();
    printf("$func ($nbParams params, $nbRequiredParams required) %s VARIADIC", $reflFunc->isVariadic() ? "IS" : "IS NOT");
    foreach ($reflFunc->getParameters() as $i => $param) {
        if ($param->isVariadic()) {
            printf(" - PARAM #%d%s IS VARIADIC", $i + 1, $param->isOptional() ? " (Opt.)" : "");
        }
    }
    echo PHP_EOL;
}

Expected result:
----------------
array_diff_uassoc (3 params, 3 required) IS VARIADIC - PARAM #2 IS VARIADIC
array_diff_ukey (3 params, 3 required) IS VARIADIC - PARAM #2 IS VARIADIC
array_intersect_uassoc (3 params, 3 required) IS VARIADIC - PARAM #2 IS VARIADIC
array_intersect_ukey (3 params, 3 required) IS VARIADIC - PARAM #2 IS VARIADIC
array_udiff (3 params, 3 required) IS VARIADIC - PARAM #2 IS VARIADIC
array_udiff_assoc (3 params, 3 required) IS VARIADIC - PARAM #2 IS VARIADIC
array_udiff_uassoc (4 params, 4 required) IS VARIADIC - PARAM #2 IS VARIADIC
array_uintersect (3 params, 3 required) IS VARIADIC - PARAM #2 IS VARIADIC
array_uintersect_assoc (3 params, 3 required) IS VARIADIC - PARAM #2 IS VARIADIC
array_uintersect_uassoc (4 params, 4 required) IS VARIADIC - PARAM #2 IS VARIADIC

Actual result:
--------------
array_diff_uassoc (3 params, 3 required) IS NOT VARIADIC
array_diff_ukey (3 params, 3 required) IS NOT VARIADIC
array_intersect_uassoc (3 params, 3 required) IS NOT VARIADIC
array_intersect_ukey (3 params, 3 required) IS NOT VARIADIC
array_udiff (3 params, 3 required) IS NOT VARIADIC
array_udiff_assoc (3 params, 3 required) IS NOT VARIADIC
array_udiff_uassoc (4 params, 4 required) IS NOT VARIADIC
array_uintersect (3 params, 3 required) IS NOT VARIADIC
array_uintersect_assoc (3 params, 3 required) IS NOT VARIADIC
array_uintersect_uassoc (4 params, 4 required) IS NOT VARIADIC


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



--
Edit this bug report at https://bugs.php.net/bug.php?id=74351&edit=1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.