From 0e3b81281fdead2431064cbc8e2fa1f36b2738cd Mon Sep 17 00:00:00 2001 From: Kamal Hosen Date: Fri, 24 Jul 2026 00:55:07 +0600 Subject: [PATCH 1/6] Fix false positive: exclude fclose from AlternativeFunctions sniff 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. --- phpcs-rulesets/plugin-check.ruleset.xml | 1 + .../testdata/plugins/test-plugin-review-phpcs-errors/load.php | 1 + .../tests/Checker/Checks/Plugin_Review_PHPCS_Check_Tests.php | 3 +++ 3 files changed, 5 insertions(+) diff --git a/phpcs-rulesets/plugin-check.ruleset.xml b/phpcs-rulesets/plugin-check.ruleset.xml index b8432c1bf..2aa253d8b 100644 --- a/phpcs-rulesets/plugin-check.ruleset.xml +++ b/phpcs-rulesets/plugin-check.ruleset.xml @@ -87,6 +87,7 @@ + diff --git a/tests/phpunit/testdata/plugins/test-plugin-review-phpcs-errors/load.php b/tests/phpunit/testdata/plugins/test-plugin-review-phpcs-errors/load.php index bbc8501b8..415a9f36d 100644 --- a/tests/phpunit/testdata/plugins/test-plugin-review-phpcs-errors/load.php +++ b/tests/phpunit/testdata/plugins/test-plugin-review-phpcs-errors/load.php @@ -37,6 +37,7 @@ file_get_contents( $url ); file_put_contents(); +fclose(); load_plugin_textdomain( 'sample-textdomain', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' ); diff --git a/tests/phpunit/tests/Checker/Checks/Plugin_Review_PHPCS_Check_Tests.php b/tests/phpunit/tests/Checker/Checks/Plugin_Review_PHPCS_Check_Tests.php index 0e0779dba..7d48df9a4 100644 --- a/tests/phpunit/tests/Checker/Checks/Plugin_Review_PHPCS_Check_Tests.php +++ b/tests/phpunit/tests/Checker/Checks/Plugin_Review_PHPCS_Check_Tests.php @@ -60,6 +60,9 @@ public function test_run_with_errors() { // There should not be WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents error on Line no 39 and column no 1. $this->assertCount( 0, wp_list_filter( $errors['load.php'][39][1], array( 'code' => 'WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents' ) ) ); + // There should not be WordPress.WP.AlternativeFunctions.file_system_operations_fclose error on Line no 40 and column no 1. + $this->assertCount( 0, wp_list_filter( $errors['load.php'][40][1], array( 'code' => 'WordPress.WP.AlternativeFunctions.file_system_operations_fclose' ) ) ); + // Check for existing forbidden functions. $forbidden_found = 'Generic.PHP.ForbiddenFunctions.Found'; From 546e9f474e9bb02a60ea75b765504787887c4d17 Mon Sep 17 00:00:00 2001 From: Kamal Hosen Date: Fri, 24 Jul 2026 22:56:39 +0600 Subject: [PATCH 2/6] Fix test assertion - line 40 has no errors after exclusion --- .../tests/Checker/Checks/Plugin_Review_PHPCS_Check_Tests.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/tests/Checker/Checks/Plugin_Review_PHPCS_Check_Tests.php b/tests/phpunit/tests/Checker/Checks/Plugin_Review_PHPCS_Check_Tests.php index 7d48df9a4..8385c5abd 100644 --- a/tests/phpunit/tests/Checker/Checks/Plugin_Review_PHPCS_Check_Tests.php +++ b/tests/phpunit/tests/Checker/Checks/Plugin_Review_PHPCS_Check_Tests.php @@ -60,8 +60,8 @@ public function test_run_with_errors() { // There should not be WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents error on Line no 39 and column no 1. $this->assertCount( 0, wp_list_filter( $errors['load.php'][39][1], array( 'code' => 'WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents' ) ) ); - // There should not be WordPress.WP.AlternativeFunctions.file_system_operations_fclose error on Line no 40 and column no 1. - $this->assertCount( 0, wp_list_filter( $errors['load.php'][40][1], array( 'code' => 'WordPress.WP.AlternativeFunctions.file_system_operations_fclose' ) ) ); + // There should not be WordPress.WP.AlternativeFunctions.file_system_operations_fclose error. + $this->assertCount( 0, wp_list_filter( $errors['load.php'], array( 'code' => 'WordPress.WP.AlternativeFunctions.file_system_operations_fclose' ) ) ); // Check for existing forbidden functions. $forbidden_found = 'Generic.PHP.ForbiddenFunctions.Found'; From 017c4e7e02f1883797f19737c3e14911136979ff Mon Sep 17 00:00:00 2001 From: Kamal Hosen Date: Sat, 25 Jul 2026 15:05:35 +0600 Subject: [PATCH 3/6] Fix shifted line numbers in test after fclose() insertion --- .../Plugin_Review_PHPCS_Check_Tests.php | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/phpunit/tests/Checker/Checks/Plugin_Review_PHPCS_Check_Tests.php b/tests/phpunit/tests/Checker/Checks/Plugin_Review_PHPCS_Check_Tests.php index 8385c5abd..47664286c 100644 --- a/tests/phpunit/tests/Checker/Checks/Plugin_Review_PHPCS_Check_Tests.php +++ b/tests/phpunit/tests/Checker/Checks/Plugin_Review_PHPCS_Check_Tests.php @@ -66,24 +66,24 @@ public function test_run_with_errors() { // Check for existing forbidden functions. $forbidden_found = 'Generic.PHP.ForbiddenFunctions.Found'; - // Check for Generic.PHP.ForbiddenFunctions.create_functionFound error on Line no 44 and column no at 1. - $this->assertSame( $forbidden_found, $errors['load.php'][44][1][0]['code'] ); - - // Check for Generic.PHP.ForbiddenFunctions.evalFound error on Line no 45 and column no at 1. - $this->assertSame( $forbidden_found, $errors['load.php'][45][1][0]['code'] ); - - // Check for Generic.PHP.ForbiddenFunctions.move_uploaded_fileFound error on Line no 46 and column no at 1. + // Check for Generic.PHP.ForbiddenFunctions.create_functionFound error on Line no 46 and column no at 1. $this->assertSame( $forbidden_found, $errors['load.php'][46][1][0]['code'] ); - // Check for Generic.PHP.ForbiddenFunctions.passthruFound error on Line no 47 and column no at 1. + // Check for Generic.PHP.ForbiddenFunctions.evalFound error on Line no 47 and column no at 1. $this->assertSame( $forbidden_found, $errors['load.php'][47][1][0]['code'] ); - // Check for Generic.PHP.ForbiddenFunctions.proc_openFound error on Line no 48 and column no at 1. + // Check for Generic.PHP.ForbiddenFunctions.move_uploaded_fileFound error on Line no 48 and column no at 1. $this->assertSame( $forbidden_found, $errors['load.php'][48][1][0]['code'] ); - // Check for Generic.PHP.ForbiddenFunctions.str_rot13Found error on Line no 49 and column no at 1. + // Check for Generic.PHP.ForbiddenFunctions.passthruFound error on Line no 49 and column no at 1. $this->assertSame( $forbidden_found, $errors['load.php'][49][1][0]['code'] ); + // Check for Generic.PHP.ForbiddenFunctions.proc_openFound error on Line no 50 and column no at 1. + $this->assertSame( $forbidden_found, $errors['load.php'][50][1][0]['code'] ); + + // Check for Generic.PHP.ForbiddenFunctions.str_rot13Found error on Line no 51 and column no at 1. + $this->assertSame( $forbidden_found, $errors['load.php'][51][1][0]['code'] ); + // Check for WordPress.Security.ValidatedSanitizedInput warnings on Line no 15 and column no at 27. $this->assertCount( 1, wp_list_filter( $warnings['load.php'][15][27], array( 'code' => 'WordPress.Security.ValidatedSanitizedInput.InputNotValidated' ) ) ); $this->assertCount( 1, wp_list_filter( $warnings['load.php'][15][27], array( 'code' => 'WordPress.Security.ValidatedSanitizedInput.MissingUnslash' ) ) ); @@ -113,34 +113,34 @@ public function test_run_with_errors() { // Check for WordPress.WP.DiscouragedFunctions.wp_reset_query_wp_reset_query warning on Line no 26 and column no at 1. $this->assertSame( 'WordPress.WP.DiscouragedFunctions.wp_reset_query_wp_reset_query', $warnings['load.php'][26][1][0]['code'] ); - // Check for PluginCheck.CodeAnalysis.DiscouragedFunctions.load_plugin_textdomainFound warning on Line no 41 and column no at 1. - $this->assertSame( 'PluginCheck.CodeAnalysis.DiscouragedFunctions.load_plugin_textdomainFound', $warnings['load.php'][41][1][0]['code'] ); + // Check for PluginCheck.CodeAnalysis.DiscouragedFunctions.load_plugin_textdomainFound warning on Line no 43 and column no at 1. + $this->assertSame( 'PluginCheck.CodeAnalysis.DiscouragedFunctions.load_plugin_textdomainFound', $warnings['load.php'][43][1][0]['code'] ); // Check for new forbidden functions - // Check for Generic.PHP.ForbiddenFunctions._cleanup_header_commentFound error on Line no 52 and column no at 1. - $this->assertSame( $forbidden_found, $errors['load.php'][52][1][0]['code'] ); - - // Check for Generic.PHP.ForbiddenFunctions._get_plugin_data_markup_translateFound error on Line no 53 and column no at 1. - $this->assertSame( $forbidden_found, $errors['load.php'][53][1][0]['code'] ); - - // Check for Generic.PHP.ForbiddenFunctions._transition_post_statusFound error on Line no 54 and column no at 1. + // Check for Generic.PHP.ForbiddenFunctions._cleanup_header_commentFound error on Line no 54 and column no at 1. $this->assertSame( $forbidden_found, $errors['load.php'][54][1][0]['code'] ); - // Check for Generic.PHP.ForbiddenFunctions._wp_post_revision_fieldsFound error on Line no 55 and column no at 1. + // Check for Generic.PHP.ForbiddenFunctions._get_plugin_data_markup_translateFound error on Line no 55 and column no at 1. $this->assertSame( $forbidden_found, $errors['load.php'][55][1][0]['code'] ); - // Check for Generic.PHP.ForbiddenFunctions.do_shortcode_tagFound error on Line no 56 and column no at 1. + // Check for Generic.PHP.ForbiddenFunctions._transition_post_statusFound error on Line no 56 and column no at 1. $this->assertSame( $forbidden_found, $errors['load.php'][56][1][0]['code'] ); - // Check for Generic.PHP.ForbiddenFunctions.get_post_type_labelsFound error on Line no 57 and column no at 1. + // Check for Generic.PHP.ForbiddenFunctions._wp_post_revision_fieldsFound error on Line no 57 and column no at 1. $this->assertSame( $forbidden_found, $errors['load.php'][57][1][0]['code'] ); - // Check for Generic.PHP.ForbiddenFunctions.wp_get_sidebars_widgetsFound error on Line no 58 and column no at 1. + // Check for Generic.PHP.ForbiddenFunctions.do_shortcode_tagFound error on Line no 58 and column no at 1. $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.get_post_type_labelsFound error on Line no 59 and column no at 1. $this->assertSame( $forbidden_found, $errors['load.php'][59][1][0]['code'] ); + // Check for Generic.PHP.ForbiddenFunctions.wp_get_sidebars_widgetsFound error on Line no 60 and column no at 1. + $this->assertSame( $forbidden_found, $errors['load.php'][60][1][0]['code'] ); + + // Check for Generic.PHP.ForbiddenFunctions.wp_get_widget_defaultsFound error on Line no 60 and column no at 1. + $this->assertSame( $forbidden_found, $errors['load.php'][60][1][0]['code'] ); + // Check for PluginCheck.CodeAnalysis.ShortURL.Found warning on Line no 69 and column no at 14. $this->assertArrayHasKey( 69, $warnings['load.php'] ); $this->assertArrayHasKey( 14, $warnings['load.php'][69] ); From 9cdc6f849324101358c04440cc61d8ecf252fc04 Mon Sep 17 00:00:00 2001 From: Kamal Hosen Date: Sat, 25 Jul 2026 15:10:40 +0600 Subject: [PATCH 4/6] Fix line numbers in test assertions after fclose() fixture shift --- .../Plugin_Review_PHPCS_Check_Tests.php | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/tests/phpunit/tests/Checker/Checks/Plugin_Review_PHPCS_Check_Tests.php b/tests/phpunit/tests/Checker/Checks/Plugin_Review_PHPCS_Check_Tests.php index 47664286c..3c2e17819 100644 --- a/tests/phpunit/tests/Checker/Checks/Plugin_Review_PHPCS_Check_Tests.php +++ b/tests/phpunit/tests/Checker/Checks/Plugin_Review_PHPCS_Check_Tests.php @@ -66,24 +66,24 @@ public function test_run_with_errors() { // Check for existing forbidden functions. $forbidden_found = 'Generic.PHP.ForbiddenFunctions.Found'; - // Check for Generic.PHP.ForbiddenFunctions.create_functionFound error on Line no 46 and column no at 1. + // Check for Generic.PHP.ForbiddenFunctions.create_functionFound error on Line no 45 and column no at 1. + $this->assertSame( $forbidden_found, $errors['load.php'][45][1][0]['code'] ); + + // Check for Generic.PHP.ForbiddenFunctions.evalFound error on Line no 46 and column no at 1. $this->assertSame( $forbidden_found, $errors['load.php'][46][1][0]['code'] ); - // Check for Generic.PHP.ForbiddenFunctions.evalFound error on Line no 47 and column no at 1. + // Check for Generic.PHP.ForbiddenFunctions.move_uploaded_fileFound error on Line no 47 and column no at 1. $this->assertSame( $forbidden_found, $errors['load.php'][47][1][0]['code'] ); - // Check for Generic.PHP.ForbiddenFunctions.move_uploaded_fileFound error on Line no 48 and column no at 1. + // Check for Generic.PHP.ForbiddenFunctions.passthruFound error on Line no 48 and column no at 1. $this->assertSame( $forbidden_found, $errors['load.php'][48][1][0]['code'] ); - // Check for Generic.PHP.ForbiddenFunctions.passthruFound error on Line no 49 and column no at 1. + // Check for Generic.PHP.ForbiddenFunctions.proc_openFound error on Line no 49 and column no at 1. $this->assertSame( $forbidden_found, $errors['load.php'][49][1][0]['code'] ); - // Check for Generic.PHP.ForbiddenFunctions.proc_openFound error on Line no 50 and column no at 1. + // Check for Generic.PHP.ForbiddenFunctions.str_rot13Found error on Line no 50 and column no at 1. $this->assertSame( $forbidden_found, $errors['load.php'][50][1][0]['code'] ); - // Check for Generic.PHP.ForbiddenFunctions.str_rot13Found error on Line no 51 and column no at 1. - $this->assertSame( $forbidden_found, $errors['load.php'][51][1][0]['code'] ); - // Check for WordPress.Security.ValidatedSanitizedInput warnings on Line no 15 and column no at 27. $this->assertCount( 1, wp_list_filter( $warnings['load.php'][15][27], array( 'code' => 'WordPress.Security.ValidatedSanitizedInput.InputNotValidated' ) ) ); $this->assertCount( 1, wp_list_filter( $warnings['load.php'][15][27], array( 'code' => 'WordPress.Security.ValidatedSanitizedInput.MissingUnslash' ) ) ); @@ -113,40 +113,40 @@ public function test_run_with_errors() { // Check for WordPress.WP.DiscouragedFunctions.wp_reset_query_wp_reset_query warning on Line no 26 and column no at 1. $this->assertSame( 'WordPress.WP.DiscouragedFunctions.wp_reset_query_wp_reset_query', $warnings['load.php'][26][1][0]['code'] ); - // Check for PluginCheck.CodeAnalysis.DiscouragedFunctions.load_plugin_textdomainFound warning on Line no 43 and column no at 1. - $this->assertSame( 'PluginCheck.CodeAnalysis.DiscouragedFunctions.load_plugin_textdomainFound', $warnings['load.php'][43][1][0]['code'] ); + // Check for PluginCheck.CodeAnalysis.DiscouragedFunctions.load_plugin_textdomainFound warning on Line no 42 and column no at 1. + $this->assertSame( 'PluginCheck.CodeAnalysis.DiscouragedFunctions.load_plugin_textdomainFound', $warnings['load.php'][42][1][0]['code'] ); // Check for new forbidden functions - // Check for Generic.PHP.ForbiddenFunctions._cleanup_header_commentFound error on Line no 54 and column no at 1. + // Check for Generic.PHP.ForbiddenFunctions._cleanup_header_commentFound error on Line no 53 and column no at 1. + $this->assertSame( $forbidden_found, $errors['load.php'][53][1][0]['code'] ); + + // Check for Generic.PHP.ForbiddenFunctions._get_plugin_data_markup_translateFound error on Line no 54 and column no at 1. $this->assertSame( $forbidden_found, $errors['load.php'][54][1][0]['code'] ); - // Check for Generic.PHP.ForbiddenFunctions._get_plugin_data_markup_translateFound error on Line no 55 and column no at 1. + // Check for Generic.PHP.ForbiddenFunctions._transition_post_statusFound error on Line no 55 and column no at 1. $this->assertSame( $forbidden_found, $errors['load.php'][55][1][0]['code'] ); - // Check for Generic.PHP.ForbiddenFunctions._transition_post_statusFound error on Line no 56 and column no at 1. + // Check for Generic.PHP.ForbiddenFunctions._wp_post_revision_fieldsFound error on Line no 56 and column no at 1. $this->assertSame( $forbidden_found, $errors['load.php'][56][1][0]['code'] ); - // Check for Generic.PHP.ForbiddenFunctions._wp_post_revision_fieldsFound error on Line no 57 and column no at 1. + // Check for Generic.PHP.ForbiddenFunctions.do_shortcode_tagFound error on Line no 57 and column no at 1. $this->assertSame( $forbidden_found, $errors['load.php'][57][1][0]['code'] ); - // Check for Generic.PHP.ForbiddenFunctions.do_shortcode_tagFound error on Line no 58 and column no at 1. + // Check for Generic.PHP.ForbiddenFunctions.get_post_type_labelsFound error on Line no 58 and column no at 1. $this->assertSame( $forbidden_found, $errors['load.php'][58][1][0]['code'] ); - // Check for Generic.PHP.ForbiddenFunctions.get_post_type_labelsFound error on Line no 59 and column no at 1. - $this->assertSame( $forbidden_found, $errors['load.php'][59][1][0]['code'] ); - // Check for Generic.PHP.ForbiddenFunctions.wp_get_sidebars_widgetsFound error on Line no 60 and column no at 1. - $this->assertSame( $forbidden_found, $errors['load.php'][60][1][0]['code'] ); + $this->assertSame( $forbidden_found, $errors['load.php'][59][1][0]['code'] ); // Check for Generic.PHP.ForbiddenFunctions.wp_get_widget_defaultsFound error on Line no 60 and column no at 1. $this->assertSame( $forbidden_found, $errors['load.php'][60][1][0]['code'] ); - // Check for PluginCheck.CodeAnalysis.ShortURL.Found warning on Line no 69 and column no at 14. - $this->assertArrayHasKey( 69, $warnings['load.php'] ); - $this->assertArrayHasKey( 14, $warnings['load.php'][69] ); - $this->assertArrayHasKey( 'code', $warnings['load.php'][69][14][0] ); - $this->assertEquals( 'PluginCheck.CodeAnalysis.ShortURL.Found', $warnings['load.php'][69][14][0]['code'] ); - $this->assertSame( 6, $warnings['load.php'][69][14][0]['severity'] ); + // Check for PluginCheck.CodeAnalysis.ShortURL.Found warning on Line no 70 and column no at 14. + $this->assertArrayHasKey(70, $warnings['load.php'] ); + $this->assertArrayHasKey( 14, $warnings['load.php'][70] ); + $this->assertArrayHasKey( 'code', $warnings['load.php'][70][14][0] ); + $this->assertEquals( 'PluginCheck.CodeAnalysis.ShortURL.Found', $warnings['load.php'][70][14][0]['code'] ); + $this->assertSame( 6, $warnings['load.php'][70][14][0]['severity'] ); } public function test_run_without_errors() { From 78679a022f5befda30f88f64849c17a409ff1b3d Mon Sep 17 00:00:00 2001 From: Kamal Hosen Date: Sat, 25 Jul 2026 15:14:30 +0600 Subject: [PATCH 5/6] Fix PHPCS lint: missing space after opening parenthesis --- .../tests/Checker/Checks/Plugin_Review_PHPCS_Check_Tests.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/Checker/Checks/Plugin_Review_PHPCS_Check_Tests.php b/tests/phpunit/tests/Checker/Checks/Plugin_Review_PHPCS_Check_Tests.php index 3c2e17819..80f33c8a2 100644 --- a/tests/phpunit/tests/Checker/Checks/Plugin_Review_PHPCS_Check_Tests.php +++ b/tests/phpunit/tests/Checker/Checks/Plugin_Review_PHPCS_Check_Tests.php @@ -142,7 +142,7 @@ public function test_run_with_errors() { $this->assertSame( $forbidden_found, $errors['load.php'][60][1][0]['code'] ); // Check for PluginCheck.CodeAnalysis.ShortURL.Found warning on Line no 70 and column no at 14. - $this->assertArrayHasKey(70, $warnings['load.php'] ); + $this->assertArrayHasKey( 70, $warnings['load.php'] ); $this->assertArrayHasKey( 14, $warnings['load.php'][70] ); $this->assertArrayHasKey( 'code', $warnings['load.php'][70][14][0] ); $this->assertEquals( 'PluginCheck.CodeAnalysis.ShortURL.Found', $warnings['load.php'][70][14][0]['code'] ); From 78de145812c488213f3db6ed04cde545d241eca5 Mon Sep 17 00:00:00 2001 From: Kamal Hosen Date: Sun, 26 Jul 2026 16:49:27 +0600 Subject: [PATCH 6/6] Fix test assertion to properly verify fclose exclusion at line 40/column 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. --- .../fclose-php-output-test.php | 31 +++++++++++++++++++ .../Plugin_Review_PHPCS_Check_Tests.php | 4 +-- 2 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 test-fixtures-for-manual-testing/fclose-php-output-test.php diff --git a/test-fixtures-for-manual-testing/fclose-php-output-test.php b/test-fixtures-for-manual-testing/fclose-php-output-test.php new file mode 100644 index 000000000..ec11628ca --- /dev/null +++ b/test-fixtures-for-manual-testing/fclose-php-output-test.php @@ -0,0 +1,31 @@ +assertCount( 0, wp_list_filter( $errors['load.php'][39][1], array( 'code' => 'WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents' ) ) ); - // There should not be WordPress.WP.AlternativeFunctions.file_system_operations_fclose error. - $this->assertCount( 0, wp_list_filter( $errors['load.php'], array( 'code' => 'WordPress.WP.AlternativeFunctions.file_system_operations_fclose' ) ) ); + // There should not be WordPress.WP.AlternativeFunctions.file_system_operations_fclose error on Line no 40 and column no 1. + $this->assertCount( 0, wp_list_filter( $errors['load.php'][40][1], array( 'code' => 'WordPress.WP.AlternativeFunctions.file_system_operations_fclose' ) ) ); // Check for existing forbidden functions. $forbidden_found = 'Generic.PHP.ForbiddenFunctions.Found';