changeset 8220:f1334857fa99 jdk7u80-b08

Merge
author asaha
date Thu, 09 Apr 2015 21:18:44 -0700
parents b3d89a284fe6 f90bbaeb7ba4
children e4722d4fdffc
files .hgtags
diffstat 4 files changed, 103 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Thu Jan 29 14:13:26 2015 +0000
+++ b/.hgtags	Thu Apr 09 21:18:44 2015 -0700
@@ -562,5 +562,6 @@
 c2a53d62b3ad7eaae0087139f7764ff2054fe132 jdk7u79-b03
 10431974d072ad8a24b003373e891bc4514d0ae6 jdk7u79-b06
 e83b7d88c57654b0ebf78b5139bd74463a130525 jdk7u79-b07
+f94dd20a1efaa3b0b4345992330dfe7cddae343b jdk7u79-b08
 f33e6ea5f4832468dd86a8d48ef50479ce91111e jdk7u80-b06
 feb04280659bf05b567dc725ff53e2a2077bdbb7 jdk7u80-b07
--- a/src/share/classes/sun/tools/jar/Main.java	Thu Jan 29 14:13:26 2015 +0000
+++ b/src/share/classes/sun/tools/jar/Main.java	Thu Apr 09 21:18:44 2015 -0700
@@ -72,8 +72,9 @@
      * flag0: no zip compression (store only)
      * Mflag: DO NOT generate a manifest file (just ZIP)
      * iflag: generate jar index
+     * pflag: preserve/don't strip leading slash and .. component from file name
      */
-    boolean cflag, uflag, xflag, tflag, vflag, flag0, Mflag, iflag;
+    boolean cflag, uflag, xflag, tflag, vflag, flag0, Mflag, iflag, pflag;
 
     static final String MANIFEST_DIR = "META-INF/";
     static final String VERSION = "1.0";
@@ -185,6 +186,7 @@
                         addMainClass(manifest, ename);
                     }
                 }
+                expand(null, files, false);
                 OutputStream out;
                 if (fname != null) {
                     out = new FileOutputStream(fname);
@@ -197,7 +199,6 @@
                         vflag = false;
                     }
                 }
-                expand(null, files, false);
                 create(new BufferedOutputStream(out, 4096), manifest);
                 if (in != null) {
                     in.close();
@@ -245,7 +246,7 @@
                     list(fname, files);
                 } else {
                     InputStream in = new FileInputStream(FileDescriptor.in);
-                    try{
+                    try {
                         list(new BufferedInputStream(in), files);
                     } finally {
                         in.close();
@@ -361,6 +362,9 @@
                 case 'e':
                      ename = args[count++];
                      break;
+                case 'P':
+                     pflag = true;
+                     break;
                 default:
                     error(formatMsg("error.illegal.option",
                                 String.valueOf(flags.charAt(i))));
@@ -607,7 +611,6 @@
         return updateOk;
     }
 
-
     private void addIndex(JarIndex index, ZipOutputStream zos)
         throws IOException
     {
@@ -643,6 +646,47 @@
         }
     }
 
+    private static final boolean isWinDriveLetter(char c) {
+        return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'));
+    }
+
+    private String safeName(String name) {
+        if (!pflag) {
+            int len = name.length();
+            int i = name.lastIndexOf("../");
+            if (i == -1) {
+                i = 0;
+            } else {
+                i += 3; // strip any dot-dot components
+            }
+            if (File.separatorChar == '\\') {
+                // the spec requests no drive letter. skip if
+                // the entry name has one.
+                while (i < len) {
+                    int off = i;
+                    if (i + 1 < len &&
+                        name.charAt(i + 1) == ':' &&
+                        isWinDriveLetter(name.charAt(i))) {
+                        i += 2;
+                    }
+                    while (i < len && name.charAt(i) == '/') {
+                        i++;
+                    }
+                    if (i == off) {
+                        break;
+                    }
+                }
+            } else {
+                while (i < len && name.charAt(i) == '/') {
+                    i++;
+                }
+            }
+            if (i != 0) {
+                name = name.substring(i);
+            }
+        }
+        return name;
+    }
 
     private String entryName(String name) {
         name = name.replace(File.separatorChar, '/');
@@ -654,10 +698,10 @@
             }
         }
         name = name.substring(matchPath.length());
