From 54166cfaf09c222a4fc9bb2abd7719c6d452921e Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Tue, 17 Mar 2009 12:59:48 +0000 Subject: [PATCH] deal with file system roots being added - was leading to IndexOutOfBoundsExceptions in File-arg constructor git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@755231 13f79535-47bb-0310-9956-ffa450edef68 --- src/main/org/apache/tools/tar/TarEntry.java | 85 ++++++++++++--------- 1 file changed, 47 insertions(+), 38 deletions(-) diff --git a/src/main/org/apache/tools/tar/TarEntry.java b/src/main/org/apache/tools/tar/TarEntry.java index 4fb5b66ff..fb0464d8d 100644 --- a/src/main/org/apache/tools/tar/TarEntry.java +++ b/src/main/org/apache/tools/tar/TarEntry.java @@ -161,6 +161,7 @@ public class TarEntry implements TarConstants { public TarEntry(String name) { this(); + name = normalizeFileName(name); boolean isDir = name.endsWith("/"); this.devMajor = 0; @@ -202,42 +203,7 @@ public class TarEntry implements TarConstants { this.file = file; - String fileName = file.getPath(); - String osname = System.getProperty("os.name").toLowerCase(Locale.US); - - if (osname != null) { - - // Strip off drive letters! - // REVIEW Would a better check be "(File.separator == '\')"? - - if (osname.startsWith("windows")) { - if (fileName.length() > 2) { - char ch1 = fileName.charAt(0); - char ch2 = fileName.charAt(1); - - if (ch2 == ':' - && ((ch1 >= 'a' && ch1 <= 'z') - || (ch1 >= 'A' && ch1 <= 'Z'))) { - fileName = fileName.substring(2); - } - } - } else if (osname.indexOf("netware") > -1) { - int colon = fileName.indexOf(':'); - if (colon != -1) { - fileName = fileName.substring(colon + 1); - } - } - } - - fileName = fileName.replace(File.separatorChar, '/'); - - // No absolute pathnames - // Windows (and Posix?) paths can start with "\\NetworkDrive\", - // so we loop on starting /'s. - while (fileName.startsWith("/")) { - fileName = fileName.substring(1); - } - + String fileName = normalizeFileName(file.getPath()); this.linkName = new StringBuffer(""); this.name = new StringBuffer(fileName); @@ -245,7 +211,8 @@ public class TarEntry implements TarConstants { this.mode = DEFAULT_DIR_MODE; this.linkFlag = LF_DIR; - if (this.name.charAt(this.name.length() - 1) != '/') { + int nameLength = name.length(); + if (nameLength == 0 || name.charAt(nameLength - 1) != '/') { this.name.append("/"); } } else { @@ -331,7 +298,7 @@ public class TarEntry implements TarConstants { * @param name This entry's new name. */ public void setName(String name) { - this.name = new StringBuffer(name); + this.name = new StringBuffer(normalizeFileName(name)); } /** @@ -635,4 +602,46 @@ public class TarEntry implements TarConstants { offset += DEVLEN; devMinor = (int) TarUtils.parseOctal(header, offset, DEVLEN); } + + /** + * Strips Windows' drive letter as well as any leading slashes, + * turns path separators into forward slahes. + */ + private static String normalizeFileName(String fileName) { + String osname = System.getProperty("os.name").toLowerCase(Locale.US); + + if (osname != null) { + + // Strip off drive letters! + // REVIEW Would a better check be "(File.separator == '\')"? + + if (osname.startsWith("windows")) { + if (fileName.length() > 2) { + char ch1 = fileName.charAt(0); + char ch2 = fileName.charAt(1); + + if (ch2 == ':' + && ((ch1 >= 'a' && ch1 <= 'z') + || (ch1 >= 'A' && ch1 <= 'Z'))) { + fileName = fileName.substring(2); + } + } + } else if (osname.indexOf("netware") > -1) { + int colon = fileName.indexOf(':'); + if (colon != -1) { + fileName = fileName.substring(colon + 1); + } + } + } + + fileName = fileName.replace(File.separatorChar, '/'); + + // No absolute pathnames + // Windows (and Posix?) paths can start with "\\NetworkDrive\", + // so we loop on starting /'s. + while (fileName.startsWith("/")) { + fileName = fileName.substring(1); + } + return fileName; + } }