Skip to content

Commit fa5e3d0

Browse files
authored
Merge pull request #314 from humanmade/upgrade-wpcs
2 parents 01ccad3 + 1401a8e commit fa5e3d0

14 files changed

Lines changed: 119 additions & 53 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ phpcs-standard/
1313

1414
# OS generated files
1515
.DS_Store
16+
.phpunit.result.cache

HM-Minimum/ruleset.xml

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,17 @@
7171
<element value="get_post_gallery" /> <!-- with param 2 set to true, the default -->
7272
</property>
7373
</properties>
74+
75+
<!--
76+
Exception messages are internal program state, not an output boundary.
77+
Escaping belongs at the point of output (catch/render), not at throw.
78+
The OutputNotEscaped rule still covers actual HTML output points.
79+
See: https://github.com/WordPress/WordPress-Coding-Standards/issues/2374
80+
81+
To opt back in to this check, add to your ruleset:
82+
<rule ref="HM.Security.EscapeOutput.ExceptionNotEscaped" />
83+
-->
84+
<exclude name="HM.Security.EscapeOutput.ExceptionNotEscaped" />
7485
</rule>
7586

7687
<!-- Disallow use of __FILE__ in menu slugs, which exposes the filesystem's data. -->
@@ -154,13 +165,12 @@
154165
<rule ref="Generic.Files.ByteOrderMark" />
155166

156167
<!-- Disallow empty statements. -->
157-
<rule ref="WordPress.CodeAnalysis.EmptyStatement" />
168+
<rule ref="Generic.CodeAnalysis.EmptyPHPStatement" />
158169

159170
<!-- Require correct usage of WP's i18n functions. -->
160171
<rule ref="WordPress.WP.I18n">
161-
<properties>
162-
<property name="check_translator_comments" value="false" />
163-
</properties>
172+
<!-- Ignore missing translator comments -->
173+
<exclude name="WordPress.WP.I18n.MissingTranslatorsComment" />
164174

165175
<!-- Allow empty strings to be translated (e.g. space character) -->
166176
<exclude name="WordPress.WP.I18n.NoEmptyStrings" />
@@ -176,9 +186,6 @@
176186
<!--
177187
Rules based on WordPress-Extra
178188
-->
179-
<!-- Disallow parts of PHP which may cause compatibility issues. -->
180-
<rule ref="Generic.Functions.CallTimePassByReference" />
181-
182189
<!-- Disallow "development" functions like var_dump/print_r/phpinfo -->
183190
<rule ref="WordPress.PHP.DevelopmentFunctions">
184191
<!-- Allow triggering errors for reporting purposes. -->

HM/Sniffs/ExtraSniffCode.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace HM\Sniffs;
44

5+
use PHP_CodeSniffer\Files\File as PhpcsFile;
56
use PHP_CodeSniffer\Util;
67

