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

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

Issue 2539583002: Use overflow-safe string-to-int parsing methods for FTP ports. (Closed)
Patch Set: Response to comments, fix tests Created 4 years 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 | « no previous file | 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the 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/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/compiler_specific.h" 9 #include "base/compiler_specific.h"
10 #include "base/metrics/histogram_macros.h" 10 #include "base/metrics/histogram_macros.h"
11 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_split.h" 12 #include "base/strings/string_split.h"
13 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
14 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
15 #include "base/values.h" 15 #include "base/values.h"
16 #include "net/base/address_list.h" 16 #include "net/base/address_list.h"
17 #include "net/base/escape.h" 17 #include "net/base/escape.h"
18 #include "net/base/net_errors.h" 18 #include "net/base/net_errors.h"
19 #include "net/base/parse_number.h"
19 #include "net/base/port_util.h" 20 #include "net/base/port_util.h"
20 #include "net/base/url_util.h" 21 #include "net/base/url_util.h"
21 #include "net/ftp/ftp_request_info.h" 22 #include "net/ftp/ftp_request_info.h"
22 #include "net/ftp/ftp_util.h" 23 #include "net/ftp/ftp_util.h"
23 #include "net/log/net_log.h" 24 #include "net/log/net_log.h"
24 #include "net/log/net_log_event_type.h" 25 #include "net/log/net_log_event_type.h"
25 #include "net/log/net_log_source.h" 26 #include "net/log/net_log_source.h"
26 #include "net/socket/client_socket_factory.h" 27 #include "net/socket/client_socket_factory.h"
27 #include "net/socket/stream_socket.h" 28 #include "net/socket/stream_socket.h"
28 #include "url/url_constants.h" 29 #include "url/url_constants.h"
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 } 117 }
117 } 118 }
118 119
119 // From RFC 2428 Section 3: 120 // From RFC 2428 Section 3:
120 // The text returned in response to the EPSV command MUST be: 121 // The text returned in response to the EPSV command MUST be:
121 // <some text> (<d><d><d><tcp-port><d>) 122 // <some text> (<d><d><d><tcp-port><d>)
122 // <d> is a delimiter character, ideally to be | 123 // <d> is a delimiter character, ideally to be |
123 bool ExtractPortFromEPSVResponse(const FtpCtrlResponse& response, int* port) { 124 bool ExtractPortFromEPSVResponse(const FtpCtrlResponse& response, int* port) {
124 if (response.lines.size() != 1) 125 if (response.lines.size() != 1)
125 return false; 126 return false;
126 const char* ptr = response.lines[0].c_str(); 127
127 while (*ptr && *ptr != '(') 128 base::StringPiece epsv_line(response.lines[0]);
128 ++ptr; 129 size_t start = epsv_line.find('(');
129 if (!*ptr) 130 // If the line doesn't have a '(' or doesn't have enough characters after the
130 return false; 131 // first '(', fail.
131 char sep = *(++ptr); 132 if (start == base::StringPiece::npos || epsv_line.length() - start < 7)
132 if (!sep || isdigit(sep) || *(++ptr) != sep || *(++ptr) != sep)
133 return false;
134 if (!isdigit(*(++ptr)))
135 return false;
136 *port = *ptr - '0';
137 while (isdigit(*(++ptr))) {
138 *port *= 10;
139 *port += *ptr - '0';
140 }
141 if (*ptr != sep)
142 return false; 133 return false;
143 134
144 return true; 135 char separator = epsv_line[start + 1];
136
137 // Make sure we have "(<d><d><d>...", where <d> is not a number.
138 if (isdigit(separator) || epsv_line[start + 2] != separator ||
eroman 2016/11/28 23:26:17 I am not sure that we should be using isdigit() he
139 epsv_line[start + 3] != separator) {
140 return false;
141 }
142
143 // Skip over those characters.
144 start += 4;
145
146 // Make sure there's a terminal <d>.
147 size_t end = epsv_line.find(separator, start);
148 if (end == base::StringPiece::npos)
149 return false;
150
151 return ParseInt32(epsv_line.substr(start, end - start),
152 ParseIntFormat::NON_NEGATIVE, port);
145 } 153 }
146 154
147 // There are two way we can receive IP address and port. 155 // There are two way we can receive IP address and port.
148 // (127,0,0,1,23,21) IP address and port encapsulated in (). 156 // (127,0,0,1,23,21) IP address and port encapsulated in ().
149 // 127,0,0,1,23,21 IP address and port without (). 157 // 127,0,0,1,23,21 IP address and port without ().
150 // 158 //
151 // See RFC 959, Section 4.1.2 159 // See RFC 959, Section 4.1.2
152 bool ExtractPortFromPASVResponse(const FtpCtrlResponse& response, int* port) { 160 bool ExtractPortFromPASVResponse(const FtpCtrlResponse& response, int* port) {
153 if (response.lines.size() != 1) 161 if (response.lines.size() != 1)
154 return false; 162 return false;
(...skipping 26 matching lines...) Expand all
181 line = line.substr(paren_pos + 1, closing_paren_pos - paren_pos - 1); 189 line = line.substr(paren_pos + 1, closing_paren_pos - paren_pos - 1);
182 } 190 }
183 191
184 // Split the line into comma-separated pieces and extract 192 // Split the line into comma-separated pieces and extract
185 // the last two. 193 // the last two.
186 std::vector<base::StringPiece> pieces = base::SplitStringPiece( 194 std::vector<base::StringPiece> pieces = base::SplitStringPiece(
187 line, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 195 line, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
188 if (pieces.size() != 6) 196 if (pieces.size() != 6)
189 return false; 197 return false;
190 198
199 LOG(ERROR) << "here? " << pieces[4].as_string();
200 LOG(ERROR) << "here? " << pieces[5].as_string();
191 // Ignore the IP address supplied in the response. We are always going 201 // Ignore the IP address supplied in the response. We are always going
192 // to connect back to the same server to prevent FTP PASV port scanning. 202 // to connect back to the same server to prevent FTP PASV port scanning.
193 int p0, p1; 203 uint32_t p0, p1;
194 if (!base::StringToInt(pieces[4], &p0)) 204 if (!ParseUint32(pieces[4], &p0))
195 return false; 205 return false;
196 if (!base::StringToInt(pieces[5], &p1)) 206 if (!ParseUint32(pieces[5], &p1))
197 return false; 207 return false;
208 if (p0 > 0xFF || p1 > 0xFF)
209 return false;
210
211 LOG(ERROR) << "here2?";
198 *port = (p0 << 8) + p1; 212 *port = (p0 << 8) + p1;
199 213 LOG(ERROR) << "here3? " << *port;
200 return true; 214 return true;
201 } 215 }
202 216
203 } // namespace 217 } // namespace
204 218
205 FtpNetworkTransaction::FtpNetworkTransaction( 219 FtpNetworkTransaction::FtpNetworkTransaction(
206 HostResolver* resolver, 220 HostResolver* resolver,
207 ClientSocketFactory* socket_factory) 221 ClientSocketFactory* socket_factory)
208 : command_sent_(COMMAND_NONE), 222 : command_sent_(COMMAND_NONE),
209 io_callback_(base::Bind(&FtpNetworkTransaction::OnIOComplete, 223 io_callback_(base::Bind(&FtpNetworkTransaction::OnIOComplete,
(...skipping 1133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1343 if (!had_error_type[type]) { 1357 if (!had_error_type[type]) {
1344 had_error_type[type] = true; 1358 had_error_type[type] = true;
1345 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened", 1359 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened",
1346 type, NUM_OF_NET_ERROR_TYPES); 1360 type, NUM_OF_NET_ERROR_TYPES);
1347 } 1361 }
1348 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount", 1362 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount",
1349 type, NUM_OF_NET_ERROR_TYPES); 1363 type, NUM_OF_NET_ERROR_TYPES);
1350 } 1364 }
1351 1365
1352 } // namespace net 1366 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/ftp/ftp_network_transaction_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698