Project

General

Profile

Revision b0dc3a2e

Added by Julien Enselme over 7 years ago

Update to Drupal 7.52

View differences:

drupal7/CHANGELOG.txt
1 1

  
2
Drupal 7.52, 2016-11-16
3
-----------------------
4
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2016-005.
5

  
6
Drupal 7.51, 2016-10-05
7
-----------------------
8
- The Update module now also checks for updates to a disabled theme that is
9
  used as an admin theme.
10
- Exceptions thrown in dblog_watchdog() are now caught and ignored.
11
- Clarified the warning that appears when modules are missing or have moved.
12
- Log messages are now XSS filtered on display.
13
- Draggable tables now work on touch screen devices.
14
- Added a setting for allowing double underscores in CSS identifiers
15
  (https://www.drupal.org/node/2810369).
16
- If a user navigates away from a page while an Ajax request is running they
17
  will no longer get an error message saying "An Ajax HTTP request terminated
18
  abnormally".
19
- The system_region_list() API function now takes an optional third parameter
20
  which allows region name translations to be skipped when they are not needed
21
  (API addition: https://www.drupal.org/node/2810365).
22
- Numerous performance improvements.
23
- Numerous bug fixes.
24
- Numerous API documentation improvements.
25
- Additional automated test coverage.
26

  
27
Drupal 7.50, 2016-07-07 
28
-----------------------
29
- Added a new "administer fields" permission for trusted users, which is
30
  required in addition to other permissions to use the field UI
31
  (https://www.drupal.org/node/2483307).
32
- Added clickjacking protection to Drupal core by setting the X-Frame-Options
33
  header to SAMEORIGIN by default (https://www.drupal.org/node/2735873).
34
- Added support for full UTF-8 (emojis, Asian symbols, mathematical symbols) on
35
  MySQL and other database drivers when the site and database are configured to
36
  allow it (https://www.drupal.org/node/2761183).
37
- Improved performance by avoiding a re-scan of directories when a file is
38
  missing; instead, trigger a PHP warning (minor API change:
39
  https://www.drupal.org/node/2581445).
40
- Made it possible to use any PHP callable in Ajax form callbacks, form API
41
  form-building functions, and form API wrapper callbacks (API addition:
42
  https://www.drupal.org/node/2761169).
43
- Fixed that following a password reset link while logged in leaves users unable
44
  to change their password (minor user interface change:
45
  https://www.drupal.org/node/2759023).
46
- Implemented various fixes for automated test failures on PHP 5.4+ and PHP 7.
47
  Drupal core automated tests now pass in these environments.
48
- Improved support for PHP 7 by fixing various problems.
49
- Fixed various bugs with PHP 5.5+ imagerotate(), including when incorrect
50
  color indices are passed in.
51
- Fixed a regression introduced in Drupal 7.43 that allowed files uploaded by
52
  anonymous users to be lost after form validation errors, and that also caused
53
  regressions with certain contributed modules.
54
- Fixed a regression introduced in Drupal 7.36 which caused the default value
55
  of hidden textarea fields to be ignored.
56
- Fixed robots.txt to allow search engines to access CSS, JavaScript and image
57
  files.
58
- Changed wording on the Update Manager settings page to clarify that the
59
  option to check for disabled module updates also applies to uninstalled
60
  modules (administrative-facing translatable string change).
61
- Changed the help text when editing menu links and configuring URL redirect
62
  actions so that it does not reference "Drupal" or the drupal.org website
63
  (administrative-facing translatable string change).
64
- Fixed the locale safety check that is used to ensure that translations are
65
  safe to allow for tokens in the href/src attributes of translated strings.
66
- Fixed that URL generation only works on port 80 when using domain based
67
  language negotation.
68
- Made method="get" forms work inside the administrative overlay. The fix adds
69
  a new hidden field to these forms when they appear inside the overlay (minor
70
  data structure change).
71
- Increased maxlength of menu link title input fields in the node form and
72
  menu link form from 128 to 255 characters.
73
- Removed meaningless post-check=0 and pre-check=0 cache control headers from
74
  Drupal HTTP responses.
75
- Added a .editorconfig file to auto-configure editors that support it.
76
- Added --directory option to run-tests.sh for easier test discovery of all
77
  tests within a project.
78
- Made run-tests.sh exit with a failure code when there are test fails or
79
  problems running the script.
80
- Fixed that cookies from previous tests are still present when a new test
81
  starts in DrupalWebTestCase.
82
- Improved performance of queries on the {authmap} database table.
83
- Fixed handling of missing files and functions inside the registry.
84
- Fixed Ajax handling for tableselect form elements that use checkboxes.
85
- Fixed a bug which caused ip_address() to return nothing when the client IP
86
  address and proxy IP address are the same.
87
- Added a new option to format_xml_elements() to allow for already encoded
88
  values.
89
- Changed the {history} table's node ID field to be an unsigned integer, to
90
  match the same field in the {node} table and to prevent errors with very
91
  large node IDs.
92
- Added an explicit page callback to the "admin/people/create" menu item in the
93
  User module (minor data structure change). Previously this automatically
94
  inherited the page callback from the parent "admin/people" menu item, which
95
  broke contributed modules that override the "admin/people" page.
96
- Numerous small bug fixes.
97
- Numerous API documentation improvements.
98
- Additional automated test coverage.
99

  
2 100
Drupal 7.44, 2016-06-15
3 101
-----------------------
4 102
- Fixed security issues (privilege escalation). See SA-CORE-2016-002.
drupal7/MAINTAINERS.txt
12 12

  
13 13
- Dries Buytaert 'dries' https://www.drupal.org/u/dries
14 14
- Angela Byron 'webchick' https://www.drupal.org/u/webchick
15
- Fabian Franz 'Fabianx' https://www.drupal.org/u/fabianx
15 16
- David Rothstein 'David_Rothstein' https://www.drupal.org/u/david_rothstein
17
- Stefan Ruijsenaars 'stefan.r' https://www.drupal.org/u/stefanr-0
16 18

  
17 19

  
18 20
Component maintainers
......
143 145
Node Access
144 146
- Moshe Weitzman 'moshe weitzman' https://www.drupal.org/u/moshe-weitzman
145 147
- Ken Rickard 'agentrickard' https://www.drupal.org/u/agentrickard
146
- Jess Myrbo 'xjm' https://www.drupal.org/u/xjm
147 148

  
148 149

  
149 150
Security team
......
266 267
- ?
267 268

  
268 269
Taxonomy module
269
- Jess Myrbo 'xjm' https://www.drupal.org/u/xjm
270 270
- Nathaniel Catchpole 'catch' https://www.drupal.org/u/catch
271 271
- Benjamin Doherty 'bangpound' https://www.drupal.org/u/bangpound
272 272

  
drupal7/includes/ajax.inc
394 394
  if (!empty($form_state['triggering_element'])) {
395 395
    $callback = $form_state['triggering_element']['#ajax']['callback'];
396 396
  }
397
  if (!empty($callback) && function_exists($callback)) {
397
  if (!empty($callback) && is_callable($callback)) {
398 398
    $result = $callback($form, $form_state);
399 399

  
400 400
    if (!(is_array($result) && isset($result['#type']) && $result['#type'] == 'ajax')) {
drupal7/includes/bootstrap.inc
8 8
/**
9 9
 * The current system version.
10 10
 */
11
define('VERSION', '7.44');
11
define('VERSION', '7.52');
12 12

  
13 13
/**
14 14
 * Core API compatibility.
......
828 828
 * @param $filename
829 829
 *   The filename of the item if it is to be set explicitly rather
830 830
 *   than by consulting the database.
831
 * @param bool $trigger_error
832
 *   Whether to trigger an error when a file is missing or has unexpectedly
833
 *   moved. This defaults to TRUE, but can be set to FALSE by calling code that
834
 *   merely wants to check whether an item exists in the filesystem.
831 835
 *
832 836
 * @return
833 837
 *   The filename of the requested item or NULL if the item is not found.
834 838
 */
835
function drupal_get_filename($type, $name, $filename = NULL) {
839
function drupal_get_filename($type, $name, $filename = NULL, $trigger_error = TRUE) {
840
  // The $files static variable will hold the locations of all requested files.
841
  // We can be sure that any file listed in this static variable actually
842
  // exists as all additions have gone through a file_exists() check.
836 843
  // The location of files will not change during the request, so do not use
837 844
  // drupal_static().
838
  static $files = array(), $dirs = array();
845
  static $files = array();
839 846

  
840 847
  // Profiles are a special case: they have a fixed location and naming.
841 848
  if ($type == 'profile') {
......
847 854
  }
848 855

  
849 856
  if (!empty($filename) && file_exists($filename)) {
857
    // Prime the static cache with the provided filename.
850 858
    $files[$type][$name] = $filename;
851 859
  }
852 860
  elseif (isset($files[$type][$name])) {
853
    // nothing
861
    // This item had already been found earlier in the request, either through
862
    // priming of the static cache (for example, in system_list()), through a
863
    // lookup in the {system} table, or through a file scan (cached or not). Do
864
    // nothing.
854 865
  }
855
  // Verify that we have an active database connection, before querying
856
  // the database. This is required because this function is called both
857
  // before we have a database connection (i.e. during installation) and
858
  // when a database connection fails.
859 866
  else {
867
    // Look for the filename listed in the {system} table. Verify that we have
868
    // an active database connection before doing so, since this function is
869
    // called both before we have a database connection (i.e. during
870
    // installation) and when a database connection fails.
871
    $database_unavailable = TRUE;
860 872
    try {
861 873
      if (function_exists('db_query')) {
862 874
        $file = db_query("SELECT filename FROM {system} WHERE name = :name AND type = :type", array(':name' => $name, ':type' => $type))->fetchField();
863 875
        if ($file !== FALSE && file_exists(DRUPAL_ROOT . '/' . $file)) {
864 876
          $files[$type][$name] = $file;
865 877
        }
878
        $database_unavailable = FALSE;
866 879
      }
867 880
    }
868 881
    catch (Exception $e) {
869 882
      // The database table may not exist because Drupal is not yet installed,
870
      // or the database might be down. We have a fallback for this case so we
871
      // hide the error completely.
883
      // the database might be down, or we may have done a non-database cache
884
      // flush while $conf['page_cache_without_database'] = TRUE and
885
      // $conf['page_cache_invoke_hooks'] = TRUE. We have a fallback for these
886
      // cases so we hide the error completely.
872 887
    }
873
    // Fallback to searching the filesystem if the database could not find the
874
    // file or the file returned by the database is not found.
888
    // Fall back to searching the filesystem if the database could not find the
889
    // file or the file does not exist at the path returned by the database.
875 890
    if (!isset($files[$type][$name])) {
876
      // We have a consistent directory naming: modules, themes...
877
      $dir = $type . 's';
878
      if ($type == 'theme_engine') {
879
        $dir = 'themes/engines';
880
        $extension = 'engine';
881
      }
882
      elseif ($type == 'theme') {
883
        $extension = 'info';
884
      }
885
      else {
886
        $extension = $type;
887
      }
891
      $files[$type][$name] = _drupal_get_filename_fallback($type, $name, $trigger_error, $database_unavailable);
892
    }
893
  }
888 894

  
889
      if (!isset($dirs[$dir][$extension])) {
890
        $dirs[$dir][$extension] = TRUE;
891
        if (!function_exists('drupal_system_listing')) {
892
          require_once DRUPAL_ROOT . '/includes/common.inc';
893
        }
894
        // Scan the appropriate directories for all files with the requested
895
        // extension, not just the file we are currently looking for. This
896
        // prevents unnecessary scans from being repeated when this function is
897
        // called more than once in the same page request.
898
        $matches = drupal_system_listing("/^" . DRUPAL_PHP_FUNCTION_PATTERN . "\.$extension$/", $dir, 'name', 0);
899
        foreach ($matches as $matched_name => $file) {
900
          $files[$type][$matched_name] = $file->uri;
895
  if (isset($files[$type][$name])) {
896
    return $files[$type][$name];
897
  }
898
}
899

  
900
/**
901
 * Performs a cached file system scan as a fallback when searching for a file.
902
 *
903
 * This function looks for the requested file by triggering a file scan,
904
 * caching the new location if the file has moved and caching the miss
905
 * if the file is missing. If a file had been marked as missing in a previous
906
 * file scan, or if it has been marked as moved and is still in the last known
907
 * location, no new file scan will be performed.
908
 *
909
 * @param string $type
910
 *   The type of the item (theme, theme_engine, module, profile).
911
 * @param string $name
912
 *   The name of the item for which the filename is requested.
913
 * @param bool $trigger_error
914
 *   Whether to trigger an error when a file is missing or has unexpectedly
915
 *   moved.
916
 * @param bool $database_unavailable
917
 *   Whether this function is being called because the Drupal database could
918
 *   not be queried for the file's location.
919
 *
920
 * @return
921
 *   The filename of the requested item or NULL if the item is not found.
922
 *
923
 * @see drupal_get_filename()
924
 */
925
function _drupal_get_filename_fallback($type, $name, $trigger_error, $database_unavailable) {
926
  $file_scans = &_drupal_file_scan_cache();
927
  $filename = NULL;
928

  
929
  // If the cache indicates that the item is missing, or we can verify that the
930
  // item exists in the location the cache says it exists in, use that.
931
  if (isset($file_scans[$type][$name]) && ($file_scans[$type][$name] === FALSE || file_exists($file_scans[$type][$name]))) {
932
    $filename = $file_scans[$type][$name];
933
  }
934
  // Otherwise, perform a new file scan to find the item.
935
  else {
936
    $filename = _drupal_get_filename_perform_file_scan($type, $name);
937
    // Update the static cache, and mark the persistent cache for updating at
938
    // the end of the page request. See drupal_file_scan_write_cache().
939
    $file_scans[$type][$name] = $filename;
940
    $file_scans['#write_cache'] = TRUE;
941
  }
942

  
943
  // If requested, trigger a user-level warning about the missing or
944
  // unexpectedly moved file. If the database was unavailable, do not trigger a
945
  // warning in the latter case, though, since if the {system} table could not
946
  // be queried there is no way to know if the location found here was
947
  // "unexpected" or not.
948
  if ($trigger_error) {
949
    $error_type = $filename === FALSE ? 'missing' : 'moved';
950
    if ($error_type == 'missing' || !$database_unavailable) {
951
      _drupal_get_filename_fallback_trigger_error($type, $name, $error_type);
952
    }
953
  }
954

  
955
  // The cache stores FALSE for files that aren't found (to be able to
956
  // distinguish them from files that have not yet been searched for), but
957
  // drupal_get_filename() expects NULL for these instead, so convert to NULL
958
  // before returning.
959
  if ($filename === FALSE) {
960
    $filename = NULL;
961
  }
962
  return $filename;
963
}
964

  
965
/**
966
 * Returns the current list of cached file system scan results.
967
 *
968
 * @return
969
 *   An associative array tracking the most recent file scan results for all
970
 *   files that have had scans performed. The keys are the type and name of the
971
 *   item that was searched for, and the values can be either:
972
 *   - Boolean FALSE if the item was not found in the file system.
973
 *   - A string pointing to the location where the item was found.
974
 */
975
function &_drupal_file_scan_cache() {
976
  $file_scans = &drupal_static(__FUNCTION__, array());
977

  
978
  // The file scan results are stored in a persistent cache (in addition to the
979
  // static cache) but because this function can be called before the
980
  // persistent cache is available, we must merge any items that were found
981
  // earlier in the page request into the results from the persistent cache.
982
  if (!isset($file_scans['#cache_merge_done'])) {
983
    try {
984
      if (function_exists('cache_get')) {
985
        $cache = cache_get('_drupal_file_scan_cache', 'cache_bootstrap');
986
        if (!empty($cache->data)) {
987
          // File scan results from the current request should take precedence
988
          // over the results from the persistent cache, since they are newer.
989
          $file_scans = drupal_array_merge_deep($cache->data, $file_scans);
901 990
        }
991
        // Set a flag to indicate that the persistent cache does not need to be
992
        // merged again.
993
        $file_scans['#cache_merge_done'] = TRUE;
902 994
      }
903 995
    }
996
    catch (Exception $e) {
997
      // Hide the error.
998
    }
904 999
  }
905 1000

  
906
  if (isset($files[$type][$name])) {
907
    return $files[$type][$name];
1001
  return $file_scans;
1002
}
1003

  
1004
/**
1005
 * Performs a file system scan to search for a system resource.
1006
 *
1007
 * @param $type
1008
 *   The type of the item (theme, theme_engine, module, profile).
1009
 * @param $name
1010
 *   The name of the item for which the filename is requested.
1011
 *
1012
 * @return
1013
 *   The filename of the requested item or FALSE if the item is not found.
1014
 *
1015
 * @see drupal_get_filename()
1016
 * @see _drupal_get_filename_fallback()
1017
 */
1018
function _drupal_get_filename_perform_file_scan($type, $name) {
1019
  // The location of files will not change during the request, so do not use
1020
  // drupal_static().
1021
  static $dirs = array(), $files = array();
1022

  
1023
  // We have a consistent directory naming: modules, themes...
1024
  $dir = $type . 's';
1025
  if ($type == 'theme_engine') {
1026
    $dir = 'themes/engines';
1027
    $extension = 'engine';
1028
  }
1029
  elseif ($type == 'theme') {
1030
    $extension = 'info';
1031
  }
1032
  else {
1033
    $extension = $type;
1034
  }
1035

  
1036
  // Check if we had already scanned this directory/extension combination.
1037
  if (!isset($dirs[$dir][$extension])) {
1038
    // Log that we have now scanned this directory/extension combination
1039
    // into a static variable so as to prevent unnecessary file scans.
1040
    $dirs[$dir][$extension] = TRUE;
1041
    if (!function_exists('drupal_system_listing')) {
1042
      require_once DRUPAL_ROOT . '/includes/common.inc';
1043
    }
1044
    // Scan the appropriate directories for all files with the requested
1045
    // extension, not just the file we are currently looking for. This
1046
    // prevents unnecessary scans from being repeated when this function is
1047
    // called more than once in the same page request.
1048
    $matches = drupal_system_listing("/^" . DRUPAL_PHP_FUNCTION_PATTERN . "\.$extension$/", $dir, 'name', 0);
1049
    foreach ($matches as $matched_name => $file) {
1050
      // Log the locations found in the file scan into a static variable.
1051
      $files[$type][$matched_name] = $file->uri;
1052
    }
1053
  }
1054

  
1055
  // Return the results of the file system scan, or FALSE to indicate the file
1056
  // was not found.
1057
  return isset($files[$type][$name]) ? $files[$type][$name] : FALSE;
1058
}
1059

  
1060
/**
1061
 * Triggers a user-level warning for missing or unexpectedly moved files.
1062
 *
1063
 * @param $type
1064
 *   The type of the item (theme, theme_engine, module, profile).
1065
 * @param $name
1066
 *   The name of the item for which the filename is requested.
1067
 * @param $error_type
1068
 *   The type of the error ('missing' or 'moved').
1069
 *
1070
 * @see drupal_get_filename()
1071
 * @see _drupal_get_filename_fallback()
1072
 */
1073
function _drupal_get_filename_fallback_trigger_error($type, $name, $error_type) {
1074
  // Hide messages due to known bugs that will appear on a lot of sites.
1075
  // @todo Remove this in https://www.drupal.org/node/2383823
1076
  if (empty($name)) {
1077
    return;
1078
  }
1079

  
1080
  // Make sure we only show any missing or moved file errors only once per
1081
  // request.
1082
  static $errors_triggered = array();
1083
  if (empty($errors_triggered[$type][$name][$error_type])) {
1084
    // Use _drupal_trigger_error_with_delayed_logging() here since these are
1085
    // triggered during low-level operations that cannot necessarily be
1086
    // interrupted by a watchdog() call.
1087
    if ($error_type == 'missing') {
1088
      _drupal_trigger_error_with_delayed_logging(format_string('The following @type is missing from the file system: %name. For information about how to fix this, see <a href="@documentation">the documentation page</a>.', array('@type' => $type, '%name' => $name, '@documentation' => 'https://www.drupal.org/node/2487215')), E_USER_WARNING);
1089
    }
1090
    elseif ($error_type == 'moved') {
1091
      _drupal_trigger_error_with_delayed_logging(format_string('The following @type has moved within the file system: %name. In order to fix this, clear caches or put the @type back in its original location. For more information, see <a href="@documentation">the documentation page</a>.', array('@type' => $type, '%name' => $name, '@documentation' => 'https://www.drupal.org/node/2487215')), E_USER_WARNING);
1092
    }
1093
    $errors_triggered[$type][$name][$error_type] = TRUE;
1094
  }
1095
}
1096

  
1097
/**
1098
 * Invokes trigger_error() with logging delayed until the end of the request.
1099
 *
1100
 * This is an alternative to PHP's trigger_error() function which can be used
1101
 * during low-level Drupal core operations that need to avoid being interrupted
1102
 * by a watchdog() call.
1103
 *
1104
 * Normally, Drupal's error handler calls watchdog() in response to a
1105
 * trigger_error() call. However, this invokes hook_watchdog() which can run
1106
 * arbitrary code. If the trigger_error() happens in the middle of an
1107
 * operation such as a rebuild operation which should not be interrupted by
1108
 * arbitrary code, that could potentially break or trigger the rebuild again.
1109
 * This function protects against that by delaying the watchdog() call until
1110
 * the end of the current page request.
1111
 *
1112
 * This is an internal function which should only be called by low-level Drupal
1113
 * core functions. It may be removed in a future Drupal 7 release.
1114
 *
1115
 * @param string $error_msg
1116
 *   The error message to trigger. As with trigger_error() itself, this is
1117
 *   limited to 1024 bytes; additional characters beyond that will be removed.
1118
 * @param int $error_type
1119
 *   (optional) The type of error. This should be one of the E_USER family of
1120
 *   constants. As with trigger_error() itself, this defaults to E_USER_NOTICE
1121
 *   if not provided.
1122
 *
1123
 * @see _drupal_log_error()
1124
 */
1125
function _drupal_trigger_error_with_delayed_logging($error_msg, $error_type = E_USER_NOTICE) {
1126
  $delay_logging = &drupal_static(__FUNCTION__, FALSE);
1127
  $delay_logging = TRUE;
1128
  trigger_error($error_msg, $error_type);
1129
  $delay_logging = FALSE;
1130
}
1131

  
1132
/**
1133
 * Writes the file scan cache to the persistent cache.
1134
 *
1135
 * This cache stores all files marked as missing or moved after a file scan
1136
 * to prevent unnecessary file scans in subsequent requests. This cache is
1137
 * cleared in system_list_reset() (i.e. after a module/theme rebuild).
1138
 */
1139
function drupal_file_scan_write_cache() {
1140
  // Only write to the persistent cache if requested, and if we know that any
1141
  // data previously in the cache was successfully loaded and merged in by
1142
  // _drupal_file_scan_cache().
1143
  $file_scans = &_drupal_file_scan_cache();
1144
  if (isset($file_scans['#write_cache']) && isset($file_scans['#cache_merge_done'])) {
1145
    unset($file_scans['#write_cache']);
1146
    cache_set('_drupal_file_scan_cache', $file_scans, 'cache_bootstrap');
908 1147
  }
909 1148
}
910 1149

  
......
1261 1500

  
1262 1501
  $default_headers = array(
1263 1502
    'Expires' => 'Sun, 19 Nov 1978 05:00:00 GMT',
1264
    'Cache-Control' => 'no-cache, must-revalidate, post-check=0, pre-check=0',
1503
    'Cache-Control' => 'no-cache, must-revalidate',
1265 1504
    // Prevent browsers from sniffing a response and picking a MIME type
1266 1505
    // different from the declared content-type, since that can lead to
1267 1506
    // XSS and other vulnerabilities.
......
1439 1678
 * available to code that needs localization. See st() and get_t() for
1440 1679
 * alternatives.
1441 1680
 *
1681
 * @section sec_context String context
1682
 * Matching source strings are normally only translated once, and the same
1683
 * translation is used everywhere that has a matching string. However, in some
1684
 * cases, a certain English source string needs to have multiple translations.
1685
 * One example of this is the string "May", which could be used as either a
1686
 * full month name or a 3-letter abbreviated month. In other languages where
1687
 * the month name for May has more than 3 letters, you would need to provide
1688
 * two different translations (one for the full name and one abbreviated), and
1689
 * the correct form would need to be chosen, depending on how "May" is being
1690
 * used. To facilitate this, the "May" string should be provided with two
1691
 * different contexts in the $options parameter when calling t(). For example:
1692
 * @code
1693
 * t('May', array(), array('context' => 'Long month name')
1694
 * t('May', array(), array('context' => 'Abbreviated month name')
1695
 * @endcode
1696
 * See https://localize.drupal.org/node/2109 for more information.
1697
 *
1442 1698
 * @param $string
1443 1699
 *   A string containing the English string to translate.
1444 1700
 * @param $args
......
1449 1705
 *   An associative array of additional options, with the following elements:
1450 1706
 *   - 'langcode' (defaults to the current language): The language code to
1451 1707
 *     translate to a language other than what is used to display the page.
1452
 *   - 'context' (defaults to the empty context): The context the source string
1453
 *     belongs to.
1708
 *   - 'context' (defaults to the empty context): A string giving the context
1709
 *     that the source string belongs to. See @ref sec_context above for more
1710
 *     information.
1454 1711
 *
1455 1712
 * @return
1456 1713
 *   The translated string.
......
2945 3202
        // Eliminate all trusted IPs.
2946 3203
        $untrusted = array_diff($forwarded, $reverse_proxy_addresses);
2947 3204

  
2948
        // The right-most IP is the most specific we can trust.
2949
        $ip_address = array_pop($untrusted);
3205
        if (!empty($untrusted)) {
3206
          // The right-most IP is the most specific we can trust.
3207
          $ip_address = array_pop($untrusted);
3208
        }
3209
        else {
3210
          // All IP addresses in the forwarded array are configured proxy IPs
3211
          // (and thus trusted). We take the leftmost IP.
3212
          $ip_address = array_shift($forwarded);
3213
        }
2950 3214
      }
2951 3215
    }
2952 3216
  }
......
3187 3451
  $cache_key = $type[0] . $name;
3188 3452
  if (isset($lookup_cache[$cache_key])) {
3189 3453
    if ($lookup_cache[$cache_key]) {
3190
      require_once DRUPAL_ROOT . '/' . $lookup_cache[$cache_key];
3454
      include_once DRUPAL_ROOT . '/' . $lookup_cache[$cache_key];
3191 3455
    }
3192 3456
    return (bool) $lookup_cache[$cache_key];
3193 3457
  }
......
3212 3476
  $lookup_cache[$cache_key] = $file;
3213 3477

  
3214 3478
  if ($file) {
3215
    require_once DRUPAL_ROOT . '/' . $file;
3479
    include_once DRUPAL_ROOT . '/' . $file;
3216 3480
    return TRUE;
3217 3481
  }
3218 3482
  else {
drupal7/includes/common.inc
760 760
 *   - headers: An array containing request headers to send as name/value pairs.
761 761
 *   - method: A string containing the request method. Defaults to 'GET'.
762 762
 *   - data: A string containing the request body, formatted as
763
 *     'param=value&param=value&...'. Defaults to NULL.
763
 *     'param=value&param=value&...'; to generate this, use http_build_query().
764
 *     Defaults to NULL.
764 765
 *   - max_redirects: An integer representing how many times a redirect
765 766
 *     may be followed. Defaults to 3.
766 767
 *   - timeout: A float representing the maximum number of seconds the function
......
785 786
 *     HTTP header names are case-insensitive (RFC 2616, section 4.2), so for
786 787
 *     easy access the array keys are returned in lower case.
787 788
 *   - data: A string containing the response body that was received.
789
 *
790
 * @see http_build_query()
788 791
 */
789 792
function drupal_http_request($url, array $options = array()) {
790 793
  // Allow an alternate HTTP client library to replace Drupal's default
......
1767 1770
 *     - 'key': element name
1768 1771
 *     - 'value': element contents
1769 1772
 *     - 'attributes': associative array of element attributes
1773
 *     - 'encoded': TRUE if 'value' is already encoded
1770 1774
 *
1771 1775
 * In both cases, 'value' can be a simple string, or it can be another array
1772 1776
 * with the same format as $array itself for nesting.
1777
 *
1778
 * If 'encoded' is TRUE it is up to the caller to ensure that 'value' is either
1779
 * entity-encoded or CDATA-escaped. Using this option is not recommended when
1780
 * working with untrusted user input, since failing to escape the data
1781
 * correctly has security implications.
1773 1782
 */
1774 1783
function format_xml_elements($array) {
1775 1784
  $output = '';
......
1782 1791
        }
1783 1792

  
1784 1793
        if (isset($value['value']) && $value['value'] != '') {
1785
          $output .= '>' . (is_array($value['value']) ? format_xml_elements($value['value']) : check_plain($value['value'])) . '</' . $value['key'] . ">\n";
1794
          $output .= '>' . (is_array($value['value']) ? format_xml_elements($value['value']) : (!empty($value['encoded']) ? $value['value'] : check_plain($value['value']))) . '</' . $value['key'] . ">\n";
1786 1795
        }
1787 1796
        else {
1788 1797
          $output .= " />\n";
......
2644 2653
  global $language;
2645 2654
  drupal_add_http_header('Content-Language', $language->language);
2646 2655

  
2656
  // By default, do not allow the site to be rendered in an iframe on another
2657
  // domain, but provide a variable to override this. If the code running for
2658
  // this page request already set the X-Frame-Options header earlier, don't
2659
  // overwrite it here.
2660
  $frame_options = variable_get('x_frame_options', 'SAMEORIGIN');
2661
  if ($frame_options && is_null(drupal_get_http_header('X-Frame-Options'))) {
2662
    drupal_add_http_header('X-Frame-Options', $frame_options);
2663
  }
2664

  
2647 2665
  // Menu status constants are integers; page content is a string or array.
2648 2666
  if (is_int($page_callback_result)) {
2649 2667
    // @todo: Break these up into separate functions?
......
2758 2776
  _registry_check_code(REGISTRY_WRITE_LOOKUP_CACHE);
2759 2777
  drupal_cache_system_paths();
2760 2778
  module_implements_write_cache();
2779
  drupal_file_scan_write_cache();
2761 2780
  system_run_automated_cron();
2762 2781
}
2763 2782

  
......
3025 3044
 */
3026 3045
function drupal_add_css($data = NULL, $options = NULL) {
3027 3046
  $css = &drupal_static(__FUNCTION__, array());
3047
  $count = &drupal_static(__FUNCTION__ . '_count', 0);
3048

  
3049
  // If the $css variable has been reset with drupal_static_reset(), there is
3050
  // no longer any CSS being tracked, so set the counter back to 0 also.
3051
  if (count($css) === 0) {
3052
    $count = 0;
3053
  }
3028 3054

  
3029 3055
  // Construct the options, taking the defaults into consideration.
3030 3056
  if (isset($options)) {
......
3060 3086
    }
3061 3087

  
3062 3088
    // Always add a tiny value to the weight, to conserve the insertion order.
3063
    $options['weight'] += count($css) / 1000;
3089
    $options['weight'] += $count / 1000;
3090
    $count++;
3064 3091

  
3065 3092
    // Add the data to the CSS array depending on the type.
3066 3093
    switch ($options['type']) {
......
3873 3900
 *   The cleaned identifier.
3874 3901
 */
3875 3902
function drupal_clean_css_identifier($identifier, $filter = array(' ' => '-', '_' => '-', '/' => '-', '[' => '-', ']' => '')) {
3903
  // Use the advanced drupal_static() pattern, since this is called very often.
3904
  static $drupal_static_fast;
3905
  if (!isset($drupal_static_fast)) {
3906
    $drupal_static_fast['allow_css_double_underscores'] = &drupal_static(__FUNCTION__ . ':allow_css_double_underscores');
3907
  }
3908
  $allow_css_double_underscores = &$drupal_static_fast['allow_css_double_underscores'];
3909
  if (!isset($allow_css_double_underscores)) {
3910
    $allow_css_double_underscores = variable_get('allow_css_double_underscores', FALSE);
3911
  }
3912

  
3913
  // Preserve BEM-style double-underscores depending on custom setting.
3914
  if ($allow_css_double_underscores) {
3915
    $filter['__'] = '__';
3916
  }
3917

  
3876 3918
  // By default, we filter using Drupal's coding standards.
3877 3919
  $identifier = strtr($identifier, $filter);
3878 3920

  
drupal7/includes/database/database.inc
296 296
   */
297 297
  protected $prefixReplace = array();
298 298

  
299
  /**
300
   * List of escaped database, table, and field names, keyed by unescaped names.
301
   *
302
   * @var array
303
   */
304
  protected $escapedNames = array();
305

  
306
  /**
307
   * List of escaped aliases names, keyed by unescaped aliases.
308
   *
309
   * @var array
310
   */
311
  protected $escapedAliases = array();
312

  
299 313
  function __construct($dsn, $username, $password, $driver_options = array()) {
300 314
    // Initialize and prepare the connection prefix.
301 315
    $this->setPrefix(isset($this->connectionOptions['prefix']) ? $this->connectionOptions['prefix'] : '');
......
919 933
   * For some database drivers, it may also wrap the table name in
920 934
   * database-specific escape characters.
921 935
   *
922
   * @return
936
   * @return string
923 937
   *   The sanitized table name string.
924 938
   */
925 939
  public function escapeTable($table) {
926
    return preg_replace('/[^A-Za-z0-9_.]+/', '', $table);
940
    if (!isset($this->escapedNames[$table])) {
941
      $this->escapedNames[$table] = preg_replace('/[^A-Za-z0-9_.]+/', '', $table);
942
    }
943
    return $this->escapedNames[$table];
927 944
  }
928 945

  
929 946
  /**
......
933 950
   * For some database drivers, it may also wrap the field name in
934 951
   * database-specific escape characters.
935 952
   *
936
   * @return
953
   * @return string
937 954
   *   The sanitized field name string.
938 955
   */
939 956
  public function escapeField($field) {
940
    return preg_replace('/[^A-Za-z0-9_.]+/', '', $field);
957
    if (!isset($this->escapedNames[$field])) {
958
      $this->escapedNames[$field] = preg_replace('/[^A-Za-z0-9_.]+/', '', $field);
959
    }
960
    return $this->escapedNames[$field];
941 961
  }
942 962

  
943 963
  /**
......
948 968
   * DatabaseConnection::escapeTable(), this doesn't allow the period (".")
949 969
   * because that is not allowed in aliases.
950 970
   *
951
   * @return
971
   * @return string
952 972
   *   The sanitized field name string.
953 973
   */
954 974
  public function escapeAlias($field) {
955
    return preg_replace('/[^A-Za-z0-9_]+/', '', $field);
975
    if (!isset($this->escapedAliases[$field])) {
976
      $this->escapedAliases[$field] = preg_replace('/[^A-Za-z0-9_]+/', '', $field);
977
    }
978
    return $this->escapedAliases[$field];
956 979
  }
957 980

  
958 981
  /**
......
1313 1336
   *   also larger than the $existing_id if one was passed in.
1314 1337
   */
1315 1338
  abstract public function nextId($existing_id = 0);
1339

  
1340
  /**
1341
   * Checks whether utf8mb4 support is configurable in settings.php.
1342
   *
1343
   * @return bool
1344
   */
1345
  public function utf8mb4IsConfigurable() {
1346
    // Since 4 byte UTF-8 is not supported by default, there is nothing to
1347
    // configure.
1348
    return FALSE;
1349
  }
1350

  
1351
  /**
1352
   * Checks whether utf8mb4 support is currently active.
1353
   *
1354
   * @return bool
1355
   */
1356
  public function utf8mb4IsActive() {
1357
    // Since 4 byte UTF-8 is not supported by default, there is nothing to
1358
    // activate.
1359
    return FALSE;
1360
  }
1361

  
1362
  /**
1363
   * Checks whether utf8mb4 support is available on the current database system.
1364
   *
1365
   * @return bool
1366
   */
1367
  public function utf8mb4IsSupported() {
1368
    // By default we assume that the database backend may not support 4 byte
1369
    // UTF-8.
1370
    return FALSE;
1371
  }
1316 1372
}
1317 1373

  
1318 1374
/**
drupal7/includes/database/mysql/database.inc
28 28

  
29 29
    $this->connectionOptions = $connection_options;
30 30

  
31
    $charset = 'utf8';
32
    // Check if the charset is overridden to utf8mb4 in settings.php.
33
    if ($this->utf8mb4IsActive()) {
34
      $charset = 'utf8mb4';
35
    }
36

  
31 37
    // The DSN should use either a socket or a host/port.
32 38
    if (isset($connection_options['unix_socket'])) {
33 39
      $dsn = 'mysql:unix_socket=' . $connection_options['unix_socket'];
......
39 45
    // Character set is added to dsn to ensure PDO uses the proper character
40 46
    // set when escaping. This has security implications. See
41 47
    // https://www.drupal.org/node/1201452 for further discussion.
42
    $dsn .= ';charset=utf8';
48
    $dsn .= ';charset=' . $charset;
43 49
    $dsn .= ';dbname=' . $connection_options['database'];
44 50
    // Allow PDO options to be overridden.
45 51
    $connection_options += array(
......
63 69
    // certain one has been set; otherwise, MySQL defaults to 'utf8_general_ci'
64 70
    // for UTF-8.
65 71
    if (!empty($connection_options['collation'])) {
66
      $this->exec('SET NAMES utf8 COLLATE ' . $connection_options['collation']);
72
      $this->exec('SET NAMES ' . $charset . ' COLLATE ' . $connection_options['collation']);
67 73
    }
68 74
    else {
69
      $this->exec('SET NAMES utf8');
75
      $this->exec('SET NAMES ' . $charset);
70 76
    }
71 77

  
72 78
    // Set MySQL init_commands if not already defined.  Default Drupal's MySQL
......
206 212
      }
207 213
    }
208 214
  }
215

  
216
  public function utf8mb4IsConfigurable() {
217
    return TRUE;
218
  }
219

  
220
  public function utf8mb4IsActive() {
221
    return isset($this->connectionOptions['charset']) && $this->connectionOptions['charset'] === 'utf8mb4';
222
  }
223

  
224
  public function utf8mb4IsSupported() {
225
    // Ensure that the MySQL driver supports utf8mb4 encoding.
226
    $version = $this->getAttribute(PDO::ATTR_CLIENT_VERSION);
227
    if (strpos($version, 'mysqlnd') !== FALSE) {
228
      // The mysqlnd driver supports utf8mb4 starting at version 5.0.9.
229
      $version = preg_replace('/^\D+([\d.]+).*/', '$1', $version);
230
      if (version_compare($version, '5.0.9', '<')) {
231
        return FALSE;
232
      }
233
    }
234
    else {
235
      // The libmysqlclient driver supports utf8mb4 starting at version 5.5.3.
236
      if (version_compare($version, '5.5.3', '<')) {
237
        return FALSE;
238
      }
239
    }
240

  
241
    // Ensure that the MySQL server supports large prefixes and utf8mb4.
242
    try {
243
      $this->query("CREATE TABLE {drupal_utf8mb4_test} (id VARCHAR(255), PRIMARY KEY(id(255))) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci ROW_FORMAT=DYNAMIC ENGINE=INNODB");
244
    }
245
    catch (Exception $e) {
246
      return FALSE;
247
    }
248
    $this->query("DROP TABLE {drupal_utf8mb4_test}");
249
    return TRUE;
250
  }
209 251
}
210 252

  
211 253

  
drupal7/includes/database/mysql/schema.inc
39 39
      $info['table'] = substr($table, ++$pos);
40 40
    }
41 41
    else {
42
      $db_info = Database::getConnectionInfo();
43
      $info['database'] = $db_info[$this->connection->getTarget()]['database'];
42
      $db_info = $this->connection->getConnectionOptions();
43
      $info['database'] = $db_info['database'];
44 44
      $info['table'] = $table;
45 45
    }
46 46
    return $info;
......
81 81
    // Provide defaults if needed.
82 82
    $table += array(
83 83
      'mysql_engine' => 'InnoDB',
84
      'mysql_character_set' => 'utf8',
84
      // Allow the default charset to be overridden in settings.php.
85
      'mysql_character_set' => $this->connection->utf8mb4IsActive() ? 'utf8mb4' : 'utf8',
85 86
    );
86 87

  
87 88
    $sql = "CREATE TABLE {" . $name . "} (\n";
......
109 110
      $sql .= ' COLLATE ' . $info['collation'];
110 111
    }
111 112

  
113
    // The row format needs to be either DYNAMIC or COMPRESSED in order to allow
114
    // for the innodb_large_prefix setting to take effect, see
115
    // https://dev.mysql.com/doc/refman/5.6/en/create-table.html
116
    if ($this->connection->utf8mb4IsActive()) {
117
      $sql .= ' ROW_FORMAT=DYNAMIC';
118
    }
119

  
112 120
    // Add table comment.
113 121
    if (!empty($table['description'])) {
114 122
      $sql .= ' COMMENT ' . $this->prepareComment($table['description'], self::COMMENT_MAX_TABLE);
drupal7/includes/database/pgsql/database.inc
216 216

  
217 217
    return $id;
218 218
  }
219

  
220
  public function utf8mb4IsActive() {
221
    return TRUE;
222
  }
223

  
224
  public function utf8mb4IsSupported() {
225
    return TRUE;
226
  }
219 227
}
220 228

  
221 229
/**
drupal7/includes/database/select.inc
1231 1231

  
1232 1232
    // Modules may alter all queries or only those having a particular tag.
1233 1233
    if (isset($this->alterTags)) {
1234
      // Many contrib modules assume that query tags used for access-checking
1235
      // purposes follow the pattern $entity_type . '_access'. But this is
1236
      // not the case for taxonomy terms, since core used to add term_access
1237
      // instead of taxonomy_term_access to its queries. Provide backwards
1238
      // compatibility by adding both tags here instead of attempting to fix
1239
      // all contrib modules in a coordinated effort.
1240
      // TODO:
1241
      // - Extract this mechanism into a hook as part of a public (non-security)
1242
      //   issue.
1243
      // - Emit E_USER_DEPRECATED if term_access is used.
1244
      //   https://www.drupal.org/node/2575081
1245
      $term_access_tags = array('term_access' => 1, 'taxonomy_term_access' => 1);
1246
      if (array_intersect_key($this->alterTags, $term_access_tags)) {
1247
        $this->alterTags += $term_access_tags;
1248
      }
1234 1249
      $hooks = array('query');
1235 1250
      foreach ($this->alterTags as $tag => $value) {
1236 1251
        $hooks[] = 'query_' . $tag;
drupal7/includes/database/sqlite/database.inc
378 378
    }
379 379
  }
380 380

  
381
  public function utf8mb4IsActive() {
382
    return TRUE;
383
  }
384

  
385
  public function utf8mb4IsSupported() {
386
    return TRUE;
387
  }
388

  
381 389
}
382 390

  
383 391
/**
drupal7/includes/entity.inc
446 446
 *
447 447
 * This class allows finding entities based on entity properties (for example,
448 448
 * node->changed), field values, and generic entity meta data (bundle,
449
 * entity type, entity id, and revision ID). It is not possible to query across
449
 * entity type, entity ID, and revision ID). It is not possible to query across
450 450
 * multiple entity types. For example, there is no facility to find published
451 451
 * nodes written by users created in the last hour, as this would require
452 452
 * querying both node->status and user->created.
......
688 688
   * @param $field
689 689
   *   Either a field name or a field array.
690 690
   * @param $column
691
   *   The column that should hold the value to be matched.
691
   *   The column that should hold the value to be matched, defined in the
692
   *   hook_field_schema() of this field. If this is omitted then all of the
693
   *   other parameters are ignored, except $field, and this call will just be
694
   *   adding a condition that says that the field has a value, rather than
695
   *   testing the value itself.
692 696
   * @param $value
693
   *   The value to test the column value against.
697
   *   The value to test the column value against. In most cases, this is a
698
   *   scalar. For more complex options, it is an array. The meaning of each
699
   *   element in the array is dependent on $operator.
694 700
   * @param $operator
695
   *   The operator to be used to test the given value.
701
   *   The operator to be used to test the given value. The possible values are:
702
   *   - '=', '<>', '>', '>=', '<', '<=', 'STARTS_WITH', 'CONTAINS': These
703
   *     operators expect $value to be a literal of the same type as the
704
   *     column.
705
   *   - 'IN', 'NOT IN': These operators expect $value to be an array of
706
   *     literals of the same type as the column.
707
   *   - 'BETWEEN': This operator expects $value to be an array of two literals
708
   *     of the same type as the column.
709
   *   The operator can be omitted, and will default to 'IN' if the value is an
710
   *   array, or to '=' otherwise.
696 711
   * @param $delta_group
697 712
   *   An arbitrary identifier: conditions in the same group must have the same
698
   *   $delta_group.
713
   *   $delta_group. For example, let's presume a multivalue field which has
714
   *   two columns, 'color' and 'shape', and for entity ID 1, there are two
715
   *   values: red/square and blue/circle. Entity ID 1 does not have values
716
   *   corresponding to 'red circle'; however if you pass 'red' and 'circle' as
717
   *   conditions, it will appear in the results -- by default queries will run
718
   *   against any combination of deltas. By passing the conditions with the
719
   *   same $delta_group it will ensure that only values attached to the same
720
   *   delta are matched, and entity 1 would then be excluded from the results.
699 721
   * @param $language_group
700 722
   *   An arbitrary identifier: conditions in the same group must have the same
701 723
   *   $language_group.
......
770 792
   * @param $field
771 793
   *   Either a field name or a field array.
772 794
   * @param $column
773
   *   A column defined in the hook_field_schema() of this field. If this is
774
   *   omitted then the query will find only entities that have data in this
775
   *   field, using the entity and property conditions if there are any.
795
   *   The column that should hold the value to be matched, defined in the
796
   *   hook_field_schema() of this field. If this is omitted then all of the
797
   *   other parameters are ignored, except $field, and this call will just be
798
   *   adding a condition that says that the field has a value, rather than
799
   *   testing the value itself.
776 800
   * @param $value
777 801
   *   The value to test the column value against. In most cases, this is a
778 802
   *   scalar. For more complex options, it is an array. The meaning of each
......
791 815
   * @param $delta_group
792 816
   *   An arbitrary identifier: conditions in the same group must have the same
793 817
   *   $delta_group. For example, let's presume a multivalue field which has
794
   *   two columns, 'color' and 'shape', and for entity id 1, there are two
818
   *   two columns, 'color' and 'shape', and for entity ID 1, there are two
795 819
   *   values: red/square and blue/circle. Entity ID 1 does not have values
796 820
   *   corresponding to 'red circle', however if you pass 'red' and 'circle' as
797
   *   conditions, it will appear in the  results - by default queries will run
821
   *   conditions, it will appear in the results -- by default queries will run
798 822
   *   against any combination of deltas. By passing the conditions with the
799 823
   *   same $delta_group it will ensure that only values attached to the same
800 824
   *   delta are matched, and entity 1 would then be excluded from the results.
drupal7/includes/errors.inc
199 199
    $number++;
200 200
  }
201 201

  
202
  watchdog('php', '%type: !message in %function (line %line of %file).', $error, $error['severity_level']);
202
  // Log the error immediately, unless this is a non-fatal error which has been
203
  // triggered via drupal_trigger_error_with_delayed_logging(); in that case
204
  // trigger it in a shutdown function. Fatal errors are always triggered
205
  // immediately since for a fatal error the page request will end here anyway.
206
  if (!$fatal && drupal_static('_drupal_trigger_error_with_delayed_logging')) {
207
    drupal_register_shutdown_function('watchdog', 'php', '%type: !message in %function (line %line of %file).', $error, $error['severity_level']);
208
  }
209
  else {
210
    watchdog('php', '%type: !message in %function (line %line of %file).', $error, $error['severity_level']);
211
  }
203 212

  
204 213
  if ($fatal) {
205 214
    drupal_add_http_header('Status', '500 Service unavailable (with message)');
drupal7/includes/file.inc
273 273
 *   The normalized URI.
274 274
 */
275 275
function file_stream_wrapper_uri_normalize($uri) {
276
  $scheme = file_uri_scheme($uri);
276
  // Inline file_uri_scheme() function call for performance reasons.
277
  $position = strpos($uri, '://');
278
  $scheme = $position ? substr($uri, 0, $position) : FALSE;
277 279

  
278 280
  if ($scheme && file_stream_wrapper_valid_scheme($scheme)) {
279 281
    $target = file_uri_target($uri);
......
2022 2024
 *
2023 2025
 * @see file_transfer()
2024 2026
 * @see file_download_access()
2025
 * @see hook_file_downlaod()
2027
 * @see hook_file_download()
2026 2028
 */
2027 2029
function file_download_headers($uri) {
2028 2030
  // Let other modules provide headers and control access to the file.
drupal7/includes/form.inc
105 105
 *   generate the same form (or very similar forms) using different $form_ids
106 106
 *   can implement hook_forms(), which maps different $form_id values to the
107 107
 *   proper form constructor function. Examples may be found in node_forms(),
108
 *   and search_forms().
108
 *   and search_forms(). hook_forms() can also be used to define forms in
109
 *   classes.
109 110
 * @param ...
110 111
 *   Any additional arguments are passed on to the functions called by
111 112
 *   drupal_get_form(), including the unique form constructor function. For
......
809 810
    }
810 811
    if (isset($form_definition['callback'])) {
811 812
      $callback = $form_definition['callback'];
812
      $form_state['build_info']['base_form_id'] = $callback;
813
      $form_state['build_info']['base_form_id'] = isset($form_definition['base_form_id']) ? $form_definition['base_form_id'] : $callback;
813 814
    }
814 815
    // In case $form_state['wrapper_callback'] is not defined already, we also
815 816
    // allow hook_forms() to define one.
......
830 831
  // the actual form builder function ($callback) expects. This allows for
831 832
  // pre-populating a form with common elements for certain forms, such as
832 833
  // back/next/save buttons in multi-step form wizards. See drupal_build_form().
833
  if (isset($form_state['wrapper_callback']) && function_exists($form_state['wrapper_callback'])) {
834
  if (isset($form_state['wrapper_callback']) && is_callable($form_state['wrapper_callback'])) {
834 835
    $form = call_user_func_array($form_state['wrapper_callback'], $args);
835 836
    // Put the prepopulated $form into $args.
836 837
    $args[0] = $form;
......
2571 2572
 *   for this element. Return nothing to use the default.
2572 2573
 */
2573 2574
function form_type_textarea_value($element, $input = FALSE) {
2574
  if ($input !== FALSE) {
2575
  if ($input !== FALSE && $input !== NULL) {
2575 2576
    // This should be a string, but allow other scalars since they might be
2576 2577
    // valid input in programmatic form submissions.
2577 2578
    return is_scalar($input) ? (string) $input : '';
......
3028 3029
function password_confirm_validate($element, &$element_state) {
3029 3030
  $pass1 = trim($element['pass1']['#value']);
3030 3031
  $pass2 = trim($element['pass2']['#value']);
3031
  if (!empty($pass1) || !empty($pass2)) {
3032
  if (strlen($pass1) > 0 || strlen($pass2) > 0) {
3032 3033
    if (strcmp($pass1, $pass2)) {
3033 3034
      form_error($element, t('The specified passwords do not match.'));
3034 3035
    }
......
3545 3546
            '#return_value' => $key,
3546 3547
            '#default_value' => isset($value[$key]) ? $key : NULL,
3547 3548
            '#attributes' => $element['#attributes'],
3549
            '#ajax' => isset($element['#ajax']) ? $element['#ajax'] : NULL,
3548 3550
          );
3549 3551
        }
3550 3552
        else {
drupal7/includes/install.core.inc
809 809

  
810 810
  variable_set('install_profile_modules', array_diff($modules, array('system')));
811 811
  $install_state['database_tables_exist'] = TRUE;
812

  
813
  // Prevent the hook_requirements() check from telling us to convert the
814
  // database to utf8mb4.
815
  $connection = Database::getConnection();
816
  if ($connection->utf8mb4IsConfigurable() && $connection->utf8mb4IsActive()) {
817
    variable_set('drupal_all_databases_are_utf8mb4', TRUE);
818
  }
812 819
}
813 820

  
814 821
/**
drupal7/includes/locale.inc
435 435
    switch (variable_get('locale_language_negotiation_url_part', LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX)) {
436 436
      case LOCALE_LANGUAGE_NEGOTIATION_URL_DOMAIN:
437 437
        if ($options['language']->domain) {
438
          // Save the original base URL. If it contains a port, we need to
439
          // retain it below.
440
          if (!empty($options['base_url'])) {
441
            // The colon in the URL scheme messes up the port checking below.
442
            $normalized_base_url = str_replace(array('https://', 'http://'), '', $options['base_url']);
443
          }
444

  
438 445
          // Ask for an absolute URL with our modified base_url.
439 446
          global $is_https;
440 447
          $url_scheme = ($is_https) ? 'https://' : 'http://';
......
449 456

  
450 457
          // Apply the appropriate protocol to the URL.
451 458
          $options['base_url'] = $url_scheme . $host;
459

  
460
          // In case either the original base URL or the HTTP host contains a
461
          // port, retain it.
462
          $http_host = $_SERVER['HTTP_HOST'];
463
          if (isset($normalized_base_url) && strpos($normalized_base_url, ':') !== FALSE) {
464
            list($host, $port) = explode(':', $normalized_base_url);
465
            $options['base_url'] .= ':' . $port;
466
          }
467
          elseif (strpos($http_host, ':') !== FALSE) {
468
            list($host, $port) = explode(':', $http_host);
469
            $options['base_url'] .= ':' . $port;
470
          }
471

  
452 472
          if (isset($options['https']) && variable_get('https', FALSE)) {
453 473
            if ($options['https'] === TRUE) {
454 474
              $options['base_url'] = str_replace('http://', 'https://', $options['base_url']);
......
523 543
 * possible attack vector (img).
524 544
 */
525 545
function locale_string_is_safe($string) {
546
  // Some strings have tokens in them. For tokens in the first part of href or
547
  // src HTML attributes, filter_xss() removes part of the token, the part
548
  // before the first colon.  filter_xss() assumes it could be an attempt to
549
  // inject javascript. When filter_xss() removes part of tokens, it causes the
550
  // string to not be translatable when it should be translatable. See
551
  // LocaleStringIsSafeTest::testLocaleStringIsSafe().
552
  //
553
  // We can recognize tokens since they are wrapped with brackets and are only
554
  // composed of alphanumeric characters, colon, underscore, and dashes. We can
555
  // be sure these strings are safe to strip out before the string is checked in
556
  // filter_xss() because no dangerous javascript will match that pattern.
557
  //
558
  // @todo Do not strip out the token. Fix filter_xss() to not incorrectly
559
  //   alter the string. https://www.drupal.org/node/2372127
560
  $string = preg_replace('/\[[a-z0-9_-]+(:[a-z0-9_-]+)+\]/i', '', $string);
561

  
526 562
  return decode_entities($string) == decode_entities(filter_xss($string, array('a', 'abbr', 'acronym', 'address', 'b', 'bdo', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'col', 'colgroup', 'dd', 'del', 'dfn', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'ins', 'kbd', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'sub', 'sup', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var')));
527 563
}
528 564

  
......
631 667
 *   translations).
632 668
 */
633 669
function _locale_import_po($file, $langcode, $mode, $group = NULL) {
634
  // Try to allocate enough time to parse and import the data.
635
  drupal_set_time_limit(240);
636

  
637 670
  // Check if we have the language already in the database.
638 671
  if (!db_query("SELECT COUNT(language) FROM {languages} WHERE language = :language", array(':language' => $langcode))->fetchField()) {
639 672
    drupal_set_message(t('The language selected for import is not supported.'), 'error');
......
717 750
  $lineno = 0;
718 751

  
719 752
  while (!feof($fd)) {
753
    // Refresh the time limit every 10 parsed rows to ensure there is always
754
    // enough time to import the data for large PO files.
755
    if (!($lineno % 10)) {
756
      drupal_set_time_limit(30);
757
    }
758

  
720 759
    // A line should not be longer than 10 * 1024.
721 760
    $line = fgets($fd, 10 * 1024);
722 761

  
drupal7/includes/menu.inc
2419 2419
          // argument placeholders (%). Such links are not contained in regular
2420 2420
          // menu trees, and have only been loaded for the additional
2421 2421
          // translation that happens here, so as to be able to display them in
2422
          // the breadcumb for the current page.
2422
          // the breadcrumb for the current page.
2423 2423
          // @see _menu_tree_check_access()
2424 2424
          // @see _menu_link_translate()
2425 2425
          if (strpos($link['href'], '%') !== FALSE) {
drupal7/includes/module.inc
227 227
  drupal_static_reset('list_themes');
228 228
  cache_clear_all('bootstrap_modules', 'cache_bootstrap');
229 229
  cache_clear_all('system_list', 'cache_bootstrap');
230

  
231
  // Clean up the bootstrap file scan cache.
232
  drupal_static_reset('_drupal_file_scan_cache');
233
  cache_clear_all('_drupal_file_scan_cache', 'cache_bootstrap');
230 234
}
231 235

  
232 236
/**
......
936 940
 *
937 941
 * @return
938 942
 *   An array of return values of the hook implementations. If modules return
939
 *   arrays from their implementations, those are merged into one array.
943
 *   arrays from their implementations, those are merged into one array
944
 *   recursively. Note: integer keys in arrays will be lost, as the merge is
945
 *   done using array_merge_recursive().
940 946
 *
941 947
 * @see drupal_alter()
942 948
 */
drupal7/includes/session.inc
163 163
  try {
164 164
    if (!drupal_save_session()) {
165 165
      // We don't have anything to do if we are not allowed to save the session.
166
      return;
166
      return TRUE;
167 167
    }
168 168

  
169 169
    // Check whether $_SESSION has been changed in this request.
......
425 425

  
426 426
  // Nothing to do if we are not allowed to change the session.
427 427
  if (!drupal_save_session()) {
428
    return;
428
    return TRUE;
429 429
  }
430 430

  
431 431
  // Delete session data.
......
446 446
  elseif (variable_get('https', FALSE)) {
447 447
    _drupal_session_delete_cookie('S' . session_name(), TRUE);
448 448
  }
449

  
450
  return TRUE;
449 451
}
450 452

  
451 453
/**
drupal7/includes/theme.inc
1248 1248
function drupal_find_theme_functions($cache, $prefixes) {
1249 1249
  $implementations = array();
1250 1250
  $functions = get_defined_functions();
1251
  $theme_functions = preg_grep('/^(' . implode(')|(', $prefixes) . ')_/', $functions['user']);
1251 1252

  
1252 1253
  foreach ($cache as $hook => $info) {
1253 1254
    foreach ($prefixes as $prefix) {
......
1264 1265
      // intermediary suggestion.
1265 1266
      $pattern = isset($info['pattern']) ? $info['pattern'] : ($hook . '__');
1266 1267
      if (!isset($info['base hook']) && !empty($pattern)) {
1267
        $matches = preg_grep('/^' . $prefix . '_' . $pattern . '/', $functions['user']);
1268
        $matches = preg_grep('/^' . $prefix . '_' . $pattern . '/', $theme_functions);
1268 1269
        if ($matches) {
1269 1270
          foreach ($matches as $match) {
1270 1271
            $new_hook = substr($match, strlen($prefix) + 1);
......
2638 2639
  // Move some variables to the top level for themer convenience and template cleanliness.
2639 2640
  $variables['show_messages'] = $variables['page']['#show_messages'];
2640 2641

  
2641
  foreach (system_region_list($GLOBALS['theme']) as $region_key => $region_name) {
2642
  foreach (system_region_list($GLOBALS['theme'], REGIONS_ALL, FALSE) as $region_key) {
2642 2643
    if (!isset($variables['page'][$region_key])) {
2643 2644
      $variables['page'][$region_key] = array();
2644 2645
    }
drupal7/includes/update.inc
795 795
function update_fix_d7_install_profile() {
796 796
  $profile = drupal_get_profile();
797 797

  
798
  // 'Default' profile has been renamed to 'Standard' in D7.
799
  // We change the profile here to prevent a broken record in the system table.
800
  // See system_update_7049().
801
  if ($profile == 'default') {
802
    $profile = 'standard';
803
    variable_set('install_profile', $profile);
804
  }
805

  
798 806
  $results = db_select('system', 's')
799 807
    ->fields('s', array('name', 'schema_version'))
800 808
    ->condition('name', $profile)
drupal7/misc/ajax.js
476 476
 * Handler for the form redirection error.
477 477
 */
478 478
Drupal.ajax.prototype.error = function (xmlhttprequest, uri, customMessage) {
479
  alert(Drupal.ajaxError(xmlhttprequest, uri, customMessage));
479
  Drupal.displayAjaxError(Drupal.ajaxError(xmlhttprequest, uri, customMessage));
480 480
  // Remove the progress element.
481 481
  if (this.progress.element) {
482 482
    $(this.progress.element).remove();
drupal7/misc/autocomplete.js
310 310
        }
311 311
      },
312 312
      error: function (xmlhttp) {
313
        alert(Drupal.ajaxError(xmlhttp, db.uri));
313
        Drupal.displayAjaxError(Drupal.ajaxError(xmlhttp, db.uri));
314 314
      }
315 315
    });
316 316
  }, this.delay);
drupal7/misc/drupal.js
413 413
  return { 'start': element.selectionStart, 'end': element.selectionEnd };
414 414
};
415 415

  
416
/**
417
 * Add a global variable which determines if the window is being unloaded.
418
 *
419
 * This is primarily used by Drupal.displayAjaxError().
420
 */
421
Drupal.beforeUnloadCalled = false;
422
$(window).bind('beforeunload pagehide', function () {
423
    Drupal.beforeUnloadCalled = true;
424
});
425

  
426
/**
427
 * Displays a JavaScript error from an Ajax response when appropriate to do so.
428
 */
429
Drupal.displayAjaxError = function (message) {
430
  // Skip displaying the message if the user deliberately aborted (for example,
431
  // by reloading the page or navigating to a different page) while the Ajax
432
  // request was still ongoing. See, for example, the discussion at
433
  // http://stackoverflow.com/questions/699941/handle-ajax-error-when-a-user-clicks-refresh.
434
  if (!Drupal.beforeUnloadCalled) {
435
    alert(message);
436
  }
437
};
438

  
416 439
/**
417 440
 * Build an error message from an Ajax response.
418 441
 */
drupal7/misc/tabledrag.js
106 106

  
107 107
  // Add mouse bindings to the document. The self variable is passed along
108 108
  // as event handlers do not have direct access to the tableDrag object.
109
  $(document).bind('mousemove', function (event) { return self.dragRow(event, self); });
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff