Releases: spaze/phpstan-disallowed-calls
(Dis)allow non-scalar params
Can disallow ParentClass::__constructor()
Allow named params & non-CSPRNG insecure calls & PHP 8.2
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 functionsrand()
,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 inbin/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
ordisallowParamFlagsInAllowed
allowExceptParamFlags
ordisallowParamFlags
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
- 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
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
Function aliases & calls in multiple namespaces, error tips, requires PHP 7.2+
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:
Disallowed namespaces/classes config alias and a few improvements
- Add
disallowedClasses
as an alias ofdisallowedNamespaces
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
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
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.