From 8e0d7381311eaeb329b0ba25b88bc803bc0c385f Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Tue, 2 Feb 2021 19:09:20 +0300 Subject: [PATCH 01/17] Add check for incorrect file/folder references in the XML manifest --- .../language/en-GB/en-GB.com_jedchecker.ini | 6 +- .../libraries/rules/xmlfiles.php | 228 ++++++++++++++++++ 2 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 administrator/components/com_jedchecker/libraries/rules/xmlfiles.php diff --git a/administrator/components/com_jedchecker/language/en-GB/en-GB.com_jedchecker.ini b/administrator/components/com_jedchecker/language/en-GB/en-GB.com_jedchecker.ini index 7231b32..f23780e 100644 --- a/administrator/components/com_jedchecker/language/en-GB/en-GB.com_jedchecker.ini +++ b/administrator/components/com_jedchecker/language/en-GB/en-GB.com_jedchecker.ini @@ -77,4 +77,8 @@ COM_JEDCHECKER_ERROR_XML_UPDATE_SERVER_LINK_NOT_FOUND="Update Server link not fo COM_JEDCHECKER_INFO_XML_UPDATE_SERVER_LINK="The Update Server link in this XML file is: %s" COM_JEDCHECKER_DELETE_FAILED="Can't delete temporary folder" COM_JEDCHECKER_DELETE_SUCCESS="Temporary folder deleted!" -COM_JEDCHECKER_EMPTY_UPLOAD_FIELD="Please, select a zipped file to be uploaded" \ No newline at end of file +COM_JEDCHECKER_EMPTY_UPLOAD_FIELD="Please, select a zipped file to be uploaded" +COM_JEDCHECKER_XML_FILES="Check files/folders references" +COM_JEDCHECKER_XML_FILES_DESC="Check for incorrect files and folders references in the XML manifest" +COM_JEDCHECKER_XML_FILES_FILE_NOT_FOUND="File not found: %s" +COM_JEDCHECKER_XML_FILES_FOLDER_NOT_FOUND="Folder not found: %s" \ No newline at end of file diff --git a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php new file mode 100644 index 0000000..7267654 --- /dev/null +++ b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php @@ -0,0 +1,228 @@ + + * eaxs + * Denis Ryabov + * + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die('Restricted access'); + + +// Include the rule base class +require_once JPATH_COMPONENT_ADMINISTRATOR . '/models/rule.php'; + + +/** + * class JedcheckerRulesXMLFiles + * + * This class searches all xml manifestes for valid files declarations + * + * @since 2.3 + */ +class JedcheckerRulesXMLFiles extends JEDcheckerRule +{ + /** + * The formal ID of this rule. For example: SE1. + * + * @var string + */ + protected $id = 'XMLFILES'; + + /** + * The title or caption of this rule. + * + * @var string + */ + protected $title = 'COM_JEDCHECKER_XML_FILES'; + + /** + * The description of this rule. + * + * @var string + */ + protected $description = 'COM_JEDCHECKER_XML_FILES_DESC'; + + /** + * List of errors. + * + * @var string[] + */ + protected $errors; + + /** + * Initiates the search and check + * + * @return void + */ + public function check() + { + // Find all XML files of the extension + $files = JFolder::files($this->basedir, '.xml$', true, true); + + // Iterate through all the xml files + foreach ($files as $file) + { + // Try to check the file + $this->find($file); + } + } + + /** + * Reads a file and validate XML manifest + * + * @param string $file - The path to the file + * + * @return boolean True if the manifest file was found, otherwise False. + */ + protected function find($file) + { + $xml = JFactory::getXml($file); + + // Failed to parse the xml file. + // Assume that this is not a extension manifest + if (!$xml) + { + return false; + } + + // Check if this is an extension manifest + if ($xml->getName() !== 'extension') + { + return false; + } + + $this->errors = array(); + + // check declared files and folders do exist + + $basedir = dirname($file) . '/'; + + // check: files[folder] (filename|folder)* + if (isset($xml->files)) + { + $node = $xml->files; + $dir = $basedir . (isset($node['folder']) ? $node['folder'] . '/' : ''); + $this->checkFiles($node->filename, $dir); + $this->checkFolders($node->folder, $dir); + } + + // check: media[folder] (filename|folder)* + if (isset($xml->media)) + { + $node = $xml->media; + $dir = $basedir . (isset($node['folder']) ? $node['folder'] . '/' : ''); + $this->checkFiles($node->filename, $dir); + $this->checkFolders($node->folder, $dir); + } + + // check files: languages[folder] language* + if (isset($xml->languages)) + { + $node = $xml->languages; + $dir = $basedir . (isset($node['folder']) ? $node['folder'] . '/' : ''); + $this->checkFiles($node->language, $dir); + } + + // check: administration files[folder] (filename|folder)* + if (isset($xml->administration->files)) + { + $node = $xml->administration->files; + $dir = $basedir . (isset($node['folder']) ? $node['folder'] . '/' : ''); + $this->checkFiles($node->filename, $dir); + $this->checkFolders($node->folder, $dir); + } + + // check: administration media[folder] (filename|folder)* + if (isset($xml->administration->media)) + { + $node = $xml->administration->media; + $dir = $basedir . (isset($node['folder']) ? $node['folder'] . '/' : ''); + $this->checkFiles($node->filename, $dir); + $this->checkFolders($node->folder, $dir); + } + + // check files: administration languages[folder] language* + if (isset($xml->administration->languages)) + { + $node = $xml->administration->languages; + $dir = $basedir . (isset($node['folder']) ? $node['folder'] . '/' : ''); + $this->checkFiles($node->language, $dir); + } + + // check file: scriptfile + if (isset($xml->scriptfile)) + { + $this->checkFiles($xml->scriptfile, $basedir); + } + + // check files: install sql file* + if (isset($xml->install->sql->file)) + { + $this->checkFiles($xml->install->sql->file, $basedir); + } + + // check files: uninstall sql file* + if (isset($xml->uninstall->sql->file)) + { + $this->checkFiles($xml->uninstall->sql->file, $basedir); + } + + // check folders: update schemas schemapath* + if (isset($xml->update->schemas->schemapath)) + { + $this->checkFolders($xml->update->schemas->schemapath, $basedir); + } + + if (count($this->errors)) + { + $this->report->addError($file, implode('
', $this->errors)); + } + + // All checks passed. Return true + return true; + } + + /** + * Check files exist + * + * @param JXMLElement $files Files to check + * @param string $dir Base directory + * + * @return void + */ + protected function checkFiles($files, $dir) + { + foreach ($files as $file) + { + if (!is_file($dir . $file)) + { + $this->errors[] = JText::sprintf('COM_JEDCHECKER_XML_FILES_FILE_NOT_FOUND', (string)$file); + } + } + } + + /** + * Check folders exist + * + * @param JXMLElement $folders Directories to check + * @param string $dir Base directory + * + * @return void + */ + protected function checkFolders($folders, $dir) + { + foreach ($folders as $folder) + { + if (!is_dir($dir . $folder)) + { + $this->errors[] = JText::sprintf('COM_JEDCHECKER_XML_FILES_FOLDER_NOT_FOUND', (string)$folder); + } + } + } +} From a206aa91ba57e713e1aa83182467664776834d9b Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Sat, 13 Feb 2021 23:56:51 +0300 Subject: [PATCH 02/17] Joomla!4 compatibility --- .../components/com_jedchecker/libraries/rules/xmlfiles.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php index 7267654..a82b6ab 100644 --- a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php +++ b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php @@ -82,7 +82,7 @@ class JedcheckerRulesXMLFiles extends JEDcheckerRule */ protected function find($file) { - $xml = JFactory::getXml($file); + $xml = simplexml_load_file($file); // Failed to parse the xml file. // Assume that this is not a extension manifest From 0bf71c095039f29266baeb749f681ec56d9ba193 Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Sat, 13 Feb 2021 23:56:59 +0300 Subject: [PATCH 03/17] fix regex --- .../components/com_jedchecker/libraries/rules/xmlfiles.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php index a82b6ab..1545048 100644 --- a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php +++ b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php @@ -63,7 +63,7 @@ class JedcheckerRulesXMLFiles extends JEDcheckerRule public function check() { // Find all XML files of the extension - $files = JFolder::files($this->basedir, '.xml$', true, true); + $files = JFolder::files($this->basedir, '\.xml$', true, true); // Iterate through all the xml files foreach ($files as $file) From a1197006e578b8215a7261f23242aa1d0dd16d41 Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Sun, 14 Feb 2021 00:02:08 +0300 Subject: [PATCH 04/17] check packages --- .../components/com_jedchecker/libraries/rules/xmlfiles.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php index 1545048..7c6d0a6 100644 --- a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php +++ b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php @@ -104,11 +104,13 @@ class JedcheckerRulesXMLFiles extends JEDcheckerRule $basedir = dirname($file) . '/'; // check: files[folder] (filename|folder)* + // for package: files[folder] (file|folder)* if (isset($xml->files)) { $node = $xml->files; $dir = $basedir . (isset($node['folder']) ? $node['folder'] . '/' : ''); $this->checkFiles($node->filename, $dir); + $this->checkFiles($node->file, $dir); // for packages $this->checkFolders($node->folder, $dir); } From 5bab76e834271ae800b1495e44841d4c8e6e12b0 Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Thu, 18 Feb 2021 15:20:00 +0300 Subject: [PATCH 05/17] don't warn on missed unzipped files (in packages) --- .../com_jedchecker/libraries/rules/xmlfiles.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php index 7c6d0a6..ad15c4e 100644 --- a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php +++ b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php @@ -202,10 +202,17 @@ class JedcheckerRulesXMLFiles extends JEDcheckerRule { foreach ($files as $file) { - if (!is_file($dir . $file)) + $filename = $dir . $file; + if (is_file($filename)) { - $this->errors[] = JText::sprintf('COM_JEDCHECKER_XML_FILES_FILE_NOT_FOUND', (string)$file); + continue; } + // extra check for unzipped files + if (preg_match('/^(.*)\.(zip|tar\.gz)$/', $filename, $matches) && is_dir($matches[1])) + { + continue; + } + $this->errors[] = JText::sprintf('COM_JEDCHECKER_XML_FILES_FILE_NOT_FOUND', (string)$file); } } From 4775ddd43b1037f0f0f3569b08e4790512c6ca86 Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Thu, 11 Mar 2021 01:17:00 +0300 Subject: [PATCH 06/17] correct authors list for new rule --- .../components/com_jedchecker/libraries/rules/xmlfiles.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php index ad15c4e..285ef2b 100644 --- a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php +++ b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php @@ -4,9 +4,7 @@ * * @copyright Copyright (C) 2017 - 2021 Open Source Matters, Inc. All rights reserved. * Copyright (C) 2008 - 2016 compojoom.com . All rights reserved. - * @author Daniel Dimitrov - * eaxs - * Denis Ryabov + * @author Denis Ryabov * * @license GNU General Public License version 2 or later; see LICENSE.txt */ From d583e82bd7f81b8b38dac6fa9ddff27b78a84285 Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Tue, 23 Feb 2021 23:57:03 +0300 Subject: [PATCH 07/17] fix path for sql files --- .../com_jedchecker/libraries/rules/xmlfiles.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php index 285ef2b..b095317 100644 --- a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php +++ b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php @@ -129,13 +129,15 @@ class JedcheckerRulesXMLFiles extends JEDcheckerRule $this->checkFiles($node->language, $dir); } + $admindir = $basedir; + // check: administration files[folder] (filename|folder)* if (isset($xml->administration->files)) { $node = $xml->administration->files; - $dir = $basedir . (isset($node['folder']) ? $node['folder'] . '/' : ''); - $this->checkFiles($node->filename, $dir); - $this->checkFolders($node->folder, $dir); + $admindir = $basedir . (isset($node['folder']) ? $node['folder'] . '/' : ''); + $this->checkFiles($node->filename, $admindir); + $this->checkFolders($node->folder, $admindir); } // check: administration media[folder] (filename|folder)* @@ -164,19 +166,19 @@ class JedcheckerRulesXMLFiles extends JEDcheckerRule // check files: install sql file* if (isset($xml->install->sql->file)) { - $this->checkFiles($xml->install->sql->file, $basedir); + $this->checkFiles($xml->install->sql->file, $admindir); } // check files: uninstall sql file* if (isset($xml->uninstall->sql->file)) { - $this->checkFiles($xml->uninstall->sql->file, $basedir); + $this->checkFiles($xml->uninstall->sql->file, $admindir); } // check folders: update schemas schemapath* if (isset($xml->update->schemas->schemapath)) { - $this->checkFolders($xml->update->schemas->schemapath, $basedir); + $this->checkFolders($xml->update->schemas->schemapath, $admindir); } if (count($this->errors)) From 8c52d0c912ce5f9d934ca5f25d92c7c7164167df Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Thu, 11 Mar 2021 01:18:39 +0300 Subject: [PATCH 08/17] change title --- .../com_jedchecker/language/en-GB/en-GB.com_jedchecker.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/administrator/components/com_jedchecker/language/en-GB/en-GB.com_jedchecker.ini b/administrator/components/com_jedchecker/language/en-GB/en-GB.com_jedchecker.ini index f23780e..14707c1 100644 --- a/administrator/components/com_jedchecker/language/en-GB/en-GB.com_jedchecker.ini +++ b/administrator/components/com_jedchecker/language/en-GB/en-GB.com_jedchecker.ini @@ -78,7 +78,7 @@ COM_JEDCHECKER_INFO_XML_UPDATE_SERVER_LINK="The Update Server link in this XML f COM_JEDCHECKER_DELETE_FAILED="Can't delete temporary folder" COM_JEDCHECKER_DELETE_SUCCESS="Temporary folder deleted!" COM_JEDCHECKER_EMPTY_UPLOAD_FIELD="Please, select a zipped file to be uploaded" -COM_JEDCHECKER_XML_FILES="Check files/folders references" +COM_JEDCHECKER_XML_FILES="XML Files references" COM_JEDCHECKER_XML_FILES_DESC="Check for incorrect files and folders references in the XML manifest" COM_JEDCHECKER_XML_FILES_FILE_NOT_FOUND="File not found: %s" -COM_JEDCHECKER_XML_FILES_FOLDER_NOT_FOUND="Folder not found: %s" \ No newline at end of file +COM_JEDCHECKER_XML_FILES_FOLDER_NOT_FOUND="Folder not found: %s" From 8d7531a04784852a2605d80779063d28dcaa65bb Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Thu, 11 Mar 2021 13:40:09 +0300 Subject: [PATCH 09/17] remove `@author` tag --- .../components/com_jedchecker/libraries/rules/xmlfiles.php | 1 - 1 file changed, 1 deletion(-) diff --git a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php index b095317..af55d7d 100644 --- a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php +++ b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php @@ -4,7 +4,6 @@ * * @copyright Copyright (C) 2017 - 2021 Open Source Matters, Inc. All rights reserved. * Copyright (C) 2008 - 2016 compojoom.com . All rights reserved. - * @author Denis Ryabov * * @license GNU General Public License version 2 or later; see LICENSE.txt */ From 0545fddb87a94e2a8de4173c133b79d80731417d Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Thu, 11 Mar 2021 15:59:54 +0300 Subject: [PATCH 10/17] fix copyright --- .../components/com_jedchecker/libraries/rules/xmlfiles.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php index af55d7d..c836ff4 100644 --- a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php +++ b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php @@ -2,8 +2,7 @@ /** * @package Joomla.JEDChecker * - * @copyright Copyright (C) 2017 - 2021 Open Source Matters, Inc. All rights reserved. - * Copyright (C) 2008 - 2016 compojoom.com . All rights reserved. + * @copyright Copyright (C) 2021 Open Source Matters, Inc. All rights reserved. * * @license GNU General Public License version 2 or later; see LICENSE.txt */ From a34f3bd138899c73d36af9bb8d4e08c9f350ee8d Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Sun, 4 Apr 2021 13:44:33 +0300 Subject: [PATCH 11/17] Joomla! code style fixes --- .../libraries/rules/xmlfiles.php | 49 ++++++++++--------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php index c836ff4..1f43567 100644 --- a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php +++ b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php @@ -17,7 +17,7 @@ require_once JPATH_COMPONENT_ADMINISTRATOR . '/models/rule.php'; /** * class JedcheckerRulesXMLFiles * - * This class searches all xml manifestes for valid files declarations + * This class searches all xml manifests for valid files declarations * * @since 2.3 */ @@ -95,22 +95,22 @@ class JedcheckerRulesXMLFiles extends JEDcheckerRule $this->errors = array(); - // check declared files and folders do exist + // Check declared files and folders do exist $basedir = dirname($file) . '/'; - // check: files[folder] (filename|folder)* - // for package: files[folder] (file|folder)* + // Check: files[folder] (filename|folder)* + // ( for package: files[folder] (file|folder)* ) if (isset($xml->files)) { $node = $xml->files; $dir = $basedir . (isset($node['folder']) ? $node['folder'] . '/' : ''); $this->checkFiles($node->filename, $dir); - $this->checkFiles($node->file, $dir); // for packages + $this->checkFiles($node->file, $dir); $this->checkFolders($node->folder, $dir); } - // check: media[folder] (filename|folder)* + // Check: media[folder] (filename|folder)* if (isset($xml->media)) { $node = $xml->media; @@ -119,7 +119,7 @@ class JedcheckerRulesXMLFiles extends JEDcheckerRule $this->checkFolders($node->folder, $dir); } - // check files: languages[folder] language* + // Check files: languages[folder] language* if (isset($xml->languages)) { $node = $xml->languages; @@ -129,7 +129,7 @@ class JedcheckerRulesXMLFiles extends JEDcheckerRule $admindir = $basedir; - // check: administration files[folder] (filename|folder)* + // Check: administration files[folder] (filename|folder)* if (isset($xml->administration->files)) { $node = $xml->administration->files; @@ -138,7 +138,7 @@ class JedcheckerRulesXMLFiles extends JEDcheckerRule $this->checkFolders($node->folder, $admindir); } - // check: administration media[folder] (filename|folder)* + // Check: administration media[folder] (filename|folder)* if (isset($xml->administration->media)) { $node = $xml->administration->media; @@ -147,7 +147,7 @@ class JedcheckerRulesXMLFiles extends JEDcheckerRule $this->checkFolders($node->folder, $dir); } - // check files: administration languages[folder] language* + // Check files: administration languages[folder] language* if (isset($xml->administration->languages)) { $node = $xml->administration->languages; @@ -155,25 +155,25 @@ class JedcheckerRulesXMLFiles extends JEDcheckerRule $this->checkFiles($node->language, $dir); } - // check file: scriptfile + // Check file: scriptfile if (isset($xml->scriptfile)) { $this->checkFiles($xml->scriptfile, $basedir); } - // check files: install sql file* + // Check files: install sql file* if (isset($xml->install->sql->file)) { $this->checkFiles($xml->install->sql->file, $admindir); } - // check files: uninstall sql file* + // Check files: uninstall sql file* if (isset($xml->uninstall->sql->file)) { $this->checkFiles($xml->uninstall->sql->file, $admindir); } - // check folders: update schemas schemapath* + // Check folders: update schemas schemapath* if (isset($xml->update->schemas->schemapath)) { $this->checkFolders($xml->update->schemas->schemapath, $admindir); @@ -191,36 +191,39 @@ class JedcheckerRulesXMLFiles extends JEDcheckerRule /** * Check files exist * - * @param JXMLElement $files Files to check - * @param string $dir Base directory + * @param SimpleXMLElement $files Files to check + * @param string $dir Base directory * - * @return void + * @return void */ protected function checkFiles($files, $dir) { foreach ($files as $file) { $filename = $dir . $file; + if (is_file($filename)) { continue; } - // extra check for unzipped files + + // Extra check for unzipped files if (preg_match('/^(.*)\.(zip|tar\.gz)$/', $filename, $matches) && is_dir($matches[1])) { continue; } - $this->errors[] = JText::sprintf('COM_JEDCHECKER_XML_FILES_FILE_NOT_FOUND', (string)$file); + + $this->errors[] = JText::sprintf('COM_JEDCHECKER_XML_FILES_FILE_NOT_FOUND', (string) $file); } } /** * Check folders exist * - * @param JXMLElement $folders Directories to check - * @param string $dir Base directory + * @param SimpleXMLElement $folders Directories to check + * @param string $dir Base directory * - * @return void + * @return void */ protected function checkFolders($folders, $dir) { @@ -228,7 +231,7 @@ class JedcheckerRulesXMLFiles extends JEDcheckerRule { if (!is_dir($dir . $folder)) { - $this->errors[] = JText::sprintf('COM_JEDCHECKER_XML_FILES_FOLDER_NOT_FOUND', (string)$folder); + $this->errors[] = JText::sprintf('COM_JEDCHECKER_XML_FILES_FOLDER_NOT_FOUND', (string) $folder); } } } From 3e03b981e8f769e7bc3aea2ca8402dd0f03c4633 Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Wed, 24 Feb 2021 14:52:58 +0300 Subject: [PATCH 12/17] check fonts in language package --- .../com_jedchecker/libraries/rules/xmlfiles.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php index 1f43567..97b2bc6 100644 --- a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php +++ b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php @@ -119,6 +119,15 @@ class JedcheckerRulesXMLFiles extends JEDcheckerRule $this->checkFolders($node->folder, $dir); } + // Check: fonts[folder] (filename|folder)* + if (isset($xml->fonts)) + { + $node = $xml->fonts; + $dir = $basedir . (isset($node['folder']) ? $node['folder'] . '/' : ''); + $this->checkFiles($node->filename, $dir); + $this->checkFolders($node->folder, $dir); + } + // Check files: languages[folder] language* if (isset($xml->languages)) { From 715b0618407a0eb2fc74450f698b84629c8aac5b Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Tue, 9 Mar 2021 23:54:58 +0300 Subject: [PATCH 13/17] Check files in the fileset node of type="file" extensions --- .../com_jedchecker/libraries/rules/xmlfiles.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php index 97b2bc6..04f8e41 100644 --- a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php +++ b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php @@ -164,6 +164,17 @@ class JedcheckerRulesXMLFiles extends JEDcheckerRule $this->checkFiles($node->language, $dir); } + // For type="file" extensions: + // Check files: fileset files[folder] (filename|file|folder)* + if (isset($xml->fileset->files)) + { + $node = $xml->fileset->files; + $dir = $basedir . (isset($node['folder']) ? $node['folder'] . '/' : ''); + $this->checkFiles($node->filename, $dir); + $this->checkFiles($node->file, $dir); + $this->checkFolders($node->folder, $dir); + } + // Check file: scriptfile if (isset($xml->scriptfile)) { From 75e93bad902a778cf457464c8c80a10f274d09f5 Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Wed, 10 Mar 2021 00:39:18 +0300 Subject: [PATCH 14/17] add "tgz" into a list of possible archive extensions --- .../components/com_jedchecker/libraries/rules/xmlfiles.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php index 04f8e41..62ef04a 100644 --- a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php +++ b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php @@ -228,7 +228,7 @@ class JedcheckerRulesXMLFiles extends JEDcheckerRule } // Extra check for unzipped files - if (preg_match('/^(.*)\.(zip|tar\.gz)$/', $filename, $matches) && is_dir($matches[1])) + if (preg_match('/^(.*)\.(zip|tgz|tar\.gz)$/', $filename, $matches) && is_dir($matches[1])) { continue; } From a88050c37bd264ba21c0e1a21ffa8de8cb0e72c8 Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Wed, 10 Mar 2021 00:40:18 +0300 Subject: [PATCH 15/17] check addfieldpath/addformpath/addrulepath directories exist --- .../libraries/rules/xmlfiles.php | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php index 62ef04a..4698d41 100644 --- a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php +++ b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php @@ -199,6 +199,111 @@ class JedcheckerRulesXMLFiles extends JEDcheckerRule $this->checkFolders($xml->update->schemas->schemapath, $admindir); } + // Check: config [add...path] directories exist + if (isset($xml->config)) + { + $attributes = array('addfieldpath', 'addformpath', 'addrulepath'); + + $extensionPath = false; + + // @TODO move element name extraction into a helper (similar code is used in XMLinfo rule) + switch ((string) $xml['type']) + { + case 'module': + if (isset($xml->element)) + { + $element = (string) $xml->element; + } + else + { + $element = (string) $xml->name; + + if (isset($xml->files)) + { + foreach ($xml->files->children() as $child) + { + if (isset($child['module'])) + { + $element = (string) $child['module']; + break; + } + } + } + } + + $element = strtolower(JFilterInput::getInstance()->clean($element, 'cmd')); + + $extensionPath = 'modules/' . $element . '/'; + break; + + case 'plugin': + if (isset($xml->element)) + { + $element = (string) $xml->element; + } + else + { + $element = (string) $xml->name; + + if (isset($xml->files)) + { + foreach ($xml->files->children() as $child) + { + if (isset($child['plugin'])) + { + $element = (string) $child['plugin']; + break; + } + } + } + } + + $element = strtolower(JFilterInput::getInstance()->clean($element, 'cmd')); + + $group = (string) $xml['group']; + + $extensionPath = 'plugins/' . $group . '/' . $element . '/'; + break; + + case 'template': + if (isset($xml->element)) + { + $element = (string) $xml->element; + } + else + { + $element = (string) $xml->name; + } + + $element = strtolower(JFilterInput::getInstance()->clean($element, 'cmd')); + + $extensionPath = 'templates/' . $element . '/'; + } + + if ($extensionPath !== false) + { + foreach ($attributes as $attribute) + { + foreach ($xml->config->xpath('//*[@' . $attribute . ']') as $node) + { + $attrPath = (string) $node[$attribute]; + $folder = ltrim($attrPath, '/'); + + // Convert absolute path to relative (if matches extension path) + if (strpos($folder, $extensionPath) === 0) + { + $folder = $sitedir . substr($folder, strlen($extensionPath)); + + if (!is_dir($folder)) + { + $this->errors[] = JText::sprintf('COM_JEDCHECKER_XML_FILES_FOLDER_NOT_FOUND', $attrPath); + } + } + } + } + } + } + if (count($this->errors)) { $this->report->addError($file, implode('
', $this->errors)); From fefbb2ca8e851f93f18723db8360bcc5180dad9d Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Wed, 10 Mar 2021 00:40:53 +0300 Subject: [PATCH 16/17] check namespace path directory exists --- .../com_jedchecker/libraries/rules/xmlfiles.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php index 4698d41..a1fd5a1 100644 --- a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php +++ b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php @@ -304,6 +304,17 @@ class JedcheckerRulesXMLFiles extends JEDcheckerRule } } + // Check /namespace[path] directory exists (Joomla!4) + if (isset($xml->namespace['path'])) + { + $folder = (string) $xml->namespace['path']; + + if (!is_dir($admindir . $folder) && !is_dir($sitedir . $folder)) + { + $this->errors[] = JText::sprintf('COM_JEDCHECKER_XML_FILES_FOLDER_NOT_FOUND', $folder); + } + } + if (count($this->errors)) { $this->report->addError($file, implode('
', $this->errors)); From ce7058f1213d566b95dc45f8ee92dc5a7efa30fb Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Wed, 10 Mar 2021 00:41:52 +0300 Subject: [PATCH 17/17] Check both filename and file nodes --- .../libraries/rules/xmlfiles.php | 42 +++++++++++++------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php index a1fd5a1..6564804 100644 --- a/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php +++ b/administrator/components/com_jedchecker/libraries/rules/xmlfiles.php @@ -99,32 +99,41 @@ class JedcheckerRulesXMLFiles extends JEDcheckerRule $basedir = dirname($file) . '/'; + $sitedir = $basedir; + // Check: files[folder] (filename|folder)* // ( for package: files[folder] (file|folder)* ) if (isset($xml->files)) { $node = $xml->files; + + // Get path to site files from "folder" attribute + $sitedir = $basedir . (isset($node['folder']) ? $node['folder'] . '/' : ''); + + $this->checkFiles($node->filename, $sitedir); + $this->checkFiles($node->file, $sitedir); + $this->checkFolders($node->folder, $sitedir); + } + + // Check: media[folder] (filename|file|folder)* + if (isset($xml->media)) + { + $node = $xml->media; $dir = $basedir . (isset($node['folder']) ? $node['folder'] . '/' : ''); + $this->checkFiles($node->filename, $dir); $this->checkFiles($node->file, $dir); $this->checkFolders($node->folder, $dir); } - // Check: media[folder] (filename|folder)* - if (isset($xml->media)) - { - $node = $xml->media; - $dir = $basedir . (isset($node['folder']) ? $node['folder'] . '/' : ''); - $this->checkFiles($node->filename, $dir); - $this->checkFolders($node->folder, $dir); - } - - // Check: fonts[folder] (filename|folder)* + // Check: fonts[folder] (filename|file|folder)* if (isset($xml->fonts)) { $node = $xml->fonts; $dir = $basedir . (isset($node['folder']) ? $node['folder'] . '/' : ''); + $this->checkFiles($node->filename, $dir); + $this->checkFiles($node->file, $dir); $this->checkFolders($node->folder, $dir); } @@ -133,26 +142,33 @@ class JedcheckerRulesXMLFiles extends JEDcheckerRule { $node = $xml->languages; $dir = $basedir . (isset($node['folder']) ? $node['folder'] . '/' : ''); + $this->checkFiles($node->language, $dir); } $admindir = $basedir; - // Check: administration files[folder] (filename|folder)* + // Check: administration files[folder] (filename|file|folder)* if (isset($xml->administration->files)) { $node = $xml->administration->files; + + // Get path to admin files from "folder" attribute $admindir = $basedir . (isset($node['folder']) ? $node['folder'] . '/' : ''); + $this->checkFiles($node->filename, $admindir); + $this->checkFiles($node->file, $admindir); $this->checkFolders($node->folder, $admindir); } - // Check: administration media[folder] (filename|folder)* + // Check: administration media[folder] (filename|file|folder)* if (isset($xml->administration->media)) { $node = $xml->administration->media; $dir = $basedir . (isset($node['folder']) ? $node['folder'] . '/' : ''); + $this->checkFiles($node->filename, $dir); + $this->checkFiles($node->file, $dir); $this->checkFolders($node->folder, $dir); } @@ -161,6 +177,7 @@ class JedcheckerRulesXMLFiles extends JEDcheckerRule { $node = $xml->administration->languages; $dir = $basedir . (isset($node['folder']) ? $node['folder'] . '/' : ''); + $this->checkFiles($node->language, $dir); } @@ -170,6 +187,7 @@ class JedcheckerRulesXMLFiles extends JEDcheckerRule { $node = $xml->fileset->files; $dir = $basedir . (isset($node['folder']) ? $node['folder'] . '/' : ''); + $this->checkFiles($node->filename, $dir); $this->checkFiles($node->file, $dir); $this->checkFolders($node->folder, $dir);