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

Unified Diff: net/http/http_util.cc

Issue 1811163002: Share link header parsing code between blink and content. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@base-optional
Patch Set: address mmenke's comments Created 4 years, 8 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: net/http/http_util.cc
diff --git a/net/http/http_util.cc b/net/http/http_util.cc
index 932f8386dadc401914a559f20805b951f66876cb..b04571ca51e4f7c726013a9d260b87d122bf262b 100644
--- a/net/http/http_util.cc
+++ b/net/http/http_util.cc
@@ -501,6 +501,55 @@ std::string HttpUtil::Unquote(const std::string& str) {
}
// static
+bool HttpUtil::StrictUnquote(std::string::const_iterator begin,
mmenke 2016/04/26 18:05:57 Hrm...Should this and Unquote share an implementat
Marijn Kruisselbrink 2016/04/27 01:49:49 Good idea. Done.
+ std::string::const_iterator end,
+ std::string* out) {
+ // Empty string
+ if (begin == end)
+ return false;
+
+ // Nothing to unquote.
+ if (!IsQuote(*begin))
+ return false;
+
+ // No terminal quote mark.
+ if (end - begin < 2 || *begin != *(end - 1))
+ return false;
+
+ char quote = *begin;
+
+ // Strip quotemarks
+ ++begin;
+ --end;
+
+ // Terminal quote is escaped.
+ if (begin != end && *(end - 1) == '\\')
mmenke 2016/04/26 18:05:57 BUG: "\\" is valid. Instead, should have a "prev
Marijn Kruisselbrink 2016/04/27 01:49:49 Yeah, just caught that myself too. Added a test an
+ return false;
+
+ // Unescape quoted-pair (defined in RFC 2616 section 2.2)
+ bool prev_escape = false;
+ std::string unescaped;
+ for (; begin != end; ++begin) {
+ char c = *begin;
+ if (c == '\\' && !prev_escape) {
+ prev_escape = true;
+ continue;
+ }
+ if (!prev_escape && c == quote)
+ return false;
+ prev_escape = false;
+ unescaped.push_back(c);
+ }
+ *out = std::move(unescaped);
+ return true;
+}
+
+// static
+bool HttpUtil::StrictUnquote(const std::string& str, std::string* out) {
+ return StrictUnquote(str.begin(), str.end(), out);
+}
+
+// static
std::string HttpUtil::Quote(const std::string& str) {
std::string escaped;
escaped.reserve(2 + str.size());
@@ -910,7 +959,8 @@ HttpUtil::NameValuePairsIterator::NameValuePairsIterator(
std::string::const_iterator begin,
std::string::const_iterator end,
char delimiter,
- OptionalValues optional_values)
+ Values optional_values,
+ Quotes strict_quotes)
: props_(begin, end, delimiter),
valid_(true),
name_begin_(end),
@@ -918,13 +968,18 @@ HttpUtil::NameValuePairsIterator::NameValuePairsIterator(
value_begin_(end),
value_end_(end),
value_is_quoted_(false),
- values_optional_(optional_values == VALUES_OPTIONAL) {}
+ values_optional_(optional_values == Values::OPTIONAL),
+ strict_quotes_(strict_quotes == Quotes::STRICT) {}
HttpUtil::NameValuePairsIterator::NameValuePairsIterator(
std::string::const_iterator begin,
std::string::const_iterator end,
char delimiter)
- : NameValuePairsIterator(begin, end, delimiter, VALUES_NOT_OPTIONAL) {}
+ : NameValuePairsIterator(begin,
+ end,
+ delimiter,
+ Values::NOT_OPTIONAL,
+ Quotes::NOT_STRICT) {}
HttpUtil::NameValuePairsIterator::NameValuePairsIterator(
const NameValuePairsIterator& other) = default;
@@ -980,6 +1035,14 @@ bool HttpUtil::NameValuePairsIterator::GetNext() {
}
if (value_begin_ != value_end_ && HttpUtil::IsQuote(*value_begin_)) {
mmenke 2016/04/26 18:05:57 So strict mode fails on foo='bar but succeeds on f
Marijn Kruisselbrink 2016/04/27 01:49:49 Argh, excellent question... And not really somethi
+ value_is_quoted_ = true;
+
+ if (strict_quotes_) {
+ if (!HttpUtil::StrictUnquote(value_begin_, value_end_, &unquoted_value_))
+ return valid_ = false;
+ return true;
+ }
+
// Trim surrounding quotemarks off the value
if (*value_begin_ != *(value_end_ - 1) || value_begin_ + 1 == value_end_) {
// NOTE: This is not as graceful as it sounds:
@@ -987,9 +1050,9 @@ bool HttpUtil::NameValuePairsIterator::GetNext() {
// (["\"hello] should give ["hello]).
// * Does not detect when the final quote is escaped
// (["value\"] should give [value"])
+ value_is_quoted_ = false;
++value_begin_; // Gracefully recover from mismatching quotes.
} else {
- value_is_quoted_ = true;
// Do not store iterators into this. See declaration of unquoted_value_.
unquoted_value_ = HttpUtil::Unquote(value_begin_, value_end_);
}

Powered by Google App Engine
This is Rietveld 408576698