8066652: Default TimeZone is GMT not local if user.timezone is invalid on Mac OS
authorrgoel
Mon, 01 Aug 2016 15:55:54 +0900
changeset 39887 8d74d858fe75
parent 39886 a0a3c3b2636e
child 39888 bec759b9b909
8066652: Default TimeZone is GMT not local if user.timezone is invalid on Mac OS Reviewed-by: okutsu
jdk/src/java.base/unix/native/libjava/TimeZone_md.c
jdk/test/java/util/TimeZone/Bug8066652.java
jdk/test/java/util/TimeZone/Bug8066652.sh
--- a/jdk/src/java.base/unix/native/libjava/TimeZone_md.c	Sun Jul 31 09:40:17 2016 +0800
+++ b/jdk/src/java.base/unix/native/libjava/TimeZone_md.c	Mon Aug 01 15:55:54 2016 +0900
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -822,18 +822,21 @@
 {
     time_t offset;
     char sign, buf[32];
-    struct tm *local_tm;
+    struct tm local_tm;
     time_t clock;
-    time_t currenttime;
 
     clock = time(NULL);
-    tzset();
-    local_tm = localtime(&clock);
-    if (local_tm->tm_gmtoff >= 0) {
-        offset = (time_t) local_tm->tm_gmtoff;
+    if (localtime_r(&clock, &local_tm) == NULL) {
+        return strdup("GMT");
+    }
+    offset = (time_t)local_tm.tm_gmtoff;
+    if (offset == 0) {
+        return strdup("GMT");
+    }
+    if (offset > 0) {
         sign = '+';
     } else {
-        offset = (time_t) -local_tm->tm_gmtoff;
+        offset = -offset;
         sign = '-';
     }
     sprintf(buf, (const char *)"GMT%c%02d:%02d",
@@ -854,7 +857,7 @@
 
     currenttime = time(NULL);
     if (localtime_r(&currenttime, &localtm) == NULL) {
-        return NULL;
+        return strdup("GMT");
     }
 
     offset = localtm.tm_isdst ? altzone : timezone;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/TimeZone/Bug8066652.java	Mon Aug 01 15:55:54 2016 +0900
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.TimeZone;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+public class Bug8066652 {
+
+    public static void main(String args[]) {
+        ExecutorService executor = Executors.newFixedThreadPool(10);
+        Callable<TimeZone> calTimeZone = () -> TimeZone.getDefault();
+        List<Callable<TimeZone>> tasks = new ArrayList<>();
+        for (int j = 1; j < 10; j++) {
+            tasks.add(calTimeZone);
+        }
+        try {
+            List<Future<TimeZone>> results = executor.invokeAll(tasks);
+            for (Future<TimeZone> f : results) {
+                TimeZone tz = f.get();
+                if (! tz.getID().equals("GMT")) {
+                    throw new RuntimeException("wrong Time zone ID: " + tz.getID()
+                            + ", It should be GMT");
+                }
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            throw new RuntimeException("Execution interrupted or Execution Exception occurred", e);
+        } finally {
+            executor.shutdown();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/TimeZone/Bug8066652.sh	Mon Aug 01 15:55:54 2016 +0900
@@ -0,0 +1,68 @@
+#!/bin/sh
+
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+# @test
+# @bug 8066652
+# @requires os.family == "mac"
+# @summary tests thread safe native function localtime_r is accessed by multiple threads at same time and
+# zone id should not be  “GMT+00:00” if default timezone is “GMT” and user specifies a fake timezone.
+# @build Bug8066652
+# @run shell/timeout=600 Bug8066652.sh
+
+
+if [ "${TESTSRC}" = "" ]
+then
+  echo "TESTSRC not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+echo "TESTSRC=${TESTSRC}"
+if [ "${TESTJAVA}" = "" ]
+then
+  echo "TESTJAVA not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+echo "TESTJAVA=${TESTJAVA}"
+if [ "${TESTCLASSES}" = "" ]
+then
+  echo "TESTCLASSES not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+echo "TESTCLASSES=${TESTCLASSES}"
+echo "CLASSPATH=${CLASSPATH}"
+
+
+# set system TimeZone to GMT using environment variable TZ
+export TZ="GMT"
+
+# Setting invalid TimeZone using VM option
+${TESTJAVA}/bin/java -Duser.timezone=Foo/Bar  ${TESTVMOPTS} -cp ${TESTCLASSES}  Bug8066652
+
+status=$?
+if [ $status -eq 0 ]
+then
+  echo "Success, Test Passed";
+else
+  echo "Test Failed";
+fi
+
+exit $status