STAR and GNU tar may use binary encoding for all numeric values, including modification time.  COMPRESS-182

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/compress/trunk@1296763 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java
index 836f212..5f076e5 100644
--- a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java
+++ b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java
@@ -808,7 +808,7 @@
 
         name = TarUtils.parseName(header, offset, NAMELEN);
         offset += NAMELEN;
-        mode = (int) TarUtils.parseOctal(header, offset, MODELEN);
+        mode = (int) TarUtils.parseOctalOrBinary(header, offset, MODELEN);
         offset += MODELEN;
         userId = (int) TarUtils.parseOctalOrBinary(header, offset, UIDLEN);
         offset += UIDLEN;
@@ -816,7 +816,7 @@
         offset += GIDLEN;
         size = TarUtils.parseOctalOrBinary(header, offset, SIZELEN);
         offset += SIZELEN;
-        modTime = TarUtils.parseOctal(header, offset, MODTIMELEN);
+        modTime = TarUtils.parseOctalOrBinary(header, offset, MODTIMELEN);
         offset += MODTIMELEN;
         offset += CHKSUMLEN;
         linkFlag = header[offset++];
@@ -830,9 +830,9 @@
         offset += UNAMELEN;
         groupName = TarUtils.parseName(header, offset, GNAMELEN);
         offset += GNAMELEN;
-        devMajor = (int) TarUtils.parseOctal(header, offset, DEVLEN);
+        devMajor = (int) TarUtils.parseOctalOrBinary(header, offset, DEVLEN);
         offset += DEVLEN;
-        devMinor = (int) TarUtils.parseOctal(header, offset, DEVLEN);
+        devMinor = (int) TarUtils.parseOctalOrBinary(header, offset, DEVLEN);
         offset += DEVLEN;
 
         int type = evaluateType(header);
diff --git a/src/test/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStreamTest.java b/src/test/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStreamTest.java
index 6ddb526..4188aab 100644
--- a/src/test/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStreamTest.java
+++ b/src/test/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStreamTest.java
@@ -23,8 +23,10 @@
 import java.io.StringReader;
 import java.net.URI;
 import java.net.URL;
+import java.util.Calendar;
 import java.util.Date;
 import java.util.Map;
+import java.util.TimeZone;
 import org.junit.Test;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
@@ -65,4 +67,23 @@
         }
     }        
 
+    @Test
+    public void datePriorToEpochInGNUFormat() throws Exception {
+        URL tar = getClass().getResource("/preepoch-gnu.tar");
+        TarArchiveInputStream in = null;
+        try {
+            in = new TarArchiveInputStream(new FileInputStream(new File(new URI(tar.toString()))));
+            TarArchiveEntry tae = in.getNextTarEntry();
+            assertEquals("foo", tae.getName());
+            Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+            cal.set(1969, 11, 31, 23, 59, 59);
+            cal.set(Calendar.MILLISECOND, 0);
+            assertEquals(cal.getTime(), tae.getLastModifiedDate());
+        } finally {
+            if (in != null) {
+                in.close();
+            }
+        }
+    }        
+
 }
\ No newline at end of file
diff --git a/src/test/resources/preepoch-gnu.tar b/src/test/resources/preepoch-gnu.tar
new file mode 100644
index 0000000..499ec8e
--- /dev/null
+++ b/src/test/resources/preepoch-gnu.tar
Binary files differ