diff options
author | phajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-26 11:08:50 +0000 |
---|---|---|
committer | phajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-26 11:08:50 +0000 |
commit | 621241a1de4dcafe244ea5aaaf513ade7e05a131 (patch) | |
tree | f675de3e2670f381eaf63071c0b7ee46285bfcde /webkit/glue | |
parent | bd57b686619dd598890cefffb82f9b06e9a8066c (diff) | |
download | chromium_src-621241a1de4dcafe244ea5aaaf513ade7e05a131.zip chromium_src-621241a1de4dcafe244ea5aaaf513ade7e05a131.tar.gz chromium_src-621241a1de4dcafe244ea5aaaf513ade7e05a131.tar.bz2 |
FTP: Detect the character encoding only after the entire listing is received.
Otherwise the parser could be confused extremely easily. Imagine a listing
which has only ASCII characters at the beginning, but after we detect it
as ASCII-encoded, some UTF-8 bytes appear. It can be made more complex though,
for example the beginning might look like UTF-8, but the entire listing
may use a different encoding incompatible with UTF-8 (that was the case here,
see bug).
This change also simplifies the directory listing parser. When we always
have the entire listing when parsing, some complex code can be removed.
BUG=76171
TEST=see bug
Review URL: http://codereview.chromium.org/6670085
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79490 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue')
-rw-r--r-- | webkit/glue/ftp_directory_listing_response_delegate.cc | 93 | ||||
-rw-r--r-- | webkit/glue/ftp_directory_listing_response_delegate.h | 31 |
2 files changed, 32 insertions, 92 deletions
diff --git a/webkit/glue/ftp_directory_listing_response_delegate.cc b/webkit/glue/ftp_directory_listing_response_delegate.cc index 0a2542b..a94d299 100644 --- a/webkit/glue/ftp_directory_listing_response_delegate.cc +++ b/webkit/glue/ftp_directory_listing_response_delegate.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -17,7 +17,6 @@ #include "net/base/net_errors.h" #include "net/base/net_util.h" #include "net/ftp/ftp_directory_listing_parser.h" -#include "net/ftp/ftp_server_type_histograms.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLLoaderClient.h" @@ -60,37 +59,40 @@ FtpDirectoryListingResponseDelegate::FtpDirectoryListingResponseDelegate( WebURLLoader* loader, const WebURLResponse& response) : client_(client), - loader_(loader), - original_response_(response), - buffer_(base::Time::Now()), - updated_histograms_(false), - had_parsing_error_(false) { - Init(); + loader_(loader) { + Init(response.url()); } void FtpDirectoryListingResponseDelegate::OnReceivedData(const char* data, int data_len) { - if (had_parsing_error_) - return; - - if (buffer_.ConsumeData(data, data_len) == net::OK) - ProcessReceivedEntries(); - else - had_parsing_error_ = true; + buffer_.append(data, data_len); } void FtpDirectoryListingResponseDelegate::OnCompletedRequest() { - if (!had_parsing_error_ && buffer_.ProcessRemainingData() == net::OK) - ProcessReceivedEntries(); - else - had_parsing_error_ = true; - - if (had_parsing_error_) + std::vector<FtpDirectoryListingEntry> entries; + int rv = net::ParseFtpDirectoryListing(buffer_, base::Time::Now(), &entries); + if (rv != net::OK) { SendDataToClient("<script>onListingParsingError();</script>\n"); + return; + } + for (size_t i = 0; i < entries.size(); i++) { + FtpDirectoryListingEntry entry = entries[i]; + + // Skip the current and parent directory entries in the listing. Our header + // always includes them. + if (EqualsASCII(entry.name, ".") || EqualsASCII(entry.name, "..")) + continue; + + bool is_directory = (entry.type == FtpDirectoryListingEntry::DIRECTORY); + int64 size = entry.size; + if (entry.type != FtpDirectoryListingEntry::FILE) + size = 0; + SendDataToClient(net::GetDirectoryListingEntry( + entry.name, entry.raw_name, is_directory, size, entry.last_modified)); + } } -void FtpDirectoryListingResponseDelegate::Init() { - GURL response_url(original_response_.url()); +void FtpDirectoryListingResponseDelegate::Init(const GURL& response_url) { UnescapeRule::Type unescape_rules = UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS; std::string unescaped_path = UnescapeURLComponent(response_url.path(), @@ -106,51 +108,6 @@ void FtpDirectoryListingResponseDelegate::Init() { } } -bool FtpDirectoryListingResponseDelegate::ConvertToServerEncoding( - const string16& filename, std::string* raw_bytes) const { - if (buffer_.encoding().empty()) { - *raw_bytes = std::string(); - return true; - } - - return base::UTF16ToCodepage(filename, buffer_.encoding().c_str(), - base::OnStringConversionError::FAIL, - raw_bytes); -} - -void FtpDirectoryListingResponseDelegate::ProcessReceivedEntries() { - if (!updated_histograms_ && buffer_.EntryAvailable()) { - // Only log the server type if we got enough data to reliably detect it. - net::UpdateFtpServerTypeHistograms(buffer_.GetServerType()); - updated_histograms_ = true; - } - - while (buffer_.EntryAvailable()) { - FtpDirectoryListingEntry entry = buffer_.PopEntry(); - - // Skip the current and parent directory entries in the listing. Our header - // always includes them. - if (EqualsASCII(entry.name, ".") || EqualsASCII(entry.name, "..")) - continue; - - bool is_directory = (entry.type == FtpDirectoryListingEntry::DIRECTORY); - int64 size = entry.size; - if (entry.type != FtpDirectoryListingEntry::FILE) - size = 0; - std::string raw_bytes; - if (ConvertToServerEncoding(entry.name, &raw_bytes)) { - SendDataToClient(net::GetDirectoryListingEntry( - entry.name, raw_bytes, is_directory, size, entry.last_modified)); - } else { - // Consider an encoding problem a non-fatal error. The server's support - // for non-ASCII characters might be buggy. Display an error message, - // but keep trying to display the rest of the listing (most file names - // are ASCII anyway, we could be just unlucky with this one). - had_parsing_error_ = true; - } - } -} - void FtpDirectoryListingResponseDelegate::SendDataToClient( const std::string& data) { client_->didReceiveData(loader_, data.data(), data.length()); diff --git a/webkit/glue/ftp_directory_listing_response_delegate.h b/webkit/glue/ftp_directory_listing_response_delegate.h index 9502761..402d618 100644 --- a/webkit/glue/ftp_directory_listing_response_delegate.h +++ b/webkit/glue/ftp_directory_listing_response_delegate.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -10,7 +10,7 @@ #include <string> -#include "net/ftp/ftp_directory_listing_buffer.h" +#include "base/basictypes.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLResponse.h" namespace WebKit { @@ -18,6 +18,8 @@ class WebURLLoader; class WebURLLoaderClient; } +class GURL; + namespace webkit_glue { class FtpDirectoryListingResponseDelegate { @@ -31,16 +33,7 @@ class FtpDirectoryListingResponseDelegate { void OnCompletedRequest(); private: - void Init(); - - // Converts |filename| to detected server encoding and puts the result - // in |raw_bytes| (if no conversion is necessary, an empty string is used). - // Returns true on success. - bool ConvertToServerEncoding(const string16& filename, - std::string* raw_bytes) const; - - // Fetches the listing entries from the buffer and sends them to the client. - void ProcessReceivedEntries(); + void Init(const GURL& response_url); void SendDataToClient(const std::string& data); @@ -49,18 +42,8 @@ class FtpDirectoryListingResponseDelegate { WebKit::WebURLLoaderClient* client_; WebKit::WebURLLoader* loader_; - // The original resource response for this request. We use this as a - // starting point for each parts response. - WebKit::WebURLResponse original_response_; - - // Data buffer also responsible for parsing the listing data. - net::FtpDirectoryListingBuffer buffer_; - - // True if we updated histogram data (we only want to do it once). - bool updated_histograms_; - - // True if we got an error when parsing the response. - bool had_parsing_error_; + // Buffer for data received from the network. + std::string buffer_; DISALLOW_COPY_AND_ASSIGN(FtpDirectoryListingResponseDelegate); }; |