summaryrefslogtreecommitdiffstats
path: root/net/ftp/ftp_network_transaction.cc
diff options
context:
space:
mode:
authorphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-21 16:19:26 +0000
committerphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-21 16:19:26 +0000
commitdd74b4d035de7833e5085f94a960ac1787edf0d3 (patch)
tree28c36997c89f3e6a9e37d1638533c306b0eba78a /net/ftp/ftp_network_transaction.cc
parentea4a9412740c21369fce50ac8fd6322334beca1c (diff)
downloadchromium_src-dd74b4d035de7833e5085f94a960ac1787edf0d3.zip
chromium_src-dd74b4d035de7833e5085f94a960ac1787edf0d3.tar.gz
chromium_src-dd74b4d035de7833e5085f94a960ac1787edf0d3.tar.bz2
Unescape FTP URL paths, Firefox-compatible.
TEST=See bug. BUG=20304 Review URL: http://codereview.chromium.org/200145 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26686 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/ftp/ftp_network_transaction.cc')
-rw-r--r--net/ftp/ftp_network_transaction.cc48
1 files changed, 19 insertions, 29 deletions
diff --git a/net/ftp/ftp_network_transaction.cc b/net/ftp/ftp_network_transaction.cc
index e1a4114caf..5a90885 100644
--- a/net/ftp/ftp_network_transaction.cc
+++ b/net/ftp/ftp_network_transaction.cc
@@ -7,6 +7,7 @@
#include "base/compiler_specific.h"
#include "base/string_util.h"
#include "net/base/connection_type_histograms.h"
+#include "net/base/escape.h"
#include "net/base/load_log.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
@@ -28,9 +29,9 @@ namespace {
// Returns true if |input| can be safely used as a part of FTP command.
bool IsValidFTPCommandString(const std::string& input) {
- // RFC 959 only allows ASCII strings.
- if (!IsStringASCII(input))
- return false;
+ // RFC 959 only allows ASCII strings, but at least Firefox can send non-ASCII
+ // characters in the command if the request path contains them. To be
+ // compatible, we do the same and allow non-ASCII characters in a command.
// Protect agains newline injection attack.
if (input.find_first_of("\r\n") != std::string::npos)
@@ -322,6 +323,17 @@ void FtpNetworkTransaction::OnIOComplete(int result) {
DoCallback(rv);
}
+std::string FtpNetworkTransaction::GetRequestPathForFtpCommand() const {
+ std::string path = (request_->url.has_path() ? request_->url.path() : "/");
+ UnescapeRule::Type unescape_rules = UnescapeRule::SPACES |
+ UnescapeRule::URL_SPECIAL_CHARS;
+ // This may unescape to non-ASCII characters, but we allow that. See the
+ // comment for IsValidFTPCommandString.
+ path = UnescapeURLComponent(path, unescape_rules);
+ DCHECK(IsValidFTPCommandString(path));
+ return path;
+}
+
int FtpNetworkTransaction::DoLoop(int result) {
DCHECK(next_state_ != STATE_NONE);
@@ -788,11 +800,7 @@ int FtpNetworkTransaction::ProcessResponsePASV(
// SIZE command
int FtpNetworkTransaction::DoCtrlWriteSIZE() {
- std::string command = "SIZE";
- if (request_->url.has_path()) {
- command.append(" ");
- command.append(request_->url.path());
- }
+ std::string command = "SIZE " + GetRequestPathForFtpCommand();
next_state_ = STATE_CTRL_READ;
return SendFtpCommand(command, COMMAND_SIZE);
}
@@ -826,13 +834,7 @@ int FtpNetworkTransaction::ProcessResponseSIZE(
// RETR command
int FtpNetworkTransaction::DoCtrlWriteRETR() {
- std::string command = "RETR";
- if (request_->url.has_path()) {
- command.append(" ");
- command.append(request_->url.path());
- } else {
- command.append(" /");
- }
+ std::string command = "RETR " + GetRequestPathForFtpCommand();
next_state_ = STATE_CTRL_READ;
return SendFtpCommand(command, COMMAND_RETR);
}
@@ -879,13 +881,7 @@ int FtpNetworkTransaction::ProcessResponseRETR(
// MDMT command
int FtpNetworkTransaction::DoCtrlWriteMDTM() {
- std::string command = "MDTM";
- if (request_->url.has_path()) {
- command.append(" ");
- command.append(request_->url.path());
- } else {
- command.append(" /");
- }
+ std::string command = "MDTM " + GetRequestPathForFtpCommand();
next_state_ = STATE_CTRL_READ;
return SendFtpCommand(command, COMMAND_MDTM);
}
@@ -915,13 +911,7 @@ int FtpNetworkTransaction::ProcessResponseMDTM(
// CWD command
int FtpNetworkTransaction::DoCtrlWriteCWD() {
- std::string command = "CWD";
- if (request_->url.has_path()) {
- command.append(" ");
- command.append(request_->url.path());
- } else {
- command.append(" /");
- }
+ std::string command = "CWD " + GetRequestPathForFtpCommand();
next_state_ = STATE_CTRL_READ;
return SendFtpCommand(command, COMMAND_CWD);
}