PHPCSStandards / PHP_CodeSniffer

PHP_CodeSniffer tokenizes PHP files and detects violations of a defined set of coding standards.
BSD 3-Clause "New" or "Revised" License
906 stars 55 forks source link

False positive on `Generic.PHP.ForbiddenFunctions.FoundWithAlternative` #439

Open p4veI opened 5 months ago

p4veI commented 5 months ago

Describe the bug

This sniff incorrectly reports an error while using in my case \Psl\Str\join function and reports forbidden use of the native PHP function

Code sample

src/a.php


<?php

use function Psl\Str\join;

class A {
  public function get(): string
  {
    $a = ['bar', 'baz', 'foo'];

    return join($a, ',');
  }
}

phpcs.xml

<?xml version="1.0"?>
<ruleset
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="vendor/squizlabs/php_codesniffer/phpcs.xsd"
>
    <arg name="basepath" value="."/>
    <arg name="cache" value=".phpcs-cache"/>

    <rule ref="Generic.PHP.ForbiddenFunctions">
        <properties>
            <property name="forbiddenFunctions" type="array">
                <element key="join" value="implode"/>
            </property>
        </properties>
    </rule>

    <file>src</file>
</ruleset>

Expected behavior

No errors

Versions (please complete the following information)

PHP version 8.3
PHP_CodeSniffer version 3.9 & master
Standard Generic

Please confirm:

DannyvdSluijs commented 5 months ago

I can confirm this is reproducible with the current master branch (commit dba1cc147947f77f1eee5703ca90a6ed1c0da9e2)

The output when running on the file using the config is:

FILE: reproductions/439.php
-----------------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
-----------------------------------------------------------------------------
 10 | ERROR | The use of function join() is forbidden; use implode() instead
-----------------------------------------------------------------------------

Time: 47ms; Memory: 4MB

Debugging the violating token shows the information as shown below. Which doesn't seem to contain any information about the function namespace. Perhaps that is where the issue lies as adjusting the code the use the full qualified function name resolves the false positive. Should we perhaps look at the uses/imports and see if there is one that matches the function name. Also one last remark is that when using \join() (the native PHP versie with the root namespace of slash) it is correctly detected.

array(8) {
  'code' =>
  int(262)
  'type' =>
  string(8) "T_STRING"
  'content' =>
  string(4) "join"
  'line' =>
  int(10)
  'column' =>
  int(16)
  'length' =>
  int(4)
  'level' =>
  int(2)
  'conditions' =>
  array(2) {
    [14] =>
    int(333)
    [23] =>
    int(310)
  }
}