diff --git a/src/linter/block.go b/src/linter/block.go index cf20136d4..46f85b3f1 100644 --- a/src/linter/block.go +++ b/src/linter/block.go @@ -1078,7 +1078,7 @@ func (b *blockWalker) checkSimpleVarNullSafety(arg ir.Node, fn meta.FuncInfo, pa if varIsNullable && !paramAllowsNull { b.report(arg, LevelWarning, "notNullSafety", "not null safety call in function %s signature of variadic param %s", - fn.Name, lastParam.Name) + strings.TrimPrefix(fn.Name, "\\"), lastParam.Name) } return } @@ -1088,7 +1088,7 @@ func (b *blockWalker) checkSimpleVarNullSafety(arg ir.Node, fn meta.FuncInfo, pa if varIsNullable && !paramAllowsNull { b.report(arg, LevelWarning, "notNullSafety", "not null safety call in function %s signature of param %s", - fn.Name, fn.Params[paramIndex].Name) + strings.TrimPrefix(fn.Name, "\\"), fn.Params[paramIndex].Name) } } @@ -1108,7 +1108,7 @@ func (b *blockWalker) checkConstFetchNullSafety(arg ir.Node, fn meta.FuncInfo, p if isNull && !paramAllowsNull { b.report(arg, LevelWarning, "notNullSafety", "null passed to non-nullable variadic parameter %s in function %s", - lastParam.Name, fn.Name) + lastParam.Name, strings.TrimPrefix(fn.Name, "\\")) } return } @@ -1118,7 +1118,7 @@ func (b *blockWalker) checkConstFetchNullSafety(arg ir.Node, fn meta.FuncInfo, p if isNull && !paramAllowsNull { b.report(arg, LevelWarning, "notNullSafety", "null passed to non-nullable parameter %s in function %s", - fn.Params[paramIndex].Name, fn.Name) + fn.Params[paramIndex].Name, strings.TrimPrefix(fn.Name, "\\")) } } @@ -1143,7 +1143,7 @@ func (b *blockWalker) checkArrayDimFetchNullSafety(arg ir.Node, fn meta.FuncInfo if types.IsTypeNullable(varInfo.Type) && !paramAllowsNull { b.report(arg, LevelWarning, "notNullSafety", "potential null array access in variadic parameter %s of function %s", - lastParam.Name, fn.Name) + lastParam.Name, strings.TrimPrefix(fn.Name, "\\")) } return } @@ -1152,7 +1152,7 @@ func (b *blockWalker) checkArrayDimFetchNullSafety(arg ir.Node, fn meta.FuncInfo if types.IsTypeNullable(varInfo.Type) && !paramAllowsNull { b.report(arg, LevelWarning, "notNullSafety", "potential null array access in parameter %s of function %s", - fn.Params[paramIndex].Name, fn.Name) + fn.Params[paramIndex].Name, strings.TrimPrefix(fn.Name, "\\")) } } @@ -1184,7 +1184,7 @@ func (b *blockWalker) checkListExprNullSafety(arg ir.Node, fn meta.FuncInfo, par if !types.IsTypeNullable(effectiveParam.Typ) { b.report(arg, LevelWarning, "notNullSafety", "potential null value in list assignment for parameter %s in function %s", - effectiveParam.Name, fn.Name) + effectiveParam.Name, strings.TrimPrefix(fn.Name, "\\")) } } } diff --git a/src/linter/cache.go b/src/linter/cache.go index b18c7a5ab..bf66e43b8 100644 --- a/src/linter/cache.go +++ b/src/linter/cache.go @@ -17,42 +17,43 @@ import ( // // Version log: // -// 27 - added Static field to meta.FuncInfo -// 28 - array type parsed as mixed[] -// 29 - updated type inference for ClassConstFetch -// 30 - resolve ClassConstFetch to a wrapped type string -// 31 - fixed plus operator type inference for arrays -// 32 - replaced Static:bool with Flags:uint8 in meta.FuncInfo -// 33 - support parsing of array and list -// 34 - support parsing of ?ClassName as "ClassName|null" -// 35 - added Flags:uint8 to meta.ClassInfo -// 36 - added FuncAbstract bit to FuncFlags -// added FuncFinal bit to FuncFlags -// added ClassFinal bit to ClassFlags -// FuncInfo now stores original function name -// ClassInfo now stores original class name -// 37 - added ClassShape bit to ClassFlags -// changed meta.scopeVar bool fields representation -// 38 - replaced TypesMap.immutable:bool with flags:uint8. -// added mapPrecise flag to mark precise type maps. -// 39 - added new field Value in ConstantInfo -// 40 - changed string const value storage (no quotes) -// 41 - const-folding affected const definition values -// 42 - bool-typed consts are now stored in meta info -// 43 - define'd const values stored in cache -// 44 - rename ConstantInfo => ConstInfo -// 45 - added Mixins field to meta.ClassInfo -// 46 - changed the way of inferring the return type of functions and methods -// 47 - forced cache version invalidation due to the #921 -// 48 - renamed meta.TypesMap to types.Map; this affects gob encoding -// 49 - for shape, names are now generated using the keys that make up this shape -// 50 - added Flags field for meta.PropertyInfo -// 51 - added anonymous classes -// 52 - renamed all PhpDoc and Phpdoc with PHPDoc -// 53 - added DeprecationInfo for functions and methods and support for some attributes -// 54 - forced cache version invalidation due to the #1165 -// 55 - updated go version 1.16 -> 1.21 -const cacheVersion = 55 +// 27 - added Static field to meta.FuncInfo +// 28 - array type parsed as mixed[] +// 29 - updated type inference for ClassConstFetch +// 30 - resolve ClassConstFetch to a wrapped type string +// 31 - fixed plus operator type inference for arrays +// 32 - replaced Static:bool with Flags:uint8 in meta.FuncInfo +// 33 - support parsing of array and list +// 34 - support parsing of ?ClassName as "ClassName|null" +// 35 - added Flags:uint8 to meta.ClassInfo +// 36 - added FuncAbstract bit to FuncFlags +// added FuncFinal bit to FuncFlags +// added ClassFinal bit to ClassFlags +// FuncInfo now stores original function name +// ClassInfo now stores original class name +// 37 - added ClassShape bit to ClassFlags +// changed meta.scopeVar bool fields representation +// 38 - replaced TypesMap.immutable:bool with flags:uint8. +// added mapPrecise flag to mark precise type maps. +// 39 - added new field Value in ConstantInfo +// 40 - changed string const value storage (no quotes) +// 41 - const-folding affected const definition values +// 42 - bool-typed consts are now stored in meta info +// 43 - define'd const values stored in cache +// 44 - rename ConstantInfo => ConstInfo +// 45 - added Mixins field to meta.ClassInfo +// 46 - changed the way of inferring the return type of functions and methods +// 47 - forced cache version invalidation due to the #921 +// 48 - renamed meta.TypesMap to types.Map; this affects gob encoding +// 49 - for shape, names are now generated using the keys that make up this shape +// 50 - added Flags field for meta.PropertyInfo +// 51 - added anonymous classes +// 52 - renamed all PhpDoc and Phpdoc with PHPDoc +// 53 - added DeprecationInfo for functions and methods and support for some attributes +// 54 - forced cache version invalidation due to the #1165 +// 55 - updated go version 1.16 -> 1.21 +// 56 - added isVariadic to meta.FuncInfo +const cacheVersion = 56 var ( errWrongVersion = errors.New("Wrong cache version") diff --git a/src/linter/cache_test.go b/src/linter/cache_test.go index 8281dc48d..1aa09d573 100644 --- a/src/linter/cache_test.go +++ b/src/linter/cache_test.go @@ -149,7 +149,7 @@ main(); // // If cache encoding changes, there is a very high chance that // encoded data lengh will change as well. - wantLen := 5952 + wantLen := 5967 haveLen := buf.Len() if haveLen != wantLen { t.Errorf("cache len mismatch:\nhave: %d\nwant: %d", haveLen, wantLen) @@ -158,7 +158,7 @@ main(); // 2. Check cache "strings" hash. // // It catches new fields in cached types, field renames and encoding of additional named attributes. - wantStrings := "690e77c94ecdd7878de0bf6f6881d786cf1fafa4588f7905f54d700646c4952aad359008ae2dcddb1c7f29163ecee62355d525672090ac30257bc414f690006f" + wantStrings := "876ec90cb8a340db375f0f833cdb625a2a5a8560e008e111baefbad4766cc964a705c0e4f0dee76bd30a61de436986f580069c98b88b2caaed3a63a53beaae24" haveStrings := collectCacheStrings(buf.String()) if haveStrings != wantStrings { t.Errorf("cache strings mismatch:\nhave: %q\nwant: %q", haveStrings, wantStrings) diff --git a/src/tests/checkers/regexpsimplify_test.go b/src/tests/checkers/regexpsimplify_test.go index c501a0d4e..d7a264597 100644 --- a/src/tests/checkers/regexpsimplify_test.go +++ b/src/tests/checkers/regexpsimplify_test.go @@ -19,6 +19,9 @@ function f($s) { test.Expect = []string{ `May re-write '~(?P[0-9])~' as '~(?P\d)~'`, `May re-write '~(?[0-9])~' as '~(?\d)~'`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, } test.RunAndMatch() } @@ -39,6 +42,9 @@ function f($s) { `May re-write '/^write([-]?\d\d*)?$/i' as '/^write(-?\d+)?$/i'`, `May re-write '/[a-a]/' as '/a/'`, `May re-write '/[a-a]*?/' as '/a*?/'`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match_all signature of param subject`, + `not null safety call in function preg_split signature of param subject`, } test.RunAndMatch() } @@ -113,6 +119,7 @@ function unrepeat($s) { preg_match('/x{0,}/', $s); } `) + test.Expect = []string{ `May re-write '/(?:x)/' as '/x/'`, `May re-write '/(?:[abc])/' as '/[abc]/'`, @@ -138,6 +145,30 @@ function unrepeat($s) { `May re-write '/[0-9]{1,}/' as '/\d+/'`, `May re-write '/[0-9]{0,1}/' as '/\d?/'`, `May re-write '/x{0,}/' as '/x*/'`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, } test.RunAndMatch() } @@ -158,6 +189,10 @@ function f($s) { `May re-write '/^http:\/\/~/' as '@^http://~@'`, `May re-write '/^http:\/\/~@/' as '#^http://~@#'`, `May re-write '@mail\@gmail\.ru@' as '/mail@gmail\.ru/'`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, } test.RunAndMatch() } @@ -354,5 +389,173 @@ function _6($s) { preg_match('/(?i)\([^)]*mix[^)]*\)$/', $s); } `) + test.Expect = []string{ + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + } test.RunAndMatch() } diff --git a/src/tests/checkers/regexpvet_test.go b/src/tests/checkers/regexpvet_test.go index c97770d64..66b26220d 100644 --- a/src/tests/checkers/regexpvet_test.go +++ b/src/tests/checkers/regexpvet_test.go @@ -26,6 +26,10 @@ function parseErrors($s) { `parse error: 'a' is not a valid delimiter`, `parse error: can't find '>' ending delimiter`, `parse error: unterminated '['`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, } test.RunAndMatch() } @@ -204,6 +208,9 @@ function f($s) { `'\s' intersects with '\t' in [\s\t]`, `'e' is duplicated in [com|org|edu|net]`, `'\w' intersects with '\d' in [\w\d]`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, } test.RunAndMatch() } @@ -273,5 +280,31 @@ function goodAnchors($s) { preg_match('~(?i)(?:)(^| )\S+~', $s); } `) + test.Expect = []string{ + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + `not null safety call in function preg_match signature of param subject`, + } test.RunAndMatch() } diff --git a/src/tests/checkers/trigger_error_test.go b/src/tests/checkers/trigger_error_test.go index a5d909af2..82432fab2 100644 --- a/src/tests/checkers/trigger_error_test.go +++ b/src/tests/checkers/trigger_error_test.go @@ -50,6 +50,7 @@ echo 'unreachable'; `) test.Expect = []string{ `Unreachable code`, + `not null safety call in function trigger_error signature of param message`, } test.RunAndMatch() } diff --git a/src/tests/golden/golden_test.go b/src/tests/golden/golden_test.go index 88657c9ec..19dddd6e1 100644 --- a/src/tests/golden/golden_test.go +++ b/src/tests/golden/golden_test.go @@ -96,7 +96,7 @@ func TestGolden(t *testing.T) { { Name: "parsedown", - Disable: []string{"missingPhpdoc", "arraySyntax", "phpAliases"}, + Disable: []string{"missingPhpdoc", "arraySyntax", "phpAliases", "notNullSafety"}, Deps: []string{ `stubs/phpstorm-stubs/pcre/pcre.php`, `stubs/phpstorm-stubs/mbstring/mbstring.php`, @@ -105,7 +105,7 @@ func TestGolden(t *testing.T) { { Name: "underscore", - Disable: []string{"missingPhpdoc", "phpAliases"}, + Disable: []string{"missingPhpdoc", "phpAliases", "notNullSafety"}, Deps: []string{ `stubs/phpstorm-stubs/pcre/pcre.php`, }, @@ -113,7 +113,7 @@ func TestGolden(t *testing.T) { { Name: "phprocksyd", - Disable: []string{"missingPhpdoc"}, + Disable: []string{"missingPhpdoc", "notNullSafety"}, Deps: []string{ `stubs/phpstorm-stubs/standard/basic.php`, `stubs/phpstorm-stubs/pcntl/pcntl.php`, @@ -124,7 +124,7 @@ func TestGolden(t *testing.T) { { Name: "flysystem", - Disable: []string{"redundantCast"}, + Disable: []string{"redundantCast", "notNullSafety"}, Deps: []string{ `stubs/phpstorm-stubs/pcre/pcre.php`, `stubs/phpstorm-stubs/SPL/SPL.php`, @@ -141,7 +141,7 @@ func TestGolden(t *testing.T) { { Name: "inflector", - Disable: []string{"missingPhpdoc"}, + Disable: []string{"missingPhpdoc", "notNullSafety"}, Deps: []string{ `stubs/phpstorm-stubs/pcre/pcre.php`, `stubs/phpstorm-stubs/SPL/SPL.php`, @@ -151,7 +151,7 @@ func TestGolden(t *testing.T) { { Name: "options-resolver", - Disable: []string{"missingPhpdoc"}, + Disable: []string{"missingPhpdoc", "notNullSafety"}, Deps: []string{ `stubs/phpstorm-stubs/SPL/SPL.php`, `stubs/phpstorm-stubs/Reflection/Reflection.php`, @@ -164,7 +164,7 @@ func TestGolden(t *testing.T) { { Name: "twitter-api-php", - Disable: []string{"missingPhpdoc", "arraySyntax"}, + Disable: []string{"missingPhpdoc", "arraySyntax", "notNullSafety"}, Deps: []string{ `stubs/phpstorm-stubs/pcre/pcre.php`, `stubs/phpstorm-stubs/SPL/SPL.php`, diff --git a/src/tests/golden/testdata/embeddedrules/golden.txt b/src/tests/golden/testdata/embeddedrules/golden.txt index e0418748c..50f964aa8 100644 --- a/src/tests/golden/testdata/embeddedrules/golden.txt +++ b/src/tests/golden/testdata/embeddedrules/golden.txt @@ -13,9 +13,21 @@ WARNING argsOrder: Potentially incorrect haystack and needle arguments order at WARNING argsOrder: Potentially incorrect replacement and subject arguments order at testdata/embeddedrules/argsOrder.php:32 $_ = preg_replace($pat, $subj, 'replacement'); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: not null safety call in function explode signature of param separator at testdata/embeddedrules/argsOrder.php:41 + $_ = explode($s, '/'); + ^^ WARNING argsOrder: Potentially incorrect delimiter and string arguments order at testdata/embeddedrules/argsOrder.php:41 $_ = explode($s, '/'); ^^^^^^^^^^^^^^^^ +WARNING notNullSafety: not null safety call in function explode signature of param string at testdata/embeddedrules/argsOrder.php:45 + $_ = explode('/', $s); + ^^ +WARNING notNullSafety: not null safety call in function explode signature of param separator at testdata/embeddedrules/argsOrder.php:46 + $_ = explode($delim, $s); + ^^^^^^ +WARNING notNullSafety: not null safety call in function explode signature of param string at testdata/embeddedrules/argsOrder.php:46 + $_ = explode($delim, $s); + ^^ WARNING argsOrder: Potentially incorrect replace and string arguments order at testdata/embeddedrules/argsOrder.php:50 $_ = str_replace($search, $subj, ' '); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/tests/golden/testdata/idn/golden.txt b/src/tests/golden/testdata/idn/golden.txt index 17aace3ae..564ebefaf 100644 --- a/src/tests/golden/testdata/idn/golden.txt +++ b/src/tests/golden/testdata/idn/golden.txt @@ -7,6 +7,9 @@ MAYBE arraySyntax: Use the short form '[]' instead of the old 'array()' at tes WARNING errorSilence: Don't use @, silencing errors is bad practice at testdata/idn/idn.php:67 @trigger_error('idn_to_ascii(): INTL_IDNA_VARIANT_2003 is deprecated', E_USER_DEPRECATED); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: not null safety call in function mb_strtolower signature of param string at testdata/idn/idn.php:71 + $domain = mb_strtolower($domain, 'utf-8'); + ^^^^^^^ MAYBE arraySyntax: Use the short form '[]' instead of the old 'array()' at testdata/idn/idn.php:87 $idna_info = array( @@ -19,9 +22,15 @@ MAYBE arraySyntax: Use the short form '[]' instead of the old 'array()' at tes WARNING errorSilence: Don't use @, silencing errors is bad practice at testdata/idn/idn.php:99 @trigger_error('idn_to_utf8(): INTL_IDNA_VARIANT_2003 is deprecated', E_USER_DEPRECATED); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: not null safety call in function explode signature of param string at testdata/idn/idn.php:102 + $parts = explode('.', $domain); + ^^^^^^^ MAYBE arraySyntax: Use the short form '[]' instead of the old 'array()' at testdata/idn/idn.php:119 $idna_info = array( +WARNING notNullSafety: not null safety call in function mb_strlen signature of param string at testdata/idn/idn.php:152 + $length = mb_strlen($input, 'utf-8'); + ^^^^^^ MAYBE arraySyntax: Use the short form '[]' instead of the old 'array()' at testdata/idn/idn.php:195 'all' => array(), ^^^^^^^ @@ -34,6 +43,12 @@ MAYBE arraySyntax: Use the short form '[]' instead of the old 'array()' at tes MAYBE arraySyntax: Use the short form '[]' instead of the old 'array()' at testdata/idn/idn.php:194 $codePoints = array( +WARNING notNullSafety: not null safety call in function mb_strlen signature of param string at testdata/idn/idn.php:200 + $length = mb_strlen($input, 'utf-8'); + ^^^^^^ +WARNING notNullSafety: not null safety call in function mb_substr signature of param string at testdata/idn/idn.php:202 + $char = mb_substr($input, $i, 1, 'utf-8'); + ^^^^^^ MAYBE redundantCast: Expression already has int type at testdata/idn/idn.php:233 $delta = (int) ($delta / 35); ^^^^^^^^^^^^^ @@ -43,6 +58,15 @@ MAYBE assignOp: Could rewrite as `$k += 36` at testdata/idn/idn.php:234 MAYBE redundantCast: Expression already has int type at testdata/idn/idn.php:237 return $k + (int) (36 * $delta / ($delta + 38)); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: not null safety call in function strrpos signature of param haystack at testdata/idn/idn.php:247 + $pos = strrpos($input, '-'); + ^^^^^^ +WARNING notNullSafety: not null safety call in function substr signature of param string at testdata/idn/idn.php:249 + $output = substr($input, 0, $pos++); + ^^^^^^ +WARNING notNullSafety: not null safety call in function strlen signature of param string at testdata/idn/idn.php:255 + $inputLength = \strlen($input); + ^^^^^^ MAYBE assignOp: Could rewrite as `$n += (int) ($i / $outputLength)` at testdata/idn/idn.php:274 $n = $n + (int) ($i / $outputLength); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/tests/golden/testdata/math/golden.txt b/src/tests/golden/testdata/math/golden.txt index ae3f8b9b4..80fa121a5 100644 --- a/src/tests/golden/testdata/math/golden.txt +++ b/src/tests/golden/testdata/math/golden.txt @@ -1,18 +1,42 @@ WARNING unused: Variable $a is unused (use $_ to ignore this inspection or specify --unused-var-regex flag) at testdata/math/src/BigDecimal.php:292 [$a, $b] = $this->scaleValues($this, $that); ^^ +WARNING notNullSafety: not null safety call in function of signature of param value at testdata/math/src/BigDecimal.php:588 + $that = BigNumber::of($that); + ^^^^^ MAYBE trailingComma: Last element in a multi-line array should have a trailing comma at testdata/math/src/BigInteger.php:435 new BigInteger($remainder) ^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: not null safety call in function of signature of param value at testdata/math/src/BigInteger.php:742 + $that = BigNumber::of($that); + ^^^^^ MAYBE ternarySimplify: Could rewrite as `$matches['fractional'] ?? ''` at testdata/math/src/BigNumber.php:90 $fractional = isset($matches['fractional']) ? $matches['fractional'] : ''; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: not null safety call in function isLessThan signature of param that at testdata/math/src/BigNumber.php:173 + if ($min === null || $value->isLessThan($min)) { + ^^^^ +WARNING notNullSafety: not null safety call in function isGreaterThan signature of param that at testdata/math/src/BigNumber.php:205 + if ($max === null || $value->isGreaterThan($max)) { + ^^^^ +WARNING notNullSafety: not null safety call in function add signature of param a at testdata/math/src/BigNumber.php:241 + $sum = self::add($sum, $value); + ^^^^ +WARNING notNullSafety: not null safety call in function minus signature of param that at testdata/math/src/BigRational.php:365 + return $this->minus($that)->getSign(); + ^^^^^ MAYBE implicitModifiers: Specify the access modifier for \Brick\Math\Internal\Calculator::powmod method explicitly at testdata/math/src/Internal/Calculator.php:260 abstract function powmod(string $base, string $exp, string $mod) : string; ^^^^^^ MAYBE assignOp: Could rewrite as `$number ^= $xor` at testdata/math/src/Internal/Calculator.php:622 $number = $number ^ $xor; ^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: not null safety call in function gmp_strval signature of param num at testdata/math/src/Internal/Calculator/GmpCalculator.php:66 + \gmp_strval($q), + ^^ +WARNING notNullSafety: not null safety call in function gmp_strval signature of param num at testdata/math/src/Internal/Calculator/GmpCalculator.php:67 + \gmp_strval($r) + ^^ MAYBE trailingComma: Last element in a multi-line array should have a trailing comma at testdata/math/src/Internal/Calculator/GmpCalculator.php:67 \gmp_strval($r) ^^^^^^^^^^^^^^^ diff --git a/src/tests/golden/testdata/mustache/golden.txt b/src/tests/golden/testdata/mustache/golden.txt index c5667a990..9987a66b7 100644 --- a/src/tests/golden/testdata/mustache/golden.txt +++ b/src/tests/golden/testdata/mustache/golden.txt @@ -1,3 +1,6 @@ +WARNING notNullSafety: not null safety call in function realpath signature of param path at testdata/mustache/src/Mustache/Autoloader.php:39 + $realDir = realpath($baseDir); + ^^^^^^^^ MAYBE ternarySimplify: Could rewrite as `$baseDir ?: 0` at testdata/mustache/src/Mustache/Autoloader.php:56 $key = $baseDir ? $baseDir : 0; ^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,24 +28,87 @@ WARNING errorSilence: Don't use @, silencing errors is bad practice at testdata/ WARNING useEval: Don't use the 'eval' function at testdata/mustache/src/Mustache/Cache/NoopCache.php:45 eval('?>' . $value); ^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null array access in parameter id of function section at testdata/mustache/src/Mustache/Compiler.php:98 + $node[Mustache_Tokenizer::NAME], + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null array access in parameter start of function section at testdata/mustache/src/Mustache/Compiler.php:100 + $node[Mustache_Tokenizer::INDEX], + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null array access in parameter end of function section at testdata/mustache/src/Mustache/Compiler.php:101 + $node[Mustache_Tokenizer::END], + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null array access in parameter otag of function section at testdata/mustache/src/Mustache/Compiler.php:102 + $node[Mustache_Tokenizer::OTAG], + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null array access in parameter ctag of function section at testdata/mustache/src/Mustache/Compiler.php:103 + $node[Mustache_Tokenizer::CTAG], + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ MAYBE ternarySimplify: Could rewrite as `$node[Mustache_Tokenizer::FILTERS] ?? array()` at testdata/mustache/src/Mustache/Compiler.php:99 isset($node[Mustache_Tokenizer::FILTERS]) ? $node[Mustache_Tokenizer::FILTERS] : array(), ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null array access in parameter id of function invertedSection at testdata/mustache/src/Mustache/Compiler.php:111 + $node[Mustache_Tokenizer::NAME], + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ MAYBE ternarySimplify: Could rewrite as `$node[Mustache_Tokenizer::FILTERS] ?? array()` at testdata/mustache/src/Mustache/Compiler.php:112 isset($node[Mustache_Tokenizer::FILTERS]) ? $node[Mustache_Tokenizer::FILTERS] : array(), ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null array access in parameter id of function partial at testdata/mustache/src/Mustache/Compiler.php:119 + $node[Mustache_Tokenizer::NAME], + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ MAYBE ternarySimplify: Could rewrite as `$node[Mustache_Tokenizer::INDENT] ?? ''` at testdata/mustache/src/Mustache/Compiler.php:120 isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '', ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null array access in parameter id of function parent at testdata/mustache/src/Mustache/Compiler.php:127 + $node[Mustache_Tokenizer::NAME], + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ MAYBE ternarySimplify: Could rewrite as `$node[Mustache_Tokenizer::INDENT] ?? ''` at testdata/mustache/src/Mustache/Compiler.php:128 isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '', ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null array access in parameter id of function blockArg at testdata/mustache/src/Mustache/Compiler.php:137 + $node[Mustache_Tokenizer::NAME], + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null array access in parameter start of function blockArg at testdata/mustache/src/Mustache/Compiler.php:138 + $node[Mustache_Tokenizer::INDEX], + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null array access in parameter end of function blockArg at testdata/mustache/src/Mustache/Compiler.php:139 + $node[Mustache_Tokenizer::END], + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null array access in parameter otag of function blockArg at testdata/mustache/src/Mustache/Compiler.php:140 + $node[Mustache_Tokenizer::OTAG], + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null array access in parameter ctag of function blockArg at testdata/mustache/src/Mustache/Compiler.php:141 + $node[Mustache_Tokenizer::CTAG], + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null array access in parameter id of function blockVar at testdata/mustache/src/Mustache/Compiler.php:149 + $node[Mustache_Tokenizer::NAME], + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null array access in parameter start of function blockVar at testdata/mustache/src/Mustache/Compiler.php:150 + $node[Mustache_Tokenizer::INDEX], + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null array access in parameter end of function blockVar at testdata/mustache/src/Mustache/Compiler.php:151 + $node[Mustache_Tokenizer::END], + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null array access in parameter otag of function blockVar at testdata/mustache/src/Mustache/Compiler.php:152 + $node[Mustache_Tokenizer::OTAG], + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null array access in parameter ctag of function blockVar at testdata/mustache/src/Mustache/Compiler.php:153 + $node[Mustache_Tokenizer::CTAG], + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null array access in parameter id of function variable at testdata/mustache/src/Mustache/Compiler.php:165 + $node[Mustache_Tokenizer::NAME], + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ MAYBE ternarySimplify: Could rewrite as `$node[Mustache_Tokenizer::FILTERS] ?? array()` at testdata/mustache/src/Mustache/Compiler.php:166 isset($node[Mustache_Tokenizer::FILTERS]) ? $node[Mustache_Tokenizer::FILTERS] : array(), ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null array access in parameter text of function text at testdata/mustache/src/Mustache/Compiler.php:173 + $code .= $this->text($node[Mustache_Tokenizer::VALUE], $level); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ WARNING unused: Variable $keystr is unused (use $_ to ignore this inspection or specify --unused-var-regex flag) at testdata/mustache/src/Mustache/Compiler.php:289 $keystr = var_export($key, true); ^^^^^^^ +WARNING notNullSafety: not null safety call in function getFindMethod signature of param id at testdata/mustache/src/Mustache/Compiler.php:556 + $method = $this->getFindMethod($name); + ^^^^^ MAYBE callSimplify: Could simplify to $id[0] at testdata/mustache/src/Mustache/Compiler.php:646 if (substr($id, 0, 1) === '.') { ^^^^^^^^^^^^^^^^^ @@ -121,12 +187,33 @@ MAYBE callSimplify: Could simplify to $this->stack[] = $value at testdata/must MAYBE callSimplify: Could simplify to $this->blockStack[] = $value at testdata/mustache/src/Mustache/Context.php:49 array_push($this->blockStack, $value); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: not null safety call in function findVariableInStack signature of param id at testdata/mustache/src/Mustache/Context.php:131 + $value = $this->findVariableInStack($first, $this->stack); + ^^^^^^ +WARNING notNullSafety: not null safety call in function findVariableInStack signature of param id at testdata/mustache/src/Mustache/Context.php:138 + $value = $this->findVariableInStack($chunk, array($value)); + ^^^^^^ +WARNING notNullSafety: not null safety call in function findVariableInStack signature of param id at testdata/mustache/src/Mustache/Context.php:174 + $value = $this->findVariableInStack($chunk, array($value)); + ^^^^^^ +WARNING notNullSafety: not null safety call in function method_exists signature of param object_or_class at testdata/mustache/src/Mustache/Context.php:218 + if (method_exists($frame, $id)) { + ^^^^^^ WARNING switchDefault: Add 'default' branch to avoid unexpected unhandled condition values at testdata/mustache/src/Mustache/Context.php:213 switch (gettype($frame)) { ^ MAYBE ternarySimplify: Could rewrite as `$options['cache_file_mode'] ?? null` at testdata/mustache/src/Mustache/Engine.php:156 $mode = isset($options['cache_file_mode']) ? $options['cache_file_mode'] : null; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: not null safety call in function setCache signature of param cache at testdata/mustache/src/Mustache/Engine.php:160 + $this->setCache($cache); + ^^^^^^ +WARNING notNullSafety: potential null array access in parameter loader of function setLoader at testdata/mustache/src/Mustache/Engine.php:168 + $this->setLoader($options['loader']); + ^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null array access in parameter partialsLoader of function setPartialsLoader at testdata/mustache/src/Mustache/Engine.php:172 + $this->setPartialsLoader($options['partials_loader']); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ MAYBE misspellComment: "entitity" is a misspelling of "entity" at testdata/mustache/src/Mustache/Engine.php:254 public function getEntityFlags() ^^^^^^^^^^^^^^ @@ -151,6 +238,12 @@ ERROR undefinedMethod: Call to undefined method {\Mustache_Cache}->setLogger() MAYBE ternarySimplify: Could rewrite as `$this->delimiters ?: '{{ }}'` at testdata/mustache/src/Mustache/Engine.php:628 'delimiters' => $this->delimiters ? $this->delimiters : '{{ }}', ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null dereference when accessing property 'charset' at testdata/mustache/src/Mustache/Engine.php:813 + return $compiler->compile($source, $tree, $name, isset($this->escape), $this->charset, $this->strictCallables, $this->entityFlags); + ^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null dereference when accessing property 'strictCallables' at testdata/mustache/src/Mustache/Engine.php:813 + return $compiler->compile($source, $tree, $name, isset($this->escape), $this->charset, $this->strictCallables, $this->entityFlags); + ^^^^^^^^^^^^^^^^^^^^^^ WARNING notExplicitNullableParam: parameter with null default value should be explicitly nullable at testdata/mustache/src/Mustache/Engine.php:727 private function loadSource($source, Mustache_Cache $cache = null) ^^^^^^^^^^^^^^ @@ -175,9 +268,48 @@ MAYBE missingPhpdoc: Missing PHPDoc for \Mustache_Exception_UnknownTemplateExc WARNING notExplicitNullableParam: parameter with null default value should be explicitly nullable at testdata/mustache/src/Mustache/Exception/UnknownTemplateException.php:23 public function __construct($templateName, Exception $previous = null) ^^^^^^^^^ +WARNING notNullSafety: not null safety call in function addLoader signature of param loader at testdata/mustache/src/Mustache/Loader/CascadingLoader.php:35 + $this->addLoader($loader); + ^^^^^^^ +WARNING notNullSafety: potential null array access in parameter string of function ltrim at testdata/mustache/src/Mustache/Loader/FilesystemLoader.php:64 + $this->extension = '.' . ltrim($options['extension'], '.'); + ^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: null passed to non-nullable parameter context in function file_get_contents at testdata/mustache/src/Mustache/Loader/InlineLoader.php:114 + $data = file_get_contents($this->fileName, false, null, $this->offset); + ^^^^ WARNING regexpVet: '\w' intersects with '\d' in [\w\d\.] at testdata/mustache/src/Mustache/Loader/InlineLoader.php:115 foreach (preg_split("/^@@(?= [\w\d\.]+$)/m", $data, -1) as $chunk) { ^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null dereference when accessing property 'stream' at testdata/mustache/src/Mustache/Logger/StreamLogger.php:61 + fclose($this->stream); + ^^^^^^^^^^^^^ +WARNING notNullSafety: not null safety call in function array_key_exists signature of param key at testdata/mustache/src/Mustache/Logger/StreamLogger.php:102 + if (!array_key_exists($level, self::$levels)) { + ^^^^^^ +WARNING notNullSafety: not null safety call in function writeLog signature of param level at testdata/mustache/src/Mustache/Logger/StreamLogger.php:107 + $this->writeLog($level, $message, $context); + ^^^^^^ +WARNING notNullSafety: potential null dereference when accessing property 'url' at testdata/mustache/src/Mustache/Logger/StreamLogger.php:128 + $this->stream = fopen($this->url, 'a'); + ^^^^^^^^^^ +WARNING notNullSafety: potential null dereference when accessing property 'stream' at testdata/mustache/src/Mustache/Logger/StreamLogger.php:136 + fwrite($this->stream, self::formatLine($level, $message, $context)); + ^^^^^^^^^^^^^ +WARNING notNullSafety: not null safety call in function enablePragma signature of param name at testdata/mustache/src/Mustache/Parser.php:58 + $this->enablePragma($pragma); + ^^^^^^^ +WARNING notNullSafety: potential null array access in parameter name of function getNameAndFilters at testdata/mustache/src/Mustache/Parser.php:88 + list($name, $filters) = $this->getNameAndFilters($token[Mustache_Tokenizer::NAME]); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null array access in parameter name of function enablePragma at testdata/mustache/src/Mustache/Parser.php:167 + $this->enablePragma($token[Mustache_Tokenizer::NAME]); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null array access in parameter string of function substr at testdata/mustache/src/Mustache/Parser.php:235 + if (substr($next[Mustache_Tokenizer::VALUE], -1) !== "\n") { + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: potential null array access in parameter subject of function preg_match at testdata/mustache/src/Mustache/Parser.php:262 + return preg_match('/^\s*$/', $token[Mustache_Tokenizer::VALUE]); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ WARNING switchDefault: Add 'default' branch to avoid unexpected unhandled condition values at testdata/mustache/src/Mustache/Parser.php:307 switch ($name) { ^ @@ -190,3 +322,15 @@ WARNING errorSilence: Don't use @, silencing errors is bad practice at testdata/ WARNING unused: Variable $v is unused (use $_ to ignore this inspection or specify --unused-var-regex flag) at testdata/mustache/src/Mustache/Template.php:122 foreach ($value as $k => $v) { ^^ +WARNING notNullSafety: not null safety call in function call_user_func signature of param callback at testdata/mustache/src/Mustache/Template.php:174 + ->loadLambda((string) call_user_func($value)) + ^^^^^^ +WARNING notNullSafety: not null safety call in function trim signature of param string at testdata/mustache/src/Mustache/Tokenizer.php:110 + if ($delimiters = trim($delimiters)) { + ^^^^^^^^^^^ +WARNING notNullSafety: not null safety call in function substr signature of param string at testdata/mustache/src/Mustache/Tokenizer.php:188 + if (substr($lastName, -1) === '}') { + ^^^^^^^^^ +WARNING notNullSafety: not null safety call in function substr signature of param string at testdata/mustache/src/Mustache/Tokenizer.php:189 + $token[self::NAME] = trim(substr($lastName, 0, -1)); + ^^^^^^^^^ diff --git a/src/tests/golden/testdata/qrcode/golden.txt b/src/tests/golden/testdata/qrcode/golden.txt index e6b2f8e57..e201c4cc7 100644 --- a/src/tests/golden/testdata/qrcode/golden.txt +++ b/src/tests/golden/testdata/qrcode/golden.txt @@ -4,12 +4,33 @@ MAYBE missingPhpdoc: Missing PHPDoc for \QRCode::output_image public method at MAYBE missingPhpdoc: Missing PHPDoc for \QRCode::render_image public method at testdata/qrcode/qrcode.php:53 public function render_image() { ^^^^^^^^^^^^ +WARNING notNullSafety: not null safety call in function imagecreatetruecolor signature of param width at testdata/qrcode/qrcode.php:56 + $image = imagecreatetruecolor($width, $height); + ^^^^^^ +WARNING notNullSafety: not null safety call in function imagecreatetruecolor signature of param height at testdata/qrcode/qrcode.php:56 + $image = imagecreatetruecolor($width, $height); + ^^^^^^^ MAYBE ternarySimplify: Could rewrite as `$this->options['bc'] ?? 'FFFFFF'` at testdata/qrcode/qrcode.php:59 $bgcolor = (isset($this->options['bc']) ? $this->options['bc'] : 'FFFFFF'); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ MAYBE ternarySimplify: Could rewrite as `$this->options['fc'] ?? '000000'` at testdata/qrcode/qrcode.php:63 $fgcolor = (isset($this->options['fc']) ? $this->options['fc'] : '000000'); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: not null safety call in function floor signature of param num at testdata/qrcode/qrcode.php:72 + $scale = (($scale > 1) ? floor($scale) : 1); + ^^^^^^ +WARNING notNullSafety: not null safety call in function substr signature of param string at testdata/qrcode/qrcode.php:134 + $r = hexdec(substr($color, 0, 2)); + ^^^^^^ +WARNING notNullSafety: not null safety call in function substr signature of param string at testdata/qrcode/qrcode.php:135 + $g = hexdec(substr($color, 2, 2)); + ^^^^^^ +WARNING notNullSafety: not null safety call in function substr signature of param string at testdata/qrcode/qrcode.php:136 + $b = hexdec(substr($color, 4, 2)); + ^^^^^^ +WARNING notNullSafety: not null safety call in function imagecolorallocate signature of param image at testdata/qrcode/qrcode.php:137 + return imagecolorallocate($image, $r, $g, $b); + ^^^^^^ WARNING deadCode: Unreachable code at testdata/qrcode/qrcode.php:155 return null; ^^^^ @@ -19,12 +40,30 @@ MAYBE trailingComma: Last element in a multi-line array should have a trailing WARNING unused: Variable $mode is unused (use $_ to ignore this inspection or specify --unused-var-regex flag) at testdata/qrcode/qrcode.php:177 list($mode, $vers, $ec, $data) = $this->qr_encode_data($data, $ecl); ^^^^^ +WARNING notNullSafety: not null safety call in function substr signature of param string at testdata/qrcode/qrcode.php:200 + $data = substr($data, 0, $max_chars); + ^^^^^ WARNING switchDefault: Add 'default' branch to avoid unexpected unhandled condition values at testdata/qrcode/qrcode.php:203 switch ($mode) { ^ WARNING maybeUndefined: Possibly undefined variable $code at testdata/qrcode/qrcode.php:221 while (count($code) % 8) { ^^^^^ +WARNING notNullSafety: not null safety call in function preg_match signature of param subject at testdata/qrcode/qrcode.php:268 + if (preg_match($numeric, $data)) { + ^^^^^ +WARNING notNullSafety: not null safety call in function preg_match signature of param subject at testdata/qrcode/qrcode.php:271 + if (preg_match($alphanumeric, $data)) { + ^^^^^ +WARNING notNullSafety: not null safety call in function preg_match signature of param subject at testdata/qrcode/qrcode.php:274 + if (preg_match($kanji, $data)) { + ^^^^^ +WARNING notNullSafety: not null safety call in function strlen signature of param string at testdata/qrcode/qrcode.php:281 + $length = strlen($data); + ^^^^^ +WARNING notNullSafety: not null safety call in function strlen signature of param string at testdata/qrcode/qrcode.php:295 + $length = strlen($data); + ^^^^^ WARNING caseBreak: Add break or '// fallthrough' to the end of the case at testdata/qrcode/qrcode.php:297 case 2: /* 27 - 40 */ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,6 +73,9 @@ WARNING caseBreak: Add break or '// fallthrough' to the end of the case at testd WARNING switchDefault: Add 'default' branch to avoid unexpected unhandled condition values at testdata/qrcode/qrcode.php:296 switch ($version_group) { ^ +WARNING notNullSafety: not null safety call in function substr signature of param string at testdata/qrcode/qrcode.php:316 + $group = substr($data, $i, 3); + ^^^^^ WARNING caseBreak: Add break or '// fallthrough' to the end of the case at testdata/qrcode/qrcode.php:318 case 3: ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -43,6 +85,9 @@ WARNING caseBreak: Add break or '// fallthrough' to the end of the case at testd WARNING switchDefault: Add 'default' branch to avoid unexpected unhandled condition values at testdata/qrcode/qrcode.php:317 switch (strlen($group)) { ^ +WARNING notNullSafety: not null safety call in function strlen signature of param string at testdata/qrcode/qrcode.php:339 + $length = strlen($data); + ^^^^^ WARNING caseBreak: Add break or '// fallthrough' to the end of the case at testdata/qrcode/qrcode.php:341 case 2: /* 27 - 40 */ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,21 +97,33 @@ WARNING caseBreak: Add break or '// fallthrough' to the end of the case at testd WARNING switchDefault: Add 'default' branch to avoid unexpected unhandled condition values at testdata/qrcode/qrcode.php:340 switch ($version_group) { ^ +WARNING notNullSafety: not null safety call in function substr signature of param string at testdata/qrcode/qrcode.php:359 + $group = substr($data, $i, 2); + ^^^^^ MAYBE callSimplify: Could simplify to $group[0] at testdata/qrcode/qrcode.php:361 $c1 = strpos($alphabet, substr($group, 0, 1)); ^^^^^^^^^^^^^^^^^^^^ MAYBE callSimplify: Could simplify to $group[1] at testdata/qrcode/qrcode.php:362 $c2 = strpos($alphabet, substr($group, 1, 1)); ^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: not null safety call in function strlen signature of param string at testdata/qrcode/qrcode.php:390 + $length = strlen($data); + ^^^^^ WARNING caseBreak: Add break or '// fallthrough' to the end of the case at testdata/qrcode/qrcode.php:393 case 1: /* 10 - 26 */ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ WARNING switchDefault: Add 'default' branch to avoid unexpected unhandled condition values at testdata/qrcode/qrcode.php:391 switch ($version_group) { ^ +WARNING notNullSafety: not null safety call in function substr signature of param string at testdata/qrcode/qrcode.php:413 + $ch = ord(substr($data, $i, 1)); + ^^^^^ MAYBE callSimplify: Could simplify to $data[$i] at testdata/qrcode/qrcode.php:413 $ch = ord(substr($data, $i, 1)); ^^^^^^^^^^^^^^^^^^^^ +WARNING notNullSafety: not null safety call in function strlen signature of param string at testdata/qrcode/qrcode.php:428 + $length = strlen($data); + ^^^^^ WARNING caseBreak: Add break or '// fallthrough' to the end of the case at testdata/qrcode/qrcode.php:430 case 2: /* 27 - 40 */ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -76,6 +133,9 @@ WARNING caseBreak: Add break or '// fallthrough' to the end of the case at testd WARNING switchDefault: Add 'default' branch to avoid unexpected unhandled condition values at testdata/qrcode/qrcode.php:429 switch ($version_group) { ^ +WARNING notNullSafety: not null safety call in function substr signature of param string at testdata/qrcode/qrcode.php:447 + $group = substr($data, $i, 2); + ^^^^^ MAYBE callSimplify: Could simplify to $group[0] at testdata/qrcode/qrcode.php:448 $c1 = ord(substr($group, 0, 1)); ^^^^^^^^^^^^^^^^^^^^