Giter VIP home page Giter VIP logo

phpstan-disallowed-calls's Introduction

Disallowed calls for PHPStan

PHPStan rules to detect disallowed calls and more, without running the code.

PHP Tests

There are some functions, methods, and constants which should not be used in production code. One good example is var_dump(), it is often used to quickly debug problems but should be removed before committing the code. And sometimes it's not.

Another example would be a generic logger. Let's say you're using one of the generic logging libraries but you have your own logger that will add some more info, or sanitize data, before calling the generic logger. Your code should not call the generic logger directly but should instead use your custom logger.

This PHPStan extension will detect such usage, if configured. It should be noted that this extension is not a way to defend against or detect hostile developers, as they can obfuscate the calls for example. This extension is meant to be another pair of eyes, detecting your own mistakes, it doesn't aim to detect-all-the-things.

Tests will provide examples what is currently detected. If it's not covered by tests, it might be, but most probably will not be detected. *Test.php files are the tests, start with those, the analyzed test code is in src, required test classes in libs.

Feel free to file issues or create pull requests if you need to detect more calls.

Installation

Install the extension using Composer:

composer require --dev spaze/phpstan-disallowed-calls

PHPStan, the PHP Static Analysis Tool, is a requirement.

If you use phpstan/extension-installer, you are all set and can skip to configuration.

For manual installation, add this to your phpstan.neon:

includes:
    - vendor/spaze/phpstan-disallowed-calls/extension.neon

Configuration files

You can start with bundled configuration files.

Custom rules

The extension supports versatile custom rules, too.

Allow some previously disallowed calls or usages

Let's say you have disallowed foo() with custom rules. But you want to re-allow it when used in your custom wrapper, or when the first parameter equals, or not, a specified value. The extension offers multiple ways of doing that:

Re-allowing attributes uses a similar configuration.

Disallow disabled functions & classes

Use the provided generator to generate a configuration snippet from PHP's disable_functions & disable_classes configuration directives.

Example output

 ------ --------------------------------------------------------
  Line   libraries/Report/Processor/CertificateTransparency.php
 ------ --------------------------------------------------------
  116    Calling var_dump() is forbidden, use logger instead
 ------ --------------------------------------------------------

Case-(in)sensitivity

Function names, method names, class names, namespaces are matched irrespective of their case (disallowing print_r will also find print_R calls), while anything else like constants, file names, paths are not.

No other rules

You can also use this extension without any other PHPStan rules. This may be useful if you want to for example check a third-party code for some calls or usage of something.

Running tests

If you want to contribute (awesome, thanks!), you should add/run tests for your contributions. First install dev dependencies by running composer install, then run PHPUnit tests with composer test, see scripts in composer.json. Tests are also run on GitHub with Actions on each push.

You can fix coding style issues automatically by running composer cs-fix.

See also

There's a similar project with a slightly different configuration, created almost at the same time (just a few days difference): PHPStan Banned Code.

Framework or package-specific configurations

phpstan-disallowed-calls's People

Contributors

backendtea avatar compwright avatar eithed avatar enumag avatar francescolaffi avatar ilazaridis avatar mad-briller avatar mnastalski avatar ondrejmirtes avatar peter279k avatar ramondantas-cp avatar ruudk avatar spaze avatar szepeviktor avatar xificurk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

phpstan-disallowed-calls's Issues

Add disallowedClasses

From docs we know that 5. disallowedNamespaces - for usages of classes from a namespace. However I need to disallow a single class usage. I could list the constructor method and all the named constructors in disallowedMethodCalls and disallowedStaticCalls but this is to much overhead than just to disallow a class. I tried the disallowedNamespaces parameter but used a FQCN instead of namespace and it worked but I don't know if this is just a coincidence or this parameters works with classes as well (if so then I would just update the docs to mention that and we can close this issue).

Thank you.

When the call/usage is not found in `allowIn`, report error

