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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: Source/platform/network/HTTPParsers.cpp
diff --git a/Source/platform/network/HTTPParsers.cpp b/Source/platform/network/HTTPParsers.cpp
index 3763f841a982adc2bdb7d428899166039bd6517f..69b1490318d05ec860844fa6f0448d1a12b5c67c 100644
--- a/Source/platform/network/HTTPParsers.cpp
+++ b/Source/platform/network/HTTPParsers.cpp
@@ -607,74 +607,88 @@ size_t parseHTTPRequestLine(const char* data, size_t length, String& failureReas
return end - data;
}
-size_t parseHTTPHeader(const char* start, size_t length, String& failureReason, AtomicString& nameStr, AtomicString& valueStr)
+static bool parseHTTPHeaderName(const char* s, size_t start, size_t size, String& failureReason, size_t* position, AtomicString* name)
{
- const char* p = start;
- const char* end = start + length;
-
- Vector<char> name;
- Vector<char> value;
- nameStr = nullAtom;
- valueStr = nullAtom;
-
- for (; p < end; p++) {
- switch (*p) {
+ size_t nameBegin = start;
+ for (size_t i = start; i < size; ++i) {
+ switch (s[i]) {
case '\r':
- if (name.isEmpty()) {
- if (p + 1 < end && *(p + 1) == '\n')
- return (p + 2) - start;
- failureReason = "CR doesn't follow LF at " + trimInputSample(p, end - p);
- return 0;
- }
- failureReason = "Unexpected CR in name at " + trimInputSample(name.data(), name.size());
- return 0;
+ failureReason = "Unexpected CR in name at " + trimInputSample(&s[nameBegin], i - nameBegin);
+ return false;
case '\n':
- failureReason = "Unexpected LF in name at " + trimInputSample(name.data(), name.size());
- return 0;
+ failureReason = "Unexpected LF in name at " + trimInputSample(&s[nameBegin], i - nameBegin);
+ return false;
case ':':
- break;
+ *position = i;
+ *name = AtomicString::fromUTF8(&s[nameBegin], i - nameBegin);
+ return true;
default:
- name.append(*p);
- continue;
- }
- if (*p == ':') {
- ++p;
break;
}
}
+ failureReason = "Unterminated header name";
+ return false;
+}
- for (; p < end && *p == 0x20; p++) { }
+static bool parseHTTPHeaderValue(const char* s, size_t start, size_t size, String& failureReason, size_t* position, AtomicString* value)
+{
+ size_t i = start;
+ 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.
+ }
+ size_t valueBegin = i;
- for (; p < end; p++) {
- switch (*p) {
- case '\r':
- break;
- case '\n':
- failureReason = "Unexpected LF in value at " + trimInputSample(value.data(), value.size());
- return 0;
- default:
- value.append(*p);
+ for (; i < size && s[i] != '\r'; ++i) {
+ if (s[i] == '\n') {
+ failureReason = "Unexpected LF in value at " + trimInputSample(&s[valueBegin], i - valueBegin);
+ return false;
}
- if (*p == '\r') {
- ++p;
- break;
+ }
+ if (i == size) {
+ failureReason = "Unterminated header value";
+ return false;
+ }
+ ASSERT(i < size && s[i] == '\r');
+ if (i + 1 >= size || s[i + 1] != '\n') {
+ 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.
+ return false;
+ }
+
+ *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
+ *value = AtomicString::fromUTF8(&s[valueBegin], i - valueBegin);
+ return true;
+}
+
+// Note that the header is already parsed and re-formatted in chromium side.
+// We assume that the input is more restricted than RFC2616.
+size_t parseHTTPHeader(const char* s, size_t size, String& failureReason, AtomicString& name, AtomicString& value)
+{
+ name = nullAtom;
+ value = nullAtom;
+ if (size >= 1 && s[0] == '\r') {
+ if (size >= 2 && s[1] == '\n') {
+ // Skip an empty line.
+ return 2;
}
+ 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.
+ return 0;
}
- if (p >= end || *p != '\n') {
- failureReason = "CR doesn't follow LF after value at " + trimInputSample(p, end - p);
+ size_t current = 0;
+ if (!parseHTTPHeaderName(s, current, size, failureReason, &current, &name)) {
return 0;
}
- nameStr = AtomicString::fromUTF8(name.data(), name.size());
- valueStr = AtomicString::fromUTF8(value.data(), value.size());
- if (nameStr.isNull()) {
+ if (name.isEmpty()) {
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"
return 0;
}
- if (valueStr.isNull()) {
- failureReason = "Invalid UTF-8 sequence in header value";
+
+ ASSERT(s[current] == ':');
+ ++current;
+
+ if (!parseHTTPHeaderValue(s, current, size, failureReason, &current, &value)) {
return 0;
}
- return p - start;
+
+ return current;
}
size_t parseHTTPRequestBody(const char* data, size_t length, Vector<unsigned char>& body)
« 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