From 3e914018def1d59501a65857eb923f60f72afb79 Mon Sep 17 00:00:00 2001
From: Dries Buytaert <dries@buytaert.net>
Date: Sat, 19 Feb 2011 13:24:32 +0000
Subject: [PATCH] - Patch #880278 by RoboPhred: cleanup
 _locale_import_read_po().

---
 includes/bootstrap.inc               |  25 +++-
 includes/locale.inc                  | 193 ++++++++++++++++++++-------
 includes/session.inc                 |   4 +-
 modules/simpletest/tests/common.test |   4 +-
 4 files changed, 167 insertions(+), 59 deletions(-)

diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index 0739332a4a01..a8ef38a5beeb 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -1136,6 +1136,7 @@ function drupal_serve_page_from_cache(stdClass $cache) {
   $etag = '"' . $cache->created . '-' . intval($return_compressed) . '"';
   header('Etag: ' . $etag);
 
+  drupal_set_configured_timezone();
   // See if the client has provided the required HTTP headers.
   $if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) : FALSE;
   $if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : FALSE;
@@ -1943,9 +1944,26 @@ function drupal_get_user_timezone() {
     return $user->timezone;
   }
   else {
-    // Ignore PHP strict notice if time zone has not yet been set in the php.ini
-    // configuration.
-    return variable_get('date_default_timezone', @date_default_timezone_get());
+    // Note that is no site-wide timezone is set, and date.timezone is not set
+    // in php.ini, then calling date functions will cause a system call and
+    // PHP will issue an E_STRICT or E_WARNING error depending on PHP version.
+    // @todo: consider always setting the date_default_timezone variable from 
+    // the installer.
+    return variable_get('date_default_timezone');
+  }
+}
+
+/**
+ * Set the timezone for a request when configured.
+ */
+function drupal_set_configured_timezone() {
+  $configured_timezone = drupal_get_user_timezone();
+  $system_timezone = ini_get('date.timezone');
+  // There is no point setting the timezone if it is configured the same
+  // as date.timezone in php.ini. Also date_default_timezone_set() validates 
+  // the timezone, which relies on a system call to get the timezone database.
+  if ($configured_timezone != $system_timezone) {
+    date_default_timezone_set($configured_timezone);
   }
 }
 
