diff options
author | phajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-08 20:31:27 +0000 |
---|---|---|
committer | phajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-08 20:31:27 +0000 |
commit | c8f489795d6b149aafb6f9c8e97e21c0904ec3d4 (patch) | |
tree | c2ebae8713cf870f92b7b79027cee8eec8b37b6e | |
parent | 72f78a720a9c06d1e588ddda321fa04327c59eac (diff) | |
download | chromium_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-13 | 3 | ||||
-rw-r--r-- | net/data/ftp/dir-listing-ls-13.expected | 26 | ||||
-rw-r--r-- | net/data/ftp/dir-listing-ls-14 | 3 | ||||
-rw-r--r-- | net/data/ftp/dir-listing-ls-14.expected | 26 | ||||
-rw-r--r-- | net/ftp/ftp_directory_listing_buffer_unittest.cc | 2 | ||||
-rw-r--r-- | net/ftp/ftp_directory_listing_parser_ls.cc | 39 | ||||
-rw-r--r-- | net/ftp/ftp_directory_listing_parser_ls.h | 5 | ||||
-rw-r--r-- | net/ftp/ftp_directory_listing_parser_ls_unittest.cc | 19 |
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; |