-
-        if (name.startsWith("/")) {
-            name = name.substring(1);
-        } else if (name.startsWith("./")) {
+        name = safeName(name);
+        // the old implementaton doesn't remove
+        // "./" if it was led by "/" (?)
+        if (name.startsWith("./")) {
             name = name.substring(2);
         }
         return name;
@@ -857,8 +901,11 @@
         for (ZipEntry ze : zes) {
             long lastModified = ze.getTime();
             if (lastModified != -1) {
-                File f = new File(ze.getName().replace('/', File.separatorChar));
-                f.setLastModified(lastModified);
+                String name = safeName(ze.getName().replace(File.separatorChar, '/'));
+                if (name.length() != 0) {
+                    File f = new File(name.replace('/', File.separatorChar));
+                    f.setLastModified(lastModified);
+                }
             }
         }
     }
@@ -902,7 +949,6 @@
         Enumeration<? extends ZipEntry> zes = zf.entries();
         while (zes.hasMoreElements()) {
             ZipEntry e = zes.nextElement();
-            InputStream is;
             if (files == null) {
                 dirs.add(extractFile(zf.getInputStream(e), e));
             } else {
@@ -926,8 +972,16 @@
      */
     ZipEntry extractFile(InputStream is, ZipEntry e) throws IOException {
         ZipEntry rc = null;
-        String name = e.getName();
-        File f = new File(e.getName().replace('/', File.separatorChar));
+        // The spec requres all slashes MUST be forward '/', it is possible
+        // an offending zip/jar entry may uses the backwards slash in its
+        // name. It might cause problem on Windows platform as it skips
+        // our "safe" check for leading slahs and dot-dot. So replace them
+        // with '/'.
+        String name = safeName(e.getName().replace(File.separatorChar, '/'));
+        if (name.length() == 0) {
+            return rc;    // leading '/' or 'dot-dot' only path
+        }
+        File f = new File(name.replace('/', File.separatorChar));
         if (e.isDirectory()) {
             if (f.exists()) {
                 if (!f.isDirectory()) {
--- a/src/share/classes/sun/tools/jar/resources/jar.properties	Thu Jan 29 14:13:26 2015 +0000
+++ b/src/share/classes/sun/tools/jar/resources/jar.properties	Thu Apr 09 21:18:44 2015 -0700
@@ -66,7 +66,7 @@
         (in = {0}) (out= {1})
 
 usage=\
-Usage: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\
+Usage: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\
 Options:\n\
 \ \   -c  create new archive\n\
 \ \   -t  list table of contents for archive\n\
@@ -78,6 +78,7 @@
 \ \   -e  specify application entry point for stand-alone application \n\
 \ \       bundled into an executable jar file\n\
 \ \   -0  store only; use no ZIP compression\n\
+\ \   -P  preserve leading '/' (absolute path) and ".." (parent directory) components from file names\n\
 \ \   -M  do not create a manifest file for the entries\n\
 \ \   -i  generate index information for the specified jar files\n\
 \ \   -C  change to the specified directory and include the following file\n\
--- a/test/java/util/logging/LogManagerAppContextDeadlock.java	Thu Jan 29 14:13:26 2015 +0000
+++ b/test/java/util/logging/LogManagerAppContextDeadlock.java	Thu Apr 09 21:18:44 2015 -0700
@@ -38,7 +38,7 @@
 
 /**
  * @test
- * @bug 8065991
+ * @bug 8065991 8071591
  * @summary check that when LogManager is initialized, a deadlock similar
  *          to that described in 8065709 will not occur.
  * @run main/othervm LogManagerAppContextDeadlock UNSECURE
@@ -107,6 +107,31 @@
                     return getAppContext();
                 }
 
+                @Override
+                public Object get(Object key) {
+                    return null;
+                }
+
+                @Override
+                public void put(Object key, Object value) {
+
+                }
+
+                @Override
+                public void remove(Object key) {
+
+                }
+
+                @Override
+                public boolean isDisposed() {
+                    return false;
+                }
+
+                @Override
+                public boolean isMainAppContext() {
+                    return false;
+                }
+
             });
         }
 
@@ -123,7 +148,7 @@
         }
     }
 
-    public static void test(TestCase test) throws Exception {
+    public static void test(final TestCase test) throws Exception {
         Thread t1 = new Thread() {
             @Override
             public void run() {
@@ -228,7 +253,12 @@
         @Override
         public void run() {
             sem3.release();
-            Configure.doPrivileged(this::loop);
+            Configure.doPrivileged(new Runnable() {
+                @Override
+                public void run() {
+                    DeadlockDetector.this.loop();
+                }
+            });
         }
         public void loop() {
             while(goOn) {