diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc index a91c398f4a..66e256f840 100644 --- a/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -3785,8 +3785,12 @@ function _drupal_shutdown_function() { chdir(DRUPAL_ROOT); try { - while (list($key, $callback) = each($callbacks)) { + // Manually iterate over the array instead of using a foreach loop. + // A foreach operates on a copy of the array, so any shutdown functions that + // were added from other shutdown functions would never be called. + while ($callback = current($callbacks)) { call_user_func_array($callback['callback'], $callback['arguments']); + next($callbacks); } } catch (Exception $exception) { diff --git a/includes/form.inc b/includes/form.inc index e749239ef9..54e77ab8d5 100644 --- a/includes/form.inc +++ b/includes/form.inc @@ -1438,10 +1438,11 @@ function _form_validate(&$elements, &$form_state, $form_id = NULL) { // length if it's a string, and the item count if it's an array. // An unchecked checkbox has a #value of integer 0, different than string // '0', which could be a valid value. - $is_empty_multiple = (!count($elements['#value'])); + $is_empty_multiple = (is_array($elements['#value']) || $elements['#value'] instanceof Countable) && count($elements['#value']) === 0; + $is_empty_null = $elements['#value'] === NULL; $is_empty_string = (is_string($elements['#value']) && drupal_strlen(trim($elements['#value'])) == 0); $is_empty_value = ($elements['#value'] === 0); - if ($is_empty_multiple || $is_empty_string || $is_empty_value) { + if ($is_empty_multiple || $is_empty_string || $is_empty_value || $is_empty_null) { // Although discouraged, a #title is not mandatory for form elements. In // case there is no #title, we cannot set a form error message. // Instead of setting no #title, form constructors are encouraged to set diff --git a/includes/install.inc b/includes/install.inc index 5e1d3c6326..b7db783586 100644 --- a/includes/install.inc +++ b/includes/install.inc @@ -779,7 +779,7 @@ function drupal_uninstall_modules($module_list = array(), $uninstall_dependents $module_list = array_flip(array_values($module_list)); $profile = drupal_get_profile(); - while (list($module) = each($module_list)) { + foreach (array_keys($module_list) as $module) { if (!isset($module_data[$module]) || drupal_get_installed_schema_version($module) == SCHEMA_UNINSTALLED) { // This module doesn't exist or is already uninstalled. Skip it. unset($module_list[$module]); diff --git a/includes/menu.inc b/includes/menu.inc index 4664d27e89..ca37ba509d 100644 --- a/includes/menu.inc +++ b/includes/menu.inc @@ -576,7 +576,8 @@ function _menu_load_objects(&$item, &$map) { // 'load arguments' in the hook_menu() entry, but they need // some processing. In this case the $function is the key to the // load_function array, and the value is the list of arguments. - list($function, $args) = each($function); + $args = current($function); + $function = key($function); $load_functions[$index] = $function; // Some arguments are placeholders for dynamic items to process. @@ -2402,7 +2403,8 @@ function menu_set_active_trail($new_trail = NULL) { // a stripped down menu tree containing the active trail only, in case // the given menu has not been built in this request yet. $tree = menu_tree_page_data($preferred_link['menu_name'], NULL, TRUE); - list($key, $curr) = each($tree); + $curr = current($tree); + next($tree); } // There is no link for the current path. else { @@ -2432,7 +2434,8 @@ function menu_set_active_trail($new_trail = NULL) { } $tree = $curr['below'] ? $curr['below'] : array(); } - list($key, $curr) = each($tree); + $curr = current($tree); + next($tree); } // Make sure the current page is in the trail to build the page title, by // appending either the preferred link or the menu router item for the diff --git a/includes/module.inc b/includes/module.inc index 2e251080b7..4c2b3fbeeb 100644 --- a/includes/module.inc +++ b/includes/module.inc @@ -404,7 +404,11 @@ function module_enable($module_list, $enable_dependencies = TRUE) { // Create an associative array with weights as values. $module_list = array_flip(array_values($module_list)); - while (list($module) = each($module_list)) { + // The array is iterated over manually (instead of using a foreach) because + // modules may be added to the list within the loop and we need to process + // them. + while ($module = key($module_list)) { + next($module_list); if (!isset($module_data[$module])) { // This module is not found in the filesystem, abort. return FALSE; @@ -540,7 +544,11 @@ function module_disable($module_list, $disable_dependents = TRUE) { $module_list = array_flip(array_values($module_list)); $profile = drupal_get_profile(); - while (list($module) = each($module_list)) { + // The array is iterated over manually (instead of using a foreach) because + // modules may be added to the list within the loop and we need to process + // them. + while ($module = key($module_list)) { + next($module_list); if (!isset($module_data[$module]) || !$module_data[$module]->status) { // This module doesn't exist or is already disabled, skip it. unset($module_list[$module]); diff --git a/includes/theme.inc b/includes/theme.inc index 9b606e9fb1..b574fd7473 100644 --- a/includes/theme.inc +++ b/includes/theme.inc @@ -1986,11 +1986,11 @@ function theme_breadcrumb($variables) { * rows. */ function theme_table($variables) { - $header = $variables['header']; - $rows = $variables['rows']; + $header = (array) $variables['header']; + $rows = (array) $variables['rows']; $attributes = $variables['attributes']; $caption = $variables['caption']; - $colgroups = $variables['colgroups']; + $colgroups = (array) $variables['colgroups']; $sticky = $variables['sticky']; $empty = $variables['empty']; diff --git a/modules/book/book.module b/modules/book/book.module index 7afed9ae42..32047f93f5 100644 --- a/modules/book/book.module +++ b/modules/book/book.module @@ -768,11 +768,13 @@ function book_prev($book_link) { return NULL; } $flat = book_get_flat_menu($book_link); - // Assigning the array to $flat resets the array pointer for use with each(). + reset($flat); $curr = NULL; do { $prev = $curr; - list($key, $curr) = each($flat); + $curr = current($flat); + $key = key($flat); + next($flat); } while ($key && $key != $book_link['mlid']); if ($key == $book_link['mlid']) { @@ -806,9 +808,10 @@ function book_prev($book_link) { */ function book_next($book_link) { $flat = book_get_flat_menu($book_link); - // Assigning the array to $flat resets the array pointer for use with each(). + reset($flat); do { - list($key, $curr) = each($flat); + $key = key($flat); + next($flat); } while ($key && $key != $book_link['mlid']); diff --git a/modules/locale/locale.test b/modules/locale/locale.test index db87e05548..b890b06147 100644 --- a/modules/locale/locale.test +++ b/modules/locale/locale.test @@ -3188,11 +3188,7 @@ class LocaleLanguageNegotiationInfoFunctionalTest extends DrupalWebTestCase { foreach (language_types_info() as $type => $info) { if (isset($info['fixed'])) { $negotiation = variable_get("language_negotiation_$type", array()); - $equal = count($info['fixed']) == count($negotiation); - while ($equal && list($id) = each($negotiation)) { - list(, $info_id) = each($info['fixed']); - $equal = $info_id == $id; - } + $equal = array_keys($negotiation) === array_values($info['fixed']); $this->assertTrue($equal, format_string('language negotiation for %type is properly set up', array('%type' => $type))); } } diff --git a/modules/system/system.tar.inc b/modules/system/system.tar.inc index 86e4e3de4a..fbf285c006 100644 --- a/modules/system/system.tar.inc +++ b/modules/system/system.tar.inc @@ -41,8 +41,8 @@ /** * Note on Drupal 8 porting. - * This file origin is Tar.php, release 1.4.0 (stable) with some code - * from PEAR.php, release 1.9.5 (stable) both at http://pear.php.net. + * This file origin is Tar.php, release 1.4.3 (stable) with some code + * from PEAR.php, release 1.10.5 (stable) both at http://pear.php.net. * To simplify future porting from pear of this file, you should not * do cosmetic or other non significant changes to this file. * The following changes have been done: @@ -259,6 +259,17 @@ class Archive_Tar return false; } } + + if (version_compare(PHP_VERSION, "5.5.0-dev") < 0) { + $this->_fmt = "a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/" . + "a8checksum/a1typeflag/a100link/a6magic/a2version/" . + "a32uname/a32gname/a8devmajor/a8devminor/a131prefix"; + } else { + $this->_fmt = "Z100filename/Z8mode/Z8uid/Z8gid/Z12size/Z12mtime/" . + "Z8checksum/Z1typeflag/Z100link/Z6magic/Z2version/" . + "Z32uname/Z32gname/Z8devmajor/Z8devminor/Z131prefix"; + } + } public function __destruct() @@ -278,7 +289,7 @@ class Archive_Tar * @param string $ext The extension name * @return bool Success or not on the dl() call */ - function loadExtension($ext) + public static function loadExtension($ext) { if (extension_loaded($ext)) { return true; @@ -287,8 +298,7 @@ class Archive_Tar // if either returns true dl() will produce a FATAL error, stop that if ( function_exists('dl') === false || - ini_get('enable_dl') != 1 || - ini_get('safe_mode') == 1 + ini_get('enable_dl') != 1 ) { return false; } @@ -714,7 +724,7 @@ class Archive_Tar } // ----- Get the arguments - $v_att_list = & func_get_args(); + $v_att_list = func_get_args(); // ----- Read the attributes $i = 0; @@ -1720,28 +1730,13 @@ class Archive_Tar // ----- Calculate the checksum $v_checksum = 0; // ..... First part of the header - for ($i = 0; $i < 148; $i++) { - $v_checksum += ord(substr($v_binary_data, $i, 1)); - } - // ..... Ignore the checksum value and replace it by ' ' (space) - for ($i = 148; $i < 156; $i++) { - $v_checksum += ord(' '); - } - // ..... Last part of the header - for ($i = 156; $i < 512; $i++) { - $v_checksum += ord(substr($v_binary_data, $i, 1)); - } + $v_binary_split = str_split($v_binary_data); + $v_checksum += array_sum(array_map('ord', array_slice($v_binary_split, 0, 148))); + $v_checksum += array_sum(array_map('ord', array(' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',))); + $v_checksum += array_sum(array_map('ord', array_slice($v_binary_split, 156, 512))); - if (version_compare(PHP_VERSION, "5.5.0-dev") < 0) { - $fmt = "a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/" . - "a8checksum/a1typeflag/a100link/a6magic/a2version/" . - "a32uname/a32gname/a8devmajor/a8devminor/a131prefix"; - } else { - $fmt = "Z100filename/Z8mode/Z8uid/Z8gid/Z12size/Z12mtime/" . - "Z8checksum/Z1typeflag/Z100link/Z6magic/Z2version/" . - "Z32uname/Z32gname/Z8devmajor/Z8devminor/Z131prefix"; - } - $v_data = unpack($fmt, $v_binary_data); + + $v_data = unpack($this->_fmt, $v_binary_data); if (strlen($v_data["prefix"]) > 0) { $v_data["filename"] = "$v_data[prefix]/$v_data[filename]"; @@ -1777,7 +1772,7 @@ class Archive_Tar $v_header['mode'] = OctDec(trim($v_data['mode'])); $v_header['uid'] = OctDec(trim($v_data['uid'])); $v_header['gid'] = OctDec(trim($v_data['gid'])); - $v_header['size'] = OctDec(trim($v_data['size'])); + $v_header['size'] = $this->_tarRecToSize($v_data['size']); $v_header['mtime'] = OctDec(trim($v_data['mtime'])); if (($v_header['typeflag'] = $v_data['typeflag']) == "5") { $v_header['size'] = 0; @@ -1796,6 +1791,40 @@ class Archive_Tar return true; } + /** + * Convert Tar record size to actual size + * + * @param string $tar_size + * @return size of tar record in bytes + */ + private function _tarRecToSize($tar_size) + { + /* + * First byte of size has a special meaning if bit 7 is set. + * + * Bit 7 indicates base-256 encoding if set. + * Bit 6 is the sign bit. + * Bits 5:0 are most significant value bits. + */ + $ch = ord($tar_size[0]); + if ($ch & 0x80) { + // Full 12-bytes record is required. + $rec_str = $tar_size . "\x00"; + + $size = ($ch & 0x40) ? -1 : 0; + $size = ($size << 6) | ($ch & 0x3f); + + for ($num_ch = 1; $num_ch < 12; ++$num_ch) { + $size = ($size * 256) + ord($rec_str[$num_ch]); + } + + return $size; + + } else { + return OctDec(trim($tar_size)); + } + } + /** * Detect and report a malicious file name *