!257 Default timezone should return zone ID if /etc/localtime is valid but not canonicalization on linux
From: @kuenking111 Reviewed-by: @jvmboy Signed-off-by: @jvmboy
This commit is contained in:
commit
214b2ece75
@ -0,0 +1,486 @@
|
||||
From 07654f80f1dc979b825c8c26c45e683547d20941 Mon Sep 17 00:00:00 2001
|
||||
From: s00478819 <sunjianye@huawei.com>
|
||||
Date: Mon, 25 Oct 2021 17:38:14 +0800
|
||||
Subject: [PATCH 1/4] 8273111: Default timezone should return zone ID if
|
||||
/etc/localtime is valid but not canonicalization on linux
|
||||
|
||||
---
|
||||
jdk/make/lib/ServiceabilityLibraries.gmk | 1 +
|
||||
.../solaris/native/java/io/canonicalize_md.c | 144 +--------------
|
||||
jdk/src/solaris/native/java/io/path_util.c | 166 ++++++++++++++++++
|
||||
jdk/src/solaris/native/java/io/path_util.h | 31 ++++
|
||||
.../solaris/native/java/util/TimeZone_md.c | 61 +++----
|
||||
5 files changed, 230 insertions(+), 173 deletions(-)
|
||||
create mode 100644 jdk/src/solaris/native/java/io/path_util.c
|
||||
create mode 100644 jdk/src/solaris/native/java/io/path_util.h
|
||||
|
||||
diff --git a/jdk/make/lib/ServiceabilityLibraries.gmk b/jdk/make/lib/ServiceabilityLibraries.gmk
|
||||
index 36b6c6811..2c80ffc00 100644
|
||||
--- a/jdk/make/lib/ServiceabilityLibraries.gmk
|
||||
+++ b/jdk/make/lib/ServiceabilityLibraries.gmk
|
||||
@@ -225,6 +225,7 @@ LIBINSTRUMENT_FILES := \
|
||||
PathCharsValidator.c \
|
||||
Reentrancy.c \
|
||||
Utilities.c \
|
||||
+ path_util.c \
|
||||
canonicalize_md.c
|
||||
|
||||
LIBINSTRUMENT_DIR := $(JDK_OUTPUTDIR)/objs/libinstrument
|
||||
diff --git a/jdk/src/solaris/native/java/io/canonicalize_md.c b/jdk/src/solaris/native/java/io/canonicalize_md.c
|
||||
index cb8ce69c8..2bd1ef2cd 100644
|
||||
--- a/jdk/src/solaris/native/java/io/canonicalize_md.c
|
||||
+++ b/jdk/src/solaris/native/java/io/canonicalize_md.c
|
||||
@@ -33,154 +33,12 @@
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
-#if !defined(_ALLBSD_SOURCE)
|
||||
-#include <alloca.h>
|
||||
-#endif
|
||||
+#include "path_util.h"
|
||||
|
||||
|
||||
/* Note: The comments in this file use the terminology
|
||||
defined in the java.io.File class */
|
||||
|
||||
-
|
||||
-/* Check the given name sequence to see if it can be further collapsed.
|
||||
- Return zero if not, otherwise return the number of names in the sequence. */
|
||||
-
|
||||
-static int
|
||||
-collapsible(char *names)
|
||||
-{
|
||||
- char *p = names;
|
||||
- int dots = 0, n = 0;
|
||||
-
|
||||
- while (*p) {
|
||||
- if ((p[0] == '.') && ((p[1] == '\0')
|
||||
- || (p[1] == '/')
|
||||
- || ((p[1] == '.') && ((p[2] == '\0')
|
||||
- || (p[2] == '/'))))) {
|
||||
- dots = 1;
|
||||
- }
|
||||
- n++;
|
||||
- while (*p) {
|
||||
- if (*p == '/') {
|
||||
- p++;
|
||||
- break;
|
||||
- }
|
||||
- p++;
|
||||
- }
|
||||
- }
|
||||
- return (dots ? n : 0);
|
||||
-}
|
||||
-
|
||||
-
|
||||
-/* Split the names in the given name sequence,
|
||||
- replacing slashes with nulls and filling in the given index array */
|
||||
-
|
||||
-static void
|
||||
-splitNames(char *names, char **ix)
|
||||
-{
|
||||
- char *p = names;
|
||||
- int i = 0;
|
||||
-
|
||||
- while (*p) {
|
||||
- ix[i++] = p++;
|
||||
- while (*p) {
|
||||
- if (*p == '/') {
|
||||
- *p++ = '\0';
|
||||
- break;
|
||||
- }
|
||||
- p++;
|
||||
- }
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-
|
||||
-/* Join the names in the given name sequence, ignoring names whose index
|
||||
- entries have been cleared and replacing nulls with slashes as needed */
|
||||
-
|
||||
-static void
|
||||
-joinNames(char *names, int nc, char **ix)
|
||||
-{
|
||||
- int i;
|
||||
- char *p;
|
||||
-
|
||||
- for (i = 0, p = names; i < nc; i++) {
|
||||
- if (!ix[i]) continue;
|
||||
- if (i > 0) {
|
||||
- p[-1] = '/';
|
||||
- }
|
||||
- if (p == ix[i]) {
|
||||
- p += strlen(p) + 1;
|
||||
- } else {
|
||||
- char *q = ix[i];
|
||||
- while ((*p++ = *q++));
|
||||
- }
|
||||
- }
|
||||
- *p = '\0';
|
||||
-}
|
||||
-
|
||||
-
|
||||
-/* Collapse "." and ".." names in the given path wherever possible.
|
||||
- A "." name may always be eliminated; a ".." name may be eliminated if it
|
||||
- follows a name that is neither "." nor "..". This is a syntactic operation
|
||||
- that performs no filesystem queries, so it should only be used to cleanup
|
||||
- after invoking the realpath() procedure. */
|
||||
-
|
||||
-static void
|
||||
-collapse(char *path)
|
||||
-{
|
||||
- char *names = (path[0] == '/') ? path + 1 : path; /* Preserve first '/' */
|
||||
- int nc;
|
||||
- char **ix;
|
||||
- int i, j;
|
||||
- char *p, *q;
|
||||
-
|
||||
- nc = collapsible(names);
|
||||
- if (nc < 2) return; /* Nothing to do */
|
||||
- ix = (char **)alloca(nc * sizeof(char *));
|
||||
- splitNames(names, ix);
|
||||
-
|
||||
- for (i = 0; i < nc; i++) {
|
||||
- int dots = 0;
|
||||
-
|
||||
- /* Find next occurrence of "." or ".." */
|
||||
- do {
|
||||
- char *p = ix[i];
|
||||
- if (p[0] == '.') {
|
||||
- if (p[1] == '\0') {
|
||||
- dots = 1;
|
||||
- break;
|
||||
- }
|
||||
- if ((p[1] == '.') && (p[2] == '\0')) {
|
||||
- dots = 2;
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
- i++;
|
||||
- } while (i < nc);
|
||||
- if (i >= nc) break;
|
||||
-
|
||||
- /* At this point i is the index of either a "." or a "..", so take the
|
||||
- appropriate action and then continue the outer loop */
|
||||
- if (dots == 1) {
|
||||
- /* Remove this instance of "." */
|
||||
- ix[i] = 0;
|
||||
- }
|
||||
- else {
|
||||
- /* If there is a preceding name, remove both that name and this
|
||||
- instance of ".."; otherwise, leave the ".." as is */
|
||||
- for (j = i - 1; j >= 0; j--) {
|
||||
- if (ix[j]) break;
|
||||
- }
|
||||
- if (j < 0) continue;
|
||||
- ix[j] = 0;
|
||||
- ix[i] = 0;
|
||||
- }
|
||||
- /* i will be incremented at the top of the loop */
|
||||
- }
|
||||
-
|
||||
- joinNames(names, nc, ix);
|
||||
-}
|
||||
-
|
||||
-
|
||||
/* Convert a pathname to canonical form. The input path is assumed to contain
|
||||
no duplicate slashes. On Solaris we can use realpath() to do most of the
|
||||
work, though once that's done we still must collapse any remaining "." and
|
||||
diff --git a/jdk/src/solaris/native/java/io/path_util.c b/jdk/src/solaris/native/java/io/path_util.c
|
||||
new file mode 100644
|
||||
index 000000000..8a533f812
|
||||
--- /dev/null
|
||||
+++ b/jdk/src/solaris/native/java/io/path_util.c
|
||||
@@ -0,0 +1,166 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2021, 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. Oracle designates this
|
||||
+ * particular file as subject to the "Classpath" exception as provided
|
||||
+ * by Oracle in the LICENSE file that accompanied this code.
|
||||
+ *
|
||||
+ * 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.
|
||||
+ */
|
||||
+
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#if !defined(_ALLBSD_SOURCE)
|
||||
+#include <alloca.h>
|
||||
+#endif
|
||||
+#include "path_util.h"
|
||||
+
|
||||
+/* Check the given name sequence to see if it can be further collapsed.
|
||||
+ Return zero if not, otherwise return the number of names in the sequence. */
|
||||
+
|
||||
+static int
|
||||
+collapsible(char *names)
|
||||
+{
|
||||
+ char *p = names;
|
||||
+ int dots = 0, n = 0;
|
||||
+
|
||||
+ while (*p) {
|
||||
+ if ((p[0] == '.') && ((p[1] == '\0')
|
||||
+ || (p[1] == '/')
|
||||
+ || ((p[1] == '.') && ((p[2] == '\0')
|
||||
+ || (p[2] == '/'))))) {
|
||||
+ dots = 1;
|
||||
+ }
|
||||
+ n++;
|
||||
+ while (*p) {
|
||||
+ if (*p == '/') {
|
||||
+ p++;
|
||||
+ break;
|
||||
+ }
|
||||
+ p++;
|
||||
+ }
|
||||
+ }
|
||||
+ return (dots ? n : 0);
|
||||
+}
|
||||
+
|
||||
+/* Split the names in the given name sequence,
|
||||
+ replacing slashes with nulls and filling in the given index array */
|
||||
+
|
||||
+static void
|
||||
+splitNames(char *names, char **ix)
|
||||
+{
|
||||
+ char *p = names;
|
||||
+ int i = 0;
|
||||
+
|
||||
+ while (*p) {
|
||||
+ ix[i++] = p++;
|
||||
+ while (*p) {
|
||||
+ if (*p == '/') {
|
||||
+ *p++ = '\0';
|
||||
+ break;
|
||||
+ }
|
||||
+ p++;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Join the names in the given name sequence, ignoring names whose index
|
||||
+ entries have been cleared and replacing nulls with slashes as needed */
|
||||
+
|
||||
+static void
|
||||
+joinNames(char *names, int nc, char **ix)
|
||||
+{
|
||||
+ int i;
|
||||
+ char *p;
|
||||
+
|
||||
+ for (i = 0, p = names; i < nc; i++) {
|
||||
+ if (!ix[i]) continue;
|
||||
+ if (i > 0) {
|
||||
+ p[-1] = '/';
|
||||
+ }
|
||||
+ if (p == ix[i]) {
|
||||
+ p += strlen(p) + 1;
|
||||
+ } else {
|
||||
+ char *q = ix[i];
|
||||
+ while ((*p++ = *q++));
|
||||
+ }
|
||||
+ }
|
||||
+ *p = '\0';
|
||||
+}
|
||||
+
|
||||
+/* Collapse "." and ".." names in the given path wherever possible.
|
||||
+ A "." name may always be eliminated; a ".." name may be eliminated if it
|
||||
+ follows a name that is neither "." nor "..". This is a syntactic operation
|
||||
+ that performs no filesystem queries, so it should only be used to cleanup
|
||||
+ after invoking the realpath() procedure. */
|
||||
+
|
||||
+void
|
||||
+collapse(char *path)
|
||||
+{
|
||||
+ char *names = (path[0] == '/') ? path + 1 : path; /* Preserve first '/' */
|
||||
+ int nc;
|
||||
+ char **ix;
|
||||
+ int i, j;
|
||||
+ char *p, *q;
|
||||
+
|
||||
+ nc = collapsible(names);
|
||||
+ if (nc < 2) return; /* Nothing to do */
|
||||
+ ix = (char **)alloca(nc * sizeof(char *));
|
||||
+ splitNames(names, ix);
|
||||
+
|
||||
+ for (i = 0; i < nc; i++) {
|
||||
+ int dots = 0;
|
||||
+
|
||||
+ /* Find next occurrence of "." or ".." */
|
||||
+ do {
|
||||
+ char *p = ix[i];
|
||||
+ if (p[0] == '.') {
|
||||
+ if (p[1] == '\0') {
|
||||
+ dots = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ if ((p[1] == '.') && (p[2] == '\0')) {
|
||||
+ dots = 2;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ i++;
|
||||
+ } while (i < nc);
|
||||
+ if (i >= nc) break;
|
||||
+
|
||||
+ /* At this point i is the index of either a "." or a "..", so take the
|
||||
+ appropriate action and then continue the outer loop */
|
||||
+ if (dots == 1) {
|
||||
+ /* Remove this instance of "." */
|
||||
+ ix[i] = 0;
|
||||
+ }
|
||||
+ else {
|
||||
+ /* If there is a preceding name, remove both that name and this
|
||||
+ instance of ".."; otherwise, leave the ".." as is */
|
||||
+ for (j = i - 1; j >= 0; j--) {
|
||||
+ if (ix[j]) break;
|
||||
+ }
|
||||
+ if (j < 0) continue;
|
||||
+ ix[j] = 0;
|
||||
+ ix[i] = 0;
|
||||
+ }
|
||||
+ /* i will be incremented at the top of the loop */
|
||||
+ }
|
||||
+
|
||||
+ joinNames(names, nc, ix);
|
||||
+}
|
||||
diff --git a/jdk/src/solaris/native/java/io/path_util.h b/jdk/src/solaris/native/java/io/path_util.h
|
||||
new file mode 100644
|
||||
index 000000000..7b0fd5eb1
|
||||
--- /dev/null
|
||||
+++ b/jdk/src/solaris/native/java/io/path_util.h
|
||||
@@ -0,0 +1,31 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2021, 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. Oracle designates this
|
||||
+ * particular file as subject to the "Classpath" exception as provided
|
||||
+ * by Oracle in the LICENSE file that accompanied this code.
|
||||
+ *
|
||||
+ * 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.
|
||||
+ */
|
||||
+
|
||||
+#ifndef PATH_UTIL_H
|
||||
+#define PATH_UTIL_H
|
||||
+
|
||||
+void collapse(char *path);
|
||||
+
|
||||
+#endif
|
||||
diff --git a/jdk/src/solaris/native/java/util/TimeZone_md.c b/jdk/src/solaris/native/java/util/TimeZone_md.c
|
||||
index c183a723d..df1450e03 100644
|
||||
--- a/jdk/src/solaris/native/java/util/TimeZone_md.c
|
||||
+++ b/jdk/src/solaris/native/java/util/TimeZone_md.c
|
||||
@@ -41,6 +41,7 @@
|
||||
|
||||
#include "jvm.h"
|
||||
#include "TimeZone_md.h"
|
||||
+#include "path_util.h"
|
||||
|
||||
static char *isFileIdentical(char* buf, size_t size, char *pathname);
|
||||
|
||||
@@ -77,6 +78,33 @@ static const char *ETC_ENVIRONMENT_FILE = "/etc/environment";
|
||||
|
||||
#if defined(__linux__) || defined(MACOSX) || defined(__solaris__)
|
||||
|
||||
+/*
|
||||
+ * remove repeated path separators ('/') in the given 'path'.
|
||||
+ */
|
||||
+static void
|
||||
+removeDuplicateSlashes(char *path)
|
||||
+{
|
||||
+ char *left = path;
|
||||
+ char *right = path;
|
||||
+ char *end = path + strlen(path);
|
||||
+
|
||||
+ for (; right < end; right++) {
|
||||
+ // Skip sequence of multiple path-separators.
|
||||
+ while (*right == '/' && *(right + 1) == '/') {
|
||||
+ right++;
|
||||
+ }
|
||||
+
|
||||
+ while (*right != '\0' && !(*right == '/' && *(right + 1) == '/')) {
|
||||
+ *left++ = *right++;
|
||||
+ }
|
||||
+
|
||||
+ if (*right == '\0') {
|
||||
+ *left = '\0';
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Returns a pointer to the zone ID portion of the given zoneinfo file
|
||||
* name, or NULL if the given string doesn't contain "zoneinfo/".
|
||||
@@ -319,36 +347,9 @@ getPlatformTimeZoneID()
|
||||
return NULL;
|
||||
}
|
||||
linkbuf[len] = '\0';
|
||||
-
|
||||
- /* linkbuf may be a relative symlink or has more than one characters, like '.' and '/' ,
|
||||
- * which will cause the function call getZoneName return to an abnormal timeZone name.
|
||||
- * For example, linkbuf is "../usr/share/zoneinfo//Asia/Shanghai", then the call of
|
||||
- * getZoneName(linkbuf) will get "/Asia/Shanghai", not "Asia/Shanghai".
|
||||
- * So we covert it to an absolute path by adding the file's (which is define by macro
|
||||
- * DEFAULT_ZONEINFO_FILE) dirname and then call glibc's realpath API to canonicalize
|
||||
- * the path.
|
||||
- */
|
||||
- char abslinkbuf[2 * (PATH_MAX + 1)];
|
||||
- if (linkbuf[0] != '/') {
|
||||
- if (sprintf(abslinkbuf, "%s/%s", DEFAULT_ZONEINFO_FILE_DIRNAME, linkbuf) < 0) {
|
||||
- jio_fprintf(stderr, (const char *) "failed to generate absolute path\n");
|
||||
- return NULL;
|
||||
- }
|
||||
- } else {
|
||||
- strncpy(abslinkbuf, linkbuf, len + 1);
|
||||
- }
|
||||
-
|
||||
- /* canonicalize the path */
|
||||
- char resolvedpath[PATH_MAX + 1];
|
||||
- resolvedpath[PATH_MAX] = '\0';
|
||||
- char *path = realpath(abslinkbuf, resolvedpath);
|
||||
- if (path == NULL) {
|
||||
- jio_fprintf(stderr, (const char *) "failed to get real path, symlink is %s\n",
|
||||
- abslinkbuf);
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- tz = getZoneName(resolvedpath);
|
||||
+ removeDuplicateSlashes(linkbuf);
|
||||
+ collapse(linkbuf);
|
||||
+ tz = getZoneName(linkbuf);
|
||||
if (tz != NULL) {
|
||||
tz = strdup(tz);
|
||||
return tz;
|
||||
--
|
||||
2.22.0
|
||||
|
||||
@ -916,7 +916,7 @@ Provides: java-%{javaver}-%{origin}-accessibility%{?1} = %{epoch}:%{version}-%{r
|
||||
|
||||
Name: java-%{javaver}-%{origin}
|
||||
Version: %{javaver}.%{updatever}.%{buildver}
|
||||
Release: 1
|
||||
Release: 2
|
||||
# java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons
|
||||
# and this change was brought into RHEL-4. java-1.5.0-ibm packages
|
||||
# also included the epoch in their virtual provides. This created a
|
||||
@ -1116,6 +1116,7 @@ Patch218: 8143251-Thread-suspend-on-VM_G1IncCollectionPause-do.patch
|
||||
Patch219: G1Uncommit-Introduce-G1PeriodGCNotRetry-control-whet.patch
|
||||
Patch220: JDK-debug-version-crash-when-using-AppCDS.patch
|
||||
Patch221: 8183543-Aarch64-C2-compilation-often-fails-with-fail--last.patch
|
||||
Patch222: 8273111-Default-timezone-should-return-zone-ID-if-locatiome-is-valid-but-not-canonicalization-on-linux.patch
|
||||
|
||||
# 8u312
|
||||
|
||||
@ -1582,6 +1583,7 @@ pushd %{top_level_dir_name}
|
||||
%patch219 -p1
|
||||
%patch220 -p1
|
||||
%patch221 -p1
|
||||
%patch222 -p1
|
||||
popd
|
||||
|
||||
# System library fixes
|
||||
@ -2199,6 +2201,9 @@ require "copy_jdk_configs.lua"
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Fri Dec 10 2021 kuenking111 <wangkun49@huawei.com> - 1:1.8.0.312-b07.2
|
||||
- add 8273111-Default-timezone-should-return-zone-ID-if-locatiome-is-valid-but-not-canonicalization-on-linux.patch
|
||||
|
||||
* Tue Nov 23 2021 lijingwei <lijingwei@uniontech.com> - 1:1.8.0.312-b07.1
|
||||
- correct spec file release number typo
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user