diff options
author | phajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-23 19:42:26 +0000 |
---|---|---|
committer | phajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-23 19:42:26 +0000 |
commit | 3a4f359fc1413e816423d137e7dc67abd8db5921 (patch) | |
tree | 21698a3038483f4dcd4bc30cbc1fdb336ccf5972 /net | |
parent | e2b292c0c84c0d3c1ac68d032927fb62b3aa25f2 (diff) | |
download | chromium_src-3a4f359fc1413e816423d137e7dc67abd8db5921.zip chromium_src-3a4f359fc1413e816423d137e7dc67abd8db5921.tar.gz chromium_src-3a4f359fc1413e816423d137e7dc67abd8db5921.tar.bz2 |
Fix recognizing FTP listings consisting of only one line.
It turns out we have to be a little more strict with that. Before
this change both ls and VMS listing parsers would claim that they
recognize the format. Also fallback to Mozilla code was broken
in that case.
TEST=Covered by net_unittests.
BUG=28263
Review URL: http://codereview.chromium.org/421006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@32831 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/data/ftp/dir-listing-ls-5 | 1 | ||||
-rw-r--r-- | net/data/ftp/dir-listing-ls-5.expected | 8 | ||||
-rw-r--r-- | net/ftp/ftp_directory_listing_buffer.cc | 31 | ||||
-rw-r--r-- | net/ftp/ftp_directory_listing_buffer.h | 4 | ||||
-rw-r--r-- | net/ftp/ftp_directory_listing_buffer_unittest.cc | 1 | ||||
-rw-r--r-- | net/ftp/ftp_directory_listing_parsers.cc | 12 | ||||
-rw-r--r-- | net/ftp/ftp_directory_listing_parsers.h | 7 | ||||
-rw-r--r-- | net/ftp/ftp_directory_listing_parsers_unittest.cc | 3 |
8 files changed, 66 insertions, 1 deletions
diff --git a/net/data/ftp/dir-listing-ls-5 b/net/data/ftp/dir-listing-ls-5 new file mode 100644 index 0000000..87c4266 --- /dev/null +++ b/net/data/ftp/dir-listing-ls-5 @@ -0,0 +1 @@ +drwxrwsr-x 4 501 501 4096 Feb 20 2007 pub diff --git a/net/data/ftp/dir-listing-ls-5.expected b/net/data/ftp/dir-listing-ls-5.expected new file mode 100644 index 0000000..3acbcf3 --- /dev/null +++ b/net/data/ftp/dir-listing-ls-5.expected @@ -0,0 +1,8 @@ +d +pub +-1 +2007 +2 +20 +0 +0 diff --git a/net/ftp/ftp_directory_listing_buffer.cc b/net/ftp/ftp_directory_listing_buffer.cc index e41cb9e..19483d0 100644 --- a/net/ftp/ftp_directory_listing_buffer.cc +++ b/net/ftp/ftp_directory_listing_buffer.cc @@ -70,7 +70,16 @@ int FtpDirectoryListingBuffer::ProcessRemainingData() { if (!buffer_.empty()) return ERR_INVALID_RESPONSE; - return ParseLines(); + rv = ParseLines(); + if (rv != OK) + return rv; + + rv = OnEndOfInput(); + if (rv != OK) + return rv; + + DCHECK(current_parser_); + return OK; } bool FtpDirectoryListingBuffer::EntryAvailable() const { @@ -146,4 +155,24 @@ int FtpDirectoryListingBuffer::ParseLines() { return OK; } +int FtpDirectoryListingBuffer::OnEndOfInput() { + ParserSet::iterator i = parsers_.begin(); + while (i != parsers_.end()) { + if ((*i)->OnEndOfInput()) { + i++; + } else { + delete *i; + parsers_.erase(i++); + } + } + + if (parsers_.size() != 1) { + current_parser_ = NULL; + return ERR_UNRECOGNIZED_FTP_DIRECTORY_LISTING_FORMAT; + } + + current_parser_ = *parsers_.begin(); + return OK; +} + } // namespace net diff --git a/net/ftp/ftp_directory_listing_buffer.h b/net/ftp/ftp_directory_listing_buffer.h index 9489135..f71685c 100644 --- a/net/ftp/ftp_directory_listing_buffer.h +++ b/net/ftp/ftp_directory_listing_buffer.h @@ -57,6 +57,10 @@ class FtpDirectoryListingBuffer { // Tries to parse full lines stored in |lines_|. Returns network error code. int ParseLines(); + // Called when we received the entire input. Propagates that info to remaining + // parsers. Returns network error code. + int OnEndOfInput(); + // Detected encoding of the response (empty if unknown or ASCII). std::string encoding_; diff --git a/net/ftp/ftp_directory_listing_buffer_unittest.cc b/net/ftp/ftp_directory_listing_buffer_unittest.cc index 97a915e..d9da0cf 100644 --- a/net/ftp/ftp_directory_listing_buffer_unittest.cc +++ b/net/ftp/ftp_directory_listing_buffer_unittest.cc @@ -22,6 +22,7 @@ TEST(FtpDirectoryListingBufferTest, Parse) { "dir-listing-ls-2", "dir-listing-ls-3", "dir-listing-ls-4", + "dir-listing-ls-5", "dir-listing-windows-1", "dir-listing-windows-2", "dir-listing-vms-1", diff --git a/net/ftp/ftp_directory_listing_parsers.cc b/net/ftp/ftp_directory_listing_parsers.cc index c2679d7..8963624 100644 --- a/net/ftp/ftp_directory_listing_parsers.cc +++ b/net/ftp/ftp_directory_listing_parsers.cc @@ -341,6 +341,10 @@ bool FtpLsDirectoryListingParser::ConsumeLine(const string16& line) { return true; } +bool FtpLsDirectoryListingParser::OnEndOfInput() { + return true; +} + bool FtpLsDirectoryListingParser::EntryAvailable() const { return !entries_.empty(); } @@ -381,6 +385,10 @@ bool FtpWindowsDirectoryListingParser::ConsumeLine(const string16& line) { return true; } +bool FtpWindowsDirectoryListingParser::OnEndOfInput() { + return true; +} + bool FtpWindowsDirectoryListingParser::EntryAvailable() const { return !entries_.empty(); } @@ -441,6 +449,10 @@ bool FtpVmsDirectoryListingParser::ConsumeLine(const string16& line) { } } +bool FtpVmsDirectoryListingParser::OnEndOfInput() { + return (state_ == STATE_END); +} + bool FtpVmsDirectoryListingParser::EntryAvailable() const { return !entries_.empty(); } diff --git a/net/ftp/ftp_directory_listing_parsers.h b/net/ftp/ftp_directory_listing_parsers.h index e02bb1d..8b11ecb 100644 --- a/net/ftp/ftp_directory_listing_parsers.h +++ b/net/ftp/ftp_directory_listing_parsers.h @@ -38,6 +38,10 @@ class FtpDirectoryListingParser { // Adds |line| to the internal parsing buffer. Returns true on success. virtual bool ConsumeLine(const string16& line) = 0; + // Called after all input has been consumed. Returns true if the parser + // recognizes all received data as a valid listing. + virtual bool OnEndOfInput() = 0; + // Returns true if there is at least one FtpDirectoryListingEntry available. virtual bool EntryAvailable() const = 0; @@ -54,6 +58,7 @@ class FtpLsDirectoryListingParser : public FtpDirectoryListingParser { // FtpDirectoryListingParser methods: virtual FtpServerType GetServerType() const { return SERVER_LS; } virtual bool ConsumeLine(const string16& line); + virtual bool OnEndOfInput(); virtual bool EntryAvailable() const; virtual FtpDirectoryListingEntry PopEntry(); @@ -72,6 +77,7 @@ class FtpWindowsDirectoryListingParser : public FtpDirectoryListingParser { // FtpDirectoryListingParser methods: virtual FtpServerType GetServerType() const { return SERVER_WINDOWS; } virtual bool ConsumeLine(const string16& line); + virtual bool OnEndOfInput(); virtual bool EntryAvailable() const; virtual FtpDirectoryListingEntry PopEntry(); @@ -89,6 +95,7 @@ class FtpVmsDirectoryListingParser : public FtpDirectoryListingParser { // FtpDirectoryListingParser methods: virtual FtpServerType GetServerType() const { return SERVER_VMS; } virtual bool ConsumeLine(const string16& line); + virtual bool OnEndOfInput(); virtual bool EntryAvailable() const; virtual FtpDirectoryListingEntry PopEntry(); diff --git a/net/ftp/ftp_directory_listing_parsers_unittest.cc b/net/ftp/ftp_directory_listing_parsers_unittest.cc index 19c6feb..80ddc7e 100644 --- a/net/ftp/ftp_directory_listing_parsers_unittest.cc +++ b/net/ftp/ftp_directory_listing_parsers_unittest.cc @@ -68,6 +68,9 @@ TEST_F(FtpDirectoryListingParsersTest, Ls) { { "lrwxrwxrwx 1 0 0 3 Oct 12 13:37 mirror -> pub", net::FtpDirectoryListingEntry::SYMLINK, "mirror", -1, now_exploded.year, 10, 12, 13, 37 }, + { "drwxrwsr-x 4 501 501 4096 Feb 20 2007 pub", + net::FtpDirectoryListingEntry::DIRECTORY, "pub", -1, + 2007, 2, 20, 0, 0 }, }; for (size_t i = 0; i < arraysize(good_cases); i++) { SCOPED_TRACE(StringPrintf("Test[%" PRIuS "]: %s", i, good_cases[i].input)); |