summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-12 22:23:45 +0000
committerphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-12 22:23:45 +0000
commitd99d9bd20ce7543ad08f36cb6126313d82e6b9ab (patch)
tree0dde1737795ad620c39e89765fbe921dc1229079 /net
parent88cb164e7b428655cb3c7adf4c22def41a013a3f (diff)
downloadchromium_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.cc72
-rw-r--r--net/ftp/ftp_directory_listing_parser_ls_unittest.cc11
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,