8066652: Default TimeZone is GMT not local if user.timezone is invalid on Mac OS
Reviewed-by: okutsu
--- 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(¤ttime, &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