From e12caa750c51aafc0e50bbe050d4f9d7958a5546 Mon Sep 17 00:00:00 2001 From: Marcelo Rocha Date: Wed, 15 Oct 2025 10:06:51 -0300 Subject: [PATCH 01/15] Disallow debug functions usage --- src/Rule/Debug/DisallowDebugFunctionsRule.php | 29 +++++++++++++ .../Debug/DisallowDebugFunctionsRuleTest.php | 43 +++++++++++++++++++ .../Rule/Debug/Fake/FailingDebugUseLogic.php | 18 ++++++++ 3 files changed, 90 insertions(+) create mode 100644 src/Rule/Debug/DisallowDebugFunctionsRule.php create mode 100644 tests/TestCase/Rule/Debug/DisallowDebugFunctionsRuleTest.php create mode 100644 tests/TestCase/Rule/Debug/Fake/FailingDebugUseLogic.php diff --git a/src/Rule/Debug/DisallowDebugFunctionsRule.php b/src/Rule/Debug/DisallowDebugFunctionsRule.php new file mode 100644 index 0000000..55b12db --- /dev/null +++ b/src/Rule/Debug/DisallowDebugFunctionsRule.php @@ -0,0 +1,29 @@ +analyse([__DIR__ . '/Fake/FailingDebugUseLogic.php'], [ + [ + 'Use of debug function "debug" is not allowed', + 16, // asserted error line + ], + ]); + } + + /** + * @inheritDoc + */ + public static function getAdditionalConfigFiles(): array + { + return [__DIR__ . '/../../../../extension.neon']; + } +} diff --git a/tests/TestCase/Rule/Debug/Fake/FailingDebugUseLogic.php b/tests/TestCase/Rule/Debug/Fake/FailingDebugUseLogic.php new file mode 100644 index 0000000..abd95ac --- /dev/null +++ b/tests/TestCase/Rule/Debug/Fake/FailingDebugUseLogic.php @@ -0,0 +1,18 @@ + Date: Wed, 15 Oct 2025 10:54:13 -0300 Subject: [PATCH 02/15] Disallow debug functions usage --- .../Debug/DisallowDebugFunctionsRuleTest.php | 40 +++++++++++++++++++ .../Rule/Debug/Fake/FailingDebugUseLogic.php | 16 +++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/tests/TestCase/Rule/Debug/DisallowDebugFunctionsRuleTest.php b/tests/TestCase/Rule/Debug/DisallowDebugFunctionsRuleTest.php index 75fef7c..d311679 100644 --- a/tests/TestCase/Rule/Debug/DisallowDebugFunctionsRuleTest.php +++ b/tests/TestCase/Rule/Debug/DisallowDebugFunctionsRuleTest.php @@ -30,6 +30,46 @@ public function testRule(): void 'Use of debug function "debug" is not allowed', 16, // asserted error line ], + [ + 'Use of debug function "debug_print_backtrace" is not allowed', + 17, // asserted error line + ], + [ + 'Use of debug function "debug_zval_dump" is not allowed', + 18, // asserted error line + ], + [ + 'Use of debug function "print_r" is not allowed', + 21, // asserted error line + ], + [ + 'Use of debug function "print_r" is not allowed', + 22, // asserted error line + ], + [ + 'Use of debug function "var_dump" is not allowed', + 23, // asserted error line + ], + [ + 'Use of debug function "var_export" is not allowed', + 25, // asserted error line + ], + [ + 'Use of debug function "var_export" is not allowed', + 26, // asserted error line + ], + [ + 'Use of debug function "stackTrace" is not allowed', + 27, // asserted error line + ], + [ + 'Use of debug function "pr" is not allowed', + 28, // asserted error line + ], + [ + 'Use of debug function "dd" is not allowed', + 30, // asserted error line + ], ]); } diff --git a/tests/TestCase/Rule/Debug/Fake/FailingDebugUseLogic.php b/tests/TestCase/Rule/Debug/Fake/FailingDebugUseLogic.php index abd95ac..b5bd706 100644 --- a/tests/TestCase/Rule/Debug/Fake/FailingDebugUseLogic.php +++ b/tests/TestCase/Rule/Debug/Fake/FailingDebugUseLogic.php @@ -13,6 +13,20 @@ class FailingDebugUseLogic public function execute(): void { $list = [1, 2, 3, 4]; - debug($list); + debug($list);//Error + debug_print_backtrace();//Error + debug_zval_dump("Hello World");//Error + ksort($list);//Not a debug should not fail + print_r(['Hello World!'], true);//No error, text is returned + print_r(['Hello World!']);//Error + print_r(['Hello World!'], false);//Error + var_dump(['a' => 1, 'b' => 2, 'c' => 3]);//Error + var_export($list, true);//No error, text is returned + var_export($list);//Error + var_export($list, false);//Error + stackTrace(); + pr(['b' => 2, 'c' => 3]); + //Last + dd(['a' => 1, 'b' => 2, 'c' => 3]); } } From 500d613727e66948c10bdfd43fa861f940c2b0a1 Mon Sep 17 00:00:00 2001 From: Marcelo Rocha Date: Wed, 15 Oct 2025 10:54:17 -0300 Subject: [PATCH 03/15] Disallow debug functions usage --- src/Rule/Debug/DisallowDebugFunctionsRule.php | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/Rule/Debug/DisallowDebugFunctionsRule.php b/src/Rule/Debug/DisallowDebugFunctionsRule.php index 55b12db..a76e3d3 100644 --- a/src/Rule/Debug/DisallowDebugFunctionsRule.php +++ b/src/Rule/Debug/DisallowDebugFunctionsRule.php @@ -3,12 +3,32 @@ namespace CakeDC\PHPStan\Rule\Debug; use PhpParser\Node; +use PhpParser\Node\Expr\ConstFetch; use PhpParser\Node\Expr\FuncCall; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; class DisallowDebugFunctionsRule implements Rule { + protected const BASIC = 'basic'; + protected const RETURNABLE = 'returnable'; + + /** + * @var array + */ + private array $disallowedFunctions = [ + 'dd' => self::BASIC, + 'debug' => self::BASIC, + 'debug_print_backtrace' => self::BASIC, + 'debug_zval_dump' => self::BASIC, + 'pr' => self::BASIC, + 'print_r' => self::RETURNABLE, + 'stacktrace' => self::BASIC, + 'var_dump' => self::BASIC, + 'var_export' => self::RETURNABLE, + ]; + /** * @inheritDoc */ @@ -24,6 +44,29 @@ public function getNodeType(): string */ public function processNode(Node $node, Scope $scope): array { - return []; + assert($node instanceof FuncCall); + if (!$node->name instanceof Node\Name) { + return []; + } + $usedName = $node->name->name; + $name = strtolower($usedName); + if (!isset($this->disallowedFunctions[$name])) { + return []; + } + if ($this->disallowedFunctions[$name] === self::RETURNABLE) { + $arg = $node->getArgs()[1]->value ?? null; + if ($arg instanceof ConstFetch && $arg->name->name == 'true') { + return []; + } + } + + return [ + RuleErrorBuilder::message(sprintf( + 'Use of debug function "%s" is not allowed', + $usedName, + )) + ->identifier('cake.entity.arrayAccess') + ->build(), + ]; } } From 2939b35b4c7d178d110407790fd742dbb8784058 Mon Sep 17 00:00:00 2001 From: Marcelo Rocha Date: Wed, 15 Oct 2025 10:57:30 -0300 Subject: [PATCH 04/15] Disallow debug functions usage --- rules.neon | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rules.neon b/rules.neon index 4b637f4..64ba321 100644 --- a/rules.neon +++ b/rules.neon @@ -9,6 +9,7 @@ parameters: getMailerExistsClassRule: true loadComponentExistsClassRule: true controllerMethodMustBeUsedRule: true + disallowDebugFunctionsRule: true parametersSchema: cakeDC: structure([ addAssociationExistsTableClassRule: anyOf(bool(), arrayOf(bool())) @@ -20,6 +21,7 @@ parametersSchema: getMailerExistsClassRule: anyOf(bool(), arrayOf(bool())) loadComponentExistsClassRule: anyOf(bool(), arrayOf(bool())) controllerMethodMustBeUsedRule: anyOf(bool(), arrayOf(bool())) + disallowDebugFunctionsRule: anyOf(bool(), arrayOf(bool())) ]) conditionalTags: @@ -43,6 +45,8 @@ conditionalTags: phpstan.rules.rule: %cakeDC.tableGetMatchOptionsTypesRule% CakeDC\PHPStan\Rule\Model\OrmSelectQueryFindMatchOptionsTypesRule: phpstan.rules.rule: %cakeDC.ormSelectQueryFindMatchOptionsTypesRule% + CakeDC\PHPStan\Rule\Model\DisallowDebugFunctionsRule: + phpstan.rules.rule: %cakeDC.disallowDebugFunctionsRule% services: - @@ -65,3 +69,5 @@ services: class: CakeDC\PHPStan\Rule\Model\TableGetMatchOptionsTypesRule - class: CakeDC\PHPStan\Rule\Model\OrmSelectQueryFindMatchOptionsTypesRule + - + class: CakeDC\PHPStan\Rule\Debug\DisallowDebugFunctionsRule From 67dae12b58db1b22c987a9d40308a5a733f5436c Mon Sep 17 00:00:00 2001 From: Marcelo Rocha Date: Wed, 15 Oct 2025 10:57:54 -0300 Subject: [PATCH 05/15] phpqa fixes --- src/Rule/Debug/DisallowDebugFunctionsRule.php | 3 ++- tests/TestCase/Rule/Debug/DisallowDebugFunctionsRuleTest.php | 1 + tests/TestCase/Rule/Debug/Fake/FailingDebugUseLogic.php | 4 +--- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Rule/Debug/DisallowDebugFunctionsRule.php b/src/Rule/Debug/DisallowDebugFunctionsRule.php index a76e3d3..7d47c91 100644 --- a/src/Rule/Debug/DisallowDebugFunctionsRule.php +++ b/src/Rule/Debug/DisallowDebugFunctionsRule.php @@ -2,6 +2,7 @@ declare(strict_types=1); namespace CakeDC\PHPStan\Rule\Debug; + use PhpParser\Node; use PhpParser\Node\Expr\ConstFetch; use PhpParser\Node\Expr\FuncCall; @@ -40,7 +41,7 @@ public function getNodeType(): string /** * @param \PhpParser\Node $node * @param \PHPStan\Analyser\Scope $scope - * @return array|\PHPStan\Rules\IdentifierRuleError[] + * @return array|array<\PHPStan\Rules\IdentifierRuleError> */ public function processNode(Node $node, Scope $scope): array { diff --git a/tests/TestCase/Rule/Debug/DisallowDebugFunctionsRuleTest.php b/tests/TestCase/Rule/Debug/DisallowDebugFunctionsRuleTest.php index d311679..effaa6d 100644 --- a/tests/TestCase/Rule/Debug/DisallowDebugFunctionsRuleTest.php +++ b/tests/TestCase/Rule/Debug/DisallowDebugFunctionsRuleTest.php @@ -2,6 +2,7 @@ declare(strict_types=1); namespace CakeDC\PHPStan\Test\TestCase\Rule\Debug; + use CakeDC\PHPStan\Rule\Debug\DisallowDebugFunctionsRule; use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; diff --git a/tests/TestCase/Rule/Debug/Fake/FailingDebugUseLogic.php b/tests/TestCase/Rule/Debug/Fake/FailingDebugUseLogic.php index b5bd706..750b096 100644 --- a/tests/TestCase/Rule/Debug/Fake/FailingDebugUseLogic.php +++ b/tests/TestCase/Rule/Debug/Fake/FailingDebugUseLogic.php @@ -3,10 +3,8 @@ namespace CakeDC\PHPStan\Test\TestCase\Rule\Debug\Fake; - class FailingDebugUseLogic { - /** * @return void */ @@ -15,7 +13,7 @@ public function execute(): void $list = [1, 2, 3, 4]; debug($list);//Error debug_print_backtrace();//Error - debug_zval_dump("Hello World");//Error + debug_zval_dump('Hello World');//Error ksort($list);//Not a debug should not fail print_r(['Hello World!'], true);//No error, text is returned print_r(['Hello World!']);//Error From 0f4c4ef6a832ce03a4d212aff3b43cf9234ab226 Mon Sep 17 00:00:00 2001 From: Marcelo Rocha Date: Wed, 15 Oct 2025 11:04:19 -0300 Subject: [PATCH 06/15] phpqa fixes --- rules.neon | 2 +- .../Debug/DisallowDebugFunctionsRuleTest.php | 22 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/rules.neon b/rules.neon index 64ba321..0175a2c 100644 --- a/rules.neon +++ b/rules.neon @@ -45,7 +45,7 @@ conditionalTags: phpstan.rules.rule: %cakeDC.tableGetMatchOptionsTypesRule% CakeDC\PHPStan\Rule\Model\OrmSelectQueryFindMatchOptionsTypesRule: phpstan.rules.rule: %cakeDC.ormSelectQueryFindMatchOptionsTypesRule% - CakeDC\PHPStan\Rule\Model\DisallowDebugFunctionsRule: + CakeDC\PHPStan\Rule\Debug\DisallowDebugFunctionsRule: phpstan.rules.rule: %cakeDC.disallowDebugFunctionsRule% services: diff --git a/tests/TestCase/Rule/Debug/DisallowDebugFunctionsRuleTest.php b/tests/TestCase/Rule/Debug/DisallowDebugFunctionsRuleTest.php index effaa6d..2fcbc4a 100644 --- a/tests/TestCase/Rule/Debug/DisallowDebugFunctionsRuleTest.php +++ b/tests/TestCase/Rule/Debug/DisallowDebugFunctionsRuleTest.php @@ -29,47 +29,47 @@ public function testRule(): void $this->analyse([__DIR__ . '/Fake/FailingDebugUseLogic.php'], [ [ 'Use of debug function "debug" is not allowed', - 16, // asserted error line + 14, // asserted error line ], [ 'Use of debug function "debug_print_backtrace" is not allowed', - 17, // asserted error line + 15, // asserted error line ], [ 'Use of debug function "debug_zval_dump" is not allowed', - 18, // asserted error line + 16, // asserted error line ], [ 'Use of debug function "print_r" is not allowed', - 21, // asserted error line + 19, // asserted error line ], [ 'Use of debug function "print_r" is not allowed', - 22, // asserted error line + 20, // asserted error line ], [ 'Use of debug function "var_dump" is not allowed', - 23, // asserted error line + 21, // asserted error line ], [ 'Use of debug function "var_export" is not allowed', - 25, // asserted error line + 23, // asserted error line ], [ 'Use of debug function "var_export" is not allowed', - 26, // asserted error line + 24, // asserted error line ], [ 'Use of debug function "stackTrace" is not allowed', - 27, // asserted error line + 25, // asserted error line ], [ 'Use of debug function "pr" is not allowed', - 28, // asserted error line + 26, // asserted error line ], [ 'Use of debug function "dd" is not allowed', - 30, // asserted error line + 28, // asserted error line ], ]); } From 08e91e9d5a8c9db3b75895d6aa1929792501d22e Mon Sep 17 00:00:00 2001 From: Marcelo Rocha Date: Wed, 15 Oct 2025 11:06:13 -0300 Subject: [PATCH 07/15] phpqa fixes --- src/Rule/Debug/DisallowDebugFunctionsRule.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Rule/Debug/DisallowDebugFunctionsRule.php b/src/Rule/Debug/DisallowDebugFunctionsRule.php index 7d47c91..a7fe860 100644 --- a/src/Rule/Debug/DisallowDebugFunctionsRule.php +++ b/src/Rule/Debug/DisallowDebugFunctionsRule.php @@ -39,9 +39,7 @@ public function getNodeType(): string } /** - * @param \PhpParser\Node $node - * @param \PHPStan\Analyser\Scope $scope - * @return array|array<\PHPStan\Rules\IdentifierRuleError> + * @inheritDoc */ public function processNode(Node $node, Scope $scope): array { @@ -56,7 +54,7 @@ public function processNode(Node $node, Scope $scope): array } if ($this->disallowedFunctions[$name] === self::RETURNABLE) { $arg = $node->getArgs()[1]->value ?? null; - if ($arg instanceof ConstFetch && $arg->name->name == 'true') { + if ($arg instanceof ConstFetch && $arg->name->name === 'true') { return []; } } From 629363fce0c992157fe8e906b917bf191edd7ee6 Mon Sep 17 00:00:00 2001 From: Marcelo Rocha Date: Wed, 15 Oct 2025 11:18:01 -0300 Subject: [PATCH 08/15] Mention the DisallowDebugFunctionsRule in ReadMe file. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 7404ced..94a4383 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,10 @@ Table::hasMany, Table::belongsToMany, Table::hasOne and AssociationCollection::l ### AddBehaviorExistsClassRule This rule check if the target behavior has a valid class when calling to Table::addBehavior and BehaviorRegistry::load. +### DisallowDebugFunctionsRule +This rule disallow use of debug functions (dd, debug, debug_print_backtrace, debug_zval_dump, pr, print_r, stacktrace, var_dump and var_export). +The use of these functions in shipped code is discouraged because they can leak sensitive information or clutter output. + ### DisallowEntityArrayAccessRule This rule disallow array access to entity in favor of object notation, is easier to detect a wrong property and to refactor code. From b9a67eddb91c347f0450c5f8bfe04a4b0b21ecb2 Mon Sep 17 00:00:00 2001 From: Marcelo Rocha Date: Wed, 15 Oct 2025 11:18:18 -0300 Subject: [PATCH 09/15] Improved error message --- src/Rule/Debug/DisallowDebugFunctionsRule.php | 5 +++-- .../Debug/DisallowDebugFunctionsRuleTest.php | 22 +++++++++---------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/Rule/Debug/DisallowDebugFunctionsRule.php b/src/Rule/Debug/DisallowDebugFunctionsRule.php index a7fe860..8479030 100644 --- a/src/Rule/Debug/DisallowDebugFunctionsRule.php +++ b/src/Rule/Debug/DisallowDebugFunctionsRule.php @@ -61,10 +61,11 @@ public function processNode(Node $node, Scope $scope): array return [ RuleErrorBuilder::message(sprintf( - 'Use of debug function "%s" is not allowed', + 'Use of debug function "%s" is not allowed. %s', $usedName, + 'The use in shipped code is discouraged because they can leak sensitive information or clutter output.', )) - ->identifier('cake.entity.arrayAccess') + ->identifier('cake.debug.debugFunctionUse') ->build(), ]; } diff --git a/tests/TestCase/Rule/Debug/DisallowDebugFunctionsRuleTest.php b/tests/TestCase/Rule/Debug/DisallowDebugFunctionsRuleTest.php index 2fcbc4a..3f030fe 100644 --- a/tests/TestCase/Rule/Debug/DisallowDebugFunctionsRuleTest.php +++ b/tests/TestCase/Rule/Debug/DisallowDebugFunctionsRuleTest.php @@ -28,47 +28,47 @@ public function testRule(): void // each error consists of the asserted error message, and the asserted error file line $this->analyse([__DIR__ . '/Fake/FailingDebugUseLogic.php'], [ [ - 'Use of debug function "debug" is not allowed', + 'Use of debug function "debug" is not allowed. The use in shipped code is discouraged because they can leak sensitive information or clutter output.', 14, // asserted error line ], [ - 'Use of debug function "debug_print_backtrace" is not allowed', + 'Use of debug function "debug_print_backtrace" is not allowed. The use in shipped code is discouraged because they can leak sensitive information or clutter output.', 15, // asserted error line ], [ - 'Use of debug function "debug_zval_dump" is not allowed', + 'Use of debug function "debug_zval_dump" is not allowed. The use in shipped code is discouraged because they can leak sensitive information or clutter output.', 16, // asserted error line ], [ - 'Use of debug function "print_r" is not allowed', + 'Use of debug function "print_r" is not allowed. The use in shipped code is discouraged because they can leak sensitive information or clutter output.', 19, // asserted error line ], [ - 'Use of debug function "print_r" is not allowed', + 'Use of debug function "print_r" is not allowed. The use in shipped code is discouraged because they can leak sensitive information or clutter output.', 20, // asserted error line ], [ - 'Use of debug function "var_dump" is not allowed', + 'Use of debug function "var_dump" is not allowed. The use in shipped code is discouraged because they can leak sensitive information or clutter output.', 21, // asserted error line ], [ - 'Use of debug function "var_export" is not allowed', + 'Use of debug function "var_export" is not allowed. The use in shipped code is discouraged because they can leak sensitive information or clutter output.', 23, // asserted error line ], [ - 'Use of debug function "var_export" is not allowed', + 'Use of debug function "var_export" is not allowed. The use in shipped code is discouraged because they can leak sensitive information or clutter output.', 24, // asserted error line ], [ - 'Use of debug function "stackTrace" is not allowed', + 'Use of debug function "stackTrace" is not allowed. The use in shipped code is discouraged because they can leak sensitive information or clutter output.', 25, // asserted error line ], [ - 'Use of debug function "pr" is not allowed', + 'Use of debug function "pr" is not allowed. The use in shipped code is discouraged because they can leak sensitive information or clutter output.', 26, // asserted error line ], [ - 'Use of debug function "dd" is not allowed', + 'Use of debug function "dd" is not allowed. The use in shipped code is discouraged because they can leak sensitive information or clutter output.', 28, // asserted error line ], ]); From ed97ede5fd0b93169ab53612fdafc3be8661adbb Mon Sep 17 00:00:00 2001 From: Marcelo Rocha Date: Wed, 15 Oct 2025 14:12:24 -0300 Subject: [PATCH 10/15] Disallow debug functions usage --- .../Debug/Fake/FailingDebugStaticUseLogic.php | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tests/TestCase/Rule/Debug/Fake/FailingDebugStaticUseLogic.php diff --git a/tests/TestCase/Rule/Debug/Fake/FailingDebugStaticUseLogic.php b/tests/TestCase/Rule/Debug/Fake/FailingDebugStaticUseLogic.php new file mode 100644 index 0000000..d4da46e --- /dev/null +++ b/tests/TestCase/Rule/Debug/Fake/FailingDebugStaticUseLogic.php @@ -0,0 +1,21 @@ + 1, 'b' => 2, 'c' => 3]); + Debugger::printVar(['y' => 10, 'x' => 20, 'z' => 30]); + DebugSql::sql(); + DebugSql::sqld(); + } +} From 08860285567e7ed2a3ffccd05a95589589b33b3b Mon Sep 17 00:00:00 2001 From: Marcelo Rocha Date: Wed, 15 Oct 2025 14:12:42 -0300 Subject: [PATCH 11/15] Disallow debug functions usage --- .../Debug/DisallowDebugStaticCallRule.php | 65 +++++++++++++++++++ .../Debug/DisallowDebugStaticCallRuleTest.php | 55 ++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 src/Rule/Debug/DisallowDebugStaticCallRule.php create mode 100644 tests/TestCase/Rule/Debug/DisallowDebugStaticCallRuleTest.php diff --git a/src/Rule/Debug/DisallowDebugStaticCallRule.php b/src/Rule/Debug/DisallowDebugStaticCallRule.php new file mode 100644 index 0000000..8b86867 --- /dev/null +++ b/src/Rule/Debug/DisallowDebugStaticCallRule.php @@ -0,0 +1,65 @@ +> + */ + private array $disallowed = [ + //Methods must be lowercased + Debugger::class => ['dump', 'printvar'], + 'DebugKit\DebugSql' => ['sql', 'sqld'], + ]; + + /** + * @inheritDoc + */ + public function getNodeType(): string + { + return StaticCall::class; + } + + /** + * @inheritDoc + */ + public function processNode(Node $node, Scope $scope): array + { + assert($node instanceof StaticCall); + if (!$node->class instanceof Name || !$node->name instanceof Identifier) { + return []; + } + + $className = (string)$node->class; + if (!isset($this->disallowed[$className])) { + return []; + } + $methodUsed = (string)$node->name; + $method = strtolower($methodUsed); + if (!in_array($method, $this->disallowed[$className], true)) { + return []; + } + + return [ + RuleErrorBuilder::message(sprintf( + 'Use of debug method "%s::%s" is not allowed. %s', + $className, + $methodUsed, + 'The use in shipped code is discouraged because they can leak sensitive information or clutter output.', + )) + ->identifier('cake.debug.debugStaticCallUse') + ->build(), + ]; + } +} diff --git a/tests/TestCase/Rule/Debug/DisallowDebugStaticCallRuleTest.php b/tests/TestCase/Rule/Debug/DisallowDebugStaticCallRuleTest.php new file mode 100644 index 0000000..b50551b --- /dev/null +++ b/tests/TestCase/Rule/Debug/DisallowDebugStaticCallRuleTest.php @@ -0,0 +1,55 @@ +analyse([__DIR__ . '/Fake/FailingDebugStaticUseLogic.php'], [ + [ + 'Use of debug method "Cake\Error\Debugger::dump" is not allowed. The use in shipped code is discouraged because they can leak sensitive information or clutter output.', + 16, // asserted error line + ], + [ + 'Use of debug method "Cake\Error\Debugger::printVar" is not allowed. The use in shipped code is discouraged because they can leak sensitive information or clutter output.', + 17, // asserted error line + ], + [ + 'Use of debug method "DebugKit\DebugSql::sql" is not allowed. The use in shipped code is discouraged because they can leak sensitive information or clutter output.', + 18, // asserted error line + ], + [ + 'Use of debug method "DebugKit\DebugSql::sqld" is not allowed. The use in shipped code is discouraged because they can leak sensitive information or clutter output.', + 19, // asserted error line + ], + ]); + } + + /** + * @inheritDoc + */ + public static function getAdditionalConfigFiles(): array + { + return [__DIR__ . '/../../../../extension.neon']; + } +} From 63cd01d45dc512829613bf00fefaad7d11d95851 Mon Sep 17 00:00:00 2001 From: Marcelo Rocha Date: Wed, 15 Oct 2025 14:12:48 -0300 Subject: [PATCH 12/15] Disallow debug functions usage --- rules.neon | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rules.neon b/rules.neon index 0175a2c..32e2802 100644 --- a/rules.neon +++ b/rules.neon @@ -10,6 +10,7 @@ parameters: loadComponentExistsClassRule: true controllerMethodMustBeUsedRule: true disallowDebugFunctionsRule: true + disallowDebugStaticCallRule: true parametersSchema: cakeDC: structure([ addAssociationExistsTableClassRule: anyOf(bool(), arrayOf(bool())) @@ -22,6 +23,7 @@ parametersSchema: loadComponentExistsClassRule: anyOf(bool(), arrayOf(bool())) controllerMethodMustBeUsedRule: anyOf(bool(), arrayOf(bool())) disallowDebugFunctionsRule: anyOf(bool(), arrayOf(bool())) + disallowDebugStaticCallRule: anyOf(bool(), arrayOf(bool())) ]) conditionalTags: @@ -47,6 +49,8 @@ conditionalTags: phpstan.rules.rule: %cakeDC.ormSelectQueryFindMatchOptionsTypesRule% CakeDC\PHPStan\Rule\Debug\DisallowDebugFunctionsRule: phpstan.rules.rule: %cakeDC.disallowDebugFunctionsRule% + CakeDC\PHPStan\Rule\Debug\DisallowDebugStaticCallRule: + phpstan.rules.rule: %cakeDC.disallowDebugStaticCallRule% services: - @@ -71,3 +75,5 @@ services: class: CakeDC\PHPStan\Rule\Model\OrmSelectQueryFindMatchOptionsTypesRule - class: CakeDC\PHPStan\Rule\Debug\DisallowDebugFunctionsRule + - + class: CakeDC\PHPStan\Rule\Debug\DisallowDebugStaticCallRule From 3913a9e37676642a218da842cf99cdd097423332 Mon Sep 17 00:00:00 2001 From: Marcelo Rocha Date: Wed, 15 Oct 2025 14:20:19 -0300 Subject: [PATCH 13/15] Disallow debug functions usage --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 94a4383..c596d9b 100644 --- a/README.md +++ b/README.md @@ -134,9 +134,20 @@ Table::hasMany, Table::belongsToMany, Table::hasOne and AssociationCollection::l This rule check if the target behavior has a valid class when calling to Table::addBehavior and BehaviorRegistry::load. ### DisallowDebugFunctionsRule -This rule disallow use of debug functions (dd, debug, debug_print_backtrace, debug_zval_dump, pr, print_r, stacktrace, var_dump and var_export). +This rule disallow use of debug functions (`dd, debug, debug_print_backtrace, debug_zval_dump, pr, print_r, stacktrace, var_dump and var_export`). + The use of these functions in shipped code is discouraged because they can leak sensitive information or clutter output. +### DisallowDebugStaticCallRule +This rule disallow use of debug methods. The use of these methods in shipped code is discouraged because they can leak sensitive information or clutter output. + +Methods covered: + + - Cake\Error\Debugger::dump + - Cake\Error\Debugger::printVar + - DebugKit\DebugSql::sql + - DebugKit\DebugSql::sqld + ### DisallowEntityArrayAccessRule This rule disallow array access to entity in favor of object notation, is easier to detect a wrong property and to refactor code. From d3eb291f88fd4bc00ed1a8123436bc226cfc5c35 Mon Sep 17 00:00:00 2001 From: Marcelo Rocha Date: Wed, 15 Oct 2025 14:23:41 -0300 Subject: [PATCH 14/15] Rename class to match phpstan naming --- README.md | 2 +- rules.neon | 10 +++++----- ...FunctionsRule.php => DisallowDebugFuncCallRule.php} | 2 +- ...sRuleTest.php => DisallowDebugFuncCallRuleTest.php} | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) rename src/Rule/Debug/{DisallowDebugFunctionsRule.php => DisallowDebugFuncCallRule.php} (97%) rename tests/TestCase/Rule/Debug/{DisallowDebugFunctionsRuleTest.php => DisallowDebugFuncCallRuleTest.php} (95%) diff --git a/README.md b/README.md index c596d9b..42a83c5 100644 --- a/README.md +++ b/README.md @@ -133,7 +133,7 @@ Table::hasMany, Table::belongsToMany, Table::hasOne and AssociationCollection::l ### AddBehaviorExistsClassRule This rule check if the target behavior has a valid class when calling to Table::addBehavior and BehaviorRegistry::load. -### DisallowDebugFunctionsRule +### DisallowDebugFuncCallRule This rule disallow use of debug functions (`dd, debug, debug_print_backtrace, debug_zval_dump, pr, print_r, stacktrace, var_dump and var_export`). The use of these functions in shipped code is discouraged because they can leak sensitive information or clutter output. diff --git a/rules.neon b/rules.neon index 32e2802..f570bd3 100644 --- a/rules.neon +++ b/rules.neon @@ -9,7 +9,7 @@ parameters: getMailerExistsClassRule: true loadComponentExistsClassRule: true controllerMethodMustBeUsedRule: true - disallowDebugFunctionsRule: true + disallowDebugFuncCallRule: true disallowDebugStaticCallRule: true parametersSchema: cakeDC: structure([ @@ -22,7 +22,7 @@ parametersSchema: getMailerExistsClassRule: anyOf(bool(), arrayOf(bool())) loadComponentExistsClassRule: anyOf(bool(), arrayOf(bool())) controllerMethodMustBeUsedRule: anyOf(bool(), arrayOf(bool())) - disallowDebugFunctionsRule: anyOf(bool(), arrayOf(bool())) + disallowDebugFuncCallRule: anyOf(bool(), arrayOf(bool())) disallowDebugStaticCallRule: anyOf(bool(), arrayOf(bool())) ]) @@ -47,8 +47,8 @@ conditionalTags: phpstan.rules.rule: %cakeDC.tableGetMatchOptionsTypesRule% CakeDC\PHPStan\Rule\Model\OrmSelectQueryFindMatchOptionsTypesRule: phpstan.rules.rule: %cakeDC.ormSelectQueryFindMatchOptionsTypesRule% - CakeDC\PHPStan\Rule\Debug\DisallowDebugFunctionsRule: - phpstan.rules.rule: %cakeDC.disallowDebugFunctionsRule% + CakeDC\PHPStan\Rule\Debug\DisallowDebugFuncCallRule: + phpstan.rules.rule: %cakeDC.disallowDebugFuncCallRule% CakeDC\PHPStan\Rule\Debug\DisallowDebugStaticCallRule: phpstan.rules.rule: %cakeDC.disallowDebugStaticCallRule% @@ -74,6 +74,6 @@ services: - class: CakeDC\PHPStan\Rule\Model\OrmSelectQueryFindMatchOptionsTypesRule - - class: CakeDC\PHPStan\Rule\Debug\DisallowDebugFunctionsRule + class: CakeDC\PHPStan\Rule\Debug\DisallowDebugFuncCallRule - class: CakeDC\PHPStan\Rule\Debug\DisallowDebugStaticCallRule diff --git a/src/Rule/Debug/DisallowDebugFunctionsRule.php b/src/Rule/Debug/DisallowDebugFuncCallRule.php similarity index 97% rename from src/Rule/Debug/DisallowDebugFunctionsRule.php rename to src/Rule/Debug/DisallowDebugFuncCallRule.php index 8479030..3d0164c 100644 --- a/src/Rule/Debug/DisallowDebugFunctionsRule.php +++ b/src/Rule/Debug/DisallowDebugFuncCallRule.php @@ -10,7 +10,7 @@ use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; -class DisallowDebugFunctionsRule implements Rule +class DisallowDebugFuncCallRule implements Rule { protected const BASIC = 'basic'; protected const RETURNABLE = 'returnable'; diff --git a/tests/TestCase/Rule/Debug/DisallowDebugFunctionsRuleTest.php b/tests/TestCase/Rule/Debug/DisallowDebugFuncCallRuleTest.php similarity index 95% rename from tests/TestCase/Rule/Debug/DisallowDebugFunctionsRuleTest.php rename to tests/TestCase/Rule/Debug/DisallowDebugFuncCallRuleTest.php index 3f030fe..392f36c 100644 --- a/tests/TestCase/Rule/Debug/DisallowDebugFunctionsRuleTest.php +++ b/tests/TestCase/Rule/Debug/DisallowDebugFuncCallRuleTest.php @@ -3,11 +3,11 @@ namespace CakeDC\PHPStan\Test\TestCase\Rule\Debug; -use CakeDC\PHPStan\Rule\Debug\DisallowDebugFunctionsRule; +use CakeDC\PHPStan\Rule\Debug\DisallowDebugFuncCallRule; use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; -class DisallowDebugFunctionsRuleTest extends RuleTestCase +class DisallowDebugFuncCallRuleTest extends RuleTestCase { /** * @return \PHPStan\Rules\Rule @@ -15,7 +15,7 @@ class DisallowDebugFunctionsRuleTest extends RuleTestCase protected function getRule(): Rule { // getRule() method needs to return an instance of the tested rule - return new DisallowDebugFunctionsRule(); + return new DisallowDebugFuncCallRule(); } /** From 7f043432ab1c9b0446cda684a209f704e57dad1d Mon Sep 17 00:00:00 2001 From: Marcelo Rocha Date: Wed, 15 Oct 2025 14:25:53 -0300 Subject: [PATCH 15/15] Rename class to match phpstan naming --- src/Rule/Debug/DisallowDebugFuncCallRule.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Rule/Debug/DisallowDebugFuncCallRule.php b/src/Rule/Debug/DisallowDebugFuncCallRule.php index 3d0164c..9cf4ebb 100644 --- a/src/Rule/Debug/DisallowDebugFuncCallRule.php +++ b/src/Rule/Debug/DisallowDebugFuncCallRule.php @@ -65,7 +65,7 @@ public function processNode(Node $node, Scope $scope): array $usedName, 'The use in shipped code is discouraged because they can leak sensitive information or clutter output.', )) - ->identifier('cake.debug.debugFunctionUse') + ->identifier('cake.debug.debugFuncCallUse') ->build(), ]; }