Fix false positive: exclude fclose from AlternativeFunctions sniff#1406
Fix false positive: exclude fclose from AlternativeFunctions sniff#1406ikamal7 wants to merge 7 commits into
Conversation
The WordPress.WP.AlternativeFunctions.file_system_operations_fclose sniff
flags fclose() even when paired with fopen('php://output') which is already
allowed as a local data stream wrapper. Since fclose is always paired with
a preceding fopen, flagging it separately is redundant noise - if the fopen
was problematic, it's already flagged.
This follows the same pattern as the existing file_put_contents exclusion.
|
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. |
|
@mukeshpanchal27 could you please review and merge this PR when you get a chance? 🙏 |
|
@ikamal7 the tests are failing. You need to fix them before we can review it. |
|
Fixed the test assertion — the previous version tried to access |
|
Same problem... ;) |
|
Test is fixed now. The root cause was that adding |
|
@davidperezgar all tests should be passing now — the lint formatting issue and the shifted line numbers are both fixed. Could you take another look? 🙏 |
|
[P2] With Codex’s help, I noticed that this assertion does not actually verify that the Could we flatten the file’s messages before filtering, or assert directly against the line 40/column 1 entry, so the regression test actually protects this exclusion? |
…umn 1 Previously the assertion used wp_list_filter() on the entire file's errors array, which never found 'code' keys since they are nested under [line][column]. This meant the test always passed even if the fclose sniff was still being reported. Now drills down to the specific line/column like the other similar assertions in the same test, so the regression test actually protects the exclusion.
|
Thanks @davidperezgar for catching this — you were absolutely right. The assertion at line 64 used Fix: Changed to Test result: |
There was a problem hiding this comment.
Pull request overview
This PR updates Plugin Check’s bundled PHPCS ruleset to prevent a known false positive from WPCS’s WordPress.WP.AlternativeFunctions sniff by excluding file_system_operations_fclose, and adjusts PHPUnit fixtures/assertions to verify the new behavior.
Changes:
- Exclude
WordPress.WP.AlternativeFunctions.file_system_operations_fclosein the Plugin Check PHPCS ruleset. - Update the PHPCS-check PHPUnit fixture (
load.php) and test assertions to ensurefcloseis not reported. - Add a manual test fixture plugin to reproduce/verify the original
php://outputscenario.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
phpcs-rulesets/plugin-check.ruleset.xml |
Excludes the file_system_operations_fclose AlternativeFunctions error code to remove the false positive. |
tests/phpunit/testdata/plugins/test-plugin-review-phpcs-errors/load.php |
Adds a fclose() call to the PHPCS error fixture so tests can assert the exclusion. |
tests/phpunit/tests/Checker/Checks/Plugin_Review_PHPCS_Check_Tests.php |
Updates expected line numbers and adds an assertion that fclose is not reported. |
test-fixtures-for-manual-testing/fclose-php-output-test.php |
Adds a manual repro plugin for the php://output use case. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| $this->assertSame( $forbidden_found, $errors['load.php'][58][1][0]['code'] ); | ||
|
|
||
| // Check for Generic.PHP.ForbiddenFunctions.wp_get_widget_defaultsFound error on Line no 59 and column no at 1. | ||
| // Check for Generic.PHP.ForbiddenFunctions.wp_get_sidebars_widgetsFound error on Line no 60 and column no at 1. |
| // This fclose() call on php://output is a common WordPress pattern | ||
| // used to end output buffering. It should NOT trigger the | ||
| // WordPress.WP.AlternativeFunctions.file_system_operations_fclose sniff | ||
| // because php://output is not a file system resource. |
| fclose( $handle ); | ||
| } | ||
|
|
||
| // This fclose() on a real file SHOULD still trigger the sniff. |
| /** | ||
| * Plugin Name: Fclose PHP Output Test | ||
| * Description: A test plugin to verify the Plugin Check plugin's fclose() false positive fix — fclose(php://output) should not trigger an AlternativeFunctions sniff. | ||
| * Version: 1.0.0 | ||
| * Requires PHP: 7.4 |
What?
Closes #1377
Exclude
WordPress.WP.AlternativeFunctions.file_system_operations_fclosefrom the plugin-check ruleset, following the same pattern as the existingfile_put_contentsexclusion.Why?
fclose()is always paired with a precedingfopen()or similar file-opening function. When used withphp://output(a local data stream wrapper), thefopencall is already handled correctly by WPCS 3.4.0's built-inallowed_local_streamscheck — but there is no correspondingcase 'fclose'in the sniff's switch statement, sofclosestill gets flagged.Since
fclosewithout a flaggedfopenis always noise (if thefopenwas inappropriate, it's already flagged separately), excluding it removes this false positive with no loss of meaningful coverage.How?
Added one line to
phpcs-rulesets/plugin-check.ruleset.xml:Testing Instructions
phpunit --filter="Plugin_Review_PHPCS_Check_Tests"fcloseerror should NOT appear in resultsAI Usage Disclosure
Screenshots or screencast
N/A