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

Side by Side Diff: net/http/http_response_headers.cc

Issue 7796025: Don't interpret embeded NULLs in a response header line as a line terminator. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Address wtc comments Created 9 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 | Annotate | Revision Log
« no previous file with comments | « net/http/http_response_headers.h ('k') | net/http/http_util.h » ('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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 // The rules for header parsing were borrowed from Firefox: 5 // The rules for header parsing were borrowed from Firefox:
6 // http://lxr.mozilla.org/seamonkey/source/netwerk/protocol/http/src/nsHttpRespo nseHead.cpp 6 // http://lxr.mozilla.org/seamonkey/source/netwerk/protocol/http/src/nsHttpRespo nseHead.cpp
7 // The rules for parsing content-types were also borrowed from Firefox: 7 // The rules for parsing content-types were also borrowed from Firefox:
8 // http://lxr.mozilla.org/mozilla/source/netwerk/base/src/nsURLHelper.cpp#834 8 // http://lxr.mozilla.org/mozilla/source/netwerk/base/src/nsURLHelper.cpp#834
9 9
10 #include "net/http/http_response_headers.h" 10 #include "net/http/http_response_headers.h"
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 return codes; 107 return codes;
108 } 108 }
109 109
110 int MapHttpResponseCode(int code) { 110 int MapHttpResponseCode(int code) {
111 if (HISTOGRAM_MIN_HTTP_RESPONSE_CODE <= code && 111 if (HISTOGRAM_MIN_HTTP_RESPONSE_CODE <= code &&
112 code <= HISTOGRAM_MAX_HTTP_RESPONSE_CODE) 112 code <= HISTOGRAM_MAX_HTTP_RESPONSE_CODE)
113 return code; 113 return code;
114 return 0; 114 return 0;
115 } 115 }
116 116
117 void CheckDoesNotHaveEmbededNulls(const std::string& str) {
118 // Care needs to be taken when adding values to the raw headers string to
119 // make sure it does not contain embeded NULLs. Any embeded '\0' may be
120 // understood as line terminators and change how header lines get tokenized.
121 CHECK(str.find('\0') == std::string::npos);
122 }
123
117 } // namespace 124 } // namespace
118 125
119 struct HttpResponseHeaders::ParsedHeader { 126 struct HttpResponseHeaders::ParsedHeader {
120 // A header "continuation" contains only a subsequent value for the 127 // A header "continuation" contains only a subsequent value for the
121 // preceding header. (Header values are comma separated.) 128 // preceding header. (Header values are comma separated.)
122 bool is_continuation() const { return name_begin == name_end; } 129 bool is_continuation() const { return name_begin == name_end; }
123 130
124 std::string::const_iterator name_begin; 131 std::string::const_iterator name_begin;
125 std::string::const_iterator name_end; 132 std::string::const_iterator name_end;
126 std::string::const_iterator value_begin; 133 std::string::const_iterator value_begin;
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 new_raw_headers.push_back('\0'); 300 new_raw_headers.push_back('\0');
294 301
295 std::string lowercase_name(name); 302 std::string lowercase_name(name);
296 StringToLowerASCII(&lowercase_name); 303 StringToLowerASCII(&lowercase_name);
297 HeaderSet to_remove; 304 HeaderSet to_remove;
298 to_remove.insert(lowercase_name); 305 to_remove.insert(lowercase_name);
299 MergeWithHeaders(new_raw_headers, to_remove); 306 MergeWithHeaders(new_raw_headers, to_remove);
300 } 307 }
301 308
302 void HttpResponseHeaders::AddHeader(const std::string& header) { 309 void HttpResponseHeaders::AddHeader(const std::string& header) {
310 CheckDoesNotHaveEmbededNulls(header);
303 DCHECK_EQ('\0', raw_headers_[raw_headers_.size() - 2]); 311 DCHECK_EQ('\0', raw_headers_[raw_headers_.size() - 2]);
304 DCHECK_EQ('\0', raw_headers_[raw_headers_.size() - 1]); 312 DCHECK_EQ('\0', raw_headers_[raw_headers_.size() - 1]);
305 // Don't copy the last null. 313 // Don't copy the last null.
306 std::string new_raw_headers(raw_headers_, 0, raw_headers_.size() - 1); 314 std::string new_raw_headers(raw_headers_, 0, raw_headers_.size() - 1);
307 new_raw_headers.append(header); 315 new_raw_headers.append(header);
308 new_raw_headers.push_back('\0'); 316 new_raw_headers.push_back('\0');
309 new_raw_headers.push_back('\0'); 317 new_raw_headers.push_back('\0');
310 318
311 // Make this object hold the new data. 319 // Make this object hold the new data.
312 raw_headers_.clear(); 320 raw_headers_.clear();
313 parsed_.clear(); 321 parsed_.clear();
314 Parse(new_raw_headers); 322 Parse(new_raw_headers);
315 } 323 }
316 324
317 void HttpResponseHeaders::ReplaceStatusLine(const std::string& new_status) { 325 void HttpResponseHeaders::ReplaceStatusLine(const std::string& new_status) {
326 CheckDoesNotHaveEmbededNulls(new_status);
318 // Copy up to the null byte. This just copies the status line. 327 // Copy up to the null byte. This just copies the status line.
319 std::string new_raw_headers(new_status); 328 std::string new_raw_headers(new_status);
320 new_raw_headers.push_back('\0'); 329 new_raw_headers.push_back('\0');
321 330
322 HeaderSet empty_to_remove; 331 HeaderSet empty_to_remove;
323 MergeWithHeaders(new_raw_headers, empty_to_remove); 332 MergeWithHeaders(new_raw_headers, empty_to_remove);
324 } 333 }
325 334
326 void HttpResponseHeaders::Parse(const std::string& raw_input) { 335 void HttpResponseHeaders::Parse(const std::string& raw_input) {
327 raw_headers_.reserve(raw_input.size()); 336 raw_headers_.reserve(raw_input.size());
(...skipping 903 matching lines...) Expand 10 before | Expand all | Expand 10 after
1231 // We have all the values; let's verify that they make sense for a 206 1240 // We have all the values; let's verify that they make sense for a 206
1232 // response. 1241 // response.
1233 if (*first_byte_position < 0 || *last_byte_position < 0 || 1242 if (*first_byte_position < 0 || *last_byte_position < 0 ||
1234 *instance_length < 0 || *instance_length - 1 < *last_byte_position) 1243 *instance_length < 0 || *instance_length - 1 < *last_byte_position)
1235 return false; 1244 return false;
1236 1245
1237 return true; 1246 return true;
1238 } 1247 }
1239 1248
1240 } // namespace net 1249 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_response_headers.h ('k') | net/http/http_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698