Commit 4452b3a9 authored by theo lem's avatar theo lem Committed by =Theo Lem
Browse files

Added modified files after core and modules update, and static files that were...

Added modified files after core and modules update, and static files that were previously ignored (logos).

Forms cron expiration

Undoing merge, forgot something.
parent ad53d1a6
......@@ -4,3 +4,9 @@ sites/*/settings*.php
# Ignore paths that contain user-generated content.
sites/*/files
sites/*/private
# Include general-purpose static files
# !sites/default/files/Framasoft_Logo.svg__0.png
#
# !sites/default/files/imgforms/*
......@@ -3,7 +3,7 @@
#
# Protect files and directories from prying eyes.
<FilesMatch "\.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)(~|\.sw[op]|\.bak|\.orig|\.save)?$|^(\.(?!well-known).*|Entries.*|Repository|Root|Tag|Template|composer\.(json|lock))$|^#.*#$|\.php(~|\.sw[op]|\.bak|\.orig\.save)$">
<FilesMatch "\.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)(~|\.sw[op]|\.bak|\.orig|\.save)?$|^(\.(?!well-known).*|Entries.*|Repository|Root|Tag|Template|composer\.(json|lock)|web\.config)$|^#.*#$|\.php(~|\.sw[op]|\.bak|\.orig\.save)$">
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
......
Drupal 7.xx, xxxx-xx-xx (development version)
-----------------------
Drupal 7.69, 2019-12-18
-----------------------
- Fixed security issues:
- SA-CORE-2019-012
Drupal 7.68, 2019-12-04
-----------------------
- Fixed: Hide toolbar when printing
- Fixed: Settings returned via ajax are not run through hook_js_alter()
- Fixed: Use drupal_http_build_query() in drupal_http_request()
- Fixed: DrupalRequestSanitizer not found fatal error when bootstrap phase order is changed
- Fixed: Block web.config in .htaccess (and vice-versa)
- Fixed: Create "scripts" element to align rendering workflow to how "styles" are handled
- PHP 7.3: Fixed 'Cannot change session id when session is active'
- PHP 7.1: Fixed 'A non-numeric value encountered in theme_pager()'
- PHP 7.x: Fixed file.inc generated .htaccess does not cover PHP 7
- PHP 5.3: Fixed check_plain() 'Invalid multibyte sequence in argument' test failures
- Fixed: Allow passing data as array to drupal_http_request()
- Fixed: Skip module_invoke/module_hook in calling hook_watchdog (excessive function_exist)
- Fixed: HTTP status 200 returned for 'Additional uncaught exception thrown while handling exception'
- Fixed: theme_table() should take an optional footer variable and produce <tfoot>
- Fixed: 'uasort() expects parameter 1 to be array, null given in node_view_multiple()'
- [regression] Fix default.settings.php permission
Drupal 7.67, 2019-05-08
-----------------------
- Fixed security issues:
......
......@@ -11,11 +11,8 @@ The Drupal Core branch maintainers oversee the development of Drupal as a whole.
The branch maintainers for Drupal 7 are:
- Dries Buytaert 'dries' https://www.drupal.org/u/dries
- Angela Byron 'webchick' https://www.drupal.org/u/webchick
- Fabian Franz 'Fabianx' https://www.drupal.org/u/fabianx
- David Rothstein 'David_Rothstein' https://www.drupal.org/u/david_rothstein
- Stefan Ruijsenaars 'stefan.r' https://www.drupal.org/u/stefanr-0
- (provisional) Pol Dellaiera 'Pol' https://www.drupal.org/u/pol
- (provisional) Drew Webber 'mcdruid' https://www.drupal.org/u/mcdruid
Component maintainers
......
......@@ -294,6 +294,7 @@ function ajax_render($commands = array()) {
// Now add a command to merge changes and additions to Drupal.settings.
$scripts = drupal_add_js();
drupal_alter('js', $scripts);
if (!empty($scripts['settings'])) {
$settings = $scripts['settings'];
array_unshift($commands, ajax_command_settings(drupal_array_merge_deep_array($settings['data']), TRUE));
......
......@@ -8,7 +8,7 @@
/**
* The current system version.
*/
define('VERSION', '7.67');
define('VERSION', '7.69');
/**
* Core API compatibility.
......@@ -1998,7 +1998,7 @@ function watchdog($type, $message, $variables = array(), $severity = WATCHDOG_NO
// It is possible that the error handling will itself trigger an error. In that case, we could
// end up in an infinite loop. To avoid that, we implement a simple static semaphore.
if (!$in_error_state && function_exists('module_implements')) {
if (!$in_error_state && function_exists('module_invoke_all')) {
$in_error_state = TRUE;
// The user object may not exist in all conditions, so 0 is substituted if needed.
......@@ -2021,9 +2021,7 @@ function watchdog($type, $message, $variables = array(), $severity = WATCHDOG_NO
);
// Call the logging hooks to log/process the message
foreach (module_implements('watchdog') as $module) {
module_invoke($module, 'watchdog', $log_entry);
}
module_invoke_all('watchdog', $log_entry);
// It is critical that the semaphore is only cleared here, in the parent
// watchdog() call (not outside the loop), to prevent recursive execution.
......@@ -2518,6 +2516,7 @@ function drupal_bootstrap($phase = NULL, $new_phase = TRUE) {
switch ($current_phase) {
case DRUPAL_BOOTSTRAP_CONFIGURATION:
require_once DRUPAL_ROOT . '/includes/request-sanitizer.inc';
_drupal_bootstrap_configuration();
break;
......@@ -2622,6 +2621,10 @@ function _drupal_exception_handler($exception) {
_drupal_log_error(_drupal_decode_exception($exception), TRUE);
}
catch (Exception $exception2) {
// Add a 500 status code in case an exception was thrown before the 500
// status could be set (e.g. while loading a maintenance theme from cache).
drupal_add_http_header('Status', '500 Internal Server Error');
// Another uncaught exception was thrown while handling the first one.
// If we are displaying errors, then do so with no possibility of a further uncaught exception being thrown.
if (error_displayable()) {
......@@ -2647,7 +2650,6 @@ function _drupal_bootstrap_configuration() {
drupal_settings_initialize();
// Sanitize unsafe keys from the request.
require_once DRUPAL_ROOT . '/includes/request-sanitizer.inc';
DrupalRequestSanitizer::sanitize();
}
......
......@@ -760,9 +760,10 @@ function drupal_access_denied() {
* (optional) An array that can have one or more of the following elements:
* - headers: An array containing request headers to send as name/value pairs.
* - method: A string containing the request method. Defaults to 'GET'.
* - data: A string containing the request body, formatted as
* 'param=value&param=value&...'; to generate this, use http_build_query().
* Defaults to NULL.
* - data: An array containing the values for the request body or a string
* containing the request body, formatted as
* 'param=value&param=value&...'; to generate this, use
* drupal_http_build_query(). Defaults to NULL.
* - max_redirects: An integer representing how many times a redirect
* may be followed. Defaults to 3.
* - timeout: A float representing the maximum number of seconds the function
......@@ -788,7 +789,7 @@ function drupal_access_denied() {
* easy access the array keys are returned in lower case.
* - data: A string containing the response body that was received.
*
* @see http_build_query()
* @see drupal_http_build_query()
*/
function drupal_http_request($url, array $options = array()) {
// Allow an alternate HTTP client library to replace Drupal's default
......@@ -930,6 +931,11 @@ function drupal_http_request($url, array $options = array()) {
$path .= '?' . $uri['query'];
}
// Convert array $options['data'] to query string.
if (is_array($options['data'])) {
$options['data'] = drupal_http_build_query($options['data']);
}
// Only add Content-Length if we actually have any content or if it is a POST
// or PUT request. Some non-standard servers get confused by Content-Length in
// at least HEAD/GET requests, and Squid always requires Content-Length in
......@@ -4441,12 +4447,54 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
}
}
$output = '';
// The index counter is used to keep aggregated and non-aggregated files in
// order by weight.
$index = 1;
$processed = array();
$files = array();
// Sort the JavaScript so that it appears in the correct order.
uasort($items, 'drupal_sort_css_js');
// Provide the page with information about the individual JavaScript files
// used, information not otherwise available when aggregation is enabled.
$setting['ajaxPageState']['js'] = array_fill_keys(array_keys($items), 1);
unset($setting['ajaxPageState']['js']['settings']);
drupal_add_js($setting, 'setting');
// If we're outputting the header scope, then this might be the final time
// that drupal_get_js() is running, so add the setting to this output as well
// as to the drupal_add_js() cache. If $items['settings'] doesn't exist, it's
// because drupal_get_js() was intentionally passed a $javascript argument
// stripped off settings, potentially in order to override how settings get
// output, so in this case, do not add the setting to this output.
if ($scope == 'header' && isset($items['settings'])) {
$items['settings']['data'][] = $setting;
}
$elements = array(
'#type' => 'scripts',
'#items' => $items,
);
return drupal_render($elements);
}
/**
* The #pre_render callback for the "scripts" element.
*
* This callback adds elements needed for <script> tags to be rendered.
*
* @param array $elements
* A render array containing:
* - '#items': The JS items as returned by drupal_add_js() and altered by
* drupal_get_js().
*
* @return array
* The $elements variable passed as argument with two more children keys:
* - "scripts": contains the Javascript items
* - "settings": contains the Javascript settings items.
* If those keys are already existing, then the items will be appended and
* their keys will be preserved.
*
* @see drupal_get_js()
* @see drupal_add_js()
*/
function drupal_pre_render_scripts(array $elements) {
$preprocess_js = (variable_get('preprocess_js', FALSE) && (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update'));
// A dummy query-string is added to filenames, to gain control over
......@@ -4467,34 +4515,29 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
// third-party code might require the use of a different query string.
$js_version_string = variable_get('drupal_js_version_query_string', 'v=');
// Sort the JavaScript so that it appears in the correct order.
uasort($items, 'drupal_sort_css_js');
$files = array();
// Provide the page with information about the individual JavaScript files
// used, information not otherwise available when aggregation is enabled.
$setting['ajaxPageState']['js'] = array_fill_keys(array_keys($items), 1);
unset($setting['ajaxPageState']['js']['settings']);
drupal_add_js($setting, 'setting');
$scripts = isset($elements['scripts']) ? $elements['scripts'] : array();
$scripts += array('#weight' => 0);
// If we're outputting the header scope, then this might be the final time
// that drupal_get_js() is running, so add the setting to this output as well
// as to the drupal_add_js() cache. If $items['settings'] doesn't exist, it's
// because drupal_get_js() was intentionally passed a $javascript argument
// stripped off settings, potentially in order to override how settings get
// output, so in this case, do not add the setting to this output.
if ($scope == 'header' && isset($items['settings'])) {
$items['settings']['data'][] = $setting;
}
$settings = isset($elements['settings']) ? $elements['settings'] : array();
$settings += array('#weight' => $scripts['#weight'] + 10);
// The index counter is used to keep aggregated and non-aggregated files in
// order by weight. Use existing scripts count as a starting point.
$index = count(element_children($scripts)) + 1;
// Loop through the JavaScript to construct the rendered output.
$element = array(
'#type' => 'html_tag',
'#tag' => 'script',
'#value' => '',
'#attributes' => array(
'type' => 'text/javascript',
),
);
foreach ($items as $item) {
foreach ($elements['#items'] as $item) {
$query_string = empty($item['version']) ? $default_query_string : $js_version_string . $item['version'];
switch ($item['type']) {
......@@ -4503,7 +4546,7 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
$js_element['#value_prefix'] = $embed_prefix;
$js_element['#value'] = 'jQuery.extend(Drupal.settings, ' . drupal_json_encode(drupal_array_merge_deep_array($item['data'])) . ");";
$js_element['#value_suffix'] = $embed_suffix;
$output .= theme('html_tag', array('element' => $js_element));
$settings[] = $js_element;
break;
case 'inline':
......@@ -4514,7 +4557,7 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
$js_element['#value_prefix'] = $embed_prefix;
$js_element['#value'] = $item['data'];
$js_element['#value_suffix'] = $embed_suffix;
$processed[$index++] = theme('html_tag', array('element' => $js_element));
$scripts[$index++] = $js_element;
break;
case 'file':
......@@ -4525,7 +4568,7 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
}
$query_string_separator = (strpos($item['data'], '?') !== FALSE) ? '&' : '?';
$js_element['#attributes']['src'] = file_create_url($item['data']) . $query_string_separator . ($item['cache'] ? $query_string : REQUEST_TIME);
$processed[$index++] = theme('html_tag', array('element' => $js_element));
$scripts[$index++] = $js_element;
}
else {
// By increasing the index for each aggregated file, we maintain
......@@ -4536,7 +4579,7 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
// leading to better front-end performance of a website as a whole.
// See drupal_add_js() for details.
$key = 'aggregate_' . $item['group'] . '_' . $item['every_page'] . '_' . $index;
$processed[$key] = '';
$scripts[$key] = '';
$files[$key][$item['data']] = $item;
}
break;
......@@ -4548,7 +4591,7 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
$js_element['#attributes']['defer'] = 'defer';
}
$js_element['#attributes']['src'] = $item['data'];
$processed[$index++] = theme('html_tag', array('element' => $js_element));
$scripts[$index++] = $js_element;
break;
}
}
......@@ -4563,14 +4606,18 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
$preprocess_file = file_create_url($uri);
$js_element = $element;
$js_element['#attributes']['src'] = $preprocess_file;
$processed[$key] = theme('html_tag', array('element' => $js_element));
$scripts[$key] = $js_element;
}
}
}
// Keep the order of JS files consistent as some are preprocessed and others are not.
// Make sure any inline or JS setting variables appear last after libraries have loaded.
return implode('', $processed) . $output;
// Keep the order of JS files consistent as some are preprocessed and others
// are not. Make sure any inline or JS setting variables appear last after
// libraries have loaded.
$element['scripts'] = $scripts;
$element['settings'] = $settings;
return $element;
}
/**
......@@ -6952,7 +6999,16 @@ function drupal_common_theme() {
'variables' => array(),
),
'table' => array(
'variables' => array('header' => NULL, 'rows' => NULL, 'attributes' => array(), 'caption' => NULL, 'colgroups' => array(), 'sticky' => TRUE, 'empty' => ''),
'variables' => array(
'header' => NULL,
'footer' => NULL,
'rows' => NULL,
'attributes' => array(),
'caption' => NULL,
'colgroups' => array(),
'sticky' => TRUE,
'empty' => '',
),
),
'tablesort_indicator' => array(
'variables' => array('style' => NULL),
......
......@@ -532,6 +532,9 @@ SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
<IfModule mod_php5.c>
php_flag engine off
</IfModule>
<IfModule mod_php7.c>
php_flag engine off
</IfModule>
EOF;
if ($private) {
......
<?php
use Drupal\Core\Security\PharExtensionInterceptor;
use TYPO3\PharStreamWrapper\Manager as PharStreamWrapperManager;
use TYPO3\PharStreamWrapper\Behavior as PharStreamWrapperBehavior;
use TYPO3\PharStreamWrapper\PharStreamWrapper;
/**
* Registers a phar stream wrapper that is more secure than PHP's built-in one.
*
* @see file_get_stream_wrappers()
*/
function file_register_phar_wrapper() {
$directory = DRUPAL_ROOT . '/misc/typo3/phar-stream-wrapper/src';
include_once $directory . '/Assertable.php';
include_once $directory . '/Behavior.php';
include_once $directory . '/Exception.php';
include_once $directory . '/Helper.php';
include_once $directory . '/Manager.php';
include_once $directory . '/PharStreamWrapper.php';
include_once $directory . '/Collectable.php';
include_once $directory . '/Interceptor/ConjunctionInterceptor.php';
include_once $directory . '/Interceptor/PharMetaDataInterceptor.php';
include_once $directory . '/Phar/Container.php';
include_once $directory . '/Phar/DeserializationException.php';
include_once $directory . '/Phar/Manifest.php';
include_once $directory . '/Phar/Reader.php';
include_once $directory . '/Phar/ReaderException.php';
include_once $directory . '/Phar/Stub.php';
include_once $directory . '/Resolvable.php';
include_once $directory . '/Resolver/PharInvocation.php';
include_once $directory . '/Resolver/PharInvocationCollection.php';
include_once $directory . '/Resolver/PharInvocationResolver.php';
include_once DRUPAL_ROOT . '/misc/typo3/drupal-security/PharExtensionInterceptor.php';
include_once DRUPAL_ROOT . '/misc/brumann/polyfill-unserialize/src/Unserialize.php';
// Set up a stream wrapper to handle insecurities due to PHP's built-in
// phar stream wrapper.
try {
$behavior = new PharStreamWrapperBehavior();
PharStreamWrapperManager::initialize(
$behavior->withAssertion(new PharExtensionInterceptor())
);
}
catch (\LogicException $e) {
// Continue if the PharStreamWrapperManager is already initialized.
// For example, this occurs following a drupal_static_reset(), such
// as during tests.
};
// To prevent file_stream_wrapper_valid_scheme() treating "phar" as a valid
// scheme, this is registered with PHP only, not with hook_stream_wrappers()
// or the internal storage of file_get_stream_wrappers().
stream_wrapper_register('phar', '\\TYPO3\\PharStreamWrapper\\PharStreamWrapper');
}
......@@ -321,7 +321,7 @@ function theme_pager($variables) {
$tags = $variables['tags'];
$element = $variables['element'];
$parameters = $variables['parameters'];
$quantity = $variables['quantity'];
$quantity = empty($variables['quantity']) ? 0 : $variables['quantity'];
global $pager_page_array, $pager_total;
// Calculate various markers within this pager piece:
......
......@@ -371,8 +371,11 @@ function drupal_session_regenerate() {
if (drupal_session_started()) {
$old_session_id = session_id();
_drupal_session_regenerate_existing();
}
else {
session_id(drupal_random_key());
}
session_id(drupal_random_key());
if (isset($old_session_id)) {
$params = session_get_cookie_params();
......@@ -412,6 +415,26 @@ function drupal_session_regenerate() {
date_default_timezone_set(drupal_get_user_timezone());
}
/**
* Regenerates an existing session.
*/
function _drupal_session_regenerate_existing() {
global $user;
// Preserve existing settings for the saving of sessions.
$original_save_session_status = drupal_save_session();
// Turn off saving of sessions.
drupal_save_session(FALSE);
session_write_close();
drupal_session_started(FALSE);
// Preserve the user object, as starting a new session will reset it.
$original_user = $user;
session_id(drupal_random_key());
drupal_session_start();
$user = $original_user;
// Restore the original settings for the saving of sessions.
drupal_save_session($original_save_session_status);
}
/**
* Session handler assigned by session_set_save_handler().
*
......
......@@ -1911,7 +1911,7 @@ function theme_breadcrumb($variables) {
/**
* Returns HTML for a table.
*
* @param $variables
* @param array $variables
* An associative array containing:
* - header: An array containing the table headers. Each element of the array
* can be either a localized string or an associative array with the
......@@ -1948,6 +1948,11 @@ function theme_breadcrumb($variables) {
* )
* );
* @endcode
* - footer: An array of table rows which will be printed within a <tfoot>
* tag, in the same format as the rows element (see above).
* The structure is the same the one defined for the "rows" key except
* that the no_striping boolean has no effect, there is no rows striping
* for the table footer.
* - attributes: An array of HTML attributes to apply to the table tag.
* - caption: A localized string to use for the <caption> tag.
* - colgroups: An array of column groups. Each element of the array can be
......@@ -1984,8 +1989,11 @@ function theme_breadcrumb($variables) {
* - sticky: Use a "sticky" table header.
* - empty: The message to display in an extra row if table does not have any
* rows.
*
* @return string
* The HTML output.
*/
function theme_table($variables) {
function theme_table(array $variables) {
$header = $variables['header'];
$rows = $variables['rows'];
$attributes = $variables['attributes'];
......@@ -2049,17 +2057,27 @@ function theme_table($variables) {
if (!empty($header)) {
foreach ($header as $header_cell) {
if (is_array($header_cell)) {
$header_count += isset($header_cell['colspan']) ? $header_cell['colspan'] : 1;
$header_count += isset($header_cell['colspan']) ?
$header_cell['colspan'] : 1;
}
else {
$header_count++;
}
}
}
$rows[] = array(array('data' => $empty, 'colspan' => $header_count, 'class' => array('empty', 'message')));
$rows[] = array(
array(
'data' => $empty,
'colspan' => $header_count,
'class' => array(
'empty',
'message'
),
),
);
}
// Format the table header:
// Format the table header.
if (!empty($header)) {
$ts = tablesort_init($header);
// HTML requires that the thead tag has tr tags in it followed by tbody
......@@ -2069,23 +2087,39 @@ function theme_table($variables) {
$cell = tablesort_header($cell, $header, $ts);
$output .= _theme_table_cell($cell, TRUE);
}
// Using ternary operator to close the tags based on whether or not there are rows
// Using ternary operator to close the tags based on whether
// or not there are rows.
$output .= (!empty($rows) ? " </tr></thead>\n" : "</tr>\n");
}
else {
$ts = array();
}
// Format the table rows:
// Format the table and footer rows.
$sections = array();
if (!empty($rows)) {
$output .= "<tbody>\n";
$sections['tbody'] = $rows;
}
if (!empty($variables['footer'])) {
$sections['tfoot'] = $variables['footer'];
}
// tbody and tfoot have the same structure and are built using the same
// procedure.
foreach ($sections as $tag => $content) {
$output .= "<" . $tag . ">\n";
$flip = array('even' => 'odd', 'odd' => 'even');
$class = 'even';
foreach ($rows as $number => $row) {
// Check if we're dealing with a simple or complex row
$default_no_striping = ($tag === 'tfoot');
foreach ($content as $number => $row) {
// Check if we're dealing with a simple or complex row.
if (isset($row['data'])) {
$cells = $row['data'];
$no_striping = isset($row['no_striping']) ? $row['no_striping'] : FALSE;
$no_striping = isset($row['no_striping']) ?
$row['no_striping'] : $default_no_striping;
// Set the attributes array and exclude 'data' and 'no_striping'.
$attributes = $row;
......@@ -2095,16 +2129,17 @@ function theme_table($variables) {
else {
$cells = $row;
$attributes = array();
$no_striping = FALSE;
$no_striping = $default_no_striping;
}
if (!empty($cells)) {
// Add odd/even class
// Add odd/even class.
if (!$no_striping) {
$class = $flip[$class];
$attributes['class'][] = $class;
}
// Build row
// Build row.
$output .= ' <tr' . drupal_attributes($attributes) . '>';
$i = 0;
foreach ($cells as $cell) {
......@@ -2114,10 +2149,12 @@ function theme_table($variables) {
$output .= " </tr>\n";
}
}
$output .= "</tbody>\n";
$output .= "</" . $tag . ">\n";
}
$output .= "</table>\n";
return $output;
}
......
/vendor/
/phpunit.xml
/.composer.lock