Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(591)

Side by Side Diff: net/ftp/ftp_network_transaction.cc

Issue 200145: Unescape FTP URL paths, Firefox-compatible. (Closed)
Patch Set: match Firefox Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/ftp/ftp_network_transaction.h ('k') | net/ftp/ftp_network_transaction_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. Use of this 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. Use of this
2 // source code is governed by a BSD-style license that can be found in the 2 // source code is governed by a BSD-style license that can be found in the
3 // LICENSE file. 3 // LICENSE file.
4 4
5 #include "net/ftp/ftp_network_transaction.h" 5 #include "net/ftp/ftp_network_transaction.h"
6 6
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/string_util.h" 8 #include "base/string_util.h"
9 #include "net/base/connection_type_histograms.h" 9 #include "net/base/connection_type_histograms.h"
10 #include "net/base/escape.h"
10 #include "net/base/load_log.h" 11 #include "net/base/load_log.h"
11 #include "net/base/net_errors.h" 12 #include "net/base/net_errors.h"
12 #include "net/base/net_util.h" 13 #include "net/base/net_util.h"
13 #include "net/ftp/ftp_network_session.h" 14 #include "net/ftp/ftp_network_session.h"
14 #include "net/ftp/ftp_request_info.h" 15 #include "net/ftp/ftp_request_info.h"
15 #include "net/socket/client_socket.h" 16 #include "net/socket/client_socket.h"
16 #include "net/socket/client_socket_factory.h" 17 #include "net/socket/client_socket_factory.h"
17 18
18 // TODO(ibrar): Try to avoid sscanf. 19 // TODO(ibrar): Try to avoid sscanf.
19 #if !defined(COMPILER_MSVC) 20 #if !defined(COMPILER_MSVC)
20 #define sscanf_s sscanf 21 #define sscanf_s sscanf
21 #endif 22 #endif
22 23
23 const char kCRLF[] = "\r\n"; 24 const char kCRLF[] = "\r\n";
24 25
25 const int kCtrlBufLen = 1024; 26 const int kCtrlBufLen = 1024;
26 27
27 namespace { 28 namespace {
28 29
29 // Returns true if |input| can be safely used as a part of FTP command. 30 // Returns true if |input| can be safely used as a part of FTP command.
30 bool IsValidFTPCommandString(const std::string& input) { 31 bool IsValidFTPCommandString(const std::string& input) {
31 // RFC 959 only allows ASCII strings.
eroman 2009/09/18 22:51:23 Please add a comment in IsValidFTPComment() that w
32 if (!IsStringASCII(input))
33 return false;
34
35 // Protect agains newline injection attack. 32 // Protect agains newline injection attack.
36 if (input.find_first_of("\r\n") != std::string::npos) 33 if (input.find_first_of("\r\n") != std::string::npos)
37 return false; 34 return false;
38 35
39 return true; 36 return true;
40 } 37 }
41 38
42 } // namespace 39 } // namespace
43 40
44 namespace net { 41 namespace net {
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 user_callback_ = NULL; 312 user_callback_ = NULL;
316 c->Run(rv); 313 c->Run(rv);
317 } 314 }
318 315
319 void FtpNetworkTransaction::OnIOComplete(int result) { 316 void FtpNetworkTransaction::OnIOComplete(int result) {
320 int rv = DoLoop(result); 317 int rv = DoLoop(result);
321 if (rv != ERR_IO_PENDING) 318 if (rv != ERR_IO_PENDING)
322 DoCallback(rv); 319 DoCallback(rv);
323 } 320 }
324 321
322 std::string FtpNetworkTransaction::GetRequestPathForFtpCommand() const {
323 std::string path = (request_->url.has_path() ? request_->url.path() : "/");
324 UnescapeRule::Type unescape_rules = UnescapeRule::SPACES |
325 UnescapeRule::URL_SPECIAL_CHARS;
326 path = UnescapeURLComponent(path, unescape_rules);
eroman 2009/09/18 22:51:23 Please add a comment that escaping to non-ASCII is
327 DCHECK(IsValidFTPCommandString(path));
328 return path;
329 }
330
325 int FtpNetworkTransaction::DoLoop(int result) { 331 int FtpNetworkTransaction::DoLoop(int result) {
326 DCHECK(next_state_ != STATE_NONE); 332 DCHECK(next_state_ != STATE_NONE);
327 333
328 int rv = result; 334 int rv = result;
329 do { 335 do {
330 State state = next_state_; 336 State state = next_state_;
331 next_state_ = STATE_NONE; 337 next_state_ = STATE_NONE;
332 switch (state) { 338 switch (state) {
333 case STATE_CTRL_INIT: 339 case STATE_CTRL_INIT:
334 DCHECK(rv == OK); 340 DCHECK(rv == OK);
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 return Stop(ERR_FAILED); 787 return Stop(ERR_FAILED);
782 default: 788 default:
783 NOTREACHED(); 789 NOTREACHED();
784 return Stop(ERR_UNEXPECTED); 790 return Stop(ERR_UNEXPECTED);
785 } 791 }
786 return OK; 792 return OK;
787 } 793 }
788 794
789 // SIZE command 795 // SIZE command
790 int FtpNetworkTransaction::DoCtrlWriteSIZE() { 796 int FtpNetworkTransaction::DoCtrlWriteSIZE() {
791 std::string command = "SIZE"; 797 std::string command = "SIZE " + GetRequestPathForFtpCommand();
792 if (request_->url.has_path()) {
793 command.append(" ");
794 command.append(request_->url.path());
795 }
796 next_state_ = STATE_CTRL_READ; 798 next_state_ = STATE_CTRL_READ;
797 return SendFtpCommand(command, COMMAND_SIZE); 799 return SendFtpCommand(command, COMMAND_SIZE);
798 } 800 }
799 801
800 int FtpNetworkTransaction::ProcessResponseSIZE( 802 int FtpNetworkTransaction::ProcessResponseSIZE(
801 const FtpCtrlResponse& response) { 803 const FtpCtrlResponse& response) {
802 switch (GetErrorClass(response.status_code)) { 804 switch (GetErrorClass(response.status_code)) {
803 case ERROR_CLASS_INITIATED: 805 case ERROR_CLASS_INITIATED:
804 break; 806 break;
805 case ERROR_CLASS_OK: 807 case ERROR_CLASS_OK:
(...skipping 13 matching lines...) Expand all
819 default: 821 default:
820 NOTREACHED(); 822 NOTREACHED();
821 return Stop(ERR_UNEXPECTED); 823 return Stop(ERR_UNEXPECTED);
822 } 824 }
823 next_state_ = STATE_CTRL_WRITE_MDTM; 825 next_state_ = STATE_CTRL_WRITE_MDTM;
824 return OK; 826 return OK;
825 } 827 }
826 828
827 // RETR command 829 // RETR command
828 int FtpNetworkTransaction::DoCtrlWriteRETR() { 830 int FtpNetworkTransaction::DoCtrlWriteRETR() {
829 std::string command = "RETR"; 831 std::string command = "RETR " + GetRequestPathForFtpCommand();
830 if (request_->url.has_path()) {
831 command.append(" ");
832 command.append(request_->url.path());
833 } else {
834 command.append(" /");
835 }
836 next_state_ = STATE_CTRL_READ; 832 next_state_ = STATE_CTRL_READ;
837 return SendFtpCommand(command, COMMAND_RETR); 833 return SendFtpCommand(command, COMMAND_RETR);
838 } 834 }
839 835
840 int FtpNetworkTransaction::ProcessResponseRETR( 836 int FtpNetworkTransaction::ProcessResponseRETR(
841 const FtpCtrlResponse& response) { 837 const FtpCtrlResponse& response) {
842 switch (GetErrorClass(response.status_code)) { 838 switch (GetErrorClass(response.status_code)) {
843 case ERROR_CLASS_INITIATED: 839 case ERROR_CLASS_INITIATED:
844 // We want the client to start reading the response at this point. 840 // We want the client to start reading the response at this point.
845 // It got here either through Start or RestartWithAuth. We want that 841 // It got here either through Start or RestartWithAuth. We want that
(...skipping 26 matching lines...) Expand all
872 break; 868 break;
873 default: 869 default:
874 NOTREACHED(); 870 NOTREACHED();
875 return Stop(ERR_UNEXPECTED); 871 return Stop(ERR_UNEXPECTED);
876 } 872 }
877 return OK; 873 return OK;
878 } 874 }
879 875
880 // MDMT command 876 // MDMT command
881 int FtpNetworkTransaction::DoCtrlWriteMDTM() { 877 int FtpNetworkTransaction::DoCtrlWriteMDTM() {
882 std::string command = "MDTM"; 878 std::string command = "MDTM " + GetRequestPathForFtpCommand();
883 if (request_->url.has_path()) {
884 command.append(" ");
885 command.append(request_->url.path());
886 } else {
887 command.append(" /");
888 }
889 next_state_ = STATE_CTRL_READ; 879 next_state_ = STATE_CTRL_READ;
890 return SendFtpCommand(command, COMMAND_MDTM); 880 return SendFtpCommand(command, COMMAND_MDTM);
891 } 881 }
892 882
893 int FtpNetworkTransaction::ProcessResponseMDTM( 883 int FtpNetworkTransaction::ProcessResponseMDTM(
894 const FtpCtrlResponse& response) { 884 const FtpCtrlResponse& response) {
895 switch (GetErrorClass(response.status_code)) { 885 switch (GetErrorClass(response.status_code)) {
896 case ERROR_CLASS_INITIATED: 886 case ERROR_CLASS_INITIATED:
897 return Stop(ERR_FAILED); 887 return Stop(ERR_FAILED);
898 case ERROR_CLASS_OK: 888 case ERROR_CLASS_OK:
899 next_state_ = STATE_CTRL_WRITE_RETR; 889 next_state_ = STATE_CTRL_WRITE_RETR;
900 break; 890 break;
901 case ERROR_CLASS_INFO_NEEDED: 891 case ERROR_CLASS_INFO_NEEDED:
902 return Stop(ERR_FAILED); 892 return Stop(ERR_FAILED);
903 case ERROR_CLASS_TRANSIENT_ERROR: 893 case ERROR_CLASS_TRANSIENT_ERROR:
904 return Stop(ERR_FAILED); 894 return Stop(ERR_FAILED);
905 case ERROR_CLASS_PERMANENT_ERROR: 895 case ERROR_CLASS_PERMANENT_ERROR:
906 next_state_ = STATE_CTRL_WRITE_RETR; 896 next_state_ = STATE_CTRL_WRITE_RETR;
907 break; 897 break;
908 default: 898 default:
909 NOTREACHED(); 899 NOTREACHED();
910 return Stop(ERR_UNEXPECTED); 900 return Stop(ERR_UNEXPECTED);
911 } 901 }
912 return OK; 902 return OK;
913 } 903 }
914 904
915 905
916 // CWD command 906 // CWD command
917 int FtpNetworkTransaction::DoCtrlWriteCWD() { 907 int FtpNetworkTransaction::DoCtrlWriteCWD() {
918 std::string command = "CWD"; 908 std::string command = "CWD " + GetRequestPathForFtpCommand();
919 if (request_->url.has_path()) {
920 command.append(" ");
921 command.append(request_->url.path());
922 } else {
923 command.append(" /");
924 }
925 next_state_ = STATE_CTRL_READ; 909 next_state_ = STATE_CTRL_READ;
926 return SendFtpCommand(command, COMMAND_CWD); 910 return SendFtpCommand(command, COMMAND_CWD);
927 } 911 }
928 912
929 int FtpNetworkTransaction::ProcessResponseCWD(const FtpCtrlResponse& response) { 913 int FtpNetworkTransaction::ProcessResponseCWD(const FtpCtrlResponse& response) {
930 switch (GetErrorClass(response.status_code)) { 914 switch (GetErrorClass(response.status_code)) {
931 case ERROR_CLASS_INITIATED: 915 case ERROR_CLASS_INITIATED:
932 return Stop(ERR_INVALID_RESPONSE); 916 return Stop(ERR_INVALID_RESPONSE);
933 case ERROR_CLASS_OK: 917 case ERROR_CLASS_OK:
934 next_state_ = STATE_CTRL_WRITE_LIST; 918 next_state_ = STATE_CTRL_WRITE_LIST;
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1038 read_data_buf_->data()[0] = 0; 1022 read_data_buf_->data()[0] = 0;
1039 return data_socket_->Read(read_data_buf_, read_data_buf_len_, 1023 return data_socket_->Read(read_data_buf_, read_data_buf_len_,
1040 &io_callback_); 1024 &io_callback_);
1041 } 1025 }
1042 1026
1043 int FtpNetworkTransaction::DoDataReadComplete(int result) { 1027 int FtpNetworkTransaction::DoDataReadComplete(int result) {
1044 return result; 1028 return result;
1045 } 1029 }
1046 1030
1047 } // namespace net 1031 } // namespace net
OLDNEW
« no previous file with comments | « net/ftp/ftp_network_transaction.h ('k') | net/ftp/ftp_network_transaction_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698