Merge branch '3.10-dev' into 4.0-dev

This commit is contained in:
wilsonge 2020-12-15 18:17:51 +00:00
commit a1158ee07f
No known key found for this signature in database
GPG Key ID: EF81319318FC9D04
27 changed files with 265 additions and 30 deletions

2
.github/SECURITY.md vendored
View File

@ -11,7 +11,7 @@ This document outlines security procedures and policies for the `Joomla! Project
The `Joomla` team and community take all security bugs in `Joomla` seriously. The Joomla! Security Strike Team (JSST) oversees the project's security issues and follows some specific procedures when dealing with these issues.
If you find a possible vulnerability, please report it to the JSST using the [online form](https://developer.joomla.org/security/contact-the-team.html) or via email at security@joomla.org
If you find a possible vulnerability, please report it to the JSST using the [online form](https://developer.joomla.org/security/contact-the-team.html) or via email at security@joomla.org
We maintain a list of [GPG keys and addresses](https://developer.joomla.org/security/gpg-keys.html) for the security@joomla.org address and members of the JSST to allow signed and encrypted communications.

View File

@ -379,6 +379,32 @@ class CategoryModel extends AdminModel
return $data;
}
/**
* Method to validate the form data.
*
* @param JForm $form The form to validate against.
* @param array $data The data to validate.
* @param string $group The name of the field group to validate.
*
* @return array|boolean Array of filtered data if valid, false otherwise.
*
* @see JFormRule
* @see JFilterInput
* @since 3.9.23
*/
public function validate($form, $data, $group = null)
{
if (!JFactory::getUser()->authorise('core.admin', $data['extension']))
{
if (isset($data['rules']))
{
unset($data['rules']);
}
}
return parent::validate($form, $data, $group);
}
/**
* Method to preprocess the form.
*

View File

@ -150,6 +150,7 @@
showon="cache_handler:redis"
autocomplete="off"
size="30"
hint="***************"
/>
<field
@ -367,6 +368,7 @@
showon="ftp_enable:1"
autocomplete="off"
size="25"
hint="***************"
/>
<field
@ -435,6 +437,7 @@
showon="proxy_enable:1"
autocomplete="off"
size="25"
hint="***************"
/>
</fieldset>
@ -613,6 +616,7 @@
filter="raw"
autocomplete="off"
size="30"
hint="***************"
/>
</fieldset>
@ -898,6 +902,7 @@
showon="session_handler:redis"
autocomplete="off"
size="30"
hint="***************"
/>
<field

View File

@ -44,6 +44,14 @@ use PHPMailer\PHPMailer\Exception as phpMailerException;
*/
class ApplicationModel extends FormModel
{
/**
* Array of protected password fields from the configuration.php
*
* @var array
* @since 3.9.23
*/
private $protectedConfigurationFields = array('password', 'secret', 'ftp_pass', 'smtppass', 'redis_server_auth', 'session_redis_server_auth');
/**
* Method to get a form object.
*
@ -278,6 +286,15 @@ class ApplicationModel extends FormModel
}
}
// Unset all protected config fields to empty
foreach ($this->protectedConfigurationFields as $fieldKey)
{
if (isset($data[$fieldKey]))
{
$data[$fieldKey] = '';
}
}
return $data;
}
@ -294,6 +311,15 @@ class ApplicationModel extends FormModel
{
$app = Factory::getApplication();
// Try to load the values from the configuration file
foreach ($this->protectedConfigurationFields as $fieldKey)
{
if (isset($data[$fieldKey]) && empty($data[$fieldKey]))
{
$data[$fieldKey] = $app->get($fieldKey);
}
}
// Check that we aren't setting wrong database configuration
$options = array(
'driver' => $data['dbtype'],

View File

@ -185,6 +185,11 @@ class ComponentModel extends FormModel
// Save the rules.
if (isset($data['params']) && isset($data['params']['rules']))
{
if (!Factory::getUser()->authorise('core.admin', $data['option']))
{
throw new \RuntimeException(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'));
}
$rules = new Rules($data['params']['rules']);
$asset = Table::getInstance('asset');

View File

@ -671,6 +671,14 @@ class ArticleModel extends AdminModel implements WorkflowModelInterface
}
}
if (!JFactory::getUser()->authorise('core.admin', 'com_content'))
{
if (isset($data['rules']))
{
unset($data['rules']);
}
}
return parent::validate($form, $data, $group);
}

View File

@ -921,6 +921,32 @@ class FieldModel extends AdminModel
return $data;
}
/**
* Method to validate the form data.
*
* @param JForm $form The form to validate against.
* @param array $data The data to validate.
* @param string $group The name of the field group to validate.
*
* @return array|boolean Array of filtered data if valid, false otherwise.
*
* @see JFormRule
* @see JFilterInput
* @since 3.9.23
*/
public function validate($form, $data, $group = null)
{
if (!JFactory::getUser()->authorise('core.admin', 'com_fields'))
{
if (isset($data['rules']))
{
unset($data['rules']);
}
}
return parent::validate($form, $data, $group);
}
/**
* Method to allow derived classes to preprocess the form.
*

View File

@ -265,6 +265,32 @@ class GroupModel extends AdminModel
}
}
/**
* Method to validate the form data.
*
* @param JForm $form The form to validate against.
* @param array $data The data to validate.
* @param string $group The name of the field group to validate.
*
* @return array|boolean Array of filtered data if valid, false otherwise.
*
* @see JFormRule
* @see JFilterInput
* @since 3.9.23
*/
public function validate($form, $data, $group = null)
{
if (!JFactory::getUser()->authorise('core.admin', 'com_fields'))
{
if (isset($data['rules']))
{
unset($data['rules']);
}
}
return parent::validate($form, $data, $group);
}
/**
* Method to get the data that should be injected in the form.
*

View File

@ -869,7 +869,7 @@ abstract class AKAbstractUnarchiver extends AKAbstractPart
*/
public function __wakeup()
{
if ($this->currentPartNumber >= 0)
if ($this->currentPartNumber >= 0 && !empty($this->archiveList[$this->currentPartNumber]))
{
$this->fp = @fopen($this->archiveList[$this->currentPartNumber], 'rb');
if ((is_resource($this->fp)) && ($this->currentPartOffset > 0))

View File

@ -205,6 +205,32 @@ class MenuModel extends FormModel
return $data;
}
/**
* Method to validate the form data.
*
* @param JForm $form The form to validate against.
* @param array $data The data to validate.
* @param string $group The name of the field group to validate.
*
* @return array|boolean Array of filtered data if valid, false otherwise.
*
* @see JFormRule
* @see JFilterInput
* @since 3.9.23
*/
public function validate($form, $data, $group = null)
{
if (!JFactory::getUser()->authorise('core.admin', 'com_menus'))
{
if (isset($data['rules']))
{
unset($data['rules']);
}
}
return parent::validate($form, $data, $group);
}
/**
* Method to save the form data.
*

View File

@ -903,6 +903,30 @@ class ModuleModel extends AdminModel
parent::preprocessForm($form, $data, $group);
}
/**
* Loads ContentHelper for filters before validating data.
*
* @param object $form The form to validate against.
* @param array $data The data to validate.
* @param string $group The name of the group(defaults to null).
*
* @return mixed Array of filtered data if valid, false otherwise.
*
* @since 1.1
*/
public function validate($form, $data, $group = null)
{
if (!Factory::getUser()->authorise('core.admin', 'com_modules'))
{
if (isset($data['rules']))
{
unset($data['rules']);
}
}
return parent::validate($form, $data, $group);
}
/**
* Method to save the form data.
*

View File

@ -145,6 +145,9 @@ class RequestController extends FormController
*/
public function emailexport()
{
// Check for request forgeries.
$this->checkToken('get');
/** @var ExportModel $model */
$model = $this->getModel('Export');

View File

@ -78,7 +78,7 @@ $urgentRequestDate->sub(new DateInterval('P' . $this->urgentRequestAge . 'D'));
<?php if ($item->status == 1 && $item->request_type === 'export') : ?>
<a class="btn tbody-icon" href="<?php echo Route::_('index.php?option=com_privacy&task=request.export&format=xml&id=' . (int) $item->id); ?>" title="<?php echo Text::_('COM_PRIVACY_ACTION_EXPORT_DATA'); ?>"><span class="icon-download" aria-hidden="true"></span><span class="sr-only"><?php echo Text::_('COM_PRIVACY_ACTION_EXPORT_DATA'); ?></span></a>
<?php if ($this->sendMailEnabled) : ?>
<a class="btn tbody-icon" href="<?php echo Route::_('index.php?option=com_privacy&task=request.emailexport&id=' . (int) $item->id); ?>" title="<?php echo Text::_('COM_PRIVACY_ACTION_EMAIL_EXPORT_DATA'); ?>"><span class="icon-envelope" aria-hidden="true"></span><span class="sr-only"><?php echo Text::_('COM_PRIVACY_ACTION_EMAIL_EXPORT_DATA'); ?></span></a>
<a class="btn tbody-icon" href="<?php echo Route::_('index.php?option=com_privacy&task=request.emailexport&id=' . (int) $item->id . '&' . Factory::getSession()->getFormToken() . '=1'); ?>" title="<?php echo Text::_('COM_PRIVACY_ACTION_EMAIL_EXPORT_DATA'); ?>"><span class="icon-envelope" aria-hidden="true"></span><span class="sr-only"><?php echo Text::_('COM_PRIVACY_ACTION_EMAIL_EXPORT_DATA'); ?></span></a>
<?php endif; ?>
<?php endif; ?>
<?php if ($item->status == 1 && $item->request_type === 'remove') : ?>

View File

@ -27,6 +27,14 @@ use Joomla\Utilities\ArrayHelper;
*/
class UsersModel extends ListModel
{
/**
* A blacklist of filter variables to not merge into the model's state
*
* @var array
* @since 3.9.23
*/
protected $filterBlacklist = array('groups', 'excluded');
/**
* Override parent constructor.
*

View File

@ -575,6 +575,7 @@ JLIB_INSTALLER_AVAILABLE_UPDATE_DB_TYPE="For the extension %1$s version %2$s is
JLIB_INSTALLER_AVAILABLE_UPDATE_PHP_VERSION="For the extension %1$s version %2$s is available, but it requires at least PHP version %3$s while your system only has %4$s"
JLIB_INSTALLER_DEFAULT_STYLE="%s - Default"
JLIB_INSTALLER_DISCOVER="Discover"
JLIB_INSTALLER_DISCOVER_INSTALL="Discover Install"
JLIB_INSTALLER_ERROR_CANNOT_UNINSTALL_CHILD_OF_PACKAGE="The %s extension is part of a package which does not allow individual extensions to be uninstalled."
JLIB_INSTALLER_ERROR_COMP_DISCOVER_STORE_DETAILS="Component Discover install: Failed to store component details."
JLIB_INSTALLER_ERROR_COMP_FAILED_TO_CREATE_DIRECTORY="Component %1$s: Failed to create folder: %2$s."

View File

@ -65,7 +65,12 @@ class FeedView extends CategoryFeedView
$item->slug = $item->alias ? ($item->id . ':' . $item->alias) : $item->id;
// URL link to article
$link = Route::_(RouteHelper::getArticleRoute($item->slug, $item->catid, $item->language));
$link = Route::_(
RouteHelper::getArticleRoute($item->slug, $item->catid, $item->language),
true,
$app->get('force_ssl') == 2 ? \JRoute::TLS_FORCE : \JRoute::TLS_IGNORE,
true
);
$item->description .= '<p class="feed-readmore"><a target="_blank" href="' . $link . '" rel="noopener">'
. Text::_('COM_CONTENT_FEED_READMORE') . '</a></p>';

View File

@ -59,7 +59,7 @@ class FeedView extends AbstractView
$row->slug = $row->alias ? ($row->id . ':' . $row->alias) : $row->id;
// URL link to article
$link = Route::_(RouteHelper::getArticleRoute($row->slug, $row->catid, $row->language));
$link = RouteHelper::getArticleRoute($row->slug, $row->catid, $row->language);
$description = '';
$obj = json_decode($row->images);
@ -77,7 +77,7 @@ class FeedView extends AbstractView
// Load individual item creator class
$item = new FeedItem;
$item->title = $title;
$item->link = $link;
$item->link = Route::_($link);
$item->date = $row->publish_up;
$item->category = array();
@ -107,7 +107,8 @@ class FeedView extends AbstractView
// Add readmore link to description if introtext is shown, show_readmore is true and fulltext exists
if (!$params->get('feed_summary', 0) && $params->get('feed_show_readmore', 0) && $row->fulltext)
{
$description .= '<p class="feed-readmore"><a target="_blank" href="' . $item->link . '" rel="noopener">'
$link = Route::_($link, true, $app->get('force_ssl') == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE, true);
$description .= '<p class="feed-readmore"><a target="_blank" href="' . $link . '" rel="noopener">'
. Text::_('COM_CONTENT_FEED_READMORE') . '</a></p>';
}

View File

@ -16,6 +16,8 @@ use Joomla\CMS\Factory;
use Joomla\CMS\Language\Multilanguage;
use Joomla\CMS\MVC\Model\ListModel;
use Joomla\Component\Finder\Administrator\Indexer\Helper;
use Joomla\Database\DatabaseQuery;
use Joomla\Utilities\ArrayHelper;
/**
* Suggestions model class for the Finder package.
@ -56,27 +58,59 @@ class SuggestionsModel extends ListModel
/**
* Method to build a database query to load the list data.
*
* @return \JDatabaseQuery A database query
* @return DatabaseQuery A database query
*
* @since 2.5
*/
protected function getListQuery()
{
$user = Factory::getUser();
$groups = ArrayHelper::toInteger($user->getAuthorisedViewLevels());
$lang = Helper::getPrimaryLanguage($this->getState('language'));
// Create a new query object.
$db = $this->getDbo();
$query = $db->getQuery(true);
$lang = Helper::getPrimaryLanguage($this->getState('language'));
$termIdQuery = $db->getQuery(true);
$termQuery = $db->getQuery(true);
// Limit term count to a reasonable number of results to reduce main query join size
$termIdQuery->select('ti.term_id')
->from($db->quoteName('#__finder_terms', 'ti'))
->where('ti.term LIKE ' . $db->quote($db->escape($this->getState('input'), true) . '%', false))
->where('ti.common = 0')
->where('ti.language IN (' . $db->quote($lang) . ', ' . $db->quote('*') . ')')
->order('ti.links DESC')
->order('ti.weight DESC');
$termIds = $db->setQuery($termIdQuery, 0, 100)->loadColumn();
// Early return on term mismatch
if (!count($termIds))
{
return $termIdQuery;
}
// Select required fields
$query->select('t.term')
$termQuery->select('DISTINCT(t.term)')
->from($db->quoteName('#__finder_terms') . ' AS t')
->where('t.term LIKE ' . $db->quote($db->escape($this->getState('input'), true) . '%'))
->where('t.common = 0')
->where('t.language IN (' . $db->quote($lang) . ', ' . $db->quote('*') . ')')
->whereIn('t.term_id', $termIds)
->order('t.links DESC')
->order('t.weight DESC');
return $query;
// Determine the relevant mapping table suffix by inverting the logic from drivers
$mappingTableSuffix = substr(md5(substr($this->getState('input'), 0, 1)), 0, 1);
// Join mapping table for term <-> link relation
$mappingTable = $db->quoteName('#__finder_links_terms' . $mappingTableSuffix);
$termQuery->join('INNER', $mappingTable . ' AS tm ON tm.term_id = t.term_id');
// Join links table
$termQuery->join('INNER', $db->quoteName('#__finder_links') . ' AS l ON (tm.link_id = l.link_id)')
->where('l.access IN (' . implode(',', $groups) . ')')
->where('l.state = 1')
->where('l.published = 1');
return $termQuery;
}
/**

View File

@ -13,7 +13,8 @@
"platform": {
"php": "7.2.5"
},
"vendor-dir": "libraries/vendor"
"vendor-dir": "libraries/vendor",
"github-protocols": ["https"]
},
"support": {
"issues": "https://issues.joomla.org",

View File

@ -231,10 +231,12 @@ JLIB_FORM_FIELD_INVALID="Invalid field:&#160;"
JLIB_FORM_VALIDATE_FIELD_INVALID="Invalid field: %s"
JLIB_FORM_VALIDATE_FIELD_REQUIRED="Field required: %s"
JLIB_INSTALLER_ABORT="Aborting language installation: %s"
JLIB_INSTALLER_ABORT_NOINSTALLPATH="Install path does not exist."
JLIB_INSTALLER_ABORT_PACK_INSTALL_CREATE_DIRECTORY="Package Install: Failed to create folder: %s."
JLIB_INSTALLER_ABORT_PACK_INSTALL_ERROR_EXTENSION="Package %1$s: There was an error installing an extension: %2$s."
JLIB_INSTALLER_ABORT_PACK_INSTALL_NO_FILES="Package %s: There were no files to install!"
JLIB_INSTALLER_ERROR_FAIL_COPY_FILE="JInstaller: :Install: Failed to copy file %1$s to %2$s."
JLIB_INSTALLER_INSTALL="Install"
JLIB_INSTALLER_NOT_ERROR="If the error is related to the installation of TinyMCE language files it has no effect on the installation of the language(s). Some language packs created prior to Joomla 3.2.0 may try to install separate TinyMCE language files. As these are now included in the core they no longer need to be installed."
JLIB_INSTALLER_WARNING_UNABLE_TO_INSTALL_CONTENT_LANGUAGE="Unable to create a content language for %s language: %s."
JLIB_UPDATER_ERROR_OPEN_UPDATE_SITE="Update: Could not open update site #%d &quot;%s&quot;, URL: %s."

View File

@ -231,10 +231,12 @@ JLIB_FORM_FIELD_INVALID="Invalid field:&#160;"
JLIB_FORM_VALIDATE_FIELD_INVALID="Invalid field: %s"
JLIB_FORM_VALIDATE_FIELD_REQUIRED="Field required: %s"
JLIB_INSTALLER_ABORT="Aborting language installation: %s"
JLIB_INSTALLER_ABORT_NOINSTALLPATH="Install path does not exist."
JLIB_INSTALLER_ABORT_PACK_INSTALL_CREATE_DIRECTORY="Package Install: Failed to create folder: %s."
JLIB_INSTALLER_ABORT_PACK_INSTALL_ERROR_EXTENSION="Package %1$s: There was an error installing an extension: %2$s."
JLIB_INSTALLER_ABORT_PACK_INSTALL_NO_FILES="Package %s: There were no files to install!"
JLIB_INSTALLER_ERROR_FAIL_COPY_FILE="JInstaller: :Install: Failed to copy file %1$s to %2$s."
JLIB_INSTALLER_INSTALL="Install"
JLIB_INSTALLER_NOT_ERROR="If the error is related to the installation of TinyMCE language files it has no effect on the installation of the language(s). Some language packs created prior to Joomla 3.2.0 may try to install separate TinyMCE language files. As these are now included in the core they no longer need to be installed."
JLIB_INSTALLER_WARNING_UNABLE_TO_INSTALL_CONTENT_LANGUAGE="Unable to create a content language for %s language: %s."
JLIB_UPDATER_ERROR_OPEN_UPDATE_SITE="Update: Could not open update site #%d &quot;%s&quot;, URL: %s."

View File

@ -575,6 +575,7 @@ JLIB_INSTALLER_AVAILABLE_UPDATE_DB_TYPE="For the extension %1$s version %2$s is
JLIB_INSTALLER_AVAILABLE_UPDATE_PHP_VERSION="For the extension %1$s version %2$s is available, but it requires at least PHP version %3$s while your system only has %4$s"
JLIB_INSTALLER_DEFAULT_STYLE="%s - Default"
JLIB_INSTALLER_DISCOVER="Discover"
JLIB_INSTALLER_DISCOVER_INSTALL="Discover Install"
JLIB_INSTALLER_ERROR_CANNOT_UNINSTALL_CHILD_OF_PACKAGE="The %s extension is part of a package which does not allow individual extensions to be uninstalled."
JLIB_INSTALLER_ERROR_COMP_DISCOVER_STORE_DETAILS="Component Discover install: Failed to store component details."
JLIB_INSTALLER_ERROR_COMP_FAILED_TO_CREATE_DIRECTORY="Component %1$s: Failed to create folder: %2$s."

View File

@ -71,7 +71,7 @@ class AliastagField extends ListField
$options,
function ($a, $b)
{
return $a->text > $b->text;
return strcmp($a->text, $b->text);
}
);

View File

@ -1,7 +0,0 @@
/**
* @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
window.addEventListener('DOMContentLoaded', function() {
document.body.appendChild(document.getElementById('versionsModal'));
});

View File

@ -34,6 +34,7 @@
name="folder"
type="text"
label="MOD_RANDOM_IMAGE_FIELD_FOLDER_LABEL"
validate="filePath"
/>
<field

View File

@ -837,10 +837,24 @@ class PlgActionlogJoomla extends ActionLogPlugin
return;
}
$loggedInUser = User::getInstance($response['username']);
// Get the user id for the given username
$query = $this->db->getQuery(true)
->select($this->db->quoteName(array('id', 'username')))
->from($this->db->quoteName('#__users'))
->where($this->db->quoteName('username') . ' = ' . $this->db->quote($response['username']));
$this->db->setQuery($query);
try
{
$loggedInUser = $this->db->loadObject();
}
catch (JDatabaseExceptionExecuting $e)
{
return;
}
// Not a valid user, return
if (!$loggedInUser->id)
if (!isset($loggedInUser->id))
{
return;
}

View File

@ -9,10 +9,7 @@
# Disallow: /joomla/administrator/
#
# For more information about the robots.txt standard, see:
# http://www.robotstxt.org/orig.html
#
# For syntax checking, see:
# http://tool.motoricerca.info/robots-checker.phtml
# https://www.robotstxt.org/orig.html
User-agent: *
Disallow: /administrator/