From badfdcdc6ea4f1b2823c05c0901b836d6aa6b1c1 Mon Sep 17 00:00:00 2001
From: "phajdan.jr@chromium.org"
 <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>
Date: Mon, 4 Nov 2013 19:58:16 +0000
Subject: FTP: fix parsing of busybox-generated directory listings

The Bad test removed here was first introduced in https://codereview.chromium.org/3327025 . It turns out we just need to accept more time formats.

BUG=312080
R=wtc@chromium.org

Review URL: https://codereview.chromium.org/56663002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@232770 0039d316-1c4b-4281-b951-d872f2087c98
---
 net/data/ftp/dir-listing-ls-32                     | 13 +++
 net/data/ftp/dir-listing-ls-32.expected            | 98 ++++++++++++++++++++++
 .../ftp_directory_listing_parser_ls_unittest.cc    |  5 +-
 net/ftp/ftp_directory_listing_parser_unittest.cc   |  1 +
 net/ftp/ftp_util.cc                                | 38 ++++-----
 5 files changed, 133 insertions(+), 22 deletions(-)
 create mode 100644 net/data/ftp/dir-listing-ls-32
 create mode 100644 net/data/ftp/dir-listing-ls-32.expected

diff --git a/net/data/ftp/dir-listing-ls-32 b/net/data/ftp/dir-listing-ls-32
new file mode 100644
index 0000000..aa21f24
--- /dev/null
+++ b/net/data/ftp/dir-listing-ls-32
@@ -0,0 +1,13 @@
+
+total 1
+drwxrwxr-x   1 500     244         660 Jan  1 00:0 bin
+drwxr-xr-x   1 0       0             0 Jan  1 00:0 dev
+drwxrwxr-x   1 500     244         272 Jan  1 00:0 etc
+drwxrwxr-x   1 500     244          16 Jan  1 00:0 mnt
+drwxrwxr-x   1 500     244           0 Jan  1 00:0 nfs
+dr-xr-xr-x  50 0       0             0 Jan  1 00:0 proc
+drwxrwxrwx   1 0       0             0 Jan  1 00:0 ram
+drwxrwxr-x   1 500     244         296 Jan  1 00:0 sbin
+lrwxrwxrwx   1 500     244           7 Jan  1 00:0 tmp -> ram/tmp
+drwxrwxr-x   1 500     244          16 Jan  1 00:0 usr
+lrwxrwxrwx   1 500     244           7 Jan  1 00:0 var -> ram/var
diff --git a/net/data/ftp/dir-listing-ls-32.expected b/net/data/ftp/dir-listing-ls-32.expected
new file mode 100644
index 0000000..ac54545
--- /dev/null
+++ b/net/data/ftp/dir-listing-ls-32.expected
@@ -0,0 +1,98 @@
+d
+bin
+-1
+1994
+1
+1
+0
+0
+
+d
+dev
+-1
+1994
+1
+1
+0
+0
+
+d
+etc
+-1
+1994
+1
+1
+0
+0
+
+d
+mnt
+-1
+1994
+1
+1
+0
+0
+
+d
+nfs
+-1
+1994
+1
+1
+0
+0
+
+d
+proc
+-1
+1994
+1
+1
+0
+0
+
+d
+ram
+-1
+1994
+1
+1
+0
+0
+
+d
+sbin
+-1
+1994
+1
+1
+0
+0
+
+l
+tmp
+-1
+1994
+1
+1
+0
+0
+
+d
+usr
+-1
+1994
+1
+1
+0
+0
+
+l
+var
+-1
+1994
+1
+1
+0
+0
diff --git a/net/ftp/ftp_directory_listing_parser_ls_unittest.cc b/net/ftp/ftp_directory_listing_parser_ls_unittest.cc
index a738944..313ef66 100644
--- a/net/ftp/ftp_directory_listing_parser_ls_unittest.cc
+++ b/net/ftp/ftp_directory_listing_parser_ls_unittest.cc
@@ -130,6 +130,10 @@ TEST_F(FtpDirectoryListingParserLsTest, Good) {
       FtpDirectoryListingEntry::DIRECTORY, "swetzel", -1,
       1994, 12, 22, 0, 0 },
 
