Skip to content

Commit 2fa767c

Browse files
authored
Merge pull request #352 from ASU/7.x-dev
Webspark 1.64 (California)
2 parents c1ef9d1 + 94912be commit 2fa767c

File tree

180 files changed

+3248
-1355
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

180 files changed

+3248
-1355
lines changed

CHANGELOG.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
Drupal 7.xx, xxxx-xx-xx (development version)
2+
-----------------------
3+
4+
Drupal 7.65, 2019-03-20
5+
-----------------------
6+
- Fixed security issues:
7+
- SA-CORE-2019-004
8+
9+
Drupal 7.64, 2019-02-06
10+
-----------------------
11+
- [regression] Unset the 'host' header in drupal_http_request() during redirect
12+
- Fixed: 7.x does not have Phar protection and Phar tests are failing on Drupal 7
13+
- Fixed: Notice: Undefined index: display_field in file_field_widget_value() (line 582 of /module/file/file.field.inc)
14+
- Performance improvement: Registry rebuild should not parse the same file twice in the same request
15+
- Fixed _registry_update() to clear caches after transaction is committed
16+
117
Drupal 7.63, 2019-01-16
218
-----------------------
319
- Fixed a fatal error for some Drush users introduced by SA-CORE-2019-002.

includes/bootstrap.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
/**
99
* The current system version.
1010
*/
11-
define('VERSION', '7.63');
11+
define('VERSION', '7.65');
1212

