feat(checks): detect production-time PHP error reporting changes#1317
feat(checks): detect production-time PHP error reporting changes#1317faisalahammad wants to merge 3 commits into
Conversation
- Add Php_Error_Reporting_Check to detect error_reporting(), ini_set('display_errors'), and redefine of debug constants (WP_DEBUG, etc.).
- Register Php_Error_Reporting_Check in Default_Check_Repository.
- Add unit tests and test plugins fixtures for verification.
Fixes WordPress#1315
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Add @SuppressWarnings(PHPMD.NPathComplexity) to check_ast() method. NPath 1206 exceeds threshold 200; method is linear AST scan, not truly complex. Same annotation pattern used in Enqueued_Scripts_Size_Check and Direct_File_Access_Check. Refs WordPress#1317
|
Faisal, Thanks for the PR. The implemented scope looks aligned with Internal Scanner’s A couple of things need tightening before this is ready:
Could you please add explicit coverage for all requested patterns, ideally including a dedicated PHPCS sniff unit test like the existing sniffs have, and fix the coding-standard issues? Once that’s done, this should be much closer. |
Extract detection logic from Php_Error_Reporting_Check into a new PhpErrorReportingSniff (PluginCheck.CodeAnalysis.PhpErrorReporting), registered in the existing PluginCheck standard. The check now extends Abstract_PHP_CodeSniffer_Check and delegates to the sniff, matching the project's existing sniff-driven check pattern. Sniff improvements over the previous AST implementation: - First-argument detection uses PHPCSUtils\Utils\PassedParameters, eliminating false positives for calls like `ini_set( some_function(), 'error_reporting' )`. - Multi-const declarations (`const A = 1, WP_DEBUG = true;`) are fully inspected and report at the offending constant, not the `const` keyword. - The error message for `const` declarations no longer reads `const()`. - Argument case is normalized to lowercase for stable error codes. Test improvements addressing reviewer feedback: - New PhpErrorReportingUnitTest with per-line assertions for all 11 patterns the sniff targets, plus a negative case and a multi-const fixture entry. - The PHPUnit check test now asserts every expected line (12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32) carries the `php_error_reporting_detected` code, instead of relying on a loose `get_warning_count() === 8` count. - Fixture now covers `ini_alter( 'error_reporting', ... )`, `define( 'WP_DEBUG_DISPLAY', ... )`, and `const` declarations, the three patterns the reviewer flagged as missing. - Removed the obsolete tests/some-test.php file; the framework's --ignore patterns handle test-directory exclusion now. All checks green: - composer run lint / phpstan / phpmd: clean - composer run run-tests (sniffs): 13/13 - npm run test-php (full suite): 474/474, 1364 assertions Refs WordPress#1315 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
faisalahammad
left a comment
There was a problem hiding this comment.
Review feedback addressed
Thanks for the detailed feedback on this PR. All blocker items + the recommended improvement are now addressed. Summary of the changes (commit a9fef37b):
Refactor — extracted a dedicated PHPCS sniff
Moved the detection logic out of the bespoke Abstract_File_Check + nikic/php-parser AST walker into a new PhpErrorReportingSniff, registered in the existing PluginCheck standard and consumed by the check via the standard Abstract_PHP_CodeSniffer_Check pattern (get_args() returns the standard + sniff code). This matches the existing pattern used by Nonce_Verification_Check → VerifyNonceSniff, so we now have one source of truth for detection and can reuse PHPCS's per-line assertion tooling.
Test coverage — granular per-line assertions
- New sniff unit test
PhpErrorReportingUnitTest+.incfixture with explicit per-linegetErrorList()for all 11 patterns, plus a negative case (ini_set( some_function(), 'error_reporting' )) and a multi-const declaration. - The PHPUnit
Php_Error_Reporting_Check_Tests::test_run_with_errorsnow asserts every line (12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32) carries thephp_error_reporting_detectedcode, instead of relying onget_warning_count() === 8. - Fixture now covers
ini_alter( 'error_reporting', ... ),define( 'WP_DEBUG_DISPLAY', ... ), andconstdeclarations — the three patterns the review flagged as missing. - The test that exercised the old AST's "skip tests directories" behaviour is gone (the framework's
--ignorepatterns handle that now).
CodeRabbit findings addressed
- First-argument detection now uses
PHPCSUtils\Utils\PassedParameters— no false positive forini_set( some_function(), 'error_reporting' ). - Multi-const declarations are fully inspected; reports point at the offending constant, not the
constkeyword. - Error message for
constdeclarations no longer saysconst(). - Argument case is normalized to lowercase for stable error codes.
Coding standards
composer run lint(phpcs): cleancomposer run phpstan: cleancomposer run phpmd: cleancomposer run run-tests(sniff suite): 13/13 greennpm run test-php(full suite): 474/474, 1364 assertions
Unchanged
- Check slug (
php_error_reporting), category (General), severity, documentation URL, and the user-facing warning text.
Let me know if anything still looks off and I'll iterate.
Summary
Adds a new static check
Php_Error_Reporting_Checkthat flags plugins which modify PHP error-reporting configurations or redefine core WordPress debug constants in production. This prevents sensitive information disclosure and ensures a standard debugging experience on WordPress sites.Fixes #1315
Changes
Php_Error_Reporting_CheckBefore:
No check existed to flag PHP error reporting changes.
After:
Why: Leverages an AST-based search (using
PhpParser\\ParserFactory) to precisely flag directerror_reporting()calls,ini_set()/ini_alter()calls witherror_reporting/display_errors, and the definition of core debug constants (WP_DEBUG, etc.). The check has a robust fallback to regex search if AST parsing fails.Default_Check_RepositoryBefore:
After:
Why: Registers the new static check class as a default check in the General category.
Testing
Test 1: Run the automated unit test suite
Result: Works as expected (2 tests, 6 assertions successfully pass).
Test 2: Perform static analysis and lint checks
composer run-script lintcomposer run-script phpstanResult: Works as expected (0 errors, completely clean).