Author: bodewig Date: Tue Mar 17 12:53:22 2009 New Revision: 755227 URL: http://svn.apache.org/viewvc?rev=755227&view=rev Log: deal with file system roots added as tar entries. SANDBOX-284
Added: commons/sandbox/compress/trunk/src/test/java/org/apache/commons/compress/archivers/tar/ commons/sandbox/compress/trunk/src/test/java/org/apache/commons/compress/archivers/tar/TarArchiveEntryTest.java (with props) Modified: commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java Modified: commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java URL: http://svn.apache.org/viewvc/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java?rev=755227&r1=755226&r2=755227&view=diff ============================================================================== --- commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java (original) +++ commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java Tue Mar 17 12:53:22 2009 @@ -158,6 +158,7 @@ public TarArchiveEntry(String name) { this(); + name = normalizeFileName(name); boolean isDir = name.endsWith("/"); this.devMajor = 0; @@ -199,42 +200,7 @@ 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); @@ -242,7 +208,8 @@ 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 { @@ -328,7 +295,7 @@ * @param name This entry's new name. */ public void setName(String name) { - this.name = new StringBuffer(name); + this.name = new StringBuffer(normalizeFileName(name)); } /** @@ -632,5 +599,47 @@ 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; + } } Added: commons/sandbox/compress/trunk/src/test/java/org/apache/commons/compress/archivers/tar/TarArchiveEntryTest.java URL: http://svn.apache.org/viewvc/commons/sandbox/compress/trunk/src/test/java/org/apache/commons/compress/archivers/tar/TarArchiveEntryTest.java?rev=755227&view=auto ============================================================================== --- commons/sandbox/compress/trunk/src/test/java/org/apache/commons/compress/archivers/tar/TarArchiveEntryTest.java (added) +++ commons/sandbox/compress/trunk/src/test/java/org/apache/commons/compress/archivers/tar/TarArchiveEntryTest.java Tue Mar 17 12:53:22 2009 @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.commons.compress.archivers.tar; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Locale; +import junit.framework.TestCase; + +public class TarArchiveEntryTest extends TestCase { + + private static final String OS = + System.getProperty("os.name").toLowerCase(Locale.US); + private static final String ROOT = + OS.startsWith("windows") || OS.startsWith("netware") ? "C:\\" : "/"; + + /** + * JIRA issue SANDBOX-284 + * + * @see https://issues.apache.org/jira/browse/SANDBOX-284 + */ + public void testFileSystemRoot() { + TarArchiveEntry t = new TarArchiveEntry(new File(ROOT)); + assertEquals("/", t.getName()); + } + + public void testTarFileWithFSRoot() throws IOException { + File f = File.createTempFile("taetest", ".tar"); + f.deleteOnExit(); + TarArchiveOutputStream tout = null; + TarArchiveInputStream tin = null; + try { + tout = new TarArchiveOutputStream(new FileOutputStream(f)); + TarArchiveEntry t = new TarArchiveEntry(new File(ROOT)); + tout.putNextEntry(t); + tout.closeEntry(); + t = new TarArchiveEntry(new File(new File(ROOT), "foo.txt")); + t.setSize(6); + tout.putNextEntry(t); + tout.write(new byte[] {'h', 'e', 'l', 'l', 'o', ' '}); + tout.closeEntry(); + t = new TarArchiveEntry(new File(new File(ROOT), "bar.txt") + .getAbsolutePath()); + t.setSize(5); + tout.putNextEntry(t); + tout.write(new byte[] {'w', 'o', 'r', 'l', 'd'}); + tout.closeEntry(); + t = new TarArchiveEntry("dummy"); + t.setName(new File(new File(ROOT), "baz.txt").getAbsolutePath()); + t.setSize(1); + tout.putNextEntry(t); + tout.write(new byte[] {'!'}); + tout.closeEntry(); + tout.close(); + tout = null; + + tin = new TarArchiveInputStream(new FileInputStream(f)); + t = tin.getNextTarEntry(); + assertEquals("/", t.getName()); + t = tin.getNextTarEntry(); + assertEquals("foo.txt", t.getName()); + t = tin.getNextTarEntry(); + assertEquals("bar.txt", t.getName()); + t = tin.getNextTarEntry(); + assertEquals("baz.txt", t.getName()); + } finally { + if (tin != null) { + tin.close(); + } + if (tout != null) { + tout.close(); + } + } + } +} Propchange: commons/sandbox/compress/trunk/src/test/java/org/apache/commons/compress/archivers/tar/TarArchiveEntryTest.java ------------------------------------------------------------------------------ svn:eol-style = native