commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From s...@apache.org
Subject svn commit: r943863 - in /commons/proper/compress/trunk: ./ src/changes/ src/main/java/org/apache/commons/compress/archivers/ar/ src/test/java/org/apache/commons/compress/archivers/ src/test/resources/longpath/
Date Thu, 13 May 2010 10:25:16 GMT
Author: sebb
Date: Thu May 13 10:25:15 2010
New Revision: 943863

URL: http://svn.apache.org/viewvc?rev=943863&view=rev
Log:
COMPRESS-112 ArArchiveInputStream does not handle GNU extended filename records (//)

Added:
    commons/proper/compress/trunk/src/test/resources/longpath/minotaur.ar   (with props)
Modified:
    commons/proper/compress/trunk/RELEASE-NOTES.txt
    commons/proper/compress/trunk/src/changes/changes.xml
    commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveInputStream.java
    commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/LongPathTest.java

Modified: commons/proper/compress/trunk/RELEASE-NOTES.txt
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/RELEASE-NOTES.txt?rev=943863&r1=943862&r2=943863&view=diff
==============================================================================
--- commons/proper/compress/trunk/RELEASE-NOTES.txt (original)
+++ commons/proper/compress/trunk/RELEASE-NOTES.txt Thu May 13 10:25:15 2010
@@ -76,11 +76,12 @@ o The ar and cpio streams now properly r
 o COMPRESS-81:  TarOutputStream can leave garbage at the end of the archive 
 
 Changes:
+o COMPRESS-112:  ArArchiveInputStream does not handle GNU extended filename records (//)

 o COMPRESS-109:  Tar implementation does not support Pax headers
        Added support for reading pax headers.
        Note: does not support global pax headers 
 o COMPRESS-105:  Document that the name of an ZipArchiveEntry determines whether
-       an entry is considered a directory or not. 
+       an entry is considered a directory or not.
        If you don't use the constructor with the File argument the entry's
         name must end in a "/" in order for the entry to be known as a directory. 
 o COMPRESS-79:  Move DOS/Java time conversions into Zip utility class. 

Modified: commons/proper/compress/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/changes/changes.xml?rev=943863&r1=943862&r2=943863&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/changes/changes.xml (original)
+++ commons/proper/compress/trunk/src/changes/changes.xml Thu May 13 10:25:15 2010
@@ -45,6 +45,9 @@ The <action> type attribute can be add,u
   </properties>
   <body>
     <release version="1.1" date="as in SVN" description="Release 1.1">
+      <action issue="COMPRESS-112" type="update" date="2010-05-13">
+       ArArchiveInputStream does not handle GNU extended filename records (//)
+      </action>
       <action issue="COMPRESS-109" type="update" date="2010-05-10">
        Tar implementation does not support Pax headers
        Added support for reading pax headers.

Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveInputStream.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveInputStream.java?rev=943863&r1=943862&r2=943863&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveInputStream.java
(original)
+++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveInputStream.java
Thu May 13 10:25:15 2010
@@ -43,6 +43,9 @@ public class ArArchiveInputStream extend
      */
     private ArArchiveEntry currentEntry = null;
     
+    // Storage area for extra long names (GNU ar)
+    private byte[] namebuffer = null;
+    
     /*
      * The offset where the current entry started. -1 if no entry has been
      * called
@@ -125,22 +128,38 @@ public class ArArchiveInputStream extend
             final byte[] realized = new byte[expected.length];
             final int read = read(realized);
             if (read != expected.length) {
-                throw new IOException("failed to read entry header. Occured at byte: " +
getBytesRead());
+                throw new IOException("failed to read entry trailer. Occured at byte: " +
getBytesRead());
             }
             for (int i = 0; i < expected.length; i++) {
                 if (expected[i] != realized[i]) {
-                    throw new IOException("invalid entry header. not read the content? Occured
at byte: " + getBytesRead());
+                    throw new IOException("invalid entry trailer. not read the content? Occured
at byte: " + getBytesRead());
                 }
             }
         }
 
         entryOffset = offset;
 
-        // SVR4/GNU adds a trailing "/" to names
+//        GNU ar stores multiple extended filenames in the data section of a file with the
name "//", this record is referred to by future headers. A header references an extended filename
by storing a "/" followed by a decimal offset to the start of the filename in the extended
filename data section. The format of this "//" file itself is simply a list of the long filenames,
each separated by one or more LF characters. Note that the decimal offsets are number of characters,
not line or string number within the "//" file.
+//
+//        GNU ar uses a '/' to mark the end of the filename; this allows for the use of spaces
without the use of an extended filename.
+
         // entry name is stored as ASCII string
         String temp = ArchiveUtils.toAsciiString(name).trim();
-        if (temp.endsWith("/")) {
+        
+        if (temp.equals("//")){ // GNU extended filenames entry
+            int bufflen = asInt(length); // Assume length will fit in an int
+            namebuffer = new byte[bufflen];
+            int read = read(namebuffer, 0, bufflen);
+            if (read != bufflen){
+                throw new IOException("Failed to read complete // record: expected="+bufflen+"
read="+read);
+            }
+            currentEntry = new ArArchiveEntry(temp, bufflen);
+            return getNextArEntry();
+        } else if (temp.endsWith("/")) { // GNU terminator
             temp = temp.substring(0, temp.length() - 1);
+        } else if (temp.matches("^/\\d+")) {// GNU long filename ref.
+            int offset = Integer.parseInt(temp.substring(1));// get the offset
+            temp = getExtendedName(offset); // convert to the long name
         }
         currentEntry = new ArArchiveEntry(temp, asLong(length), asInt(userid),
                                           asInt(groupid), asInt(filemode, 8),
@@ -148,6 +167,27 @@ public class ArArchiveInputStream extend
         return currentEntry;
     }
 
+    /**
+     * Get an extended name from the GNU extended name buffer.
+     * 
+     * @param offset pointer to entry within the buffer
+     * @return the extended file name; without trailing "/" if present.
+     * @throws IOException if name not found or buffer not set up
+     */
+    private String getExtendedName(int offset) throws IOException{
+        if (namebuffer == null) {
+            throw new IOException("Cannot process GNU long filename as no // record was found");
+        }
+        for(int i=offset; i < namebuffer.length; i++){
+            if (namebuffer[i]=='\012'){
+                if (namebuffer[i-1]=='/') {
+                    i--; // drop trailing /
+                }
+                return ArchiveUtils.toAsciiString(namebuffer, offset, i-offset);
+            }
+        }
+        throw new IOException("Failed to read entry: "+offset);
+    }
     private long asLong(byte[] input) {
         return Long.parseLong(new String(input).trim());
     }

Modified: commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/LongPathTest.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/LongPathTest.java?rev=943863&r1=943862&r2=943863&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/LongPathTest.java
(original)
+++ commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/LongPathTest.java
Thu May 13 10:25:15 2010
@@ -31,6 +31,7 @@ import junit.framework.Test;
 import junit.framework.TestSuite;
 
 import org.apache.commons.compress.AbstractTestCase;
+import org.apache.commons.compress.archivers.ar.ArArchiveInputStream;
 import org.apache.commons.compress.archivers.cpio.CpioArchiveInputStream;
 import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
 import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
@@ -112,6 +113,21 @@ public class LongPathTest extends Abstra
                     expected.set(i, ent.substring(0, ent.length()-1));
                 }
             }
+        } else if (name.endsWith(".ar")){
+            assertTrue(ais instanceof ArArchiveInputStream);
+            // CPIO does not store directories or directory names
+            expected.clear();
+            for(int i=0; i < fileList.size(); i++){
+                String ent = (String) fileList.get(i);
+                if (!ent.endsWith("/")){// not a directory
+                    final int lastSlash = ent.lastIndexOf('/');
+                    if (lastSlash >= 0) { // extract path name
+                        expected.add(ent.substring(lastSlash+1, ent.length()));         
              
+                    } else {
+                        expected.add(ent);
+                    }
+                }
+            }
         } else {
             fail("Unexpected file type: "+name);
         }

Added: commons/proper/compress/trunk/src/test/resources/longpath/minotaur.ar
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/resources/longpath/minotaur.ar?rev=943863&view=auto
==============================================================================
Binary file - no diff available.

Propchange: commons/proper/compress/trunk/src/test/resources/longpath/minotaur.ar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream



Mime
View raw message