1313
/**
1414
* Core API compatibility.

includes/common.inc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,6 +1094,11 @@ function drupal_http_request($url, array $options = array()) {
10941094
elseif ($options['max_redirects']) {
10951095
// Redirect to the new location.
10961096
$options['max_redirects']--;
1097+
1098+
// We need to unset the 'Host' header
1099+
// as we are redirecting to a new location.
1100+
unset($options['headers']['Host']);
1101+
10971102
$result = drupal_http_request($location, $options);
10981103
$result->redirect_code = $code;
10991104
}

includes/file.inc

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -997,16 +997,22 @@ function file_build_uri($path) {
997997
* @return
998998
* The destination filepath, or FALSE if the file already exists
999999
* and FILE_EXISTS_ERROR is specified.
1000+
*
1001+
* @throws RuntimeException
1002+
* Thrown if the filename contains invalid UTF-8.
10001003
*/
10011004
function file_destination($destination, $replace) {
1005+
$basename = drupal_basename($destination);
1006+
if (!drupal_validate_utf8($basename)) {
1007+
throw new RuntimeException(sprintf("Invalid filename '%s'", $basename));
1008+
}
10021009
if (file_exists($destination)) {
10031010
switch ($replace) {
10041011
case FILE_EXISTS_REPLACE:
10051012
// Do nothing here, we want to overwrite the existing file.
10061013
break;
10071014

10081015
case FILE_EXISTS_RENAME:
1009-
$basename = drupal_basename($destination);
10101016
$directory = drupal_dirname($destination);
10111017
$destination = file_create_filename($basename, $directory);
10121018
break;
@@ -1222,11 +1228,20 @@ function file_unmunge_filename($filename) {
12221228
* @return
12231229
* File path consisting of $directory and a unique filename based off
12241230
* of $basename.
1231+
*
1232+
* @throws RuntimeException
1233+
* Thrown if the $basename is not valid UTF-8 or another error occurs
1234+
* stripping control characters.
12251235
*/
12261236
function file_create_filename($basename, $directory) {
1237+
$original = $basename;
12271238
// Strip control characters (ASCII value < 32). Though these are allowed in
12281239
// some filesystems, not many applications handle them well.
12291240
$basename = preg_replace('/[\x00-\x1F]/u', '_', $basename);
1241+
if (preg_last_error() !== PREG_NO_ERROR) {
1242+
throw new RuntimeException(sprintf("Invalid filename '%s'", $original));
1243+
}
1244+
12301245
if (substr(PHP_OS, 0, 3) == 'WIN') {
12311246
// These characters are not allowed in Windows filenames
12321247
$basename = str_replace(array(':', '*', '?', '"', '<', '>', '|'), '_', $basename);
@@ -1567,7 +1582,13 @@ function file_save_upload($form_field_name, $validators = array(), $destination
15671582
if (substr($destination, -1) != '/') {
15681583
$destination .= '/';
15691584
}
1570-
$file->destination = file_destination($destination . $file->filename, $replace);
1585+
try {
1586+
$file->destination = file_destination($destination . $file->filename, $replace);
1587+
}
1588+
catch (RuntimeException $e) {
1589+
drupal_set_message(t('The file %source could not be uploaded because the name is invalid.', array('%source' => $form_field_name)), 'error');
1590+
return FALSE;
1591+
}
15711592
// If file_destination() returns FALSE then $replace == FILE_EXISTS_ERROR and
15721593
// there's an existing file so we need to bail.
15731594
if ($file->destination === FALSE) {
@@ -2134,9 +2155,33 @@ function file_download_access($uri) {
21342155
* 'filename', and 'name' members corresponding to the matching files.
21352156
*/
21362157
function file_scan_directory($dir, $mask, $options = array(), $depth = 0) {
2158+
// Default nomask option.
2159+
$nomask = '/(\.\.?|CVS)$/';
2160+
2161+
// Overrides the $nomask variable accordingly if $options['nomask'] is set.
2162+
//
2163+
// Allow directories specified in settings.php to be ignored. You can use this
2164+
// to not check for files in common special-purpose directories. For example,
2165+
// node_modules and bower_components. Ignoring irrelevant directories is a
2166+
// performance boost.
2167+
if (!isset($options['nomask'])) {
2168+
$ignore_directories = variable_get(
2169+
'file_scan_ignore_directories',
2170+
array()
2171+
);
2172+
2173+
foreach ($ignore_directories as $index => $ignore_directory) {
2174+
$ignore_directories[$index] = preg_quote($ignore_directory, '/');
2175+
}
2176+
2177+
if (!empty($ignore_directories)) {
2178+
$nomask = '/^(\.\.?)|CVS|' . implode('|', $ignore_directories) . '$/';
2179+
}
2180+
}
2181+
21372182
// Merge in defaults.
21382183
$options += array(
2139-
'nomask' => '/(\.\.?|CVS)$/',
2184+
'nomask' => $nomask,
21402185
'callback' => 0,
21412186
'recurse' => TRUE,
21422187
'key' => 'uri',

includes/registry.inc

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
* Does the work for registry_update().
2020
*/
2121
function _registry_update() {
22-
2322
// The registry serves as a central autoloader for all classes, including
2423
// the database query builders. However, the registry rebuild process
2524
// requires write ability to the database, which means having access to the
@@ -33,6 +32,11 @@ function _registry_update() {
3332
require_once DRUPAL_ROOT . '/includes/database/select.inc';
3433
require_once DRUPAL_ROOT . '/includes/database/' . $driver . '/query.inc';
3534

35+
// During the first registry rebuild in a request, we check all the files.
36+
// During subsequent rebuilds, we only add new files. It makes the rebuilding
37+
// process faster during installation of modules.
38+
static $check_existing_files = TRUE;
39+
3640
// Get current list of modules and their files.
3741
$modules = db_query("SELECT * FROM {system} WHERE type = 'module'")->fetchAll();
3842
// Get the list of files we are going to parse.
@@ -55,6 +59,9 @@ function _registry_update() {
5559
$files["$filename"] = array('module' => '', 'weight' => 0);
5660
}
5761

62+
// Initialize an empty array for the unchanged files.
63+
$unchanged_files = array();
64+
5865
$transaction = db_transaction();
5966
try {
6067
// Allow modules to manually modify the list of files before the registry
@@ -63,10 +70,19 @@ function _registry_update() {
6370
// list can then be added to the list of files that the registry will parse,
6471
// or modify attributes of a file.
6572
drupal_alter('registry_files', $files, $modules);
73+
6674
foreach (registry_get_parsed_files() as $filename => $file) {
6775
// Add the hash for those files we have already parsed.
6876
if (isset($files[$filename])) {
69-
$files[$filename]['hash'] = $file['hash'];
77+
if ($check_existing_files === TRUE) {
78+
$files[$filename]['hash'] = $file['hash'];
79+
}
80+
else {
81+
// Ignore that file for this request, it has been parsed previously
82+
// and it is unlikely it has changed.
83+
unset($files[$filename]);
84+
$unchanged_files[$filename] = $file;
85+
}
7086
}
7187
else {
7288
// Flush the registry of resources in files that are no longer on disc
@@ -79,8 +95,12 @@ function _registry_update() {
7995
->execute();
8096
}
8197
}
98+
8299
$parsed_files = _registry_parse_files($files);
83100

101+
// Add unchanged files to the files.
102+
$files += $unchanged_files;
103+
84104
$unchanged_resources = array();
85105
$lookup_cache = array();
86106
if ($cache = cache_get('lookup_cache', 'cache_bootstrap')) {
@@ -89,19 +109,24 @@ function _registry_update() {
89109
foreach ($lookup_cache as $key => $file) {
90110
// If the file for this cached resource is carried over unchanged from
91111
// the last registry build, then we can safely re-cache it.
92-
if ($file && in_array($file, array_keys($files)) && !in_array($file, $parsed_files)) {
112+
if ($file && isset($files[$file]) && !in_array($file, $parsed_files, TRUE)) {
93113
$unchanged_resources[$key] = $file;
94114
}
95115
}
96-
module_implements('', FALSE, TRUE);
97-
_registry_check_code(REGISTRY_RESET_LOOKUP_CACHE);
98116
}
99117
catch (Exception $e) {
100118
$transaction->rollback();
101119
watchdog_exception('registry', $e);
102120
throw $e;
103121
}
104122

123+
module_implements('', FALSE, TRUE);
124+
_registry_check_code(REGISTRY_RESET_LOOKUP_CACHE);
125+
126+
// During the next run in this request, don't bother re-checking existing
127+
// files.
128+
$check_existing_files = FALSE;
129+
105130
// We have some unchanged resources, warm up the cache - no need to pay
106131
// for looking them up again.
107132
if (count($unchanged_resources) > 0) {

modules/field/modules/number/number.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class NumberFieldTestCase extends DrupalWebTestCase {
6969
preg_match('|test-entity/manage/(\d+)/edit|', $this->url, $match);
7070
$id = $match[1];
7171
$this->assertRaw(t('test_entity @id has been created.', array('@id' => $id)), 'Entity was created');
72-
$this->assertRaw(round($value, 2), 'Value is displayed.');
72+
$this->assertRaw($value, 'Value is displayed.');
7373

7474
// Try to create entries with more than one decimal separator; assert fail.
7575
$wrong_entries = array(

modules/file/file.field.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ function file_field_widget_value($element, $input = FALSE, $form_state) {
599599
// If the display field is present make sure its unchecked value is saved.
600600
$field = field_widget_field($element, $form_state);
601601
if (empty($input['display'])) {
602-
$input['display'] = $field['settings']['display_field'] ? 0 : 1;
602+
$input['display'] = !empty($field['settings']['display_field']) ? 0 : 1;
603603
}
604604
}
605605

modules/file/tests/file.test

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1875,3 +1875,60 @@ class FileFieldAnonymousSubmission extends FileFieldTestCase {
18751875
}
18761876

18771877
}
1878+
1879+
/**
1880+
* Tests the file_scan_directory() function.
1881+
*/
1882+
class FileScanDirectory extends FileFieldTestCase {
1883+
1884+
/**
1885+
* @var string
1886+
*/
1887+
protected $path;
1888+
1889+
/**
1890+
* {@inheritdoc}
1891+
*/
1892+
public static function getInfo() {
1893+
return array(
1894+
'name' => 'File ScanDirectory',
1895+
'description' => 'Tests the file_scan_directory() function.',
1896+
'group' => 'File',
1897+
);
1898+
}
1899+
1900+
/**
1901+
* {@inheritdoc}
1902+
*/
1903+
function setUp() {
1904+
parent::setUp();
1905+
1906+
$this->path = 'modules/file/tests/fixtures/file_scan_ignore';
1907+
}
1908+
1909+
/**
1910+
* Tests file_scan_directory() obeys 'file_scan_ignore_directories' setting.
1911+
* If nomask is not passed as argument, it should use the default settings.
1912+
* If nomask is passed as argument, it should obey this rule.
1913+
*/
1914+
public function testNoMask() {
1915+
$files = file_scan_directory($this->path, '/\.txt$/');
1916+
$this->assertEqual(3, count($files), '3 text files found when not ignoring directories.');
1917+
1918+
global $conf;
1919+
$conf['file_scan_ignore_directories'] = array('frontend_framework');
1920+
1921+
$files = file_scan_directory($this->path, '/\.txt$/');
1922+
$this->assertEqual(1, count($files), '1 text files found when ignoring directories called "frontend_framework".');
1923+
1924+
// Make that directories specified by default still work when a new nomask is provided.
1925+
$files = file_scan_directory($this->path, '/\.txt$/', array('nomask' => '/^c.txt/'));
1926+
$this->assertEqual(2, count($files), '2 text files found when an "nomask" option is passed in.');
1927+
1928+
// Ensure that the directories in file_scan_ignore_directories are escaped using preg_quote.
1929+
$conf['file_scan_ignore_directories'] = array('frontend.*');
1930+
$files = file_scan_directory($this->path, '/\.txt$/');
1931+
$this->assertEqual(3, count($files), '2 text files found when ignoring a directory that is not there.');
1932+
}
1933+
1934+
}

modules/file/tests/fixtures/file_scan_ignore/a.txt

Whitespace-only changes.

modules/file/tests/fixtures/file_scan_ignore/frontend_framework/b.txt

Whitespace-only changes.

0 commit comments

Comments
 (0)