Given a configuration like this for example:

	disallowedFunctionCalls:
		-
			function: 'pcntl_*()'
			allowIn:
				- vendor/foo/bar/Baz.php

when any pcntl call is not found in vendor/foo/bar/Baz.php, report error and suggest removing the allowIn item to keep the config clean and up to date.

This is similar to what PHPStan reports when a ignoreErrors error wasn't hit.

Support language constructs

Hello ๐Ÿ‘‹

Firstly, thank you for creating this package. I really like the ability to add my own rules for code that shouldn't be used.

I couldn't manage to find anywhere info regarding the support for language constructs like die, exit etc. Are these supported or not currently? I tried adding them under disallowedFunctionCalls because I saw this in the readme, but that doesn't seem to work:
You can treat eval() as a function (although it's a language construct) and disallow it in disallowedFunctionCalls.

Am I missing something? If the case is they are not currently supported, how involved do you think it would be to support them? I can see ekino/phpstan-banned-code supports them but the implementation of the whole thing there is completely different and a lot simpler (I'm not sure what the drawbacks are!).

Cheers!

ShouldNotHappenException in NonObjectTypeTrait when analyzing one of the classes

Hello everyone,

Just tried out your nice tool on one of our projects and in one of the files I get the following error:

Stack trace:

#0 /app/vendor/spaze/phpstan-disallowed-calls/src/ClassConstantUsages.php(73): PHPStan\Type\StringType->getConstant('STEP_NAME')
#1 phar:///app/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/FileAnalyser.php(70): Spaze\PHPStan\Rules\Disallowed\ClassConstantUsages->processNode(Object(PhpParser\Node\Expr\ClassConstFetch), Object(PHPStan\Analyser\MutatingScope))
#2 phar:///app/vendor/phpstan/phpstan/phpstan.phar/src/Node/ClassStatementsGatherer.php(91): PHPStan\Analyser\FileAnalyser->PHPStan\Analyser\{closure}(Object(PhpParser\Node\Expr\ClassConstFetch), Object(PHPStan\Analyser\MutatingScope))
#3 phar:///app/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(389): PHPStan\Node\ClassStatementsGatherer->__invoke(Object(PhpParser\Node\Expr\ClassConstFetch), Object(PHPStan\Analyser\MutatingScope))
#4 phar:///app/vendor/phpstan/phpst in phar:///app/vendor/phpstan/phpstan/phpstan.phar/src/Type/Traits/NonObjectTypeTrait.php on line 47

It breaks when analyzing a class that calls the STEP_NAME constant. The constant with this name is defined in multiple other classes.

Please let me know if you need more details.

Document things which are detected and which are not

This extension doesn't aim to detect all the things, some calls are not detected and it's a bug and some undetected calls are a feature, more or less.

It should be documented, what the user can expect to be detected. Could reference users to tests, because if it's tested then it's guaranteed to be detected, otherwise YMMV.

For that purpose, tests should be restructured so they're mode readable.

*CallsTest.php files are quite readable but the disallowed-calls.php file is a mess right now and should be split into several files, e.g.:

  • disallowed/methodCalls.php
  • disallowed/staticCalls.php
  • disallowed/functionCalls.php
    Similar applies to disallowed-calls-allowed.php)

Classes like Traits etc moved to libs or something.

Support $foo::BAR where foo is declared as a string or a class-string

These should be supported

/** @var string $monster */
$monster = DateTime::class;
$monster::COOKIE;
/** @var class-string $monster */
$monster = DateTime::class;
$monster::COOKIE;

But currently they aren't:

[
'Cannot access constant COOKIE on string',
10,
],
[
'Cannot access constant COOKIE on class-string',
14,
],

This is a follow-up to #42, which was fixed by #43 to just not crash.

Limit upper version of PHP Parser

Seems that the new PHPStan version that will be released with the new PHP Parser will be PHPStan 1.0. Let's support 0.12.x by specifying the upper PHP Parser version that can be used until then.

This should get failing tests (#81) back to passing state.

error messages end with a dot

in phpstan usually rule error messages end with a dot.

with a configuration like

    disallowedSuperglobals:
        -
            superglobal: '$_SESSION'
            message: 'use rex_request::session() and rex_request::setSession() instead for proper per instance scoping.'

it seems the extension is even trimming the configured dot.

Case insensitive function calls

I'm writing function print_r() very often as print_R(). Probably because of holding shift for _ and also (. Everything works because function names are case-insensitive, but this extension can't identify it as disallowed.

Failing test case added here.

`disallowedSuperglobals` rule will fail in PHPStan 1.6+bleeding edge

Seems like the disallowedSuperglobals feature (#105) will break in the upcoming PHPStan version 1.6 with bleeding edge rules (which this repository is using to test itself), and in the upcoming major version for everyone because it is using the parent attribute which will be null:

$parentNode = $variable->getAttribute('parent');

The reason is memory optimisation.

There are a few options mentioned in the article but they seem like an overkill here (the custom node visitor) or would prevent PHPStan memory savings (the config change).

I think that just a list of superglobal names (_GET, _POST, etc.) in the rule class would do โ€“ although I like the current superglobal detection (a variable that's not defined in the current scope is treated as a superglobal).

The risk of PHP adding a new superglobal, and thus the code not detecting it because it would be missing in the list, is probably super low and would be a deal big enough to notice rather sooner than later.

Having a hardcoded list of superglobal variable names would break the test here:

[
'Using $TEST_GLOBAL_VARIABLE is forbidden, the cake is a lie',
19,
],

But I'm fine with that. Shouldn't break others though.

Allow params with any value

Currently, params can be allowed using allowParamsInAllowed or allowParamsAnywhere but they always require a value.

It would be nice if a param would be allowed having any value, or a list of values. This would allow to create a config that would disallow all calls unless there's a param (say) nr. 2 specified.

Allow calls only in some other calls

Starting with #134, you can disallow some calls etc. by path. It would be nice if I could disallow some calls in some other calls. Let's say I have a redirect() method but I don't want it to be used in __construct() because a dependency is not yet available.

Disallowed definition without parentheses

Right now, disallowed calls definitions need to have parentheses:

method: 'Foo\Bar::get()'

It would be nice, if () were optional, and detection worked even when specified without, like:

method: 'Foo\Bar::get'

Object of class PhpParser\Node\Expr\PropertyFetch could not be converted to string in file

When using your extentions and phpstan is trying to parse this file I get this error.

Internal error: Internal error: Object of class
PhpParser\Node\Expr\PropertyFetch could not be converted to string in
file
/app/Services/BusinessReports/BusinessReport.php

<?php
namespace App\Services\BusinessReports;

use Illuminate\Support\Collection;

class BusinessReport
{
    /**
     * The report type.
     *
     * @var string
     */
    protected string $type;

    /**
     * The filters.
     *
     * @var array
     */
    protected array $filters = [];

    /**
     * The order by.
     *
     * @var array
     */
    protected array $orderBy = [];

    /**
     * Set the type of report.
     *
     * @param  string $type
     *
     * @return self
     */
    public function setType(string $type): self
    {
        $this->type = __NAMESPACE__ . '\\' . ucfirst($type);

        return $this;
    }

    /**
     * Set the filters.
     *
     * @param  array $filters
     *
     * @return self
     */
    public function setFilters(array $filters): self
    {
        $this->filters = $filters;

        return $this;
    }

    /**
     * Set the order by.
     *
     * @param  array $orderBy
     *
     * @return self
     */
    public function setOrderBy(array $orderBy): self
    {
        $this->orderBy = $orderBy;

        return $this;
    }

    /**
     * Get the data.
     *
     * @return \Illuminate\Support\Collection
     */
    public function get(): Collection
    {
        return $this->type::getQuery($this->filters, $this->orderBy)->get();
    }
}

Use semver (and PHPStan version constraints in composer.json)

Hello,

firstly, thanks for the very userful plugin.

I'd habe a suggestion though. Could you please use versioning-numbers as they are (usually) intended? If you have breaking changes you should increase the major number, or at least the minor, for that matter.
We use the plugin in our pipeline and am quite busy fixing it over the last weeks.^^
With proper numbering I could use composer to update only minor (non-breaking) changes / patches, and deal with the big one on my machine first.

Explain how to fix code style issues

Would be great to add a script to composer like cs-fix that fixes this automatically:

FILE: /Users/Ruud/opensource/phpstan-disallowed-calls/src/FunctionCalls.php
------------------------------------------------------------------------------------------------------------------------------------------------------------------
FOUND 2 ERRORS AFFECTING 2 LINES
------------------------------------------------------------------------------------------------------------------------------------------------------------------
 50 | ERROR | [x] Whitespace found at end of line (Squiz.WhiteSpace.SuperfluousWhitespace.EndLine)
 51 | ERROR | [x] Expected 0 lines between different annotations types, found 1.
    |       |     (SlevomatCodingStandard.Commenting.DocCommentSpacing.IncorrectLinesCountBetweenDifferentAnnotationsTypes)
------------------------------------------------------------------------------------------------------------------------------------------------------------------
PHPCBF CAN FIX THE 2 MARKED SNIFF VIOLATIONS AUTOMATICALLY
------------------------------------------------------------------------------------------------------------------------------------------------------------------

As I don't use phpcbf I have no idea how to fix these automatically.

Prepare for PHPStan 1.0

Hello everyone ๐Ÿ‘‹

I announced today that PHPStan 1.0 is going to be released on November 1st 2021.

I'm approaching you as one of the most popular PHPStan extensions. I'd love if you could prepare your code for PHPStan 1.0 in advance so that it's ready to release on the same day.

Here's a brief guide how to approach the upgrade:

  1. Create a branch ๐ŸŒด
  2. Update your composer.json to "phpstan/phpstan": "^1.0", add "minimum-stability": "dev" and "prefer-stable": true if necessary.
  3. Update your code with the BC breaks below in mind. ๐Ÿ”ง
  4. Fix the code so that it passes PHPStan's analysis ๐Ÿค“
  5. Wait for PHPStan 1.0 release on November 1st, merge your branch and tag the next major version ๐Ÿ‘

Thank you!


Here are the BC breaks. The list is huge but most of those have very little impact.

There are new rules around using PHPStan internals in regard to backward compatibility promise: https://phpstan.org/developing-extensions/backward-compatibility-promise

It's possible that not everything you use is covered by it - so I'm here to help you to transition to correct usage, or add some @api annotations in PHPStan itself so that more is covered by the promise. Let me know!

BC breaks for end-users

The following are interesting only if you create a custom ruleset in your configuration file:

BC breaks for extension developers

When alternative function has same name as disallowed function, using the alternative function is reported as an error in files where it is not explicitly imported

This one is a bit tough to explain, so here's a code example:

<?php declare(strict_types=1);
namespace MyNamespace;

use function __ as wp__;

function __(string $str): string {
	return wp__($str, 'foo');
}

function someOtherFn(): string {
	return __('whatever'); // The __ used here is MyNamespace\__
}
parameters:
	disallowedFunctionCalls:
		-
			function: '__'
			message: 'use MyNamespace\__ instead'

When running PHPStan, 2 usages of __ are reported, even though there's only 1 (the other is actually MyNamespace\__. (In the above example, I even renamed __ for the file, but that didn't help.)

This issue happens anywhere that MyNamespace\__ isn't explicitly imported via use function MyNamespace\__. For example, files in the exact same MyNamespace namespace can use MyNamespace\__ without a use, and a person's IDE tends to suggest removing any seemingly redundant uses. But spaze/phpstan-disallowed-calls will think the occurrences of __ are the root-level __, and thus report false positives.

When running phpstan from a subdirectory, allowIn is ignored

When you run phpstan from a subdirectory of the project the allowIn is not checked

../../vendor/bin/phpstan --configuration=../../phpstan.neon

    disallowedFunctionCalls:
      - function: 'var_export()'
        message: 'use logger instead'
        allowIn:
        - tests/ExtendedFakes/ExtendedQueueFake.php
      - function: 'var_dump()'
        message: 'use logger instead'
      - function: 'print_r()'
        message: 'use logger instead'
      - function: 'dd()'
        message: 'forbidden function'
      - function: 'dump()'
        message: 'forbidden function'
        allowIn:
        - tests/ExtendedFakes/ExtendedQueueFake.php
      - function: 'exit()'
        message: 'forbidden function'
      - function: 'die()'
        message: 'forbidden function'

Gives me:

 ------ ------------------------------------------------------- 
 Line   tests/ExtendedFakes/ExtendedQueueFake.php              
------ ------------------------------------------------------- 
 51     Calling dump() is forbidden, forbidden function        
 68     Calling var_export() is forbidden, use logger instead  
 77     Calling dump() is forbidden, forbidden function        
------ ------------------------------------------------------- 

Edit: running from the root, gives no errors

Support PHP Parser that supports first-class callables

Currently, tests are now failing with:

 ------ ---------------------------------------------------------------- 
  Line   DisallowedHelper.php                                            
 ------ ---------------------------------------------------------------- 
  129    Access to an undefined property                                 
         PhpParser\Node\Arg|PhpParser\Node\VariadicPlaceholder::$value.  
 ------ ---------------------------------------------------------------- 

That's because PHP Parser 4.13.0 is being installed and that version has introduced support for PHP 8.1's first-class callables with the VariadicPlaceholder class.

Disallow classes to be used more than N times

In our project we are using a GraphQL code generator that produces PHP classes that can be used to run the GraphQL queries. The goal of GraphQL is to write tailor made queries per use case. But sometimes, people re-use the generated PHP classes in other parts of the system.

I'm trying to prevent this. My idea is that 1 generated class can only be used in 1 file in src. For example, it's fine to use it more times in tests.

This extension is capable of finding all these usages, and we already have many rules set-up to disallow certain things.

Would it be an idea to include an allowCount property?
Something like this:

    disallowedNamespaces:
        -
            namespace: 'Generated\GraphQL\Query\GetUserDetailsQuery'
            message: 'GraphQL queries cannot be reused'
            allowCount: 1

This would mean that the namespace can only be used once.

Another issue here is that a namespace is often found twice in a file, one to import it , and once as part of a constructor. Not sure yet how to solve that. One idea could be to count the number of files instead of the number of usages.

Would this be something for this extension? If so, I can try to work on a PR. If not, I'll have to make something custom.

`disallowedSuperglobals` with `allowIn` doesn't seem to work when referencing a trait

I'm trying out the new disallowedSuperglobals rule while allowing a use inside trait:

parameters:
    disallowedSuperglobals:
        -
            superglobal: '$_SERVER'
            message: 'use <fg=yellow>Symfony\Component\HttpFoundation\Request</> object instead'
            allowIn:
                - **/src/Infrastructure/Persistence/Doctrine/DBAL/QueryBuffering.php
                - **/src/Kernel.php

It seems that the fix for traits doesn't work for super globals.

I get this error:

Using $_SERVER is forbidden, use Symfony\Component\HttpFoundation\Request object instead
โ†ณ src/Core/SearchBundle/CliCommand/IndexUsersCommand.php:24
โ†ณ src/Infrastructure/Persistence/.../DBAL/QueryBuffering.php:24

/cc @ekisu @spaze

`allowCount` should be scoped to FQCN

I made a small error in my thinking while working on this PR.

This works fine:

parameters:
    disallowedMethodCalls:
        -
            method: 'Generated\MyNamedQuery::execute*()'
            message: 'do not reuse GraphQL queries.'
            allowCount: 1

It will only allow one call to Generated\MyNamedQuery::execute*.

But I want to go to a situation where I have 1 rule generic rule

parameters:
    disallowedMethodCalls:
        -
            method: 'Generated\*Query::execute*()'
            message: 'do not reuse GraphQL queries.'
            allowCount: 1

and it should track it's usages by FQCN instead of by rule.

For example, I have 2 generated classes:

  • Generated\MyNamedQuery
  • Generated\MyOtherQuery

MyNamedQuery::execute() should be allowed to called once, and MyOtherQuery::execute() should be allowed to call once.

With the current setup, it tracks its usage on the rule and therefore blocks the second call to a separate class.

Originally posted by @ruudk in #87 (comment)

Disallowing method calls but allowing usage within a trait does not work as expected

I wanted to create a failing test PR but it didn't work, therefore this issue instead.

I'm trying to disallow calls to AbstractController::getUser() while encouraging people to use my special UserTrait::getUserOrThrow() wrapper that in turn uses AbstractController::getUser().

It turns out that it's not possible currently.

This is my configuration:

parameters:
    disallowedMethodCalls:
        -
            method: 'Symfony\Bundle\FrameworkBundle\Controller\AbstractController::getUser()'
            message: 'import UserTrait and use getUserOrThrow() instead.'
            allowIn:
                - **/src/UserTrait.php

This is the code from Symfony that I want to disallow:

namespace Symfony\Bundle\FrameworkBundle\Controller;

abstract class AbstractController implements ServiceSubscriberInterface
{
    protected function getUser()
    {
        // returns the user
    }
}

My trait, that people should use instead:

namespace App;

trait UserTrait
{
    /**
     * @throws UserNotLoggedInException
     */
    public function getUserOrThrow() : User
    {
        $user = $this->getUser();

        if ($user instanceof User === false) {
            throw UserNotLoggedInException::create();
        }

        return $user;
    }
}

An example of the usage of the UserTrait:

namespace App;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

final class MyController extends AbstractController
{
    use UserTrait;

    public function myAction()
    {
        $user = $this->getUserOrThrow();
    }
}

But this results in the following error:

 ------ -----------------------------------------------------------------------------------------------------------------------------------------------------------------
  Line  UserTrait.php (in context of class MyController)
 ------ -----------------------------------------------------------------------------------------------------------------------------------------------------------------
  10     Calling Symfony\Bundle\FrameworkBundle\Controller\AbstractController::getUser() (as MyController::getUser()) is forbidden, import UserTrait and use getUserOrThrow() instead.
         โœ๏ธ  phpstorm://open?file=/Volumes/CS/www/website/src/UserTrait.php&line=22

Disallow function when a param matches value, otherwise allow

#61 wants to disallow md5() but there's also hash('md5', ...) that should be disallowed as well.

Maybe there should be a way to disallow a certain call when a param matches, otherwise don't disallow, but keep in mind that the param in hash is case insensitive so should figure out a way to disallow in a case-insensitive way.

disallowedClasses does not work when nullable

Hello, I found out that nullable types are not reported by this extension.

class MyClass
{
    public \DateTime $datetime; // is reported
    public ?\DateTime $datetime2; // does not report
}

Offer some defaults that can be included

Add some file which can be used when starting with this extension and don't want to spend time custom-configuring it. That config file would need to be included manually.

For ideas what should be disallowed by default see #6 (comment)

Introduce `disallowIn` as inverse of `allowIn`

It would be great if I could enforce some rules that only apply in some directories.

Currently, the only way to get that working is to construct a list of all options using wildcards, and then exclude the target from it. Not very ideal / scalable.

What do you think, would this be worth adding? Of course I can work on a PR to address it.

Create "strict" config

The config should allow these calls with these params, disallow otherwise

  • in_array(..., ..., true)
  • htmlspecialchars(..., ENT_QUOTES)

And possibly other, feel free to post some ideas.

Allow print_r(..., true)

Hello, would you mind to allow print_r() with $return = true argument?

We are using it quite often for a better format in logs.

I mean something like (print_r() specific):

services:
    -
        class: Spaze\PHPStan\Rules\Disallowed\FunctionCalls
        tags:
            - phpstan.rules.rule
        arguments:
            forbiddenCalls:
                -
                    function: 'print_r()'
                    allowReturn: true    #configurable
                    message: 'use logger instead'

https://github.com/spaze/phpstan-disallowed-calls/blob/master/src/FunctionCalls.php#L61 :

 if ($name === $forbiddenCall['function']) {
                $returnArg = $node->args[1] ? $node->args[1]->value->name->__toString() === 'true' : false;
                if ($returnArg === true && $forbiddenCall['allowReturn']) {
                    return [];
                }
}

Thanks.

Allow rule for specific file patterns

For example, I want to disallow call file_get_contents and replace them with Nette\Utils\FileSystem::read() everywhere exept the PhpUnit test files...

Disallow any usage of namespace in code

Can this library also be used to clock the usage of certain namespaces?

For example, I want to forbid importing, static calls, instantiation, method calls on Carbon namespace and suggest Chronos (just an example).

allowParamsAnywhere named parameters

Hello,

it would be awesome if instead of the order of the parameter declared as an integer, the named parameter could be used.

So for example in

function: 'json_decode()'
message: ''
allowParamsAnywhere:
    4: ::JSON_THROW_ON_ERROR

instead of 4, flags could be used, so that we don't need to define all the ommited parameters before flags.

md5() should be reported

Hi, as we have already addressed via e-mail, the md5() function should be reported as potentially dangerous.

The developer sets the few places where it makes sense as ignoring the rules.

Thanks.

Feature Request: Configure SuperGlobals as array

This would allow me to make the config significantly easier and shorter:

    disallowedSuperglobals:
        -
            superglobal: '$_GET'
            allowIn:
                - lib/*
                - admin/legacy/*
        -
            superglobal: '$_POST'
            allowIn:
                - lib/*
                - admin/legacy/*
        -
            superglobal: '$_REQUEST'
            allowIn:
                - lib/*
                - admin/legacy/*
        -
            superglobal: '$_COOKIE'
            allowIn:
                - lib/*
                - admin/legacy/*
        -
            superglobal: '$_SERVER'
            allowIn:
                - lib/*
                - admin/legacy/*
    disallowedSuperglobals:
        -
            superglobal: ['$_GET', '$_POST', '$_REQUEST', '$_COOKIE', '$_SERVER']
            allowIn:
                - lib/*
                - admin/legacy/*

Or is this already possible and I just missed it?

Disabling Else / Elseif

Hey hey,
I would love to enable else/elseif in my codebase.

How would one go and do that, I tried all kinds of wildcard strings whitespace etc etc with your package but it didn't pick up any else & elseifs

I managed to detect elseifs with the banned code extension like this:

            -
                type: Stmt_ElseIf
                functions: null

Tried it with:

 disallowedMethodCalls:
            -
                method: 'PhpParser\Node\Stm\Else::__construct'
                message: 'use earlier return types and/or smaller methods'
            -
                method: 'PhpParser\Node\Stm\ElseIf::___construct'
                message: 'use earlier return types and/or smaller methods'
                
    disallowedFunctionCalls:
        -
            function: 'else*(*)*'
            message: 'use logger instead'
        -
            function: 'ElseIf*'
            message: 'use logger instead'
        -
            function: 'elseif*'
            message: 'use logger instead'
        -
            function: 'elseIf '
            message: 'use logger instead'
        -
            function: 'ElseIf()'
            message: 'use logger instead'
        -
            function: 'ElseIf ()'
            message: 'use logger instead'                

Disallowed functions are allowed in any namespace (besides the global one) when neither `use`d nor qualified.

Disallowed functions are actually not disallowed at all when they're used in somewhere without being explicitly used or qualified.

# In PHPStan config...
includes:
	- vendor/spaze/phpstan-disallowed-calls/disallowed-insecure-calls.neon
<?php declare(strict_types=1);
// This is in the global namespace.

$x = \md5('blah'); // This is reported as expected.
<?php declare(strict_types=1);
namespace My\Namespace;

$x = \md5('blah'); // This is reported as expected.
$y = md5('blah'); // This SHOULD be reported, but isn't!

This regression was introduced in 2.6.0 - presumably as an unintended side-effect of #119.

support `tip`

phpstan RuleErrorBuilder supports a tip which brings additional information besides the error message.

this tip is rendered below a error message in the analysis result

would be great a tip could be configured in the config file, like

    disallowedStaticCalls:
        -
            method: 'PotentiallyDangerous\Debugger::log()'
            message: 'use our own logger instead'
            tip: 'see https://our-docs.com/logging on how logging should be used'

`allowInMethod`/`allowInFunction` support

Add ability to allow a disallowed call only in a method/function.

Currently, calls can be allowed only per file with allowIn which might not be limiting enough.

I'd like to be able to limit a call to a single method (or multiple methods).

Add PHPCS sniffs

Maybe this should have a code sniffer in place.

#21 tried to add PHPCS with PSR-2 which is now deprecated but I think an up-to-date sniffs should be used in a lib targetting PHP 7.1+, like PSR-12 or Slevomat.

No code changes should be made when the sniffer is introduced, we'll need see how bad it is first :)

The author of #21 didn't want to finish what he has started so this issue is free to grab.

disallowedConstants resolve to actual value, making the rule useless

When using this configuration:

disallowedConstants:
        -
            constant: "DATE_ISO8601"
            message: 'use DATE_ATOM instead'
        -
            constant: "DateTime::ISO8601"
            message: 'use DateTimeInterface::ATOM instead'
        -
            constant: "DateTimeInterface::ISO8601"
            message: 'use DateTimeInterface::ATOM instead'
        -
            constant: "DateTimeImmutable::ISO8601"
            message: 'use DateTimeImmutable::ATOM instead'

I noticed that PHPStan resolves all the constants (except the first) to the actual value.

This makes the check useless as it will now compare DateTimeImmutable::ISO8601 against Y-m-d\TH:i:sO.

I dumped DisallowedHelper::createConstantsFromConfig and saw this:

^ array:4 [
  0 => array:2 [
    "constant" => "DATE_ISO8601"
    "message" => "use DATE_ATOM instead"
  ]
  1 => array:2 [
    "constant" => "Y-m-d\TH:i:sO"
    "message" => "use DateTimeInterface::ATOM instead"
  ]
  2 => array:2 [
    "constant" => "Y-m-d\TH:i:sO"
    "message" => "use DateTimeInterface::ATOM instead"
  ]
  3 => array:2 [
    "constant" => "Y-m-d\TH:i:sO"
    "message" => "use DateTimeImmutable::ATOM instead"
  ]
]

DisallowedClass now introduces 2 errors instead of 1 that has count: 2

I just tried to use the new disallowedClass alias for disallowedNamespace which looks great.

But it now produces 2 errors instead of 1 in the baseline:

+		-
+			message: "#^Class Sentry\\\\State\\\\HubInterface is forbidden, use \\<fg\\=yellow\\>Tracker</\\> instead\\.$#"
+			count: 1
+			path: src/File.php
+
 		-
 			message: "#^Namespace Sentry\\\\State\\\\HubInterface is forbidden, use \\<fg\\=yellow\\>Tracker</\\> instead\\.$#"
-			count: 2
+			count: 1
 			path: src/File.php

This is because src/File.php does an import use Sentry\State\HubInterface; and something like __construct(HubInterface $sentry).

After thinking about this, I don't care if people import a class. I just don't want them to use it. PHP-CS-Fixer will take care of unused imports anyway.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.