2021-02-02 22:14:16 +00:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* @package Joomla.JEDChecker
|
|
|
|
*
|
2021-03-11 13:00:58 +00:00
|
|
|
* @copyright Copyright (C) 2021 Open Source Matters, Inc. All rights reserved.
|
2021-02-02 22:14:16 +00:00
|
|
|
*
|
|
|
|
* @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 JedcheckerRulesLanguage
|
|
|
|
*
|
|
|
|
* This class validates language ini file
|
|
|
|
*
|
|
|
|
* @since 2.3
|
|
|
|
*/
|
|
|
|
class JedcheckerRulesLanguage extends JEDcheckerRule
|
|
|
|
{
|
2021-02-22 21:00:06 +00:00
|
|
|
/**
|
|
|
|
* The formal ID of this rule. For example: SE1.
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $id = 'LANG';
|
2021-02-02 22:14:16 +00:00
|
|
|
|
2021-02-22 21:00:06 +00:00
|
|
|
/**
|
|
|
|
* The title or caption of this rule.
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $title = 'COM_JEDCHECKER_LANG';
|
2021-02-02 22:14:16 +00:00
|
|
|
|
2021-02-22 21:00:06 +00:00
|
|
|
/**
|
|
|
|
* The description of this rule.
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $description = 'COM_JEDCHECKER_LANG_DESC';
|
2021-02-02 22:14:16 +00:00
|
|
|
|
2021-02-22 21:00:06 +00:00
|
|
|
/**
|
|
|
|
* Initiates the search and check
|
|
|
|
*
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function check()
|
|
|
|
{
|
|
|
|
// Find all INI files of the extension (in the format tag.extension.ini or tag.extension.sys.ini)
|
|
|
|
$files = JFolder::files($this->basedir, '^[a-z]{2,3}-[A-Z]{2}\.\w+(?:\.sys)?\.ini$', true, true);
|
2021-02-02 22:14:16 +00:00
|
|
|
|
2021-02-22 21:00:06 +00:00
|
|
|
// Iterate through all the ini files
|
|
|
|
foreach ($files as $file)
|
|
|
|
{
|
|
|
|
// Try to validate the file
|
|
|
|
$this->find($file);
|
|
|
|
}
|
|
|
|
}
|
2021-02-02 22:14:16 +00:00
|
|
|
|
2021-02-22 21:00:06 +00:00
|
|
|
/**
|
|
|
|
* Reads and validates an ini file
|
|
|
|
*
|
|
|
|
* @param string $file - The path to the file
|
|
|
|
*
|
|
|
|
* @return bool True on success, otherwise False.
|
|
|
|
*/
|
|
|
|
protected function find($file)
|
|
|
|
{
|
|
|
|
$lines = file($file);
|
|
|
|
foreach ($lines as $lineno => $line)
|
|
|
|
{
|
|
|
|
$line = trim($line);
|
2021-03-10 22:35:15 +00:00
|
|
|
|
|
|
|
// Check for BOM sequence
|
2021-02-23 19:26:09 +00:00
|
|
|
if ($lineno === 0 && strncmp($line, "\xEF\xBB\xBF", 3) === 0)
|
|
|
|
{
|
|
|
|
$this->report->addError($file, JText::_('COM_JEDCHECKER_LANG_BOM_FOUND'), 1);
|
2021-03-10 22:35:15 +00:00
|
|
|
// Romeve BOM for further checks
|
2021-02-23 19:26:09 +00:00
|
|
|
$line = substr($line, 3);
|
|
|
|
}
|
2021-03-10 22:35:15 +00:00
|
|
|
|
|
|
|
// Skip empty lines, comments, and section names
|
2021-02-22 21:00:06 +00:00
|
|
|
if ($line === '' || $line[0] === ';' || $line[0] === '[')
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2021-03-10 22:35:15 +00:00
|
|
|
|
|
|
|
// Report incorrect comment character
|
2021-02-22 21:00:06 +00:00
|
|
|
if ($line[0] === '#')
|
|
|
|
{
|
|
|
|
$this->report->addError($file, JText::_('COM_JEDCHECKER_LANG_INCORRECT_COMMENT') .
|
|
|
|
'<br>' . htmlspecialchars($line), $lineno);
|
|
|
|
continue;
|
|
|
|
}
|
2021-03-10 22:35:15 +00:00
|
|
|
|
|
|
|
// Check for "=" character in the line
|
2021-02-22 21:00:06 +00:00
|
|
|
if (strpos($line, '=') === false)
|
|
|
|
{
|
|
|
|
$this->report->addError($file, JText::_('COM_JEDCHECKER_LANG_WRONG_LINE') .
|
|
|
|
'<br>' . htmlspecialchars($line), $lineno);
|
|
|
|
continue;
|
|
|
|
}
|
2021-03-10 22:35:15 +00:00
|
|
|
|
|
|
|
// Extract key and value
|
2021-02-22 21:00:06 +00:00
|
|
|
list ($key, $value) = explode('=', $line, 2);
|
2021-02-02 22:14:16 +00:00
|
|
|
|
2021-02-22 21:00:06 +00:00
|
|
|
$key = rtrim($key);
|
2021-03-10 22:35:15 +00:00
|
|
|
|
|
|
|
// Check for empty key
|
2021-02-22 21:00:06 +00:00
|
|
|
if ($key === '')
|
|
|
|
{
|
|
|
|
$this->report->addError($file, JText::_('COM_JEDCHECKER_LANG_KEY_EMPTY') .
|
|
|
|
'<br>' . htmlspecialchars($line), $lineno);
|
|
|
|
continue;
|
|
|
|
}
|
2021-03-10 22:35:15 +00:00
|
|
|
|
|
|
|
// Check for spaces in the key name
|
2021-02-22 21:00:06 +00:00
|
|
|
if (strpos($key, ' ') !== false)
|
|
|
|
{
|
|
|
|
$this->report->addError($file, JText::_('COM_JEDCHECKER_LANG_KEY_WHITESPACE') .
|
|
|
|
'<br>' . htmlspecialchars($line), $lineno);
|
|
|
|
continue;
|
|
|
|
}
|
2021-03-10 22:35:15 +00:00
|
|
|
|
|
|
|
// Check for invalid characters (see https://www.php.net/manual/en/function.parse-ini-file.php)
|
2021-02-22 21:00:06 +00:00
|
|
|
if (strpbrk($key, '{}|&~![()^"') !== false)
|
|
|
|
{
|
|
|
|
$this->report->addError($file, JText::_('COM_JEDCHECKER_LANG_KEY_INVALID_CHARACTER') .
|
|
|
|
'<br>' . htmlspecialchars($line), $lineno);
|
|
|
|
continue;
|
|
|
|
}
|
2021-03-10 22:35:15 +00:00
|
|
|
|
|
|
|
// Check for invalid key names (see https://www.php.net/manual/en/function.parse-ini-file.php)
|
2021-02-22 21:00:06 +00:00
|
|
|
if (in_array($key, array('null', 'yes', 'no', 'true', 'false', 'on', 'off', 'none'), true))
|
|
|
|
{
|
|
|
|
$this->report->addError($file, JText::_('COM_JEDCHECKER_LANG_KEY_RESERVED') .
|
|
|
|
'<br>' . htmlspecialchars($line), $lineno);
|
|
|
|
continue;
|
|
|
|
}
|
2021-03-10 22:35:15 +00:00
|
|
|
|
2021-02-22 21:00:06 +00:00
|
|
|
$value = ltrim($value);
|
2021-03-10 22:35:15 +00:00
|
|
|
|
2021-02-22 21:00:06 +00:00
|
|
|
if (strlen($value) <2 || $value[0] !== '"' || substr($value, -1) !== '"')
|
|
|
|
{
|
|
|
|
$this->report->addError($file, JText::_('COM_JEDCHECKER_LANG_TRANSLATION_QUOTES') .
|
|
|
|
'<br>' . htmlspecialchars($line), $lineno);
|
|
|
|
continue;
|
|
|
|
}
|
2021-03-10 22:35:15 +00:00
|
|
|
|
|
|
|
// Check for empty value
|
2021-02-22 21:00:06 +00:00
|
|
|
if ($value === '""')
|
|
|
|
{
|
|
|
|
$this->report->addWarning($file, JText::_('COM_JEDCHECKER_LANG_TRANSLATION_EMPTY') .
|
|
|
|
'<br>' . htmlspecialchars($line), $lineno);
|
|
|
|
continue;
|
|
|
|
}
|
2021-02-02 22:14:16 +00:00
|
|
|
|
2021-03-10 22:35:15 +00:00
|
|
|
// Remove quotes around
|
2021-02-22 21:00:06 +00:00
|
|
|
$value = substr($value, 1, -1);
|
2021-03-10 22:35:15 +00:00
|
|
|
|
|
|
|
// Check for legacy "_QQ_" code (deprecated since Joomla! 3.9 if favor of escaped double quote \"; removed in Joomla! 4)
|
2021-02-22 21:00:06 +00:00
|
|
|
if (strpos($value, '"_QQ_"') !== false)
|
|
|
|
{
|
|
|
|
$this->report->addInfo($file, JText::_('COM_JEDCHECKER_LANG_QQ_DEPRECATED') .
|
|
|
|
'<br>' . htmlspecialchars($line), $lineno);
|
|
|
|
}
|
|
|
|
}
|
2021-02-02 22:14:16 +00:00
|
|
|
|
2021-02-22 21:00:06 +00:00
|
|
|
// All checks passed. Return true
|
|
|
|
return true;
|
|
|
|
}
|
2021-02-02 22:14:16 +00:00
|
|
|
}
|