+    { "drwxrwxr-x   1 500     244         660 Jan  1 00:0 bin",
+      FtpDirectoryListingEntry::DIRECTORY, "bin", -1,
+      1994, 1, 1, 0, 0 },
+
     // Garbage in date (but still parseable).
     { "lrw-rw-rw-   1 user     group         542 "
       "/t11/member/incomingFeb  8  2007 "
@@ -197,7 +201,6 @@ TEST_F(FtpDirectoryListingParserLsTest, Bad) {
     "-rw-r--r-- ftp ftp 528 Foo 01 2007 README",
     "-rw-r--r-- 1 ftp ftp",
     "-rw-r--r-- 1 ftp ftp 528 Foo 01 2007 README",
-    "drwxrwxrwx   1 owner    group               1024 Sep 13  0:3 audio",
 
     // Invalid month value (30).
     "drwxrwxrwx 2 root root  4096 2012-30-07 00:31 notas_servico",
diff --git a/net/ftp/ftp_directory_listing_parser_unittest.cc b/net/ftp/ftp_directory_listing_parser_unittest.cc
index 73d19bc..f27007a 100644
--- a/net/ftp/ftp_directory_listing_parser_unittest.cc
+++ b/net/ftp/ftp_directory_listing_parser_unittest.cc
@@ -141,6 +141,7 @@ const char* kTestFiles[] = {
   "dir-listing-ls-29",
   "dir-listing-ls-30",
   "dir-listing-ls-31",
+  "dir-listing-ls-32",  // busybox
 
   "dir-listing-netware-1",
   "dir-listing-netware-2",
diff --git a/net/ftp/ftp_util.cc b/net/ftp/ftp_util.cc
index c5e18c8..472275a 100644
--- a/net/ftp/ftp_util.cc
+++ b/net/ftp/ftp_util.cc
@@ -245,29 +245,25 @@ bool FtpUtil::LsDateListingToTime(const base::string16& month,
     return false;
 
   if (!base::StringToInt(rest, &time_exploded.year)) {
-    // Maybe it's time. Does it look like time (HH:MM)?
-    if (rest.length() == 5 && rest[2] == ':') {
-      if (!base::StringToInt(StringPiece16(rest.begin(), rest.begin() + 2),
-                             &time_exploded.hour)) {
-        return false;
-      }
+    // Maybe it's time. Does it look like time? Note that it can be any of
+    // "HH:MM", "H:MM", "HH:M" or maybe even "H:M".
+    if (rest.length() > 5)
+      return false;
 
-      if (!base::StringToInt(StringPiece16(rest.begin() + 3, rest.begin() + 5),
-                             &time_exploded.minute)) {
-        return false;
-      }
-    } else if (rest.length() == 4 && rest[1] == ':') {
-      // Sometimes it's just H:MM.
-      if (!base::StringToInt(StringPiece16(rest.begin(), rest.begin() + 1),
-                             &time_exploded.hour)) {
-        return false;
-      }
+    size_t colon_pos = rest.find(':');
+    if (colon_pos == string16::npos)
+      return false;
+    if (colon_pos > 2)
+      return false;
 
-      if (!base::StringToInt(StringPiece16(rest.begin() + 2, rest.begin() + 4),
-                             &time_exploded.minute)) {
-        return false;
-      }
-    } else {
+    if (!base::StringToInt(
+            StringPiece16(rest.begin(), rest.begin() + colon_pos),
+            &time_exploded.hour)) {
+      return false;
+    }
+    if (!base::StringToInt(
+            StringPiece16(rest.begin() + colon_pos + 1, rest.end()),
+            &time_exploded.minute)) {
       return false;
     }
 
-- 
cgit v1.1