![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/dev/tests/static/framework/Magento/TestFramework/Inspection/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ /** * Finder for a list of preconfigured words */ namespace Magento\TestFramework\Inspection; class WordsFinder { /** * List of file extensions, that indicate a binary file * * @var array */ protected $_binaryExtensions = [ 'jpg', 'jpeg', 'png', 'gif', 'swf', 'mp3', 'avi', 'mov', 'flv', 'jar', 'zip', 'eot', 'ttf', 'woff', 'woff2', 'ico', 'svg', ]; /** * Copyright string which must be present in every non-binary file * * @var string */ protected $copyrightString = 'Copyright © Magento, Inc. All rights reserved.'; /** * Copying string which must be present in every non-binary file right after copyright string * * @var string */ protected $copyingString = 'See COPYING.txt for license details.'; /** * List of extensions for which copyright check must be skipped * * @var array */ protected $copyrightSkipExtensions = ['csv', 'json', 'lock', 'md', 'txt']; /** * List of paths where copyright check must be skipped * * @var array */ protected $copyrightSkipList = [ 'lib/web/legacy-build.min.js' ]; /** * Whether copyright presence should be checked or not * * @var bool */ protected $isCopyrightChecked; /** * Words to search for * * @var array */ protected $_words = []; /** * Map of whitelisted paths to whitelisted words * * @var array */ protected $_whitelist = []; /** * Path to base dir, used to calculate relative paths * * @var string */ protected $_baseDir; /** * Component Registrar * * @var \Magento\Framework\Component\ComponentRegistrar */ protected $componentRegistrar; /** * Map of phrase to exclude from the file content * * @var array */ private $exclude = []; /** * @param string|array $configFiles * @param string $baseDir * @param \Magento\Framework\Component\ComponentRegistrar $componentRegistrar * @param bool $isCopyrightChecked * @throws \Magento\TestFramework\Inspection\Exception */ public function __construct($configFiles, $baseDir, $componentRegistrar, $isCopyrightChecked = false) { if (!is_dir($baseDir)) { throw new \Magento\TestFramework\Inspection\Exception("Base directory {$baseDir} does not exist"); } $this->_baseDir = str_replace('\\', '/', realpath($baseDir)); $this->componentRegistrar = $componentRegistrar; // Load config files if (!is_array($configFiles)) { $configFiles = [$configFiles]; } foreach ($configFiles as $configFile) { $this->_loadConfig($configFile); } // Add config files to whitelist, as they surely contain banned words foreach ($configFiles as $configFile) { $configFile = str_replace('\\', '/', realpath($configFile)); $this->_whitelist[$configFile] = []; } $this->_normalizeWhitelistPaths(); // Final verifications if (!$this->_words) { throw new \Magento\TestFramework\Inspection\Exception('No words to check'); } $this->isCopyrightChecked = $isCopyrightChecked; } /** * Load configuration from file, adding words and whitelisted entries to main config * * @param string $configFile * @throws \Magento\TestFramework\Inspection\Exception */ protected function _loadConfig($configFile) { if (!file_exists($configFile)) { throw new \Magento\TestFramework\Inspection\Exception("Configuration file {$configFile} does not exist"); } try { $xml = new \SimpleXMLElement(file_get_contents($configFile)); } catch (\Exception $e) { throw new \Magento\TestFramework\Inspection\Exception($e->getMessage(), $e->getCode(), $e); } $this->_extractWords($xml)->_extractWhitelist($xml); } /** * Extract words from configuration xml * * @param \SimpleXMLElement $configXml * @return \Magento\TestFramework\Inspection\WordsFinder * @throws \Magento\TestFramework\Inspection\Exception */ protected function _extractWords(\SimpleXMLElement $configXml) { $words = []; $nodes = $configXml->xpath('//config/words/word'); foreach ($nodes as $node) { $words[] = (string)$node; } $words = array_filter($words); $words = array_merge($this->_words, $words); $this->_words = array_unique($words); return $this; } /** * Extract whitelisted entries and words from configuration xml * * @param \SimpleXMLElement $configXml * @return \Magento\TestFramework\Inspection\WordsFinder * @throws \Magento\TestFramework\Inspection\Exception * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ protected function _extractWhitelist(\SimpleXMLElement $configXml) { // Load whitelist entries $whitelist = []; $exclude = []; $nodes = $configXml->xpath('//config/whitelist/item'); foreach ($nodes as $node) { $path = $node->xpath('path'); if (!$path) { throw new \Magento\TestFramework\Inspection\Exception( 'A "path" must be defined for the whitelisted item' ); } $component = $node->xpath('component'); if ($component) { $componentType = $component[0]->xpath('@type')[0]; $componentName = $component[0]->xpath('@name')[0]; $path = $this->componentRegistrar->getPath((string)$componentType, (string)$componentName) . '/' . (string)$path[0]; } else { $path = $this->_baseDir . '/' . (string)$path[0]; } // Words $words = []; $wordNodes = $node->xpath('word'); if ($wordNodes) { foreach ($wordNodes as $wordNode) { $words[] = (string)$wordNode; } } $whitelist[$path] = $words; $excludeNodes = $node->xpath('exclude'); $excludes = []; if ($excludeNodes) { foreach ($excludeNodes as $extractNode) { $excludes[] = (string)$extractNode; } } if (isset($exclude[$path])) { $exclude[$path] = array_merge($excludes, $exclude[$path]); } else { $exclude[$path] = $excludes; } } // Merge with already present whitelist foreach ($whitelist as $newPath => $newWords) { if (isset($this->_whitelist[$newPath])) { $newWords = array_merge($this->_whitelist[$newPath], $newWords); } $this->_whitelist[$newPath] = array_unique($newWords); } foreach ($exclude as $newPath => $newWords) { if (isset($this->exclude[$newPath])) { $newWords = array_merge($this->exclude[$newPath], $newWords); } $this->exclude[$newPath] = array_unique($newWords); } return $this; } /** * Normalize whitelist paths, so that they containt only native directory separators */ protected function _normalizeWhitelistPaths() { $whitelist = $this->_whitelist; $this->_whitelist = []; foreach ($whitelist as $whitelistFile => $whitelistWords) { $whitelistFile = str_replace('\\', '/', $whitelistFile); $this->_whitelist[$whitelistFile] = $whitelistWords; } } /** * Checks the file content and name against the list of words. Do not check content of binary files. * Exclude whitelisted entries. * * @param string $file * @return array Words, found */ public function findWords($file) { $foundWords = $this->_findWords($file); if (!$foundWords) { return []; } return self::_removeWhitelistedWords($file, $foundWords); } /** * Checks the file content and name against the list of words. Do not check content of binary files. * * @param string $file * @return array * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ protected function _findWords($file) { $checkContents = !$this->_isBinaryFile($file); $path = $this->getSearchablePath($file); $contents = $checkContents ? file_get_contents($file) : ''; if (isset($this->exclude[$file]) && !empty($this->exclude[$file])) { foreach ($this->exclude[$file] as $stringToEliminate) { $contents = str_replace($stringToEliminate, "", $contents); } } $foundWords = []; foreach ($this->_words as $word) { if (stripos($path, $word) !== false || stripos($contents, $word) !== false) { $foundWords[] = $word; } } if ($contents && $this->isCopyrightChecked && !$this->isCopyrightCheckSkipped($file) && (($copyrightStringPosition = mb_strpos($contents, $this->copyrightString)) === false || ($copyingStringPosition = strpos($contents, $this->copyingString)) === false || $copyingStringPosition - $copyrightStringPosition - mb_strlen($this->copyrightString) > 10) ) { $foundWords[] = 'Copyright string is missing'; } return $foundWords; } /** * @param string $path * @return bool */ protected function isCopyrightCheckSkipped($path) { if (in_array(pathinfo($path, PATHINFO_EXTENSION), $this->copyrightSkipExtensions)) { return true; } foreach ($this->copyrightSkipList as $dir) { if (strpos($path, $dir) !== false) { return true; } } return false; } /** * Check, whether file is a binary one * * @param string $file * @return bool */ protected function _isBinaryFile($file) { return in_array(pathinfo($file, PATHINFO_EXTENSION), $this->_binaryExtensions); } /** * Removes whitelisted words from array of found words * * @param string $path * @param array $foundWords * @return array */ protected function _removeWhitelistedWords($path, $foundWords) { $path = str_replace('\\', '/', $path); foreach ($this->_whitelist as $whitelistPath => $whitelistWords) { if (strncmp($whitelistPath, $path, strlen($whitelistPath)) != 0) { continue; } if (!$whitelistWords) { // All words are permitted there return []; } $foundWords = array_diff($foundWords, $whitelistWords); } return $foundWords; } /** * Return the path for words search * * @param string $file * @return string */ protected function getSearchablePath($file) { if (strpos($file, $this->_baseDir) === false) { return $file; } return substr($file, strlen($this->_baseDir) + 1); } }