changeset 6511:3eff4e241313

8021245: (process) file leak in jdk/src/windows/native/java/lang/ProcessImpl_md.c Reviewed-by: alanb
author uta
date Wed, 31 Jul 2013 13:57:40 +0400
parents 221420eaa1d0
children 258b1aa653f8
files src/windows/native/java/lang/ProcessImpl_md.c
diffstat 1 files changed, 38 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/src/windows/native/java/lang/ProcessImpl_md.c	Mon Jul 29 19:02:14 2013 -0700
+++ b/src/windows/native/java/lang/ProcessImpl_md.c	Wed Jul 31 13:57:40 2013 +0400
@@ -63,46 +63,52 @@
     return source;
 }
 
+static const char EXE_EXT[] = ".exe";
+
 DWORD
 selectProcessFlag(JNIEnv *env, jstring cmd0)
 {
-    char buf[MAX_PATH];
     DWORD newFlag = 0;
-    char *exe, *p, *name;
-    unsigned char buffer[2];
-    long headerLoc = 0;
-    int fd = 0;
-
-    exe = (char *)JNU_GetStringPlatformChars(env, cmd0, 0);
-    exe = extractExecutablePath(env, exe);
-
+    char *exe = (char *)JNU_GetStringPlatformChars(env, cmd0, 0);
     if (exe != NULL) {
-        if ((p = strchr(exe, '\\')) == NULL) {
-            SearchPath(NULL, exe, ".exe", MAX_PATH, buf, &name);
-        } else {
-            p = strrchr(exe, '\\');
-            *p = 0;
-            p++;
-            SearchPath(exe, p, ".exe", MAX_PATH, buf, &name);
-        }
-    }
-
-    fd = _open(buf, _O_RDONLY);
-    if (fd > 0) {
-        _read(fd, buffer, 2);
-        if (buffer[0] == 'M' && buffer[1] == 'Z') {
-            _lseek(fd, 60L, SEEK_SET);
-            _read(fd, buffer, 2);
-            headerLoc = (long)buffer[1] << 8 | (long)buffer[0];
-            _lseek(fd, headerLoc, SEEK_SET);
-            _read(fd, buffer, 2);
-            if (buffer[0] == 'P' && buffer[1] == 'E') {
-                newFlag = DETACHED_PROCESS;
+        char buf[MAX_PATH];
+        char *name;
+        DWORD len;
+        exe = extractExecutablePath(env, exe);
+        if (exe != NULL) {
+            /* We are here for Win9x/Me, so the [/] is not the path sep */
+            char *p = strrchr(exe, '\\');
+            if (p == NULL) {
+                len = SearchPath(NULL, exe, EXE_EXT, MAX_PATH, buf, &name);
+            } else {
+                *p = 0;
+                len = SearchPath(exe, p + 1, EXE_EXT, MAX_PATH, buf, &name);
             }
         }
-        _close(fd);
+
+        if (len > 0 && len < MAX_PATH) {
+            /* Here the [buf] path is valid and null terminated */
+            int fd = _open(buf, _O_RDONLY);
+            if (fd != -1) {
+                unsigned char buffer[2];
+                if (_read(fd, buffer, 2) == 2
+                    && buffer[0] == 'M' && buffer[1] == 'Z'
+                    && _lseek(fd, 60L, SEEK_SET) == 60L
+                    && _read(fd, buffer, 2) == 2)
+                {
+                    long headerLoc = (long)buffer[1] << 8 | (long)buffer[0];
+                    if (_lseek(fd, headerLoc, SEEK_SET) == headerLoc
+                        && _read(fd, buffer, 2) == 2
+                        && buffer[0] == 'P' && buffer[1] == 'E')
+                    {
+                        newFlag = DETACHED_PROCESS;
+                    }
+                }
+                _close(fd);
+            }
+        }
+        JNU_ReleaseStringPlatformChars(env, cmd0, exe);
     }
-    JNU_ReleaseStringPlatformChars(env, cmd0, exe);
     return newFlag;
 }