зеркало из https://github.com/mozilla/gecko-dev.git
Bug 666562. fix quoted-string unescaping in HTTP link header fields, r=bzbarsky
This commit is contained in:
Родитель
79403fff16
Коммит
4a4110664c
|
@ -557,13 +557,6 @@ nsContentSink::DoProcessLinkHeader()
|
|||
ProcessLinkHeader(nsnull, value);
|
||||
}
|
||||
|
||||
static const PRUnichar kSemiCh = PRUnichar(';');
|
||||
static const PRUnichar kCommaCh = PRUnichar(',');
|
||||
static const PRUnichar kEqualsCh = PRUnichar('=');
|
||||
static const PRUnichar kLessThanCh = PRUnichar('<');
|
||||
static const PRUnichar kGreaterThanCh = PRUnichar('>');
|
||||
|
||||
|
||||
// check whether the Link header field applies to the context resource
|
||||
// see <http://tools.ietf.org/html/rfc5988#section-5.2>
|
||||
|
||||
|
@ -642,22 +635,31 @@ nsContentSink::ProcessLinkHeader(nsIContent* aElement,
|
|||
end = start;
|
||||
last = end - 1;
|
||||
|
||||
PRBool needsUnescape = PR_FALSE;
|
||||
|
||||
// look for semicolon or comma
|
||||
while (*end != kNullCh && *end != kSemiCh && *end != kCommaCh) {
|
||||
while (*end != kNullCh && *end != kSemicolon && *end != kComma) {
|
||||
PRUnichar ch = *end;
|
||||
|
||||
if (ch == kApostrophe || ch == kQuote || ch == kLessThanCh) {
|
||||
if (ch == kApostrophe || ch == kQuote || ch == kLessThan) {
|
||||
// quoted string
|
||||
|
||||
PRUnichar quote = *end;
|
||||
if (quote == kLessThanCh) {
|
||||
quote = kGreaterThanCh;
|
||||
PRUnichar quote = ch;
|
||||
if (quote == kLessThan) {
|
||||
quote = kGreaterThan;
|
||||
}
|
||||
|
||||
|
||||
needsUnescape = (ch == kQuote);
|
||||
|
||||
PRUnichar* closeQuote = (end + 1);
|
||||
|
||||
// seek closing quote
|
||||
while (*closeQuote != kNullCh && quote != *closeQuote) {
|
||||
// in quoted-string, "\" is an escape character
|
||||
if (needsUnescape && *closeQuote == kBackSlash && *(closeQuote + 1) != kNullCh) {
|
||||
++closeQuote;
|
||||
}
|
||||
|
||||
++closeQuote;
|
||||
}
|
||||
|
||||
|
@ -671,14 +673,14 @@ nsContentSink::ProcessLinkHeader(nsIContent* aElement,
|
|||
|
||||
ch = *(end + 1);
|
||||
|
||||
if (ch != kNullCh && ch != kSemiCh && ch != kCommaCh) {
|
||||
if (ch != kNullCh && ch != kSemicolon && ch != kComma) {
|
||||
// end string here
|
||||
*(++end) = kNullCh;
|
||||
|
||||
ch = *(end + 1);
|
||||
|
||||
// keep going until semi or comma
|
||||
while (ch != kNullCh && ch != kSemiCh && ch != kCommaCh) {
|
||||
while (ch != kNullCh && ch != kSemicolon && ch != kComma) {
|
||||
++end;
|
||||
|
||||
ch = *end;
|
||||
|
@ -697,7 +699,7 @@ nsContentSink::ProcessLinkHeader(nsIContent* aElement,
|
|||
*end = kNullCh;
|
||||
|
||||
if (start < end) {
|
||||
if ((*start == kLessThanCh) && (*last == kGreaterThanCh)) {
|
||||
if ((*start == kLessThan) && (*last == kGreaterThan)) {
|
||||
*last = kNullCh;
|
||||
|
||||
if (href.IsEmpty()) { // first one wins
|
||||
|
@ -707,7 +709,7 @@ nsContentSink::ProcessLinkHeader(nsIContent* aElement,
|
|||
} else {
|
||||
PRUnichar* equals = start;
|
||||
|
||||
while ((*equals != kNullCh) && (*equals != kEqualsCh)) {
|
||||
while ((*equals != kNullCh) && (*equals != kEqual)) {
|
||||
equals++;
|
||||
}
|
||||
|
||||
|
@ -727,6 +729,21 @@ nsContentSink::ProcessLinkHeader(nsIContent* aElement,
|
|||
value++;
|
||||
}
|
||||
|
||||
if (needsUnescape) {
|
||||
// unescape in-place
|
||||
PRUnichar* unescaped = value;
|
||||
PRUnichar *src = value;
|
||||
|
||||
while (*src != kNullCh) {
|
||||
if (*src == kBackSlash && *(src + 1) != kNullCh) {
|
||||
src++;
|
||||
}
|
||||
*unescaped++ = *src++;
|
||||
}
|
||||
|
||||
*unescaped = kNullCh;
|
||||
}
|
||||
|
||||
if (attr.LowerCaseEqualsLiteral("rel")) {
|
||||
if (rel.IsEmpty()) {
|
||||
rel = value;
|
||||
|
@ -759,7 +776,7 @@ nsContentSink::ProcessLinkHeader(nsIContent* aElement,
|
|||
}
|
||||
}
|
||||
|
||||
if (endCh == kCommaCh) {
|
||||
if (endCh == kComma) {
|
||||
// hit a comma, process what we've got so far
|
||||
|
||||
href.Trim(" \t\n\r\f"); // trim HTML5 whitespace
|
||||
|
|
Загрузка…
Ссылка в новой задаче