@@ -2046,7 +2064,6 @@ function _drupal_bootstrap_page_cache() {
       // Restore the metadata cached with the page.
       $_GET['q'] = $cache->data['path'];
       drupal_set_title($cache->data['title'], PASS_THROUGH);
-      date_default_timezone_set(drupal_get_user_timezone());
       // If the skipping of the bootstrap hooks is not enforced, call
       // hook_boot.
       if (variable_get('page_cache_invoke_hooks', TRUE)) {
diff --git a/includes/locale.inc b/includes/locale.inc
index d6db7c17c6a0..9a1224842fbf 100644
--- a/includes/locale.inc
+++ b/includes/locale.inc
@@ -586,159 +586,250 @@ function _locale_import_po($file, $langcode, $mode, $group = NULL) {
  */
 function _locale_import_read_po($op, $file, $mode = NULL, $lang = NULL, $group = 'default') {
 
-  $fd = fopen($file->uri, "rb"); // File will get closed by PHP on return
+  // The file will get closed by PHP on returning from this function.
+  $fd = fopen($file->uri, 'rb');
   if (!$fd) {
     _locale_import_message('The translation import failed, because the file %filename could not be read.', $file);
     return FALSE;
   }
 
-  $context = "COMMENT"; // Parser context: COMMENT, MSGID, MSGID_PLURAL, MSGSTR and MSGSTR_ARR
-  $current = array();   // Current entry being read
-  $plural = 0;          // Current plural form
-  $lineno = 0;          // Current line
+  /*
+   * The parser context. Can be:
+   *  - 'COMMENT' (#)
+   *  - 'MSGID' (msgid)
+   *  - 'MSGID_PLURAL' (msgid_plural)
+   *  - 'MSGCTXT' (msgctxt)
+   *  - 'MSGSTR' (msgstr or msgstr[])
+   *  - 'MSGSTR_ARR' (msgstr_arg)
+   */
+  $context = 'COMMENT';
+
+  // Current entry being read.
+  $current = array();
+
+  // Current plurality for 'msgstr[]'.
+  $plural = 0;
+
+  // Current line.
+  $lineno = 0;
 
   while (!feof($fd)) {
-    $line = fgets($fd, 10*1024); // A line should not be this long
+    // A line should not be longer than 10 * 1024.
+    $line = fgets($fd, 10 * 1024);
+
     if ($lineno == 0) {
       // The first line might come with a UTF-8 BOM, which should be removed.
       $line = str_replace("\xEF\xBB\xBF", '', $line);
     }
+
     $lineno++;
+
+    // Trim away the linefeed.
     $line = trim(strtr($line, array("\\\n" => "")));
 
-    if (!strncmp("#", $line, 1)) { // A comment
-      if ($context == "COMMENT") { // Already in comment context: add
-        $current["#"][] = substr($line, 1);
+    if (!strncmp('#', $line, 1)) {
+      // Lines starting with '#' are comments.
+
+      if ($context == 'COMMENT') {
+        // Already in comment token, insert the comment.
+        $current['#'][] = substr($line, 1);
       }
-      elseif (($context == "MSGSTR") || ($context == "MSGSTR_ARR")) { // End current entry, start a new one
+      elseif (($context == 'MSGSTR') || ($context == 'MSGSTR_ARR')) {
+        // We are currently in string token, close it out.
         _locale_import_one_string($op, $current, $mode, $lang, $file, $group);
-        $current = array();
-        $current["#"][] = substr($line, 1);
-        $context = "COMMENT";
+
+        // Start a new entry for the comment.
+        $current         = array();
+        $current['#'][]  = substr($line, 1);
+
+        $context = 'COMMENT';
       }
-      else { // Parse error
+      else {
+        // A comment following any other token is a syntax error.
         _locale_import_message('The translation file %filename contains an error: "msgstr" was expected but not found on line %line.', $file, $lineno);
         return FALSE;
       }
     }
-    elseif (!strncmp("msgid_plural", $line, 12)) {
-      if ($context != "MSGID") { // Must be plural form for current entry
+    elseif (!strncmp('msgid_plural', $line, 12)) {
+      // A plural form for the current message.
+
+      if ($context != 'MSGID') {
+        // A plural form cannot be added to anything else but the id directly.
         _locale_import_message('The translation file %filename contains an error: "msgid_plural" was expected but not found on line %line.', $file, $lineno);
         return FALSE;
       }
+
+      // Remove 'msgid_plural' and trim away whitespace.
       $line = trim(substr($line, 12));
+      // At this point, $line should now contain only the plural form.
+
       $quoted = _locale_import_parse_quoted($line);
       if ($quoted === FALSE) {
+        // The plural form must be wrapped in quotes.
         _locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
         return FALSE;
       }
-      $current["msgid"] = $current["msgid"] . "\0" . $quoted;
-      $context = "MSGID_PLURAL";
+
+      // Append the plural form to the current entry.
+      $current['msgid'] .= "\0" . $quoted;
+
+      $context = 'MSGID_PLURAL';
     }
-    elseif (!strncmp("msgid", $line, 5)) {
-      if (($context == "MSGSTR") || ($context == "MSGSTR_ARR")) {   // End current entry, start a new one
+    elseif (!strncmp('msgid', $line, 5)) {
+      // Starting a new message.
+
+      if (($context == 'MSGSTR') || ($context == 'MSGSTR_ARR')) {
+        // We are currently in a message string, close it out.
         _locale_import_one_string($op, $current, $mode, $lang, $file, $group);
+
+        // Start a new context for the id.
         $current = array();
       }
-      elseif ($context == "MSGID") { // Already in this context? Parse error
+      elseif ($context == 'MSGID') {
+        // We are currently already in the context, meaning we passed an id with no data.
         _locale_import_message('The translation file %filename contains an error: "msgid" is unexpected on line %line.', $file, $lineno);
         return FALSE;
       }
+
+      // Remove 'msgid' and trim away whitespace.
       $line = trim(substr($line, 5));
+      // At this point, $line should now contain only the message id.
+
       $quoted = _locale_import_parse_quoted($line);
       if ($quoted === FALSE) {
+        // The message id must be wrapped in quotes.
         _locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
         return FALSE;
       }
-      $current["msgid"] = $quoted;
-      $context = "MSGID";
+
+      $current['msgid'] = $quoted;
+      $context = 'MSGID';
     }
-    elseif (!strncmp("msgctxt", $line, 7)) {
-      if (($context == "MSGSTR") || ($context == "MSGSTR_ARR")) {   // End current entry, start a new one
+    elseif (!strncmp('msgctxt', $line, 7)) {
+      // Starting a new context.
+
+      if (($context == 'MSGSTR') || ($context == 'MSGSTR_ARR')) {
+        // We are currently in a message, start a new one.
         _locale_import_one_string($op, $current, $mode, $lang, $file, $group);
         $current = array();
       }
-      elseif (!empty($current["msgctxt"])) { // Already in this context? Parse error
+      elseif (!empty($current['msgctxt'])) {
+        // A context cannot apply to another context.
         _locale_import_message('The translation file %filename contains an error: "msgctxt" is unexpected on line %line.', $file, $lineno);
         return FALSE;
       }
+
+      // Remove 'msgctxt' and trim away whitespaces.
       $line = trim(substr($line, 7));
+      // At this point, $line should now contain the context.
+
       $quoted = _locale_import_parse_quoted($line);
       if ($quoted === FALSE) {
+        // The context string must be quoted.
         _locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
         return FALSE;
       }
-      $current["msgctxt"] = $quoted;
-      $context = "MSGCTXT";
+
+      $current['msgctxt'] = $quoted;
+
+      $context = 'MSGCTXT';
     }
-    elseif (!strncmp("msgstr[", $line, 7)) {
-      if (($context != "MSGID") && ($context != "MSGCTXT") && ($context != "MSGID_PLURAL") && ($context != "MSGSTR_ARR")) { // Must come after msgid, msgxtxt, msgid_plural, or msgstr[]
+    elseif (!strncmp('msgstr[', $line, 7)) {
+      // A message string for a specific plurality.
+
+      if (($context != 'MSGID') && ($context != 'MSGCTXT') && ($context != 'MSGID_PLURAL') && ($context != 'MSGSTR_ARR')) {
+        // Message strings must come after msgid, msgxtxt, msgid_plural, or other msgstr[] entries.
         _locale_import_message('The translation file %filename contains an error: "msgstr[]" is unexpected on line %line.', $file, $lineno);
         return FALSE;
       }
-      if (strpos($line, "]") === FALSE) {
+
+      // Ensure the plurality is terminated.
+      if (strpos($line, ']') === FALSE) {
         _locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
         return FALSE;
       }
-      $frombracket = strstr($line, "[");
-      $plural = substr($frombracket, 1, strpos($frombracket, "]") - 1);
+
+      // Extract the plurality.
+      $frombracket = strstr($line, '[');
+      $plural = substr($frombracket, 1, strpos($frombracket, ']') - 1);
+
+      // Skip to the next whitespace and trim away any further whitespace, bringing $line to the message data.
       $line = trim(strstr($line, " "));
+
       $quoted = _locale_import_parse_quoted($line);
       if ($quoted === FALSE) {
+        // The string must be quoted.
         _locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
         return FALSE;
       }
-      $current["msgstr"][$plural] = $quoted;
-      $context = "MSGSTR_ARR";
+
+      $current['msgstr'][$plural] = $quoted;
+
+      $context = 'MSGSTR_ARR';
     }
     elseif (!strncmp("msgstr", $line, 6)) {
-      if (($context != "MSGID") && ($context != "MSGCTXT")) {   // Should come just after a msgid or msgctxt block
+      // A string for the an id or context.
+
+      if (($context != 'MSGID') && ($context != 'MSGCTXT')) {
+        // Strings are only valid within an id or context scope.
         _locale_import_message('The translation file %filename contains an error: "msgstr" is unexpected on line %line.', $file, $lineno);
         return FALSE;
       }
+
+      // Remove 'msgstr' and trim away away whitespaces.
       $line = trim(substr($line, 6));
+      // At this point, $line should now contain the message.
+
       $quoted = _locale_import_parse_quoted($line);
       if ($quoted === FALSE) {
+        // The string must be quoted.
         _locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
         return FALSE;
       }
-      $current["msgstr"] = $quoted;
-      $context = "MSGSTR";
+
+      $current['msgstr'] = $quoted;
+
+      $context = 'MSGSTR';
     }
-    elseif ($line != "") {
+    elseif ($line != '') {
+      // Anything that is not a token may be a continuation of a previous token.
+
       $quoted = _locale_import_parse_quoted($line);
       if ($quoted === FALSE) {
+        // The string must be quoted.
         _locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
         return FALSE;
       }
-      if (($context == "MSGID") || ($context == "MSGID_PLURAL")) {
-        $current["msgid"] .= $quoted;
+
+      // Append the string to the current context.
+      if (($context == 'MSGID') || ($context == 'MSGID_PLURAL')) {
+        $current['msgid'] .= $quoted;
       }
-      elseif ($context == "MSGCTXT") {
-        $current["msgctxt"] .= $quoted;
+      elseif ($context == 'MSGCTXT') {
+        $current['msgctxt'] .= $quoted;
       }
-      elseif ($context == "MSGSTR") {
-        $current["msgstr"] .= $quoted;
+      elseif ($context == 'MSGSTR') {
+        $current['msgstr'] .= $quoted;
       }
-      elseif ($context == "MSGSTR_ARR") {
-        $current["msgstr"][$plural] .= $quoted;
+      elseif ($context == 'MSGSTR_ARR') {
+        $current['msgstr'][$plural] .= $quoted;
       }
       else {
+        // No valid context to append to.
         _locale_import_message('The translation file %filename contains an error: there is an unexpected string on line %line.', $file, $lineno);
         return FALSE;
       }
     }
   }
 
-  // End of PO file, flush last entry.
-  if (($context == "MSGSTR") || ($context == "MSGSTR_ARR")) {
+  // End of PO file, closed out the last entry.
+  if (($context == 'MSGSTR') || ($context == 'MSGSTR_ARR')) {
     _locale_import_one_string($op, $current, $mode, $lang, $file, $group);
   }
-  elseif ($context != "COMMENT") {
+  elseif ($context != 'COMMENT') {
     _locale_import_message('The translation file %filename ended unexpectedly at line %line.', $file, $lineno);
     return FALSE;
   }
-
 }
 
 /**
diff --git a/includes/session.inc b/includes/session.inc
index 23af6bd64193..478079b4f57c 100644
--- a/includes/session.inc
+++ b/includes/session.inc
@@ -259,7 +259,7 @@ function drupal_session_initialize() {
     // a user becomes authenticated.
     session_id(drupal_hash_base64(uniqid(mt_rand(), TRUE)));
   }
-  date_default_timezone_set(drupal_get_user_timezone());
+  drupal_set_configured_timezone();
 }
 
 /**
@@ -387,7 +387,7 @@ function drupal_session_regenerate() {
     drupal_session_start();
     $user = $account;
   }
-  date_default_timezone_set(drupal_get_user_timezone());
+  drupal_set_configured_timezone();
 }
 
 /**
diff --git a/modules/simpletest/tests/common.test b/modules/simpletest/tests/common.test
index f48497559a77..52a8a7fe2ee8 100644
--- a/modules/simpletest/tests/common.test
+++ b/modules/simpletest/tests/common.test
@@ -2226,7 +2226,7 @@ class FormatDateUnitTest extends DrupalWebTestCase {
     $real_language = $language->language;
     $language->language = $user->language;
     // Simulate a Drupal bootstrap with the logged-in user.
-    date_default_timezone_set(drupal_get_user_timezone());
+    drupal_set_configured_timezone();
 
     $this->assertIdentical(format_date($timestamp, 'custom', 'l, d-M-y H:i:s T', 'America/Los_Angeles', 'en'), 'Sunday, 25-Mar-07 17:00:00 PDT', t('Test a different language.'));
     $this->assertIdentical(format_date($timestamp, 'custom', 'l, d-M-y H:i:s T', 'Europe/London'), 'Monday, 26-Mar-07 01:00:00 BST', t('Test a different time zone.'));
@@ -2240,7 +2240,7 @@ class FormatDateUnitTest extends DrupalWebTestCase {
     $user = $real_user;
     $language->language = $real_language;
     // Restore default time zone.
-    date_default_timezone_set(drupal_get_user_timezone());
+    drupal_set_configured_timezone();
     drupal_save_session(TRUE);
   }
 }
-- 
GitLab