Mercurial > hg > release > icedtea7-forest-2.5 > jdk
changeset 8161:9e69fb9109d1
8064601: Improve jar file handling
Reviewed-by: sherman, coffeys
author | robm |
---|---|
date | Wed, 28 Jan 2015 18:47:45 +0000 |
parents | 4ced6a9ddaaa |
children | 8cca2c58dd9d |
files | src/share/classes/sun/tools/jar/Main.java src/share/classes/sun/tools/jar/resources/jar.properties |
diffstat | 2 files changed, 69 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/sun/tools/jar/Main.java Tue Nov 11 17:45:02 2014 +0300 +++ b/src/share/classes/sun/tools/jar/Main.java Wed Jan 28 18:47:45 2015 +0000 @@ -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 Tue Nov 11 17:45:02 2014 +0300 +++ b/src/share/classes/sun/tools/jar/resources/jar.properties Wed Jan 28 18:47:45 2015 +0000 @@ -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\