Commit 98fbeaf3 authored by Dave Reid's avatar Dave Reid
Browse files

Fixing merge with 8.x upstream.

parent 6340061b
......@@ -16,6 +16,8 @@ Drupal 8.0, xxxx-xx-xx (development version)
* Profile
* Trigger
- Removed the Garland theme from core.
- Removed backwards-compatibility with 'magic_quotes_gpc'/'magic_quotes_runtime'
PHP configuration settings. Both are required to be disabled.
- Universally Unique IDentifier (UUID):
* Support for generating and validating UUIDs.
- JavaScript changes:
......
......@@ -232,6 +232,22 @@
*/
const LANGUAGE_RTL = 1;
/**
* Indicates an error during check for PHP unicode support.
*/
const UNICODE_ERROR = -1;
/**
* Indicates that standard PHP (emulated) unicode support is being used.
*/
const UNICODE_SINGLEBYTE = 0;
/**
* Indicates that full unicode support with the PHP mbstring extension is being
* used.
*/
const UNICODE_MULTIBYTE = 1;
/**
* Time of the current request in seconds elapsed since the Unix Epoch.
*
......@@ -562,8 +578,13 @@ function drupal_environment_initialize() {
// sites/default/default.settings.php contains more runtime settings.
// The .htaccess file contains settings that cannot be changed at runtime.
// Don't escape quotes when reading files from the database, disk, etc.
ini_set('magic_quotes_runtime', '0');
// Deny execution with enabled "magic quotes" (both GPC and runtime).
if (get_magic_quotes_gpc() || get_magic_quotes_runtime()) {
header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error');
print "PHP's 'magic_quotes_gpc' and 'magic_quotes_runtime' settings are not supported and must be disabled.";
exit;
}
// Use session cookies, not transparent sessions that puts the session id in
// the query string.
ini_set('session.use_cookies', '1');
......@@ -578,6 +599,9 @@ function drupal_environment_initialize() {
// Set sane locale settings, to ensure consistent string, dates, times and
// numbers handling.
setlocale(LC_ALL, 'C');
// Detect string handling method.
unicode_check();
}
/**
......@@ -590,6 +614,51 @@ function drupal_valid_http_host($host) {
return preg_match('/^\[?(?:[a-zA-Z0-9-:\]_]+\.?)+$/', $host);
}
/**
* Checks for Unicode support in PHP and sets the proper settings if possible.
*
* Because Drupal needs to be able to handle text in various encodings, we do
* not support mbstring function overloading. HTTP input/output conversion must
* be disabled for similar reasons.
*
* @return string
* A string identifier of a failed multibyte extension check, if any.
* Otherwise, an empty string.
*/
function unicode_check() {
global $multibyte;
// Check for mbstring extension.
if (!function_exists('mb_strlen')) {
$multibyte = UNICODE_SINGLEBYTE;
return 'mb_strlen';
}
// Check mbstring configuration.
if (ini_get('mbstring.func_overload') != 0) {
$multibyte = UNICODE_ERROR;
return 'mbstring.func_overload';
}
if (ini_get('mbstring.encoding_translation') != 0) {
$multibyte = UNICODE_ERROR;
return 'mbstring.encoding_translation';
}
if (ini_get('mbstring.http_input') != 'pass') {
$multibyte = UNICODE_ERROR;
return 'mbstring.http_input';
}
if (ini_get('mbstring.http_output') != 'pass') {
$multibyte = UNICODE_ERROR;
return 'mbstring.http_output';
}
// Set appropriate configuration.
mb_internal_encoding('utf-8');
mb_language('uni');
$multibyte = UNICODE_MULTIBYTE;
return '';
}
/**
* Sets the base URL, cookie domain, and session name from configuration.
*/
......
......@@ -1025,67 +1025,6 @@ function drupal_http_request($url, array $options = array()) {
* @} End of "defgroup http_handling".
*/
/**
* Strips slashes from a string or array of strings.
*
* Callback for array_walk() within fix_gpx_magic().
*
* @param $item
* An individual string or array of strings from superglobals.
*/
function _fix_gpc_magic(&$item) {
if (is_array($item)) {
array_walk($item, '_fix_gpc_magic');
}
else {
$item = stripslashes($item);
}
}
/**
* Strips slashes from $_FILES items.
*
* Callback for array_walk() within fix_gpc_magic().
*
* The tmp_name key is skipped keys since PHP generates single backslashes for
* file paths on Windows systems.
*
* @param $item
* An item from $_FILES.
* @param $key
* The key for the item within $_FILES.
*
* @see http://php.net/manual/features.file-upload.php#42280
*/
function _fix_gpc_magic_files(&$item, $key) {
if ($key != 'tmp_name') {
if (is_array($item)) {
array_walk($item, '_fix_gpc_magic_files');
}
else {
$item = stripslashes($item);
}
}
}
/**
* Fixes double-escaping caused by "magic quotes" in some PHP installations.
*
* @see _fix_gpc_magic()
* @see _fix_gpc_magic_files()
*/
function fix_gpc_magic() {
static $fixed = FALSE;
if (!$fixed && ini_get('magic_quotes_gpc')) {
array_walk($_GET, '_fix_gpc_magic');
array_walk($_POST, '_fix_gpc_magic');
array_walk($_COOKIE, '_fix_gpc_magic');
array_walk($_REQUEST, '_fix_gpc_magic');
array_walk($_FILES, '_fix_gpc_magic_files');
}
$fixed = TRUE;
}
/**
* @defgroup validation Input validation
* @{
......@@ -5180,13 +5119,7 @@ function _drupal_bootstrap_code() {
require_once DRUPAL_ROOT . '/core/includes/errors.inc';
require_once DRUPAL_ROOT . '/core/includes/schema.inc';
// @todo Move this to earlier in bootstrap: http://drupal.org/node/1569456.
unicode_check();
// @todo Remove this: http://drupal.org/node/1569456.
fix_gpc_magic();
// Load all enabled modules.
// Load all enabled modules
module_load_all();
// Make sure all stream wrappers are registered.
......
......@@ -29,6 +29,11 @@ function _registry_update() {
$connection_info = Database::getConnectionInfo();
$driver = $connection_info['default']['driver'];
// During the first registry rebuild in a request, we check all the files.
// During subsequent rebuilds, we only add new files. It makes the rebuilding
// process faster during installation of modules.
static $check_existing_files = TRUE;
// Get current list of modules and their files.
$modules = db_query("SELECT * FROM {system} WHERE type = 'module'")->fetchAll();
// Get the list of files we are going to parse.
......@@ -59,7 +64,14 @@ function _registry_update() {
foreach (registry_get_parsed_files() as $filename => $file) {
// Add the hash for those files we have already parsed.
if (isset($files[$filename])) {
$files[$filename]['hash'] = $file['hash'];
if ($check_existing_files) {
$files[$filename]['hash'] = $file['hash'];
}
else {
// Ignore that file for this request, it has been parsed previously
// and it is unlikely it has changed.
unset($files[$filename]);
}
}
else {
// Flush the registry of resources in files that are no longer on disc
......@@ -95,6 +107,10 @@ function _registry_update() {
throw $e;
}
// During the next run in this request, don't bother re-checking existing
// files.
$check_existing_files = FALSE;
// We have some unchanged resources, warm up the cache - no need to pay
// for looking them up again.
if (count($unchanged_resources) > 0) {
......
<?php
/**
* Indicates an error during check for PHP unicode support.
*/
const UNICODE_ERROR = -1;
/**
* Indicates that standard PHP (emulated) unicode support is being used.
*/
const UNICODE_SINGLEBYTE = 0;
/**
* Indicates that full unicode support with the PHP mbstring extension is being
* used.
*/
const UNICODE_MULTIBYTE = 1;
/**
* Matches Unicode characters that are word boundaries.
*
......@@ -77,53 +61,6 @@
'\x{FE10}-\x{FE19}\x{FE30}-\x{FE6B}\x{FEFF}-\x{FF0F}\x{FF1A}-\x{FF20}' .
'\x{FF3B}-\x{FF40}\x{FF5B}-\x{FF65}\x{FFE0}-\x{FFFD}');
/**
* Wrapper around _unicode_check().
*/
function unicode_check() {
list($GLOBALS['multibyte']) = _unicode_check();
}
/**
* Perform checks about Unicode support in PHP, and set the right settings if
* needed.
*
* Because Drupal needs to be able to handle text in various encodings, we do
* not support mbstring function overloading. HTTP input/output conversion must
* be disabled for similar reasons.
*
* @param $errors
* Whether to report any fatal errors with form_set_error().
*/
function _unicode_check() {
// Ensure translations don't break at install time
$t = get_t();
// Check for mbstring extension
if (!function_exists('mb_strlen')) {
return array(UNICODE_SINGLEBYTE, $t('Operations on Unicode strings are emulated on a best-effort basis. Install the <a href="@url">PHP mbstring extension</a> for improved Unicode support.', array('@url' => 'http://www.php.net/mbstring')));
}
// Check mbstring configuration
if (ini_get('mbstring.func_overload') != 0) {
return array(UNICODE_ERROR, $t('Multibyte string function overloading in PHP is active and must be disabled. Check the php.ini <em>mbstring.func_overload</em> setting. Please refer to the <a href="@url">PHP mbstring documentation</a> for more information.', array('@url' => 'http://www.php.net/mbstring')));
}
if (ini_get('mbstring.encoding_translation') != 0) {
return array(UNICODE_ERROR, $t('Multibyte string input conversion in PHP is active and must be disabled. Check the php.ini <em>mbstring.encoding_translation</em> setting. Please refer to the <a href="@url">PHP mbstring documentation</a> for more information.', array('@url' => 'http://www.php.net/mbstring')));
}
if (ini_get('mbstring.http_input') != 'pass') {
return array(UNICODE_ERROR, $t('Multibyte string input conversion in PHP is active and must be disabled. Check the php.ini <em>mbstring.http_input</em> setting. Please refer to the <a href="@url">PHP mbstring documentation</a> for more information.', array('@url' => 'http://www.php.net/mbstring')));
}
if (ini_get('mbstring.http_output') != 'pass') {
return array(UNICODE_ERROR, $t('Multibyte string output conversion in PHP is active and must be disabled. Check the php.ini <em>mbstring.http_output</em> setting. Please refer to the <a href="@url">PHP mbstring documentation</a> for more information.', array('@url' => 'http://www.php.net/mbstring')));
}
// Set appropriate configuration
mb_internal_encoding('utf-8');
mb_language('uni');
return array(UNICODE_MULTIBYTE, '');
}
/**
* Return Unicode library status and errors.
*/
......@@ -138,21 +75,40 @@ function unicode_requirements() {
);
$severities = array(
UNICODE_SINGLEBYTE => REQUIREMENT_WARNING,
UNICODE_MULTIBYTE => REQUIREMENT_OK,
UNICODE_MULTIBYTE => NULL,
UNICODE_ERROR => REQUIREMENT_ERROR,
);
list($library, $description) = _unicode_check();
$failed_check = unicode_check();
$library = $GLOBALS['multibyte'];
$requirements['unicode'] = array(
'title' => $t('Unicode library'),
'value' => $libraries[$library],
'severity' => $severities[$library],
);
if ($description) {
$requirements['unicode']['description'] = $description;
$t_args = array('@url' => 'http://www.php.net/mbstring');
switch ($failed_check) {
case 'mb_strlen':
$requirements['unicode']['description'] = $t('Operations on Unicode strings are emulated on a best-effort basis. Install the <a href="@url">PHP mbstring extension</a> for improved Unicode support.', $t_args);
break;
case 'mbstring.func_overload':
$requirements['unicode']['description'] = $t('Multibyte string function overloading in PHP is active and must be disabled. Check the php.ini <em>mbstring.func_overload</em> setting. Please refer to the <a href="@url">PHP mbstring documentation</a> for more information.', $t_args);
break;
case 'mbstring.encoding_translation':
$requirements['unicode']['description'] = $t('Multibyte string input conversion in PHP is active and must be disabled. Check the php.ini <em>mbstring.encoding_translation</em> setting. Please refer to the <a href="@url">PHP mbstring documentation</a> for more information.', $t_args);
break;
case 'mbstring.http_input':
$requirements['unicode']['description'] = $t('Multibyte string input conversion in PHP is active and must be disabled. Check the php.ini <em>mbstring.http_input</em> setting. Please refer to the <a href="@url">PHP mbstring documentation</a> for more information.', $t_args);
break;
case 'mbstring.http_output':
$requirements['unicode']['description'] = $t('Multibyte string output conversion in PHP is active and must be disabled. Check the php.ini <em>mbstring.http_output</em> setting. Please refer to the <a href="@url">PHP mbstring documentation</a> for more information.', $t_args);
break;
}
$requirements['unicode']['severity'] = $severities[$library];
return $requirements;
}
......
......@@ -84,7 +84,6 @@ function update_prepare_d8_bootstrap() {
// Allow the database system to work even if the registry has not been
// created yet.
include_once DRUPAL_ROOT . '/core/includes/install.inc';
include_once DRUPAL_ROOT . '/core/modules/entity/entity.controller.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE);
// If the site has not updated to Drupal 8 yet, check to make sure that it is
......
......@@ -20,10 +20,7 @@ function color_requirements($phase) {
);
// Check for PNG support.
if (function_exists('imagecreatefrompng')) {
$requirements['color_gd']['severity'] = REQUIREMENT_OK;
}
else {
if (!function_exists('imagecreatefrompng')) {
$requirements['color_gd']['severity'] = REQUIREMENT_WARNING;
$requirements['color_gd']['description'] = t('The GD library for PHP is enabled, but was compiled without PNG support. Check the <a href="@url">PHP image documentation</a> for information on how to correct this.', array('@url' => 'http://www.php.net/manual/ref.image.php'));
}
......
......@@ -51,7 +51,7 @@ function comment_reply(Node $node, $pid = NULL) {
if (user_access('access comments')) {
// Load the parent comment.
$comment = comment_load($pid);
if ($comment->status = COMMENT_PUBLISHED) {
if ($comment->status == COMMENT_PUBLISHED) {
// If that comment exists, make sure that the current comment and the
// parent comment both belong to the same parent node.
if ($comment->nid != $node->nid) {
......
......@@ -123,6 +123,12 @@ class CommentInterfaceTest extends CommentTestBase {
$this->assertTrue($this->commentExists($reply, TRUE), t('Page two exists. %s'));
$this->setCommentsPerPage(50);
// Attempt to reply to an unpublished comment.
$reply_loaded->status = COMMENT_NOT_PUBLISHED;
$reply_loaded->save();
$this->drupalGet('comment/reply/' . $this->node->nid . '/' . $reply_loaded->cid);
$this->assertText(t('The comment you are replying to does not exist.'), 'Replying to an unpublished comment');
// Attempt to post to node with comments disabled.
$this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'comment' => COMMENT_NODE_HIDDEN));
$this->assertTrue($this->node, t('Article node created.'));
......
......@@ -112,14 +112,9 @@ function contact_category_edit_form($form, &$form_state, array $category = array
'#description' => t('When listing categories, those with lighter (smaller) weights get listed before categories with heavier (larger) weights. Categories with equal weights are sorted alphabetically.'),
);
$form['selected'] = array(
'#type' => 'select',
'#title' => t('Selected'),
'#options' => array(
0 => t('No'),
1 => t('Yes'),
),
'#type' => 'checkbox',
'#title' => t('Make this the default category.'),
'#default_value' => $category['selected'],
'#description' => t('Set this to <em>Yes</em> if you would like this category to be selected by default.'),
);
$form['cid'] = array(
'#type' => 'value',
......
......@@ -221,7 +221,7 @@ class ContactSitewideTestCase extends WebTestBase {
$edit['category'] = $category;
$edit['recipients'] = $recipients;
$edit['reply'] = $reply;
$edit['selected'] = ($selected ? '1' : '0');
$edit['selected'] = ($selected ? TRUE : FALSE);
$this->drupalPost('admin/structure/contact/add', $edit, t('Save'));
}
......@@ -244,7 +244,7 @@ class ContactSitewideTestCase extends WebTestBase {
$edit['category'] = $category;
$edit['recipients'] = $recipients;
$edit['reply'] = $reply;
$edit['selected'] = ($selected ? '1' : '0');
$edit['selected'] = ($selected ? TRUE : FALSE);
$this->drupalPost('admin/structure/contact/edit/' . $category_id, $edit, t('Save'));
return ($category_id);
}
......
......@@ -536,51 +536,33 @@ function _field_sort_items_value_helper($a, $b) {
/**
* Gets or sets administratively defined bundle settings.
*
* For each bundle, settings are provided as a nested array with the following
* structure:
* @code
* array(
* 'view_modes' => array(
* // One sub-array per view mode for the entity type:
* 'full' => array(
* 'custom_display' => Whether the view mode uses custom display
* settings or settings of the 'default' mode,
* ),
* 'teaser' => ...
* ),
* 'extra_fields' => array(
* 'form' => array(
* // One sub-array per pseudo-field in displayed entities:
* 'extra_field_1' => array(
* 'weight' => The weight of the pseudo-field,
* ),
* 'extra_field_2' => ...
* ),
* 'display' => array(
* // One sub-array per pseudo-field in displayed entities:
* 'extra_field_1' => array(
* // One sub-array per view mode for the entity type, including
* // the 'default' mode:
* 'default' => array(
* 'weight' => The weight of the pseudo-field,
* 'visible' => TRUE if the pseudo-field is visible, FALSE if hidden,
* ),
* 'full' => ...
* ),
* 'extra_field_2' => ...
* ),
* ),
* );
* @endcode
*
* @param $entity_type
* @param string $entity_type
* The type of $entity; e.g., 'node' or 'user'.
* @param $bundle
* @param string $bundle
* The bundle name.
* @param $settings
* (optional) The settings to store.
* @param array|null $settings
* (optional) The settings to store, an associative array with the following
* elements:
* - view_modes: An associative array keyed by view mode, with the following
* key/value pairs:
* - custom_settings: Boolean specifying whether the view mode uses a
* dedicated set of display options (TRUE), or the 'default' options
* (FALSE). Defaults to FALSE.
* - extra_fields: An associative array containing the form and display
* settings for extra fields (also known as pseudo-fields):
* - form: An associative array whose keys are the names of extra fields,
* and whose values are associative arrays with the following elements:
* - weight: The weight of the extra field, determining its position on an
* entity form.
* - display: An associative array whose keys are the names of extra fields,
* and whose values are associative arrays keyed by the name of view
* modes. This array must include an item for the 'default' view mode.
* Each view mode sub-array contains the following elements:
* - weight: The weight of the extra field, determining its position when
* an entity is viewed.
* - visible: TRUE if the extra field is visible, FALSE otherwise.
*
* @return
* @return array|null
* If no $settings are passed, the current settings are returned.
*/
function field_bundle_settings($entity_type, $bundle, $settings = NULL) {
......
......@@ -60,36 +60,29 @@ function file_requirements($phase) {
if (!$apache) {
$value = t('Not enabled');
$description = t('Your server is not capable of displaying file upload progress. File upload progress requires an Apache server running PHP with mod_php.');
$severity = REQUIREMENT_INFO;
}
elseif ($fastcgi) {
$value = t('Not enabled');
$description = t('Your server is not capable of displaying file upload progress. File upload progress requires PHP be run with mod_php and not as FastCGI.');
$severity = REQUIREMENT_INFO;
}
elseif (!$implementation && extension_loaded('apc')) {
$value = t('Not enabled');
$description = t('Your server is capable of displaying file upload progress through APC, but it is not enabled. Add <code>apc.rfc1867 = 1</code> to your php.ini configuration. Alternatively, it is recommended to use <a href="http://pecl.php.net/package/uploadprogress">PECL uploadprogress</a>, which supports more than one simultaneous upload.');
$severity = REQUIREMENT_INFO;
}
elseif (!$implementation) {
$value = t('Not enabled');
$description = t('Your server is capable of displaying file upload progress, but does not have the required libraries. It is recommended to install the <a href="http://pecl.php.net/package/uploadprogress">PECL uploadprogress library</a> (preferred) or to install <a href="http://php.net/apc">APC</a>.');
$severity = REQUIREMENT_INFO;
}
elseif ($implementation == 'apc') {
$value = t('Enabled (<a href="http://php.net/manual/apc.configuration.php#ini.apc.rfc1867">APC RFC1867</a>)');
$description = t('Your server is capable of displaying file upload progress using APC RFC1867. Note that only one upload at a time is supported. It is recommended to use the <a href="http://pecl.php.net/package/uploadprogress">PECL uploadprogress library</a> if possible.');
$severity = REQUIREMENT_OK;
}
elseif ($implementation == 'uploadprogress') {
$value = t('Enabled (<a href="http://pecl.php.net/package/uploadprogress">PECL uploadprogress</a>)');
$severity = REQUIREMENT_OK;
}
$requirements['file_progress'] = array(
'title' => t('Upload progress'),
'value' => $value,
'severity' => $severity,
'description' => $description,
);
}
......
......@@ -86,10 +86,7 @@ function image_requirements($phase) {
);
// Check for filter and rotate support.
if (function_exists('imagefilter') && function_exists('imagerotate')) {
$requirements['image_gd']['severity'] = REQUIREMENT_OK;
}
else {
if (!function_exists('imagefilter') || !function_exists('imagerotate')) {
$requirements['image_gd']['severity'] = REQUIREMENT_WARNING;
$requirements['image_gd']['description'] = t('The GD Library for PHP is enabled, but was compiled without support for functions used by the rotate and desaturate effects. It was probably compiled using the official GD libraries from http://www.libgd.org instead of the GD library bundled with PHP. You should recompile PHP --with-gd using the bundled GD library. See <a href="http://www.php.net/manual/book.image.php">the PHP manual</a>.');
}
......
......@@ -4,4 +4,3 @@ package = Core
version = VERSION
core = 8.x
configure = admin/config/regional/language
files[] = language.test
......@@ -220,6 +220,11 @@ function language_from_url($languages) {
break;
case LANGUAGE_NEGOTIATION_URL_DOMAIN:
// Get only the host, not the port.
$http_host= $_SERVER['HTTP_HOST'];
if (strpos($http_host, ':') !== FALSE) {
$http_host = current(explode(':', $http_host));
}
$domains = language_negotiation_url_domains();
foreach ($languages as $language) {
// Skip the check if the language doesn't have a domain.
......@@ -228,7 +233,7 @@ function language_from_url($languages) {
// the hostname.
$host = 'http://' . str_replace(array('http://', 'https://'), '', $domains[$language->langcode]);
$host = parse_url($host, PHP_URL_HOST);
if ($_SERVER['HTTP_HOST'] == $host) {
if ($http_host == $host) {
$language_url = $language->langcode;
break;
}
......
<?php
/**
* @file
* Definition of Drupal\language\Tests\LanguageBrowserDetectionUnitTest.
*/
namespace Drupal\language\Tests;
use Drupal\simpletest\UnitTestBase;
/**
* Test browser language detection.
*/
class LanguageBrowserDetectionUnitTest extends UnitTestBase {
public static function getInfo() {
return array(
'name' => 'Browser language detection',
'description' => 'Tests for the browser language detection.',
'group' => 'Language',
);
}