NET-294 UnixFTPEntryParser fails to parse some entries

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/net/branches/NET_2_0@814446 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java b/src/main/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java
index 408d247..e1b1919 100644
--- a/src/main/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java
+++ b/src/main/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java
@@ -84,21 +84,24 @@
     private static final String REGEX =
         "([bcdelfmpSs-])"
         +"(((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-])))\\+?\\s*"
-        + "(\\d+)\\s+"
+        + "(\\d+)\\s+"                                  // link count
         + "(?:(\\S+(?:\\s\\S+)*?)\\s+)?"                // owner name (optional spaces)
         + "(?:(\\S+(?:\\s\\S+)*)\\s+)?"                 // group name (optional spaces)
-        + "(\\d+(?:,\\s*\\d+)?)\\s+"
+        + "(\\d+(?:,\\s*\\d+)?)\\s+"                    // size or n,m
         /*
-          numeric or standard format date
+         * numeric or standard format date:
+         *   yyyy-mm-dd (expecting hh:mm to follow)
+         *   MMMM [d]d
+         *   [d]d MMM
         */
-        + "((?:\\d+[-/]\\d+[-/]\\d+)|(?:[a-zA-Z0-9]+\\s+\\S+))\\s+"
+        + "((?:\\d+[-/]\\d+[-/]\\d+)|(?:[a-zA-Z]{3}\\s+\\d{1,2})|(?:\\d{1,2}\\s+[a-zA-Z]{3}))\\s+"
         /* 
-           year (for non-recent standard format) 
-           or time (for numeric or recent standard format  
+           year (for non-recent standard format) - yyyy
+           or time (for numeric or recent standard format) [h]h:mm  
         */
         + "(\\d+(?::\\d+)?)\\s+"
         
-        + "(\\S*)(\\s*.*)";
+        + "(\\S*)(\\s*.*)"; // the rest
 
 
     /**
@@ -186,6 +189,7 @@
             case 'c':
                 isDevice = true;
                 // break; - fall through
+                //$FALL-THROUGH$ TODO change this if DEVICE_TYPE implemented
             case 'f':
             case '-':
                 type = FTPFile.FILE_TYPE;
diff --git a/src/site/xdoc/changes.xml b/src/site/xdoc/changes.xml
index 930898a..4d3d2ba 100644
--- a/src/site/xdoc/changes.xml
+++ b/src/site/xdoc/changes.xml
@@ -99,6 +99,9 @@
 			<action dev="rwinston" type="fix">
 				Fix inconsistent handling of socket read/write buffer size
 			</action>
+            <action dev="sebb" type="fix" issue="NET-294">
+                UnixFTPEntryParser fails to parse some entries
+            </action>
 		</release>
 
 		<release version="2.0" date="October 20, 2008" description="Java 5.0 release">
diff --git a/src/test/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParserTest.java b/src/test/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParserTest.java
index c942300..2fb615e 100644
--- a/src/test/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParserTest.java
+++ b/src/test/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParserTest.java
@@ -74,7 +74,8 @@
             "lrwxrwxrwx   1 neeme neeme             23 Mar  2 18:06 macros -> ./../../global/macros/.",
             "-rw-r--r--   1 ftp      group with spaces in it as allowed in cygwin see bug 38634   83853 Jan 22  2001 zxJDBC-1.2.4.tar.gz",
             "crw-r----- 1 root kmem 0, 27 Jan 30 11:42 kmem",  //FreeBSD device
-            "crw-------   1 root     sys      109,767 Jul  2  2004 pci@1c,600000:devctl" //Solaris device
+            "crw-------   1 root     sys      109,767 Jul  2  2004 pci@1c,600000:devctl", //Solaris device
+            "-rwxrwx---   1 ftp      ftp-admin 816026400 Oct  5  2008 bloplab 7 cd1.img", // NET-294
 
 
         };
@@ -158,6 +159,18 @@
         assertEquals("test group", f.getGroup());
     }
     
+    public void testNET294() {
+        FTPFile f = getParser().parseFTPEntry(
+                "-rwxrwx---   1 ftp      ftp-admin 816026400 Oct  5  2008 bloplab 7 cd1.img");
+        assertNotNull(f);
+        assertEquals("ftp", f.getUser());
+        assertEquals("ftp-admin", f.getGroup());
+        assertEquals(816026400L,f.getSize());
+        assertNotNull("Timestamp should not be null",f.getTimestamp());
+        assertEquals(2008,f.getTimestamp().get(Calendar.YEAR));
+        assertEquals("bloplab 7 cd1.img",f.getName());
+    }
+    
     public void testGroupNameWithSpaces() {
         FTPFile f = getParser().parseFTPEntry("drwx------ 4 maxm Domain Users 512 Oct 2 10:59 .metadata");
         assertNotNull(f);
@@ -343,6 +356,7 @@
         case 'b':
         case 'c':
             assertEquals(0, f.getHardLinkCount());
+            //$FALL-THROUGH$ TODO this needs to be fixed if a device type is introduced
         case 'f':
         case '-':
             assertEquals("Type of "+ test, type, FTPFile.FILE_TYPE);
@@ -365,5 +379,8 @@
             }
         }
 
+        assertNotNull("Expected to find a timestamp",f.getTimestamp());
+// Perhaps check date range (need to ensure all good examples qualify)
+//        assertTrue(test,f.getTimestamp().get(Calendar.YEAR)>=2000);
     }
 }