You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by se...@apache.org on 2016/07/14 13:46:19 UTC

svn commit: r1752661 - in /commons/proper/net/trunk/src: changes/changes.xml main/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java test/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParserTest.java

Author: sebb
Date: Thu Jul 14 13:46:19 2016
New Revision: 1752661

URL: http://svn.apache.org/viewvc?rev=1752661&view=rev
Log:
NET-597 FTP fails to parse listings for Solaris 10 FTPd in Japanese

Modified:
    commons/proper/net/trunk/src/changes/changes.xml
    commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java
    commons/proper/net/trunk/src/test/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParserTest.java

Modified: commons/proper/net/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/changes/changes.xml?rev=1752661&r1=1752660&r2=1752661&view=diff
==============================================================================
--- commons/proper/net/trunk/src/changes/changes.xml [utf-8] (original)
+++ commons/proper/net/trunk/src/changes/changes.xml [utf-8] Thu Jul 14 13:46:19 2016
@@ -64,6 +64,9 @@ The <action> type attribute can be add,u
 
     <body>
         <release version="3.6" date="TBA" description="">
+            <action issue="NET-597" type="fix" dev="sebb" due-to="Hiroki Taniura">
+            FTP fails to parse listings for Solaris 10 FTPd in Japanese
+            </action>
             <action issue="NET-599" type="update" dev="sebb">
             Add shorthand FTPClientConfig constructor
             </action>

Modified: commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java?rev=1752661&r1=1752660&r2=1752661&view=diff
==============================================================================
--- commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java (original)
+++ commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java Thu Jul 14 13:46:19 2016
@@ -45,6 +45,17 @@ public class UnixFTPEntryParser extends
     static final String NUMERIC_DATE_FORMAT
         = "yyyy-MM-dd HH:mm"; //2001-11-09 20:06
 
+    // Suffixes used in Japanese listings after the numeric values
+    private static final String JA_MONTH = "\u6708";
+    private static final String JA_DAY   = "\u65e5";
+    private static final String JA_YEAR  = "\u5e74";
+
+    private static final String DEFAULT_DATE_FORMAT_JA
+        = "M'" + JA_MONTH + "' d'" + JA_DAY + "' yyyy'" + JA_YEAR + "'"; //6月 3日 2003年
+
+    private static final String DEFAULT_RECENT_DATE_FORMAT_JA
+        = "M'" + JA_MONTH + "' d'" + JA_DAY + "' HH:mm"; //8月 17日 20:10
+
     /**
      * Some Linux distributions are now shipping an FTP server which formats
      * file listing dates in an all-numeric format:
@@ -111,16 +122,24 @@ public class UnixFTPEntryParser extends
          *   [d]d MMM
          *   N.B. use non-space for MMM to allow for languages such as German which use
          *   diacritics (e.g. umlaut) in some abbreviations.
+         *   Japanese uses numeric day and month with suffixes to distinguish them
+         *   [d]dXX [d]dZZ
         */
-        + "((?:\\d+[-/]\\d+[-/]\\d+)|(?:\\S{3}\\s+\\d{1,2})|(?:\\d{1,2}\\s+\\S{3}))"
+        + "("+
+            "(?:\\d+[-/]\\d+[-/]\\d+)" + // yyyy-mm-dd
+            "|(?:\\S{3}\\s+\\d{1,2})" +  // MMM [d]d
+            "|(?:\\d{1,2}\\s+\\S{3})" + // [d]d MMM
+            "|(?:\\d{1,2}" + JA_MONTH + "\\s+\\d{1,2}" + JA_DAY + ")"+
+           ")"
 
         + "\\s+" // separator
 
         /*
            year (for non-recent standard format) - yyyy
            or time (for numeric or recent standard format) [h]h:mm
+           or Japanese year - yyyyXX
         */
-        + "(\\d+(?::\\d+)?)" // (20)
+        + "((?:\\d+(?::\\d+)?)|(?:\\d{4}" + JA_YEAR + "))" // (20)
 
         + "\\s" // separator
 
@@ -228,7 +247,14 @@ public class UnixFTPEntryParser extends
 
             try
             {
-                file.setTimestamp(super.parseTimestamp(datestr));
+                if (group(19).contains(JA_MONTH)) { // special processing for Japanese format
+                    FTPTimestampParserImpl jaParser = new FTPTimestampParserImpl();
+                    jaParser.configure(new FTPClientConfig(
+                            FTPClientConfig.SYST_UNIX, DEFAULT_DATE_FORMAT_JA, DEFAULT_RECENT_DATE_FORMAT_JA));
+                    file.setTimestamp(jaParser.parseTimestamp(datestr));
+                } else {
+                    file.setTimestamp(super.parseTimestamp(datestr));
+                }
             }
             catch (ParseException e)
             {
@@ -347,8 +373,7 @@ public class UnixFTPEntryParser extends
         return new FTPClientConfig(
                 FTPClientConfig.SYST_UNIX,
                 DEFAULT_DATE_FORMAT,
-                DEFAULT_RECENT_DATE_FORMAT,
-                null, null, null);
+                DEFAULT_RECENT_DATE_FORMAT);
     }
 
 }

