Skip to content

Commit cc9d3fd

Browse files
committed
Report on missing exit after redirect
Fixes #54
1 parent 76cf2f2 commit cc9d3fd

File tree

5 files changed

+126
-1
lines changed

5 files changed

+126
-1
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
/**
3+
* WordPress-VIP-Minimum Coding Standard.
4+
*
5+
* @package VIPCS\WordPressVIPMinimum
6+
* @link https://github.com/Automattic/VIP-Coding-Standards
7+
*/
8+
9+
namespace WordPressVIPMinimum\Sniffs\VIP;
10+
11+
use PHP_CodeSniffer_File as File;
12+
use PHP_CodeSniffer_Tokens as Tokens;
13+
14+
/**
15+
* Require `exit;` being called after wp_redirect and wp_safe_redirect.
16+
*
17+
* @package VIPCS\WordPressVIPMinimum
18+
*/
19+
class ExitAfterRedirectSniff implements \PHP_CodeSniffer_Sniff {
20+
21+
/**
22+
* Returns an array of tokens this test wants to listen for.
23+
*
24+
* @return array
25+
*/
26+
public function register() {
27+
return Tokens::$functionNameTokens;
28+
}
29+
30+
/**
31+
* Process this test when one of its tokens is encountered
32+
*
33+
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
34+
* @param int $stackPtr The position of the current token in the stack passed in $tokens.
35+
*
36+
* @return void
37+
*/
38+
public function process( File $phpcsFile, $stackPtr ) {
39+
40+
$tokens = $phpcsFile->getTokens();
41+
42+
if ( 'wp_redirect' !== $tokens[ $stackPtr ]['content'] && 'wp_safe_redirect' !== $tokens[ $stackPtr ]['content'] ) {
43+
return;
44+
}
45+
46+
$openBracket = $phpcsFile->findNext( Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true );
47+
48+
if ( T_OPEN_PARENTHESIS !== $tokens[ $openBracket ]['code'] ) {
49+
return;
50+
}
51+
52+
$next_token = $phpcsFile->findNext( array_merge( Tokens::$emptyTokens, array( T_SEMICOLON, T_CLOSE_PARENTHESIS ) ), ( $tokens[ $openBracket ]['parenthesis_closer'] + 1 ), null, true );
53+
54+
if ( T_OPEN_CURLY_BRACKET === $tokens[ $next_token ]['code'] ) {
55+
$is_exit_in_scope = false;
56+
for ( $i = $tokens[ $next_token ]['scope_opener']; $i <= $tokens[ $next_token ]['scope_closer']; $i++ ) {
57+
if ( T_EXIT === $tokens[ $i ]['code'] ) {
58+
$is_exit_in_scope = true;
59+
}
60+
}
61+
if ( false === $is_exit_in_scope ) {
62+
$phpcsFile->addError( sprintf( '%s should almost always be followed by a call to exit;', $tokens[ $stackPtr ]['content'] ), $stackPtr, 'NoExitInConditional' );
63+
}
64+
} elseif ( T_EXIT !== $tokens[ $next_token ]['code'] ) {
65+
$phpcsFile->addError( sprintf( '%s should almost always be followed by a call to exit;', $tokens[ $stackPtr ]['content'] ), $stackPtr, 'NoExit' );
66+
}
67+
}//end process()
68+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
wp_redirect( 'https://vip.wordpress.com' ); //Ok.
4+
5+
exit();
6+
7+
wp_safe_redirect( 'https.//vip.wordpress.com' ); // NOK.
8+
9+
wp_redirect( 'https://vip.wordpress.com' ); // NOK.
10+
11+
if ( wp_redirect( 'https://vip.wordpress.com' ) ) { //Ok.
12+
exit;
13+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
/**
3+
* Unit test class for WordPressVIPMinimum Coding Standard.
4+
*
5+
* @package VIPCS\WordPressVIPMinimum
6+
*/
7+
8+
namespace WordPressVIPMinimum\Tests\VIP;
9+
10+
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
11+
12+
/**
13+
* Unit test class for the ExitAfterRedirect sniff.
14+
*
15+
* @package VIPCS\WordPressVIPMinimum
16+
*/
17+
class FlushRewriteRulesUnitTest extends AbstractSniffUnitTest {
18+
19+
/**
20+
* Returns the lines where errors should occur.
21+
*
22+
* @return array <int line number> => <int number of errors>
23+
*/
24+
public function getErrorList() {
25+
return array(
26+
7 => 1,
27+
9 => 1,
28+
);
29+
}
30+
31+
/**
32+
* Returns the lines where warnings should occur.
33+
*
34+
* @return array <int line number> => <int number of warnings>
35+
*/
36+
public function getWarningList() {
37+
return array();
38+
39+
}
40+
41+
} // End class.

ruleset_test.inc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,5 +167,7 @@ echo "<a href='" . esc_attr( $some_var ) . "'></a>"; // NOK. Error.
167167

168168
$hello = true === isset( $_GET['utm_medium'] ) ? true : false; // NOK. Warning 3 times.
169169

170+
wp_safe_redirect( 'https.//vip.wordpress.com' ); // NOK. Error.
171+
170172
?>
171173

ruleset_test.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@
4949
133 => 1,
5050
157 => 1,
5151
166 => 1,
52-
170 => 1, // Error on the end of the file. When any code is added, bounce this.
52+
170 => 1,
53+
172 => 1, // Error on the end of the file. When any code is added, bounce this.
5354
),
5455
'warnings' => array(
5556
9 => 1,

0 commit comments

Comments
 (0)