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

Side by Side Diff: Source/platform/network/HTTPParsers.cpp

Issue 318613002: Allow empty header value in the blink HTTP header parser. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 6 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 | « no previous file | Source/platform/network/HTTPParsersTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) 2 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
3 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 3 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
4 * Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ 4 * Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/
5 * Copyright (C) 2009 Google Inc. All rights reserved. 5 * Copyright (C) 2009 Google Inc. All rights reserved.
6 * Copyright (C) 2011 Apple Inc. All Rights Reserved. 6 * Copyright (C) 2011 Apple Inc. All Rights Reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 else if (httpVersionString[7] == '0') 600 else if (httpVersionString[7] == '0')
601 httpVersion = HTTP_1_0; 601 httpVersion = HTTP_1_0;
602 else if (httpVersionString[7] == '1') 602 else if (httpVersionString[7] == '1')
603 httpVersion = HTTP_1_1; 603 httpVersion = HTTP_1_1;
604 else 604 else
605 httpVersion = Unknown; 605 httpVersion = Unknown;
606 606
607 return end - data; 607 return end - data;
608 } 608 }
609 609
610 size_t parseHTTPHeader(const char* start, size_t length, String& failureReason, AtomicString& nameStr, AtomicString& valueStr) 610 static bool parseHTTPHeaderName(const char* s, size_t start, size_t size, String & failureReason, size_t* position, AtomicString* name)
611 { 611 {
612 const char* p = start; 612 size_t nameBegin = start;
613 const char* end = start + length; 613 for (size_t i = start; i < size; ++i) {
614 614 switch (s[i]) {
615 Vector<char> name;
616 Vector<char> value;
617 nameStr = nullAtom;
618 valueStr = nullAtom;
619
620 for (; p < end; p++) {
621 switch (*p) {
622 case '\r': 615 case '\r':
623 if (name.isEmpty()) { 616 failureReason = "Unexpected CR in name at " + trimInputSample(&s[nam eBegin], i - nameBegin);
624 if (p + 1 < end && *(p + 1) == '\n') 617 return false;
625 return (p + 2) - start; 618 case '\n':
626 failureReason = "CR doesn't follow LF at " + trimInputSample(p, end - p); 619 failureReason = "Unexpected LF in name at " + trimInputSample(&s[nam eBegin], i - nameBegin);
627 return 0; 620 return false;
621 case ':':
622 if (i == nameBegin) {
623 failureReason = "Header name is missing";
624 return false;
628 } 625 }
629 failureReason = "Unexpected CR in name at " + trimInputSample(name.d ata(), name.size()); 626 *name = AtomicString::fromUTF8(&s[nameBegin], i - nameBegin);
630 return 0; 627 if (name->isNull()) {
631 case '\n': 628 failureReason = "Invalid UTF-8 sequence in header name";
632 failureReason = "Unexpected LF in name at " + trimInputSample(name.d ata(), name.size()); 629 return false;
633 return 0; 630 }
634 case ':': 631 *position = i;
635 break; 632 return true;
636 default: 633 default:
637 name.append(*p);
638 continue;
639 }
640 if (*p == ':') {
641 ++p;
642 break; 634 break;
643 } 635 }
644 } 636 }
637 failureReason = "Unterminated header name";
638 return false;
639 }
645 640
646 for (; p < end && *p == 0x20; p++) { } 641 static bool parseHTTPHeaderValue(const char* s, size_t start, size_t size, Strin g& failureReason, size_t* position, AtomicString* value)
642 {
643 size_t i = start;
644 for (; i < size && s[i] == ' '; ++i) {
645 }
646 size_t valueBegin = i;
647 647
648 for (; p < end; p++) { 648 for (; i < size && s[i] != '\r'; ++i) {
649 switch (*p) { 649 if (s[i] == '\n') {
650 case '\r': 650 failureReason = "Unexpected LF in value at " + trimInputSample(&s[va lueBegin], i - valueBegin);
651 break; 651 return false;
652 case '\n':
653 failureReason = "Unexpected LF in value at " + trimInputSample(value .data(), value.size());
654 return 0;
655 default:
656 value.append(*p);
657 }
658 if (*p == '\r') {
659 ++p;
660 break;
661 } 652 }
662 } 653 }
663 if (p >= end || *p != '\n') { 654 if (i == size) {
664 failureReason = "CR doesn't follow LF after value at " + trimInputSample (p, end - p); 655 failureReason = "Unterminated header value";
656 return false;
657 }
658
659 ASSERT(i < size && s[i] == '\r');
660 if (i + 1 >= size || s[i + 1] != '\n') {
661 failureReason = "LF doesn't follow CR after value at " + trimInputSample (&s[i + 1], size - i - 1);
662 return false;
663 }
664
665 *value = AtomicString::fromUTF8(&s[valueBegin], i - valueBegin);
666 if (i != valueBegin && value->isNull()) {
667 failureReason = "Invalid UTF-8 sequence in header value";
668 return false;
tyoshino (SeeGerritForStatus) 2014/06/05 02:07:32 nice!
669 }
670
671 *position = i + 1;
672 return true;
673 }
674
675 // Note that the header is already parsed and re-formatted in chromium side.
676 // We assume that the input is more restricted than RFC2616.
677 size_t parseHTTPHeader(const char* s, size_t size, String& failureReason, Atomic String& name, AtomicString& value)
678 {
679 name = nullAtom;
680 value = nullAtom;
681 if (size >= 1 && s[0] == '\r') {
682 if (size >= 2 && s[1] == '\n') {
683 // Skip an empty line.
684 return 2;
685 }
686 failureReason = "LF doesn't follow CR at " + trimInputSample(0, size);
665 return 0; 687 return 0;
666 } 688 }
667 nameStr = AtomicString::fromUTF8(name.data(), name.size()); 689 size_t current = 0;
668 valueStr = AtomicString::fromUTF8(value.data(), value.size()); 690 if (!parseHTTPHeaderName(s, current, size, failureReason, &current, &name)) {
669 if (nameStr.isNull()) {
670 failureReason = "Invalid UTF-8 sequence in header name";
671 return 0; 691 return 0;
672 } 692 }
673 if (valueStr.isNull()) { 693 ASSERT(s[current] == ':');
674 failureReason = "Invalid UTF-8 sequence in header value"; 694 ++current;
695
696 if (!parseHTTPHeaderValue(s, current, size, failureReason, &current, &value) ) {
675 return 0; 697 return 0;
676 } 698 }
677 return p - start; 699
700 return current;
678 } 701 }
679 702
680 size_t parseHTTPRequestBody(const char* data, size_t length, Vector<unsigned cha r>& body) 703 size_t parseHTTPRequestBody(const char* data, size_t length, Vector<unsigned cha r>& body)
681 { 704 {
682 body.clear(); 705 body.clear();
683 body.append(data, length); 706 body.append(data, length);
684 707
685 return length; 708 return length;
686 } 709 }
687 710
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
821 if (!cacheControlHeader.containsNoCache) { 844 if (!cacheControlHeader.containsNoCache) {
822 // Handle Pragma: no-cache 845 // Handle Pragma: no-cache
823 // This is deprecated and equivalent to Cache-control: no-cache 846 // This is deprecated and equivalent to Cache-control: no-cache
824 // Don't bother tokenizing the value, it is not important 847 // Don't bother tokenizing the value, it is not important
825 cacheControlHeader.containsNoCache = pragmaValue.lower().contains(noCach eDirective); 848 cacheControlHeader.containsNoCache = pragmaValue.lower().contains(noCach eDirective);
826 } 849 }
827 return cacheControlHeader; 850 return cacheControlHeader;
828 } 851 }
829 852
830 } 853 }
OLDNEW
« no previous file with comments | « no previous file | Source/platform/network/HTTPParsersTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698