Modified: commons/proper/net/trunk/src/test/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParserTest.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/test/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParserTest.java?rev=1752661&r1=1752660&r2=1752661&view=diff
==============================================================================
--- commons/proper/net/trunk/src/test/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParserTest.java (original)
+++ commons/proper/net/trunk/src/test/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParserTest.java Thu Jul 14 13:46:19 2016
@@ -76,8 +76,12 @@ public class UnixFTPEntryParserTest exte
             "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
 
+            // http://mail-archives.apache.org/mod_mbox/commons-dev/200408.mbox/%3c4122F3C1.9090402@tanukisoftware.com%3e
+            "-rw-r--r-- 1 1 3518644 May 25 12:12 std",
+            "-rw-rw---- 1 ep1adm sapsys 0 6\u6708 3\u65e5 2003\u5e74 \u8a66\u9a13\u30d5\u30a1\u30a4\u30eb.csv",
+            "-rw-rw---- 1 ep1adm sapsys 0 8\u6708 17\u65e5 20:10 caerrinf",
 
-        };
+    };
 
     public UnixFTPEntryParserTest(String name) {
         super(name);
@@ -325,6 +329,59 @@ public class UnixFTPEntryParserTest exte
         assertEquals(df.format(cal.getTime()), df.format(f.getTimestamp().getTime()));
     }
 
+    // http://mail-archives.apache.org/mod_mbox/commons-dev/200408.mbox/%3c4122F3C1.9090402@tanukisoftware.com%3e
+    public void testParseFieldsOnFileJapaneseTime() throws Exception
+    {
+        FTPFile f = getParser().parseFTPEntry("-rwxr-xr-x 2 user group 4096 3\u6708 2\u65e5 15:13 zxbox");
+        assertNotNull("Could not parse entry.", f);
+        assertTrue("Should have been a file.", f.isFile());
+        checkPermissions(f);
+        assertEquals(2, f.getHardLinkCount());
+        assertEquals("user", f.getUser());
+        assertEquals("group", f.getGroup());
+        assertEquals("zxbox", f.getName());
+        assertEquals(4096, f.getSize());
+
+        assertNotNull("Timestamp not null", f.getTimestamp());
+        Calendar cal = Calendar.getInstance();
+        cal.set(Calendar.MONTH, Calendar.MARCH);
+        cal.set(Calendar.DATE,1);
+        cal.set(Calendar.HOUR_OF_DAY, 0);
+        cal.set(Calendar.MINUTE, 0);
+        cal.set(Calendar.SECOND, 0);
+        if (f.getTimestamp().getTime().before(cal.getTime())) {
+            cal.add(Calendar.YEAR, -1);
+        }
+        cal.set(Calendar.DATE,2);
+        cal.set(Calendar.HOUR_OF_DAY, 15);
+        cal.set(Calendar.MINUTE, 13);
+        assertEquals(df.format(cal.getTime()), df.format(f.getTimestamp().getTime()));
+    }
+
+ // http://mail-archives.apache.org/mod_mbox/commons-dev/200408.mbox/%3c4122F3C1.9090402@tanukisoftware.com%3e
+    public void testParseFieldsOnFileJapaneseYear() throws Exception {
+        FTPFile f = getParser().parseFTPEntry(
+                "-rwxr-xr-x 2 user group 4096 3\u6708 2\u65e5 2003\u5e74 \u8a66\u9a13\u30d5\u30a1\u30a4\u30eb.csv");
+        assertNotNull("Could not parse entry.", f);
+        assertTrue("Should have been a file.", f.isFile());
+        checkPermissions(f);
+        assertEquals(2, f.getHardLinkCount());
+        assertEquals("user", f.getUser());
+        assertEquals("group", f.getGroup());
+        assertEquals("\u8a66\u9a13\u30d5\u30a1\u30a4\u30eb.csv", f.getName());
+        assertEquals(4096, f.getSize());
+
+        assertNotNull("Timestamp not null", f.getTimestamp());
+        Calendar cal = Calendar.getInstance();
+        cal.set(Calendar.YEAR, 2003);
+        cal.set(Calendar.MONTH, Calendar.MARCH);
+        cal.set(Calendar.DATE, 2);
+        cal.set(Calendar.HOUR_OF_DAY, 0);
+        cal.set(Calendar.MINUTE, 0);
+        cal.set(Calendar.SECOND, 0);
+        assertEquals(df.format(cal.getTime()), df.format(f.getTimestamp().getTime()));
+    }
+
     @Override
     protected void doAdditionalGoodTests(String test, FTPFile f) {
         String link = f.getLink();