diff options
author | phajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-12 22:23:45 +0000 |
---|---|---|
committer | phajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-12 22:23:45 +0000 |
commit | d99d9bd20ce7543ad08f36cb6126313d82e6b9ab (patch) | |
tree | 0dde1737795ad620c39e89765fbe921dc1229079 /net | |
parent | 88cb164e7b428655cb3c7adf4c22def41a013a3f (diff) | |
download | chromium_src-d99d9bd20ce7543ad08f36cb6126313d82e6b9ab.zip chromium_src-d99d9bd20ce7543ad08f36cb6126313d82e6b9ab.tar.gz chromium_src-d99d9bd20ce7543ad08f36cb6126313d82e6b9ab.tar.bz2 |
FTP: support YYYY-MM-DD HH:MM date format in "ls -l" directory listings.
BUG=138529
TEST=Covered by net_unittests.
Review URL: https://chromiumcodereview.appspot.com/11293227
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@167250 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/ftp/ftp_directory_listing_parser_ls.cc | 72 | ||||
-rw-r--r-- | net/ftp/ftp_directory_listing_parser_ls_unittest.cc | 11 |
2 files changed, 74 insertions, 9 deletions
diff --git a/net/ftp/ftp_directory_listing_parser_ls.cc b/net/ftp/ftp_directory_listing_parser_ls.cc index c4d3c78..ab0f487 100644 --- a/net/ftp/ftp_directory_listing_parser_ls.cc +++ b/net/ftp/ftp_directory_listing_parser_ls.cc @@ -51,12 +51,51 @@ bool LooksLikeUnixPermissionsListing(const string16& text) { LooksLikeUnixPermission(text.substr(4, 3))); } +bool TwoColumnDateListingToTime(const string16& date, + const string16& time, + base::Time* result) { + base::Time::Exploded time_exploded = { 0 }; + + // Date should be in format YYYY-MM-DD. + std::vector<string16> date_parts; + base::SplitString(date, '-', &date_parts); + if (date_parts.size() != 3) + return false; + if (!base::StringToInt(date_parts[0], &time_exploded.year)) + return false; + if (!base::StringToInt(date_parts[1], &time_exploded.month)) + return false; + if (!base::StringToInt(date_parts[2], &time_exploded.day_of_month)) + return false; + + // Time should be in format HH:MM + if (time.length() != 5) + return false; + + std::vector<string16> time_parts; + base::SplitString(time, ':', &time_parts); + if (time_parts.size() != 2) + return false; + if (!base::StringToInt(time_parts[0], &time_exploded.hour)) + return false; + if (!base::StringToInt(time_parts[1], &time_exploded.minute)) + return false; + if (!time_exploded.HasValidValues()) + return false; + + // We don't know the time zone of the server, so just use local time. + *result = base::Time::FromLocalExploded(time_exploded); + return true; +} + // Returns the column index of the end of the date listing and detected // last modification time. -bool DetectColumnOffsetAndModificationTime(const std::vector<string16>& columns, - const base::Time& current_time, - size_t* offset, - base::Time* modification_time) { +bool DetectColumnOffsetSizeAndModificationTime( + const std::vector<string16>& columns, + const base::Time& current_time, + size_t* offset, + string16* size, + base::Time* modification_time) { // The column offset can be arbitrarily large if some fields // like owner or group name contain spaces. Try offsets from left to right // and use the first one that matches a date listing. @@ -79,6 +118,7 @@ bool DetectColumnOffsetAndModificationTime(const std::vector<string16>& columns, columns[i], current_time, modification_time)) { + *size = columns[i - 3]; *offset = i; return true; } @@ -93,6 +133,18 @@ bool DetectColumnOffsetAndModificationTime(const std::vector<string16>& columns, columns[i], current_time, modification_time)) { + *size = columns[i - 3]; + *offset = i; + return true; + } + } + + // Some FTP listings use a different date format. + for (size_t i = 5U; i < columns.size(); i++) { + if (TwoColumnDateListingToTime(columns[i - 1], + columns[i], + modification_time)) { + *size = columns[i - 2]; *offset = i; return true; } @@ -140,10 +192,12 @@ bool ParseFtpDirectoryListingLs( FtpDirectoryListingEntry entry; size_t column_offset; - if (!DetectColumnOffsetAndModificationTime(columns, - current_time, - &column_offset, - &entry.last_modified)) { + string16 size; + if (!DetectColumnOffsetSizeAndModificationTime(columns, + current_time, + &column_offset, + &size, + &entry.last_modified)) { // Some servers send a message in one of the first few lines. // All those messages have in common is the string ".:", // where "." means the current directory, and ":" separates it @@ -164,7 +218,7 @@ bool ParseFtpDirectoryListingLs( entry.type = FtpDirectoryListingEntry::FILE; } - if (!base::StringToInt64(columns[column_offset - 3], &entry.size)) { + if (!base::StringToInt64(size, &entry.size)) { // Some FTP servers do not separate owning group name from file size, // like "group1234". We still want to display the file name for that // entry, but can't really get the size (What if the group is named diff --git a/net/ftp/ftp_directory_listing_parser_ls_unittest.cc b/net/ftp/ftp_directory_listing_parser_ls_unittest.cc index b14d5c0..9da23cf 100644 --- a/net/ftp/ftp_directory_listing_parser_ls_unittest.cc +++ b/net/ftp/ftp_directory_listing_parser_ls_unittest.cc @@ -116,6 +116,14 @@ TEST_F(FtpDirectoryListingParserLsTest, Good) { { "drwxrwx 2 10 4096 Jul 28 02:41 tmp", FtpDirectoryListingEntry::DIRECTORY, "tmp", -1, 1994, 7, 28, 2, 41 }, + + // Completely different date format (YYYY-MM-DD). + { "drwxrwxrwx 2 root root 4096 2012-02-07 00:31 notas_servico", + FtpDirectoryListingEntry::DIRECTORY, "notas_servico", -1, + 2012, 2, 7, 0, 31 }, + { "-rwxrwxrwx 2 root root 4096 2012-02-07 00:31 notas_servico", + FtpDirectoryListingEntry::FILE, "notas_servico", 4096, + 2012, 2, 7, 0, 31 }, }; for (size_t i = 0; i < arraysize(good_cases); i++) { SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s", i, @@ -172,6 +180,9 @@ TEST_F(FtpDirectoryListingParserLsTest, Bad) { "drwxrwxrwx 1 owner group 1024 Sep 13 0:3 audio", "-qqqqqqqqq+ 2 sys 512 Mar 27 2009 pub", + + // Invalid month value (30). + "drwxrwxrwx 2 root root 4096 2012-30-07 00:31 notas_servico", }; for (size_t i = 0; i < arraysize(bad_cases); i++) { SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s", i, |