Skip to content

Releases: spaze/phpstan-disallowed-calls

(Dis)allow non-scalar params

06 Jan 18:10
800f5f8
Compare
Choose a tag to compare

You can now disallow/allow/require params (directives like allowParamsInAllowed, allowParamsAnywhere, docs) that are non-scalar, like callbacks etc., previously only scalar types (strings, integers, ...) were accepted (#159, thanks @ruudk!)

Can disallow ParentClass::__constructor()

27 Dec 14:38
f1f319b
Compare
Choose a tag to compare
  • Child constructors should be disallowed when parent constructor or an interface constructor is disallowed (#147)

Internal change only:

  • Drop redundant Value in param class names (#157)

Allow named params & non-CSPRNG insecure calls & PHP 8.2

07 Dec 03:48
59afcfe
Compare
Choose a tag to compare

Note: Named params configuration didn't really work in 2.11.0 (#156), this release fixes it. Please find the original 2.11.0 announcement below

Overview

Bit more things this time I even had to use headings. In no particular order:

  • PHP 8.2 is now supported (by running tests on 8.2) (#143)
  • Can allow a previously disallowed call when done with a named parameter in allowParams* config options, see below, previously only positional params were accepted (#141, thanks @ilazaridis for the inital implementation)
  • Can allow a previously disallowed call when done only with a flag set in a bitmask param, see below (#150, #151)
  • disallowed-insecure-calls.neon bundled config file now disallows insecure randomness functions rand(), mt_rand(), lcg_value(), uniqid() (#145, thanks @compwright)
  • It may be a good idea to disallow functions and classes disabled in PHP config (disable_functions, disable_classes) and now there's a config generator script in bin/generate-from-disabled.php which will read the PHP config and dump the generated NEON config to STDOUT which you can fine-tune and commit to your repository (#149, loosely based on an idea by @staabm, thanks)

Named params

Named params are now fully supported, even mixed usage of both positional and named

For example, to allow a function foo(string $message, bool $alert): void when called with $alert = true:

allowParamsAnywhere:
    -
        position: 2
        name: 'alert'
        value: true

All keys are optional although I'd definitely recommend adding both position and name. The value key doesn't need to be specified with allowParams*AnyValue.

The old-style shortcusts still work:

allowParamsInAllowed:
    1: 'foo'
    2: true

But they're not recommended because sometimes, somewhere, you may suddenly use a named parameter and you'd start to see disallowed calls for no apparent reason. Some of the bundled config files still use these shortcuts, so they'll be supported for, I think, ever.

Allow a call with a flag in a bitmask param

This very same excerpt was also added to the README.

Some functions can be called with flags or bitmasks, for example

json_encode($foo, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT);

Let's say you want to disallow json_encode() except when called with JSON_HEX_APOS (integer 4) flag. In the call above, the value of the second parameter (JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT) is 13 (1 | 4 | 8).
For the extension to be able to "find" the 4 in 13, you need to use the ParamFlags family of config options:

  • allowParamFlagsInAllowed
  • allowParamFlagsAnywhere
  • allowExceptParamFlagsInAllowed or disallowParamFlagsInAllowed
  • allowExceptParamFlags or disallowParamFlags

They work like their non-flags Param counterparts except they're looking if specific bits in the mask parameter are set.

The json_encode() example mentioned above would look like the following snippet:

parameters:
    disallowedFunctionCalls:
            function: 'json_encode'
            allowParamFlagsAnywhere:
                -
                    position: 2
                    value: ::JSON_HEX_APOS

Disallow calls only in some other calls

23 Nov 04:30
332969d
Compare
Choose a tag to compare
  • Functions & methods can be disallowed only when called from listed functions & methods (#138)

If you need to disallow a method or a function call only when done from a particular method or function, use allowExceptInFunctions (with aliases allowExceptInMethods, disallowInFunctions, disallowInMethods):

parameters:
    disallowedMethodCalls:
        -
            method: 'Controller::redirect()'
            message: 'redirect in startup() instead'
            allowExceptInMethods:
                - Controller\Foo\Bar\*::__construct()

Added allowExceptIn, disallowIn

04 Nov 18:51
885582f
Compare
Choose a tag to compare

You can now disallow methods, functions, constants, namespaces, classes, superglobals only in specified paths (#134)

Done with allowExceptIn, disallowIn (which is just an alias of allowExceptIn), this allows to create an inverse of allowIn setup:

parameters:
    allowInRootDir: %rootDir%/../../..
    disallowedMethodCalls:
        -
            method: 'PotentiallyDangerous\Logger::log()'
            allowExceptIn:
                - path/to/some/dir/*.php

This will disallow PotentiallyDangerous\Logger::log() calls in %rootDir%/../../../path/to/some/dir/*.php.

You don't need to use allowInRootDir, it's here just to show that the path specified by the option is also used in this case too ☺️

Disallowing classes in nullable & union & intersection types

22 Oct 13:12
7a68d5c
Compare
Choose a tag to compare
  • Support disallowing classes in nullable (?DateTime) & union (DateTime|FooBar|null) & intersection (DateTime&FooBar) types (#132)
  • Add composer keywords to prompt users if they would like to add these packages to require-dev (#130)

Function aliases & calls in multiple namespaces, error tips, requires PHP 7.2+

08 Oct 18:39
1cd9884
Compare
Choose a tag to compare

Note: 2.6.0 release contained a regression bug and was quickly removed. This release contains features originally found in 2.6.0 plus some more.

  • Use namespaces function name when checking disallowed calls, helps when there are two functions with the same name but in different namespaces (#119)
  • When a function is aliased (use function foo as bar), the alias is also added to error messages e.g. Calling foo() (as bar()) (#120)
  • Using errorTip, you can configure a tip that will be displayed with a bulb icon (💡) below the error message (#128)
  • Remove support for PHP 7.1, PHP 7.2 or newer is now required (#122)

Internal:

  • The newest coding standard is required but that doesn't really change anything (#121)
  • If there's no error identifier configured, make it null instead of an empty string (#127)

Disallowed namespaces/classes config alias and a few improvements

21 Jul 00:39
80945f8
Compare
Choose a tag to compare
  • Add disallowedClasses as an alias of disallowedNamespaces to make it more straightforward to disallow particular classes (#113)
  • In error messages, disallowed classes/namespaces now tell whether it's a class, a trait, or a namespace. Where previously you could see 2 errors mentioning a disallowed namespace, you may now see one error mentioning a disallowed namespace and another one mentioning a disallowed class (#114)
  • Disallowed classes/namespaces are now also detected in new _DisallowedClass_ (#115)

Multiple calls can be specified as arrays/lists

30 May 13:30
90fa943
Compare
Choose a tag to compare

If you want to disallow multiple calls, constants, class constants (same-class only), namespaces or variables that share the same message and other config keys, you can use a list or an array to specify them all:

parameters:
    disallowedFunctionCalls:
        -
            function:
                - 'var_dump()'
                - 'print_r()'
            message: 'use logger instead'

    disallowedConstants:
        -
            class: 'DateTimeInterface'
            constant: ['ISO8601', 'RFC3339', 'W3C']
            message: 'use DateTimeInterface::ATOM instead'

(#111)

Change how superglobals are detected

20 Apr 14:53
9193052
Compare
Choose a tag to compare

2.3.0 has added a way to detect and disallow superglobal usage, this release changes the way the detection works: now there's a list of all superglobals PHP offers and you can disallow any of them. No changes necessary in your config, this is an internal change to allow for memory optimization in upcoming versions of PHPStan.