78
trait ExtraSniffCode {
@@ -11,13 +12,14 @@ trait ExtraSniffCode {
1112
* This allows overriding an existing sniff and retaining the existing
1213
* ignore statements.
1314
*
15+
* @param PhpcsFile $file File being checked.
1416
* @param string $legacy Legacy sniff code
1517
*/
16-
protected function duplicate_ignores( $legacy ) {
18+
protected function duplicate_ignores( PhpcsFile $file, $legacy ) {
1719
$expression = sprintf( '/^%s(\..+)?$/', preg_quote( $legacy ) );
1820
$base_code = Util\Common::getSniffCode( get_class( $this ) );
1921

20-
foreach ( $this->phpcsFile->tokenizer->ignoredLines as $line => $ignored ) {
22+
foreach ( $file->tokenizer->ignoredLines as $line => $ignored ) {
2123
$additional = [];
2224

2325
if ( empty( $ignored ) ) {
@@ -38,7 +40,7 @@ protected function duplicate_ignores( $legacy ) {
3840
}
3941

4042
if ( ! empty( $additional ) ) {
41-
$this->phpcsFile->tokenizer->ignoredLines[ $line ] = array_merge( $ignored, $additional );
43+
$file->tokenizer->ignoredLines[ $line ] = array_merge( $ignored, $additional );
4244
}
4345
}
4446

HM/Sniffs/Performance/SlowMetaQuerySniff.php

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
use PHP_CodeSniffer\Files\File;
66
use PHP_CodeSniffer\Util\Tokens;
7+
use PHPCSUtils\Utils\Arrays;
8+
use PHPCSUtils\Utils\MessageHelper;
9+
use PHPCSUtils\Utils\TextStrings;
710
use WordPressCS\WordPress\AbstractArrayAssignmentRestrictionsSniff;
811

912
/**
@@ -104,7 +107,8 @@ protected function check_meta_query_item( int $array_open ) {
104107
$array_open_token = $this->tokens[ $array_open ];
105108
if ( $array_open_token['code'] !== T_ARRAY && $array_open_token['code'] !== T_OPEN_SHORT_ARRAY ) {
106109
// Dynamic value, we can't check.
107-
$this->addMessage(
110+
MessageHelper::addMessage(
111+
$this->phpcsFile,
108112
'meta_query is dynamic, cannot be checked.',
109113
$array_open,
110114
'warning',
@@ -114,7 +118,7 @@ protected function check_meta_query_item( int $array_open ) {
114118
return;
115119
}
116120

117-
$array_bounds = $this->find_array_open_close( $array_open );
121+
$array_bounds = Arrays::getOpenClose( $this->phpcsFile, $array_open );
118122
$elements = $this->get_array_indices( $array_bounds['opener'], $array_bounds['closer'] );
119123

120124
// Is this a "first-order" query?
@@ -138,7 +142,7 @@ protected function check_meta_query_item( int $array_open ) {
138142

139143
foreach ( $elements as $element ) {
140144
if ( isset( $element['index_start'] ) ) {
141-
$index = $this->strip_quotes( $this->tokens[ $element['index_start'] ]['content'] );
145+
$index = TextStrings::stripQuotes( $this->tokens[ $element['index_start'] ]['content'] );
142146
if ( strtolower( $index ) === 'relation' ) {
143147
// Skip 'relation' element.
144148
continue;
@@ -176,7 +180,7 @@ protected function get_static_value_for_element( array $element ) : ?string {
176180
return static::DYNAMIC_VALUE;
177181
}
178182

179-
return $this->strip_quotes( $this->tokens[ $value_start ]['content'] );
183+
return TextStrings::stripQuotes( $this->tokens[ $value_start ]['content'] );
180184
}
181185

182186
/**
@@ -208,7 +212,7 @@ protected function find_key_in_array( array $elements, string $array_key ) : ?ar
208212
continue;
209213
}
210214

211-
$index = $this->strip_quotes( $this->tokens[ $start ]['content'] );
215+
$index = TextStrings::stripQuotes( $this->tokens[ $start ]['content'] );
212216
if ( $index !== $array_key ) {
213217
// Not the item we want, skip.
214218
continue;
@@ -270,15 +274,17 @@ protected function check_compare_value( string $compare, int $stackPtr = null )
270274
}
271275

272276
if ( $compare === static::DYNAMIC_VALUE ) {
273-
$this->addMessage(
277+
MessageHelper::addMessage(
278+
$this->phpcsFile,
274279
'meta_query is using a dynamic comparison; this cannot be checked automatically, and may be non-performant.',
275280
$stackPtr,
276281
'warning',
277282
'dynamic_compare'
278283
);
279284
} elseif ( $compare !== 'EXISTS' && $compare !== 'NOT EXISTS' ) {
280285
// Add a message ourselves.
281-
$this->addMessage(
286+
MessageHelper::addMessage(
287+
$this->phpcsFile,
282288
'meta_query is using %s comparison, which is non-performant.',
283289
$stackPtr,
284290
'warning',

HM/Sniffs/Performance/SlowOrderBySniff.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace HM\Sniffs\Performance;
44

5+
use PHPCSUtils\Utils\MessageHelper;
6+
use PHPCSUtils\Utils\TextStrings;
57
use WordPressCS\WordPress\AbstractArrayAssignmentRestrictionsSniff;
68

79
/**
@@ -57,11 +59,13 @@ public function process_token( $stackPtr ) {
5759
* with custom error message passed to ->process().
5860
*/
5961
public function callback( $key, $val, $line, $group ) {
62+
$val = TextStrings::stripQuotes( $val );
6063
switch ( $val ) {
6164
case 'rand':
6265
case 'meta_value':
6366
case 'meta_value_num':
64-
$this->addMessage(
67+
MessageHelper::addMessage(
68+
$this->phpcsFile,
6569
'Ordering query results by %s is not performant.',
6670
$this->stackPtr,
6771
'warning',

HM/Sniffs/Security/EscapeOutputSniff.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
*
1515
* @see https://github.com/WordPress/WordPress-Coding-Standards/issues/1864
1616
*/
17+
#[\AllowDynamicProperties]
1718
class EscapeOutputSniff extends WPCSEscapeOutputSniff {
1819
use ExtraSniffCode;
1920

@@ -56,13 +57,13 @@ public function __construct() {
5657
}
5758

5859
/**
59-
* Override init to duplicate any ignores.
60+
* Override process to duplicate any ignores.
6061
*
61-
* @param PhpcsFile $phpcsFile
62+
* @param PhpcsFile $file
63+
* @param int $stackPtr
6264
*/
63-
protected function init( PhpcsFile $phpcsFile ) {
64-
parent::init( $phpcsFile );
65-
66-
$this->duplicate_ignores( 'WordPress.Security.EscapeOutput' );
65+
public function process( PhpcsFile $file, $stackPtr ) {
66+
$this->duplicate_ignores( $file, 'WordPress.Security.EscapeOutput' );
67+
return parent::process( $file, $stackPtr );
6768
}
6869
}

HM/Sniffs/Security/NonceVerificationSniff.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,17 @@ class NonceVerificationSniff extends WPCSNonceVerificationSniff {
2727
public $allowQueryVariables = false;
2828

2929
/**
30-
* Override init to override config and duplicate any ignores.
30+
* Override process to override config and duplicate any ignores.
3131
*
3232
* @param PhpcsFile $phpcsFile
33+
* @param int $stackPtr
3334
*/
34-
public function init( PhpcsFile $file ) {
35-
parent::init( $file );
36-
35+
public function process( PhpcsFile $file, $stackPtr ) {
3736
if ( $this->allowQueryVariables ) {
3837
unset( $this->superglobals[ '$_GET' ] );
3938
}
4039

41-
$this->duplicate_ignores( 'WordPress.Security.NonceVerification' );
40+
$this->duplicate_ignores( $file, 'WordPress.Security.NonceVerification' );
41+
return parent::process( $file, $stackPtr );
4242
}
4343
}

HM/Sniffs/Security/ValidatedSanitizedInputSniff.php

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
use HM\Sniffs\ExtraSniffCode;
66
use PHP_CodeSniffer\Files\File as PhpcsFile;
7+
use PHPCSUtils\Utils\TextStrings;
8+
use WordPressCS\WordPress\Helpers\VariableHelper;
79
use WordPressCS\WordPress\Sniffs\Security\ValidatedSanitizedInputSniff as WPCSValidatedSanitizedInputSniff;
810

911
class ValidatedSanitizedInputSniff extends WPCSValidatedSanitizedInputSniff {
@@ -34,14 +36,14 @@ class ValidatedSanitizedInputSniff extends WPCSValidatedSanitizedInputSniff {
3436
];
3537

3638
/**
37-
* Override init to duplicate any ignores.
39+
* Override process to duplicate any ignores.
3840
*
3941
* @param PhpcsFile $phpcsFile
42+
* @param int $stackPtr
4043
*/
41-
protected function init( PhpcsFile $phpcsFile ) {
42-
parent::init( $phpcsFile );
43-
44-
$this->duplicate_ignores( 'WordPress.Security.ValidatedSanitizedInput' );
44+
public function process( PhpcsFile $file, $stackPtr ) {
45+
$this->duplicate_ignores( $file, 'WordPress.Security.ValidatedSanitizedInput' );
46+
return parent::process( $file, $stackPtr );
4547
}
4648

4749
/**
@@ -71,7 +73,7 @@ public function process_token( $stackPtr ) {
7173
* @return bool True if this is a $_SERVER variable and is safe, false to run regular checks.
7274
*/
7375
protected function check_server_variable( $stackPtr ) {
74-
$key = $this->get_array_access_key( $stackPtr );
76+
$key = VariableHelper::get_array_access_key( $this->phpcsFile, $stackPtr );
7577

7678
// Find the next non-whitespace token.
7779
$open_bracket = $this->phpcsFile->findNext( T_WHITESPACE, ( $stackPtr + 1 ), null, true );
@@ -94,7 +96,7 @@ protected function check_server_variable( $stackPtr ) {
9496
}
9597

9698
// Constant string, check if it's allowed.
97-
$key = $this->strip_quotes( $this->tokens[ $index_token ]['content'] );
99+
$key = TextStrings::stripQuotes( $this->tokens[ $index_token ]['content'] );
98100
if ( ! in_array( $key, $this->allowedServerKeys, true ) ) {
99101
// Unsafe key, requires sanitising.
100102
return false;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace HM\Coding\Standards\Tests;
4+
5+
use \HM\Other;
6+
use \WP_Post;
7+
8+
function some_function( $some_argument ) {
9+
$variable = 'some string';
10+
11+
return $variable;
12+
}
13+
14+
class MyTest Class {
15+
16+
__construct() {
17+
do_something();
18+
}
19+
20+
public function another_function() {
21+
return null;
22+
}
23+
}

HM/ruleset.xml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
<exclude name="WordPress.PHP.DevelopmentFunctions.error_log_trigger_error" />
2525
<exclude name="Generic.Formatting.MultipleStatementAlignment.NotSameWarning" />
2626

27-
<!-- We like short arrays and ternaries around here -->
28-
<exclude name="Generic.Arrays.DisallowShortArraySyntax" />
29-
<exclude name="WordPress.PHP.DisallowShortTernary" />
27+
<!-- We like short arrays and short ternaries around here -->
28+
<exclude name="Universal.Arrays.DisallowShortArraySyntax" />
29+
<exclude name="Universal.Operators.DisallowShortTernary" />
3030

3131
<!--
3232
OK, real talk right now. Yoda conditions are ridiculous.
@@ -71,18 +71,18 @@
7171
<property name="additionalWordDelimiters" value="." />
7272
</properties>
7373
</rule>
74-
74+
7575
<!-- Ease up on the PHP DOM* objects. -->
7676
<rule ref="WordPress.NamingConventions.ValidVariableName">
7777
<properties>
78-
<property name="customPropertiesWhitelist" type="array">
78+
<property name="allowed_custom_properties" type="array">
7979
<!-- DOMDocument::$documentElement -->
8080
<element value="documentElement" />
81-
<!-- DOMElement::$childElementCount -->
81+
<!-- DOMElement::$childElementCount -->
8282
<element value="childElementCount" />
8383
<!-- DOMElement::$parentNode -->
8484
<element value="parentNode" />
85-
<!-- DOMNode::$childNodes -->
85+
<!-- DOMNode::$childNodes -->
8686
<element value="childNodes" />
8787
</property>
8888
</properties>

0 commit comments

Comments
 (0)