changeset 58337:590ac5a59078

8240725: Some functions might not work with CJK character Reviewed-by: naoto
author ysuenaga
date Wed, 11 Mar 2020 13:14:40 +0900
parents 8c78138be591
children 8c5697ed51b2
files src/java.base/share/native/libzip/zip_util.c src/java.base/windows/native/libjava/canonicalize_md.c src/java.base/windows/native/libjli/java_md.c src/jdk.incubator.jpackage/windows/native/libapplauncher/WindowsPlatform.cpp
diffstat 4 files changed, 72 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/native/libzip/zip_util.c	Wed Mar 11 10:33:33 2020 +0800
+++ b/src/java.base/share/native/libzip/zip_util.c	Wed Mar 11 13:14:40 2020 +0900
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2020, 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
@@ -101,7 +101,7 @@
 ZFILE_Open(const char *fname, int flags) {
 #ifdef WIN32
     WCHAR *wfname, *wprefixed_fname;
-    size_t converted_chars, fname_length;
+    size_t fname_length;
     jlong fhandle;
     const DWORD access =
         (flags & O_RDWR)   ? (GENERIC_WRITE | GENERIC_READ) :
@@ -135,10 +135,17 @@
             flagsAndAttributes, /* flags and attributes */
             NULL);
     } else {
-        if ((wfname = (WCHAR*)malloc((fname_length + 1) * sizeof(WCHAR))) == NULL)
+        /* Get required buffer size to convert to Unicode */
+        int wfname_len = MultiByteToWideChar(CP_THREAD_ACP, MB_ERR_INVALID_CHARS,
+                                             fname, -1, NULL, 0);
+        if (wfname_len == 0) {
             return (jlong)INVALID_HANDLE_VALUE;
-
-        if (mbstowcs_s(&converted_chars, wfname, fname_length + 1, fname, fname_length) != 0) {
+        }
+        if ((wfname = (WCHAR*)malloc(wfname_len * sizeof(WCHAR))) == NULL) {
+            return (jlong)INVALID_HANDLE_VALUE;
+        }
+        if (MultiByteToWideChar(CP_THREAD_ACP, MB_ERR_INVALID_CHARS,
+                                fname, -1, wfname, wfname_len) == 0) {
             free(wfname);
             return (jlong)INVALID_HANDLE_VALUE;
         }
--- a/src/java.base/windows/native/libjava/canonicalize_md.c	Wed Mar 11 10:33:33 2020 +0800
+++ b/src/java.base/windows/native/libjava/canonicalize_md.c	Wed Mar 11 13:14:40 2020 +0900
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2020, 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
@@ -330,15 +330,22 @@
 JDK_Canonicalize(const char *orig, char *out, int len) {
     wchar_t* wpath = NULL;
     wchar_t* wresult = NULL;
-    size_t conv;
-    size_t path_len = strlen(orig);
+    int wpath_len;
     int ret = -1;
 
-    if ((wpath = (wchar_t*) malloc(sizeof(wchar_t) * (path_len + 1))) == NULL) {
+    /* Get required buffer size to convert to Unicode */
+    wpath_len = MultiByteToWideChar(CP_THREAD_ACP, MB_ERR_INVALID_CHARS,
+                                    orig, -1, NULL, 0);
+    if (wpath_len == 0) {
         goto finish;
     }
 
-    if (mbstowcs_s(&conv, wpath, path_len + 1, orig, path_len) != 0) {
+    if ((wpath = (wchar_t*) malloc(sizeof(wchar_t) * wpath_len)) == NULL) {
+        goto finish;
+    }
+
+    if (MultiByteToWideChar(CP_THREAD_ACP, MB_ERR_INVALID_CHARS,
+                            orig, -1, wpath, wpath_len) == 0) {
         goto finish;
     }
 
@@ -350,7 +357,8 @@
         goto finish;
     }
 
-    if (wcstombs_s(&conv, out, (size_t) len, wresult, (size_t) (len - 1)) != 0) {
+    if (WideCharToMultiByte(CP_THREAD_ACP, 0,
+                            wresult, -1, out, len, NULL, NULL) == 0) {
         goto finish;
     }
 
--- a/src/java.base/windows/native/libjli/java_md.c	Wed Mar 11 10:33:33 2020 +0800
+++ b/src/java.base/windows/native/libjli/java_md.c	Wed Mar 11 13:14:40 2020 +0900
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, 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
@@ -496,6 +496,38 @@
     return rc;
 }
 
+static errno_t convert_to_unicode(const char* path, const wchar_t* prefix, wchar_t** wpath) {
+    int unicode_path_len;
+    size_t prefix_len, wpath_len;
+
+    /*
+     * Get required buffer size to convert to Unicode.
+     * The return value includes the terminating null character.
+     */
+    unicode_path_len = MultiByteToWideChar(CP_THREAD_ACP, MB_ERR_INVALID_CHARS,
+                                           path, -1, NULL, 0);
+    if (unicode_path_len == 0) {
+        return EINVAL;
+    }
+
+    prefix_len = wcslen(prefix);
+    wpath_len = prefix_len + unicode_path_len;
+    *wpath = (wchar_t*)JLI_MemAlloc(wpath_len * sizeof(wchar_t));
+    if (*wpath == NULL) {
+        return ENOMEM;
+    }
+
+    wcsncpy(*wpath, prefix, prefix_len);
+    if (MultiByteToWideChar(CP_THREAD_ACP, MB_ERR_INVALID_CHARS,
+                            path, -1, &((*wpath)[prefix_len]), (int)wpath_len) == 0) {
+        JLI_MemFree(*wpath);
+        *wpath = NULL;
+        return EINVAL;
+    }
+
+    return ERROR_SUCCESS;
+}
+
 /* taken from hotspot and slightly adjusted for jli lib;
  * creates a UNC/ELP path from input 'path'
  * the return buffer is allocated in C heap and needs to be freed using
@@ -508,30 +540,13 @@
     if (path[0] == '\\' && path[1] == '\\') {
         if (path[2] == '?' && path[3] == '\\') {
             /* if it already has a \\?\ don't do the prefix */
-            wpath = (wchar_t*) JLI_MemAlloc(path_len * sizeof(wchar_t));
-            if (wpath != NULL) {
-                *err = mbstowcs_s(&converted_chars, wpath, path_len, path, path_len);
-            } else {
-                *err = ENOMEM;
-            }
+            *err = convert_to_unicode(path, L"", &wpath);
         } else {
             /* only UNC pathname includes double slashes here */
-            wpath = (wchar_t*) JLI_MemAlloc((path_len + 7) * sizeof(wchar_t));
-            if (wpath != NULL) {
-                wcscpy(wpath, L"\\\\?\\UNC\0");
-                *err = mbstowcs_s(&converted_chars, &wpath[7], path_len, path, path_len);
-            } else {
-                *err = ENOMEM;
-            }
+            *err = convert_to_unicode(path, L"\\\\?\\UNC", &wpath);
         }
     } else {
-        wpath = (wchar_t*) JLI_MemAlloc((path_len + 4) * sizeof(wchar_t));
-        if (wpath != NULL) {
-            wcscpy(wpath, L"\\\\?\\\0");
-            *err = mbstowcs_s(&converted_chars, &wpath[4], path_len, path, path_len);
-        } else {
-            *err = ENOMEM;
-        }
+        *err = convert_to_unicode(path, L"\\\\?\\", &wpath);
     }
     return wpath;
 }
--- a/src/jdk.incubator.jpackage/windows/native/libapplauncher/WindowsPlatform.cpp	Wed Mar 11 10:33:33 2020 +0800
+++ b/src/jdk.incubator.jpackage/windows/native/libapplauncher/WindowsPlatform.cpp	Wed Mar 11 13:14:40 2020 +0900
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2020, 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
@@ -404,11 +404,17 @@
         return result;
     }
 
-    mbstowcs_s(&count, NULL, 0, value, _TRUNCATE);
+    count = MultiByteToWideChar(CP_THREAD_ACP, MB_ERR_INVALID_CHARS,
+                                value, -1, NULL, 0);
 
     if (count > 0) {
-        result.data = new wchar_t[count + 1];
-        mbstowcs_s(&result.length, result.data, count, value, count);
+        result.data = new wchar_t[count];
+        result.length = MultiByteToWideChar(CP_THREAD_ACP, MB_ERR_INVALID_CHARS,
+                                            value, -1, result.data, (int)count);
+        if (result.length == 0) {
+            delete[] result.data;
+            result.data = NULL;
+        }
     }
 
     return result;