Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 34 additions & 2 deletions WordPressVIPMinimum/Sniffs/Files/IncludingFileSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
/**
* WordPressVIPMinimum_Sniffs_Files_IncludingFileSniff.
*
* Checks that __DIR__, dirname( __FILE__ ) or plugin_dir_path( __FILE__ )
* is used when including or requiring files.
* Checks for custom variables, functions and constants, and external URLs used in file inclusion.
*
* @package VIPCS\WordPressVIPMinimum
*/
Expand Down Expand Up @@ -55,6 +54,17 @@ class IncludingFileSniff extends AbstractFunctionRestrictionsSniff {
'WP_PLUGIN_DIR',
];

/**
* List of keywords allowed for use in custom constants.
* Note: Customizing this property will overwrite current default values.
*
* @var array
*/
public $allowedKeywords = [
'PATH',
'DIR',
];

/**
* Functions used for modify slashes.
*
Expand Down Expand Up @@ -122,6 +132,11 @@ public function process_token( $stackPtr ) {
return;
}

if ( $this->has_custom_path( $this->tokens[ $nextToken ]['content'] ) === true ) {
// The construct is using a constant with an allowed keyword.
return;
}

if ( array_key_exists( $this->tokens[ $nextToken ]['content'], $this->restrictedConstants ) === true ) {
// The construct is using one of the restricted constants.
$message = '`%s` constant might not be defined or available. Use `%s()` instead.';
Expand Down Expand Up @@ -172,4 +187,21 @@ public function process_token( $stackPtr ) {
$message = 'Absolute include path must be used. Use `get_template_directory()`, `get_stylesheet_directory()` or `plugin_dir_path()`.';
$this->phpcsFile->addError( $message, $nextToken, 'NotAbsolutePath' );
}

/**
* Check if a content string contains a keyword in custom paths.
*
* @param string $content Content string.
*
* @return bool True if the string partially matches a keyword in $allowedCustomKeywords, false otherwise.
*/
private function has_custom_path( $content ) {
foreach ( $this->allowedKeywords as $keyword ) {
if ( strpos( $content, $keyword ) !== false ) {
return true;
}
}

return false;
}
}
11 changes: 10 additions & 1 deletion WordPressVIPMinimum/Tests/Files/IncludingFileUnitTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,13 @@ require_once "my_file.php"; // Not absolute path.
require '../my_file.php'; // Not absolute path.
require '../../my_file.php'; // Not absolute path.
include( 'http://www.google.com/bad_file.php' ); // External URL.
include_once("http://www.google.com/bad_file.php"); // External URL.
include_once("http://www.google.com/bad_file.php"); // External URL.

// Allowed keywords
include 'https://path.com/bad_file.php'; // Error - external URL with keyword from $allowedKeywords.
require $path; // Warning - custom variable with keyword from $allowedKeywords.
include_once dir_function(); // Error - custom functionm with keyword from $allowedKeywords.
require CUSTOM_CONSTANT_DIR . 'file.php'; // OK.
require_once ( VIPCS_PATH ) . 'file.php'; // OK.
include_once
DIR_CUSTOM , 'file.php'; // OK.
3 changes: 3 additions & 0 deletions WordPressVIPMinimum/Tests/Files/IncludingFileUnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public function getErrorList() {
26 => 1,
27 => 1,
28 => 1,
31 => 1,
];
}

Expand All @@ -43,6 +44,8 @@ public function getWarningList() {
19 => 1,
20 => 1,
21 => 1,
32 => 1,
33 => 1,
];
}

Expand Down