From 1a201318c6590137b24d5543f68be9007550e4f4 Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Tue, 23 Feb 2021 22:22:29 +0300 Subject: [PATCH] use a single regex match in the jexec rule --- .../com_jedchecker/libraries/rules/jexec.php | 100 ++++++------------ 1 file changed, 33 insertions(+), 67 deletions(-) diff --git a/administrator/components/com_jedchecker/libraries/rules/jexec.php b/administrator/components/com_jedchecker/libraries/rules/jexec.php index b3d5c29..34aba0a 100644 --- a/administrator/components/com_jedchecker/libraries/rules/jexec.php +++ b/administrator/components/com_jedchecker/libraries/rules/jexec.php @@ -46,6 +46,13 @@ class JedcheckerRulesJexec extends JEDcheckerRule */ protected $description = 'COM_JEDCHECKER_RULE_PH2_DESC'; + /** + * Regexp to match _JEXEC-like guard + * + * @var string + */ + protected $regex; + /** * Initiates the file search and check * @@ -53,6 +60,8 @@ class JedcheckerRulesJexec extends JEDcheckerRule */ public function check() { + $this->init_jexec(); + // Find all php files of the extension $files = JFolder::files($this->basedir, '\.php$', true, true); @@ -86,79 +95,36 @@ class JedcheckerRulesJexec extends JEDcheckerRule return true; } - $content = preg_split('/(?:\r\n|\n|\r)(?!$)/', $content); + // check guards + if (preg_match($this->regex, $content)) + { + return true; + } - // Get the constants to look for + return false; + } + + /** + * Prepare regexp aforehand + * + * @return void + */ + protected function init_jexec() + { $defines = $this->params->get('constants'); $defines = explode(',', $defines); - $hascode = 0; - - foreach ($content AS $line) + foreach ($defines as $i => $define) { - $tline = trim($line); - - if ($tline == '' || $tline == '') - { - continue; - } - - if ($tline['0'] != '/' && $tline['0'] != '*') - { - $hascode = 1; - } - - // Search for "defined" - $pos_1 = stripos($line, 'defined'); - - // Skip the line if "defined" is not found - if ($pos_1 === false) - { - continue; - } - - // Search for "die". - // "or" may not be present depending on syntax - $pos_3 = stripos($line, 'die'); - - // Check for "exit" - if ($pos_3 === false) - { - $pos_3 = stripos($line, 'exit'); - - // Skip the line if "die" or "exit" is not found - if ($pos_3 === false) - { - continue; - } - } - - // Search for the constant name - foreach ($defines AS $define) - { - $define = trim($define); - - // Search for the define - $pos_2 = strpos($line, $define); - - // Skip the line if the define is not found - if ($pos_2 === false) - { - continue; - } - - // Check the position of the words - if ($pos_2 > $pos_1 && $pos_3 > $pos_2) - { - unset($content); - - return true; - } - } + $defines[$i] = preg_quote(trim($define), '#'); } - unset($content); - - return $hascode ? false : true; + $this->regex + = '#^' // at the beginning of the file + . '<\?php\s+' // there is an opening php tag + . 'defined ?\( ?' // followed by defined test + . '([\'"])(?:' . implode('|', $defines) . ')\1' // of any of given constant + . ' ?\) ?(?:or |\|\| ?)(?:die|exit)\b' // or exit + . '#i'; // (case insensitive) } }