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

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
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;
626 failureReason = "CR doesn't follow LF at " + trimInputSample(p, end - p);
627 return 0;
628 }
629 failureReason = "Unexpected CR in name at " + trimInputSample(name.d ata(), name.size());
630 return 0;
631 case '\n': 618 case '\n':
632 failureReason = "Unexpected LF in name at " + trimInputSample(name.d ata(), name.size()); 619 failureReason = "Unexpected LF in name at " + trimInputSample(&s[nam eBegin], i - nameBegin);
633 return 0; 620 return false;
634 case ':': 621 case ':':
635 break; 622 *position = i;
623 *name = AtomicString::fromUTF8(&s[nameBegin], i - nameBegin);
624 return true;
636 default: 625 default:
637 name.append(*p);
638 continue;
639 }
640 if (*p == ':') {
641 ++p;
642 break; 626 break;
643 } 627 }
644 } 628 }
629 failureReason = "Unterminated header name";
630 return false;
631 }
645 632
646 for (; p < end && *p == 0x20; p++) { } 633 static bool parseHTTPHeaderValue(const char* s, size_t start, size_t size, Strin g& failureReason, size_t* position, AtomicString* value)
634 {
635 size_t i = start;
636 for (i = start; i < size && s[i] == ' '; ++i) {
tyoshino (SeeGerritForStatus) 2014/06/04 08:24:12 remove "i = start"?
yhirano 2014/06/04 09:14:03 Done.
637 }
638 size_t valueBegin = i;
647 639
648 for (; p < end; p++) { 640 for (; i < size && s[i] != '\r'; ++i) {
649 switch (*p) { 641 if (s[i] == '\n') {
650 case '\r': 642 failureReason = "Unexpected LF in value at " + trimInputSample(&s[va lueBegin], i - valueBegin);
651 break; 643 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 } 644 }
662 } 645 }
663 if (p >= end || *p != '\n') { 646 if (i == size) {
664 failureReason = "CR doesn't follow LF after value at " + trimInputSample (p, end - p); 647 failureReason = "Unterminated header value";
648 return false;
649 }
650 ASSERT(i < size && s[i] == '\r');
651 if (i + 1 >= size || s[i + 1] != '\n') {
652 failureReason = "CR doesn't follow LF after value at " + trimInputSample (&s[i + 1], size - i - 1);
tyoshino (SeeGerritForStatus) 2014/06/04 08:24:12 not your mistake but this should be "LF doesn't fo
yhirano 2014/06/04 09:14:03 Done.
653 return false;
654 }
655
656 *position = i + 1;
tyoshino (SeeGerritForStatus) 2014/06/04 08:24:12 is this correct?
yhirano 2014/06/04 09:14:03 Currently parseHTTPHeader returns (the number of c
657 *value = AtomicString::fromUTF8(&s[valueBegin], i - valueBegin);
658 return true;
659 }
660
661 // Note that the header is already parsed and re-formatted in chromium side.
662 // We assume that the input is more restricted than RFC2616.
663 size_t parseHTTPHeader(const char* s, size_t size, String& failureReason, Atomic String& name, AtomicString& value)
664 {
665 name = nullAtom;
666 value = nullAtom;
667 if (size >= 1 && s[0] == '\r') {
668 if (size >= 2 && s[1] == '\n') {
669 // Skip an empty line.
670 return 2;
671 }
672 failureReason = "CR doesn't follow LF at " + trimInputSample(0, size);
tyoshino (SeeGerritForStatus) 2014/06/04 08:24:12 ditto
yhirano 2014/06/04 09:14:03 Done.
665 return 0; 673 return 0;
666 } 674 }
667 nameStr = AtomicString::fromUTF8(name.data(), name.size()); 675 size_t current = 0;
668 valueStr = AtomicString::fromUTF8(value.data(), value.size()); 676 if (!parseHTTPHeaderName(s, current, size, failureReason, &current, &name)) {
669 if (nameStr.isNull()) { 677 return 0;
678 }
679 if (name.isEmpty()) {
670 failureReason = "Invalid UTF-8 sequence in header name"; 680 failureReason = "Invalid UTF-8 sequence in header name";
tyoshino (SeeGerritForStatus) 2014/06/04 08:24:12 It's better to say that that header name was missi
yhirano 2014/06/04 09:14:03 I added some messages: - "Header name is missing"
671 return 0; 681 return 0;
672 } 682 }
673 if (valueStr.isNull()) { 683
674 failureReason = "Invalid UTF-8 sequence in header value"; 684 ASSERT(s[current] == ':');
685 ++current;
686
687 if (!parseHTTPHeaderValue(s, current, size, failureReason, &current, &value) ) {
675 return 0; 688 return 0;
676 } 689 }
677 return p - start; 690
691 return current;
678 } 692 }
679 693
680 size_t parseHTTPRequestBody(const char* data, size_t length, Vector<unsigned cha r>& body) 694 size_t parseHTTPRequestBody(const char* data, size_t length, Vector<unsigned cha r>& body)
681 { 695 {
682 body.clear(); 696 body.clear();
683 body.append(data, length); 697 body.append(data, length);
684 698
685 return length; 699 return length;
686 } 700 }
687 701
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
821 if (!cacheControlHeader.containsNoCache) { 835 if (!cacheControlHeader.containsNoCache) {
822 // Handle Pragma: no-cache 836 // Handle Pragma: no-cache
823 // This is deprecated and equivalent to Cache-control: no-cache 837 // This is deprecated and equivalent to Cache-control: no-cache
824 // Don't bother tokenizing the value, it is not important 838 // Don't bother tokenizing the value, it is not important
825 cacheControlHeader.containsNoCache = pragmaValue.lower().contains(noCach eDirective); 839 cacheControlHeader.containsNoCache = pragmaValue.lower().contains(noCach eDirective);
826 } 840 }
827 return cacheControlHeader; 841 return cacheControlHeader;
828 } 842 }
829 843
830 } 844 }
OLDNEW
« no previous file with comments | « no previous file | Source/platform/network/HTTPParsersTest.cpp » ('j') | Source/platform/network/HTTPParsersTest.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698