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

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

Issue 2225933004: Avoid adding invalid headers in AddHeaderFromString (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 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
« net/http/http_util.h ('K') | « net/http/http_util.h ('k') | no next file » | 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 // The rules for parsing content-types were borrowed from Firefox: 5 // The rules for parsing content-types were borrowed from Firefox:
6 // http://lxr.mozilla.org/mozilla/source/netwerk/base/src/nsURLHelper.cpp#834 6 // http://lxr.mozilla.org/mozilla/source/netwerk/base/src/nsURLHelper.cpp#834
7 7
8 #include "net/http/http_util.h" 8 #include "net/http/http_util.h"
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 base::StartsWith(lower_name, "sec-", base::CompareCase::SENSITIVE)) 333 base::StartsWith(lower_name, "sec-", base::CompareCase::SENSITIVE))
334 return false; 334 return false;
335 for (size_t i = 0; i < arraysize(kForbiddenHeaderFields); ++i) { 335 for (size_t i = 0; i < arraysize(kForbiddenHeaderFields); ++i) {
336 if (lower_name == kForbiddenHeaderFields[i]) 336 if (lower_name == kForbiddenHeaderFields[i])
337 return false; 337 return false;
338 } 338 }
339 return true; 339 return true;
340 } 340 }
341 341
342 // static 342 // static
343 bool HttpUtil::IsValidHeaderName(const std::string& name) { 343 bool HttpUtil::IsValidHeaderName(const base::StringPiece& name) {
344 // Check whether the header name is RFC 2616-compliant. 344 // Check whether the header name is RFC 2616-compliant.
345 return HttpUtil::IsToken(name); 345 return HttpUtil::IsToken(name);
346 } 346 }
347 347
348 // static 348 // static
349 bool HttpUtil::IsValidHeaderValue(const std::string& value) { 349 bool HttpUtil::IsValidHeaderValue(const base::StringPiece& value) {
350 // Just a sanity check: disallow NUL, CR and LF. 350 // Just a sanity check: disallow NUL, CR and LF.
351 return value.find_first_of("\0\r\n", 0, 3) == std::string::npos; 351 for (char c : value) {
352 if (c == '\0' || c == '\r' || c == '\n')
353 return false;
354 }
355 return true;
352 } 356 }
353 357
354 // static 358 // static
355 std::string HttpUtil::StripHeaders(const std::string& headers, 359 std::string HttpUtil::StripHeaders(const std::string& headers,
356 const char* const headers_to_remove[], 360 const char* const headers_to_remove[],
357 size_t headers_to_remove_len) { 361 size_t headers_to_remove_len) {
358 std::string stripped_headers; 362 std::string stripped_headers;
359 HttpUtil::HeadersIterator it(headers.begin(), headers.end(), "\r\n"); 363 HttpUtil::HeadersIterator it(headers.begin(), headers.end(), "\r\n");
360 364
361 while (it.GetNext()) { 365 while (it.GetNext()) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 kNonCoalescingHeaders[i])) 406 kNonCoalescingHeaders[i]))
403 return true; 407 return true;
404 } 408 }
405 return false; 409 return false;
406 } 410 }
407 411
408 bool HttpUtil::IsLWS(char c) { 412 bool HttpUtil::IsLWS(char c) {
409 return strchr(HTTP_LWS, c) != NULL; 413 return strchr(HTTP_LWS, c) != NULL;
410 } 414 }
411 415
412 void HttpUtil::TrimLWS(std::string::const_iterator* begin, 416 namespace {
413 std::string::const_iterator* end) { 417 template <typename ConstIterator>
418 void TrimLWSImplementation(ConstIterator* begin, ConstIterator* end) {
414 // leading whitespace 419 // leading whitespace
415 while (*begin < *end && IsLWS((*begin)[0])) 420 while (*begin < *end && HttpUtil::IsLWS((*begin)[0]))
416 ++(*begin); 421 ++(*begin);
417 422
418 // trailing whitespace 423 // trailing whitespace
419 while (*begin < *end && IsLWS((*end)[-1])) 424 while (*begin < *end && HttpUtil::IsLWS((*end)[-1]))
420 --(*end); 425 --(*end);
421 } 426 }
427 } // namespace
mmenke 2016/08/09 16:54:47 The more common pattern in net/ is to use a single
Adam Rice 2016/08/10 03:19:07 Done. I can move the rest of the anonymous namespa
428
429 // static
430 void HttpUtil::TrimLWS(std::string::const_iterator* begin,
431 std::string::const_iterator* end) {
432 TrimLWSImplementation(begin, end);
433 }
434
435 // static
436 base::StringPiece HttpUtil::TrimLWS(const base::StringPiece& string) {
437 const char* begin = string.data();
438 const char* end = string.data() + string.size();
439 TrimLWSImplementation(&begin, &end);
440 return base::StringPiece(begin, end - begin);
441 }
422 442
423 bool HttpUtil::IsQuote(char c) { 443 bool HttpUtil::IsQuote(char c) {
424 // Single quote mark isn't actually part of quoted-text production, 444 // Single quote mark isn't actually part of quoted-text production,
425 // but apparently some servers rely on this. 445 // but apparently some servers rely on this.
426 return c == '"' || c == '\''; 446 return c == '"' || c == '\'';
427 } 447 }
428 448
429 namespace { 449 namespace {
430 bool IsTokenChar(unsigned char c) { 450 bool IsTokenChar(unsigned char c) {
431 return !(c >= 0x80 || c <= 0x1F || c == 0x7F || c == '(' || c == ')' || 451 return !(c >= 0x80 || c <= 0x1F || c == 0x7F || c == '(' || c == ')' ||
432 c == '<' || c == '>' || c == '@' || c == ',' || c == ';' || 452 c == '<' || c == '>' || c == '@' || c == ',' || c == ';' ||
433 c == ':' || c == '\\' || c == '"' || c == '/' || c == '[' || 453 c == ':' || c == '\\' || c == '"' || c == '/' || c == '[' ||
434 c == ']' || c == '?' || c == '=' || c == '{' || c == '}' || 454 c == ']' || c == '?' || c == '=' || c == '{' || c == '}' ||
435 c == ' ' || c == '\t'); 455 c == ' ' || c == '\t');
436 } 456 }
437 } // anonymous namespace 457 } // anonymous namespace
438 458
439 // See RFC 2616 Sec 2.2 for the definition of |token|. 459 // See RFC 2616 Sec 2.2 for the definition of |token|.
440 bool HttpUtil::IsToken(std::string::const_iterator begin, 460 bool HttpUtil::IsToken(const base::StringPiece& string) {
441 std::string::const_iterator end) { 461 if (string.size() == 0)
mmenke 2016/08/09 16:54:47 !string.empty() is preferred, as it doesn't requir
Adam Rice 2016/08/10 03:19:07 I can't believe I did that. Fixed.
442 if (begin == end)
443 return false; 462 return false;
444 for (std::string::const_iterator iter = begin; iter != end; ++iter) { 463 for (char c : string) {
445 if (!IsTokenChar(*iter)) 464 if (!IsTokenChar(c))
446 return false; 465 return false;
447 } 466 }
448 return true; 467 return true;
449 } 468 }
450 469
451 // See RFC 5987 Sec 3.2.1 for the definition of |parmname|. 470 // See RFC 5987 Sec 3.2.1 for the definition of |parmname|.
452 bool HttpUtil::IsParmName(std::string::const_iterator begin, 471 bool HttpUtil::IsParmName(std::string::const_iterator begin,
453 std::string::const_iterator end) { 472 std::string::const_iterator end) {
454 if (begin == end) 473 if (begin == end)
455 return false; 474 return false;
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after
1053 return true; 1072 return true;
1054 } 1073 }
1055 1074
1056 bool HttpUtil::NameValuePairsIterator::IsQuote(char c) const { 1075 bool HttpUtil::NameValuePairsIterator::IsQuote(char c) const {
1057 if (strict_quotes_) 1076 if (strict_quotes_)
1058 return c == '"'; 1077 return c == '"';
1059 return HttpUtil::IsQuote(c); 1078 return HttpUtil::IsQuote(c);
1060 } 1079 }
1061 1080
1062 } // namespace net 1081 } // namespace net
OLDNEW
« net/http/http_util.h ('K') | « net/http/http_util.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698