summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-08 20:31:27 +0000
committerphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-08 20:31:27 +0000
commitc8f489795d6b149aafb6f9c8e97e21c0904ec3d4 (patch)
treec2ebae8713cf870f92b7b79027cee8eec8b37b6e
parent72f78a720a9c06d1e588ddda321fa04327c59eac (diff)
downloadchromium_src-c8f489795d6b149aafb6f9c8e97e21c0904ec3d4.zip
chromium_src-c8f489795d6b149aafb6f9c8e97e21c0904ec3d4.tar.gz
chromium_src-c8f489795d6b149aafb6f9c8e97e21c0904ec3d4.tar.bz2
Compatibility improvements for "ls -l" FTP LIST response format.
TEST=Covered by net_unittests. BUG=25520 Review URL: http://codereview.chromium.org/460139 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34079 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--net/data/ftp/dir-listing-ls-133
-rw-r--r--net/data/ftp/dir-listing-ls-13.expected26
-rw-r--r--net/data/ftp/dir-listing-ls-143
-rw-r--r--net/data/ftp/dir-listing-ls-14.expected26
-rw-r--r--net/ftp/ftp_directory_listing_buffer_unittest.cc2
-rw-r--r--net/ftp/ftp_directory_listing_parser_ls.cc39
-rw-r--r--net/ftp/ftp_directory_listing_parser_ls.h5
-rw-r--r--net/ftp/ftp_directory_listing_parser_ls_unittest.cc19
8 files changed, 104 insertions, 19 deletions
diff --git a/net/data/ftp/dir-listing-ls-13 b/net/data/ftp/dir-listing-ls-13
new file mode 100644
index 0000000..b2b7bff
--- /dev/null
+++ b/net/data/ftp/dir-listing-ls-13
@@ -0,0 +1,3 @@
+-r--r--r-- 1 ftp -A--- 93064 Dec 28 2007 test.jpg
+dr--r--r-- 1 ftp ----- 0 Nov 17 17:08 kernels
+-r--r--r-- 1 ftp -A--- 13274 Mar 1 2006 UpTime.exe
diff --git a/net/data/ftp/dir-listing-ls-13.expected b/net/data/ftp/dir-listing-ls-13.expected
new file mode 100644
index 0000000..7bbf9ad
--- /dev/null
+++ b/net/data/ftp/dir-listing-ls-13.expected
@@ -0,0 +1,26 @@
+-
+test.jpg
+93064
+2007
+12
+28
+0
+0
+
+d
+kernels
+-1
+current
+11
+17
+17
+8
+
+-
+UpTime.exe
+13274
+2006
+3
+1
+0
+0
diff --git a/net/data/ftp/dir-listing-ls-14 b/net/data/ftp/dir-listing-ls-14
new file mode 100644
index 0000000..84edee4
--- /dev/null
+++ b/net/data/ftp/dir-listing-ls-14
@@ -0,0 +1,3 @@
+-rwxr-xr-x 0 214 214 Jun 30 2005 !readme
+drwxr-xr-x folder 0 Jul 17 2006 online
+-rwxr-xr-x 332 7 339 Feb 5 2004 welcome.txt
diff --git a/net/data/ftp/dir-listing-ls-14.expected b/net/data/ftp/dir-listing-ls-14.expected
new file mode 100644
index 0000000..05c0398
--- /dev/null
+++ b/net/data/ftp/dir-listing-ls-14.expected
@@ -0,0 +1,26 @@
+-
+!readme
+214
+2005
+6
+30
+0
+0
+
+d
+online
+-1
+2006
+7
+17
+0
+0
+
+-
+welcome.txt
+339
+2004
+2
+5
+0
+0
diff --git a/net/ftp/ftp_directory_listing_buffer_unittest.cc b/net/ftp/ftp_directory_listing_buffer_unittest.cc
index 559256e..1f739cf 100644
--- a/net/ftp/ftp_directory_listing_buffer_unittest.cc
+++ b/net/ftp/ftp_directory_listing_buffer_unittest.cc
@@ -30,6 +30,8 @@ TEST(FtpDirectoryListingBufferTest, Parse) {
"dir-listing-ls-10",
"dir-listing-ls-11",
"dir-listing-ls-12",
+ "dir-listing-ls-13",
+ "dir-listing-ls-14",
"dir-listing-netware-1",
"dir-listing-netware-2",
"dir-listing-vms-1",
diff --git a/net/ftp/ftp_directory_listing_parser_ls.cc b/net/ftp/ftp_directory_listing_parser_ls.cc
index cc09ca0..f5136db 100644
--- a/net/ftp/ftp_directory_listing_parser_ls.cc
+++ b/net/ftp/ftp_directory_listing_parser_ls.cc
@@ -64,7 +64,7 @@ bool DetectColumnOffset(const std::vector<string16>& columns, int* offset) {
net::FtpUtil::LsDateListingToTime(columns[5], columns[6], columns[7],
&time)) {
// Standard listing, exactly like ls -l.
- *offset = 1;
+ *offset = 2;
return true;
}
@@ -72,6 +72,15 @@ bool DetectColumnOffset(const std::vector<string16>& columns, int* offset) {
net::FtpUtil::LsDateListingToTime(columns[4], columns[5], columns[6],
&time)) {
// wu-ftpd listing, no "number of links" column.
+ *offset = 1;
+ return true;
+ }
+
+ if (columns.size() >= 6 &&
+ net::FtpUtil::LsDateListingToTime(columns[3], columns[4], columns[5],
+ &time)) {
+ // Xplain FTP Server listing for folders, like this:
+ // drwxr-xr-x folder 0 Jul 17 2006 online
*offset = 0;
return true;
}
@@ -86,20 +95,21 @@ namespace net {
FtpDirectoryListingParserLs::FtpDirectoryListingParserLs()
: received_nonempty_line_(false),
- received_total_line_(false),
- column_offset_(-1) {
+ received_total_line_(false) {
}
bool FtpDirectoryListingParserLs::ConsumeLine(const string16& line) {
- std::vector<string16> columns;
- SplitString(CollapseWhitespace(line, false), ' ', &columns);
-
if (line.empty() && !received_nonempty_line_) {
// Allow empty lines only at the beginning of the listing. For example VMS
// systems in Unix emulation mode add an empty line before the first listing
// entry.
return true;
}
+ received_nonempty_line_ = true;
+
+ std::vector<string16> columns;
+ SplitString(CollapseWhitespace(line, false), ' ', &columns);
+
// Some FTP servers put a "total n" line at the beginning of the listing
// (n is an integer). Allow such a line, but only once, and only if it's
// the first non-empty line. Do not match the word exactly, because it may be
@@ -116,14 +126,15 @@ bool FtpDirectoryListingParserLs::ConsumeLine(const string16& line) {
return true;
}
- if (!received_nonempty_line_ && !DetectColumnOffset(columns, &column_offset_))
+
+ int column_offset;
+ if (!DetectColumnOffset(columns, &column_offset))
return false;
- received_nonempty_line_ = true;
// We may receive file names containing spaces, which can make the number of
// columns arbitrarily large. We will handle that later. For now just make
// sure we have all the columns that should normally be there.
- if (columns.size() < 8U + column_offset_)
+ if (columns.size() < 7U + column_offset)
return false;
if (!LooksLikeUnixPermissionsListing(columns[0]))
@@ -138,21 +149,21 @@ bool FtpDirectoryListingParserLs::ConsumeLine(const string16& line) {
entry.type = FtpDirectoryListingEntry::FILE;
}
- if (!StringToInt64(columns[3 + column_offset_], &entry.size))
+ if (!StringToInt64(columns[2 + column_offset], &entry.size))
return false;
if (entry.size < 0)
return false;
if (entry.type != FtpDirectoryListingEntry::FILE)
entry.size = -1;
- if (!FtpUtil::LsDateListingToTime(columns[4 + column_offset_],
- columns[5 + column_offset_],
- columns[6 + column_offset_],
+ if (!FtpUtil::LsDateListingToTime(columns[3 + column_offset],
+ columns[4 + column_offset],
+ columns[5 + column_offset],
&entry.last_modified)) {
return false;
}
- entry.name = GetStringPartAfterColumns(line, 7 + column_offset_);
+ entry.name = GetStringPartAfterColumns(line, 6 + column_offset);
if (entry.type == FtpDirectoryListingEntry::SYMLINK) {
string16::size_type pos = entry.name.rfind(ASCIIToUTF16(" -> "));
if (pos == string16::npos)
diff --git a/net/ftp/ftp_directory_listing_parser_ls.h b/net/ftp/ftp_directory_listing_parser_ls.h
index 50e0a1f..3fd0d32 100644
--- a/net/ftp/ftp_directory_listing_parser_ls.h
+++ b/net/ftp/ftp_directory_listing_parser_ls.h
@@ -30,11 +30,6 @@ class FtpDirectoryListingParserLs : public FtpDirectoryListingParser {
// integer. Only one such header is allowed per listing.
bool received_total_line_;
- // There is a variant of the listing served by wu-ftpd which doesn't contain
- // the "number of links" column (the second column in a "standard" ls -l
- // listing). Store an offset to reference later columns.
- int column_offset_;
-
std::queue<FtpDirectoryListingEntry> entries_;
DISALLOW_COPY_AND_ASSIGN(FtpDirectoryListingParserLs);
diff --git a/net/ftp/ftp_directory_listing_parser_ls_unittest.cc b/net/ftp/ftp_directory_listing_parser_ls_unittest.cc
index f0ec455..4107f9f 100644
--- a/net/ftp/ftp_directory_listing_parser_ls_unittest.cc
+++ b/net/ftp/ftp_directory_listing_parser_ls_unittest.cc
@@ -54,6 +54,19 @@ TEST_F(FtpDirectoryListingParserLsTest, Good) {
{ "-rw-r--r-- 2 3 3447432 May 18 2009 Foo - Manual.pdf",
net::FtpDirectoryListingEntry::FILE, "Foo - Manual.pdf", 3447432,
2009, 5, 18, 0, 0 },
+
+ // Tests for "ls -l" style listings sent by an OS/2 server (FtpServer):
+ { "-r--r--r-- 1 ftp -A--- 13274 Mar 1 2006 UpTime.exe",
+ net::FtpDirectoryListingEntry::FILE, "UpTime.exe", 13274,
+ 2006, 3, 1, 0, 0 },
+ { "dr--r--r-- 1 ftp ----- 0 Nov 17 17:08 kernels",
+ net::FtpDirectoryListingEntry::DIRECTORY, "kernels", -1,
+ now_exploded.year, 11, 17, 17, 8 },
+
+ // Tests for "ls -l" style listing sent by Xplain FTP Server.
+ { "drwxr-xr-x folder 0 Jul 17 2006 online",
+ net::FtpDirectoryListingEntry::DIRECTORY, "online", -1,
+ 2006, 7, 17, 0, 0 },
};
for (size_t i = 0; i < arraysize(good_cases); i++) {
SCOPED_TRACE(StringPrintf("Test[%" PRIuS "]: %s", i, good_cases[i].input));
@@ -78,6 +91,12 @@ TEST_F(FtpDirectoryListingParserLsTest, Bad) {
"qrwwr--r-- 1 ftp ftp 528 Nov 01 2007 README",
"-rw-r--r-- 1 ftp ftp -528 Nov 01 2007 README",
"-rw-r--r-- 1 ftp ftp 528 Foo 01 2007 README",
+
+ // Tests important for security: verify that after we detect the column
+ // offset we don't try to access invalid memory on malformed input.
+ "drwxr-xr-x 3 ftp ftp 4096 May 15 18:11",
+ "drwxr-xr-x 3 ftp 4096 May 15 18:11",
+ "drwxr-xr-x folder 0 May 15 18:11",
};
for (size_t i = 0; i < arraysize(bad_cases); i++) {
net::FtpDirectoryListingParserLs parser;