2013-04-11 13:23:19 +00:00
|
|
|
<?php
|
|
|
|
/**
|
2019-03-09 19:44:14 +00:00
|
|
|
* @package Joomla.JEDChecker
|
|
|
|
*
|
2019-03-10 16:09:42 +00:00
|
|
|
* @copyright Copyright (C) 2017 - 2019 Open Source Matters, Inc. All rights reserved.
|
|
|
|
* Copyright (C) 2008 - 2016 compojoom.com . All rights reserved.
|
2019-03-10 08:49:52 +00:00
|
|
|
* @author Daniel Dimitrov <daniel@compojoom.com>
|
|
|
|
*
|
2019-03-09 19:44:14 +00:00
|
|
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
2013-04-11 13:23:19 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
defined('_JEXEC') or die('Restricted access');
|
|
|
|
|
|
|
|
|
|
|
|
// Include the rule base class
|
2021-04-04 10:31:35 +00:00
|
|
|
require_once JPATH_COMPONENT_ADMINISTRATOR . '/models/rule.php';
|
2013-04-11 13:23:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
2013-11-05 20:17:39 +00:00
|
|
|
* class JedcheckerRulesGpl
|
|
|
|
*
|
2021-04-04 10:31:35 +00:00
|
|
|
* This class searches all files for the GPL/compatible licenses
|
2013-04-11 13:23:19 +00:00
|
|
|
*
|
2013-11-05 20:17:39 +00:00
|
|
|
* @since 1.0
|
2013-04-11 13:23:19 +00:00
|
|
|
*/
|
2013-11-05 20:17:39 +00:00
|
|
|
class JedcheckerRulesGpl extends JEDcheckerRule
|
2013-04-11 13:23:19 +00:00
|
|
|
{
|
|
|
|
/**
|
|
|
|
* The formal ID of this rule. For example: SE1.
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $id = 'PH1';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The title or caption of this rule.
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $title = 'COM_JEDCHECKER_RULE_PH1';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The description of this rule.
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $description = 'COM_JEDCHECKER_RULE_PH1_DESC';
|
|
|
|
|
2021-05-17 20:21:34 +00:00
|
|
|
/**
|
|
|
|
* The ordering value to sort rules in the menu.
|
|
|
|
*
|
|
|
|
* @var integer
|
|
|
|
*/
|
|
|
|
public static $ordering = 500;
|
|
|
|
|
2021-08-28 16:10:50 +00:00
|
|
|
/**
|
2021-01-31 08:52:32 +00:00
|
|
|
* Regular expression to match GPL licenses.
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
2021-04-04 10:31:35 +00:00
|
|
|
protected $regexGPLLicenses;
|
2021-01-31 08:52:32 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Regular expression to match GPL-compatible licenses.
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
2021-04-04 10:31:35 +00:00
|
|
|
protected $regexCompatLicenses;
|
2021-01-31 08:52:32 +00:00
|
|
|
|
2013-04-11 13:23:19 +00:00
|
|
|
/**
|
|
|
|
* Initiates the file search and check
|
|
|
|
*
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function check()
|
|
|
|
{
|
2021-01-31 08:52:32 +00:00
|
|
|
// Prepare regexp
|
|
|
|
$this->init();
|
|
|
|
|
2013-04-11 13:23:19 +00:00
|
|
|
// Find all php files of the extension
|
2021-02-13 20:12:08 +00:00
|
|
|
$files = JFolder::files($this->basedir, '\.php$', true, true);
|
2013-04-11 13:23:19 +00:00
|
|
|
|
|
|
|
// Iterate through all files
|
|
|
|
foreach ($files as $file)
|
|
|
|
{
|
|
|
|
// Try to find the _JEXEC check in the file
|
|
|
|
if (!$this->find($file))
|
|
|
|
{
|
|
|
|
// Add as error to the report if it was not found
|
|
|
|
$this->report->addError($file, JText::_('COM_JEDCHECKER_ERROR_GPL_NOT_FOUND'));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-01-31 08:52:32 +00:00
|
|
|
* Initialization (prepare regular expressions)
|
2013-04-11 13:23:19 +00:00
|
|
|
*
|
2021-04-04 10:31:35 +00:00
|
|
|
* @return void
|
2013-04-11 13:23:19 +00:00
|
|
|
*/
|
2021-01-31 08:52:32 +00:00
|
|
|
protected function init()
|
2013-04-11 13:23:19 +00:00
|
|
|
{
|
2021-04-04 10:31:35 +00:00
|
|
|
$GPLLicenses = (array) file(__DIR__ . '/gpl/gnu.txt');
|
|
|
|
$this->regexGPLLicenses = $this->generateRegexp($GPLLicenses);
|
2013-11-05 20:17:39 +00:00
|
|
|
|
2021-04-04 10:31:35 +00:00
|
|
|
$compatLicenses = (array) file(__DIR__ . '/gpl/compat.txt');
|
2013-04-11 13:23:19 +00:00
|
|
|
|
2021-04-04 10:31:35 +00:00
|
|
|
$extraLicenses = $this->params->get('constants');
|
|
|
|
$extraLicenses = explode(',', $extraLicenses);
|
2013-11-04 14:17:11 +00:00
|
|
|
|
2021-04-04 10:31:35 +00:00
|
|
|
$compatLicenses = array_merge($compatLicenses, $extraLicenses);
|
2021-01-31 08:52:32 +00:00
|
|
|
|
2021-04-04 10:31:35 +00:00
|
|
|
$this->regexCompatLicenses = $this->generateRegexp($compatLicenses);
|
2021-01-31 08:52:32 +00:00
|
|
|
}
|
2013-11-04 14:17:11 +00:00
|
|
|
|
2021-01-31 08:52:32 +00:00
|
|
|
/**
|
|
|
|
* Generate regular expression to match the given list of license names
|
2021-04-04 10:31:35 +00:00
|
|
|
* @param array $lines List of license names
|
|
|
|
*
|
2021-01-31 08:52:32 +00:00
|
|
|
* @return string
|
|
|
|
*/
|
2021-04-04 10:31:35 +00:00
|
|
|
protected function generateRegexp($lines)
|
2021-01-31 08:52:32 +00:00
|
|
|
{
|
|
|
|
$titles = array();
|
|
|
|
$ids = array();
|
2013-11-04 14:17:11 +00:00
|
|
|
|
2021-01-31 08:52:32 +00:00
|
|
|
foreach ($lines as $line)
|
2013-04-11 13:23:19 +00:00
|
|
|
{
|
2021-01-31 08:52:32 +00:00
|
|
|
$line = trim($line);
|
2013-11-04 14:17:11 +00:00
|
|
|
|
2021-01-31 08:52:32 +00:00
|
|
|
if ($line === '' || $line[0] === '#')
|
2013-11-04 14:17:11 +00:00
|
|
|
{
|
2021-04-04 10:31:35 +00:00
|
|
|
// Skip empty and commented lines
|
2013-11-04 14:17:11 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-01-31 08:52:32 +00:00
|
|
|
$title = $line;
|
|
|
|
if (substr($line, -1, 1) === ')')
|
2013-11-04 14:17:11 +00:00
|
|
|
{
|
2021-04-04 10:31:35 +00:00
|
|
|
// Extract identifier
|
2021-01-31 08:52:32 +00:00
|
|
|
$pos = strrpos($line, '(');
|
2013-04-11 13:23:19 +00:00
|
|
|
|
2021-01-31 08:52:32 +00:00
|
|
|
if ($pos !== false)
|
|
|
|
{
|
|
|
|
$title = trim(substr($line, 0, $pos));
|
2013-04-11 13:23:19 +00:00
|
|
|
|
2021-01-31 08:52:32 +00:00
|
|
|
$id = trim(substr($line, $pos + 1, -1));
|
2013-11-05 20:17:39 +00:00
|
|
|
|
2021-01-31 08:52:32 +00:00
|
|
|
if ($id !== '')
|
|
|
|
{
|
|
|
|
$id = preg_quote($id, '#');
|
|
|
|
$ids[$id] = 1;
|
|
|
|
}
|
|
|
|
}
|
2013-04-11 13:23:19 +00:00
|
|
|
}
|
|
|
|
|
2021-01-31 08:52:32 +00:00
|
|
|
if ($title !== '')
|
2013-04-11 13:23:19 +00:00
|
|
|
{
|
2021-01-31 08:52:32 +00:00
|
|
|
$title = preg_quote($title, '#');
|
2013-04-11 13:23:19 +00:00
|
|
|
|
2021-04-04 10:31:35 +00:00
|
|
|
// Expand vN.N to different version formats
|
2021-01-31 08:52:32 +00:00
|
|
|
$title = preg_replace('/(?<=\S)\s+v(?=\d)/', ',?\s+(?:v\.?\s*|version\s+)?', $title);
|
2013-11-05 20:17:39 +00:00
|
|
|
|
2021-01-31 08:52:32 +00:00
|
|
|
$title = preg_replace('/\s+/', '\s+', $title);
|
2013-11-05 20:17:39 +00:00
|
|
|
|
2021-01-31 08:52:32 +00:00
|
|
|
$titles[$title] = 1;
|
2013-04-11 13:23:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-31 08:52:32 +00:00
|
|
|
if (count($titles) === 0)
|
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
$titles = implode('|', array_keys($titles));
|
|
|
|
|
|
|
|
if (count($ids))
|
|
|
|
{
|
|
|
|
$ids = implode('|', array_keys($ids));
|
|
|
|
$titles .=
|
|
|
|
'|\blicense\b.+?(?:' . $ids . ')' .
|
|
|
|
'|\b(?:' . $ids . ')\s+license\b';
|
|
|
|
}
|
|
|
|
|
|
|
|
return '#^.*?(?:' . $titles . ').*?$#im';
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Reads a file and searches for its license
|
|
|
|
*
|
|
|
|
* @param string $file - The path to the file
|
|
|
|
*
|
|
|
|
* @return boolean True if the statement was found, otherwise False.
|
|
|
|
*/
|
|
|
|
protected function find($file)
|
|
|
|
{
|
|
|
|
$content = php_strip_whitespace($file);
|
2021-02-23 23:27:30 +00:00
|
|
|
|
2021-05-11 11:43:39 +00:00
|
|
|
// Check the file is empty, comments-only, or nonexecutable
|
|
|
|
if (empty($content) || preg_match('#^<\?php\s+(?:$|(?:die|exit)(?:\(\))?;)#', $content))
|
2021-01-31 08:52:32 +00:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-05-11 11:43:39 +00:00
|
|
|
// Reload file to preserve comments and line numbers
|
2021-01-31 08:52:32 +00:00
|
|
|
$content = file_get_contents($file);
|
|
|
|
|
2021-02-23 18:07:30 +00:00
|
|
|
// Remove leading "*" characters from phpDoc-like comments
|
|
|
|
$content = preg_replace('/^\s*\*/m', '', $content);
|
|
|
|
|
2021-04-04 10:31:35 +00:00
|
|
|
if (preg_match($this->regexGPLLicenses, $content, $match, PREG_OFFSET_CAPTURE))
|
2021-01-31 08:52:32 +00:00
|
|
|
{
|
2021-04-04 10:31:35 +00:00
|
|
|
$lineno = substr_count($content, "\n", 0, $match[0][1]) + 1;
|
2021-01-31 08:52:32 +00:00
|
|
|
$this->report->addInfo(
|
|
|
|
$file,
|
2021-02-23 23:27:30 +00:00
|
|
|
JText::_('COM_JEDCHECKER_PH1_LICENSE_FOUND'),
|
2021-04-04 10:31:35 +00:00
|
|
|
$lineno,
|
2021-02-23 23:27:30 +00:00
|
|
|
$match[0][0]
|
2021-01-31 08:52:32 +00:00
|
|
|
);
|
2021-02-23 23:27:30 +00:00
|
|
|
|
2021-01-31 08:52:32 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-04-04 10:31:35 +00:00
|
|
|
if (preg_match($this->regexCompatLicenses, $content, $match, PREG_OFFSET_CAPTURE))
|
2021-01-31 08:52:32 +00:00
|
|
|
{
|
2021-04-04 10:31:35 +00:00
|
|
|
$lineno = substr_count($content, "\n", 0, $match[0][1]) + 1;
|
2021-07-30 19:02:33 +00:00
|
|
|
$this->report->addWarning(
|
2021-01-31 08:52:32 +00:00
|
|
|
$file,
|
2021-02-23 23:27:30 +00:00
|
|
|
JText::_('COM_JEDCHECKER_GPL_COMPATIBLE_LICENSE_WAS_FOUND'),
|
2021-04-04 10:31:35 +00:00
|
|
|
$lineno,
|
2021-02-23 23:27:30 +00:00
|
|
|
$match[0][0]
|
2021-01-31 08:52:32 +00:00
|
|
|
);
|
2021-02-23 23:27:30 +00:00
|
|
|
|
2021-01-31 08:52:32 +00:00
|
|
|
return true;
|
|
|
|
}
|
2013-04-11 13:23:19 +00:00
|
|
|
|
2021-01-31 08:52:32 +00:00
|
|
|
return false;
|
2013-04-11 13:23:19 +00:00
|
|
|
}
|
|
|
|
}
|