mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1149987 - Part 5: Do not store or match Response objects with a Vary:* header; r=bkelly
This commit is contained in:
parent
49ca5f135b
commit
bbf8a918b8
@ -73,4 +73,5 @@ MSG_DEF(MSG_INVALID_RESPONSE_STATUSCODE_ERROR, 0, JSEXN_RANGEERR, "Invalid respo
|
||||
MSG_DEF(MSG_INVALID_REDIRECT_STATUSCODE_ERROR, 0, JSEXN_RANGEERR, "Invalid redirect status code.")
|
||||
MSG_DEF(MSG_INVALID_URL_SCHEME, 2, JSEXN_TYPEERR, "{0} URL {1} must be either http:// or https://.")
|
||||
MSG_DEF(MSG_RESPONSE_URL_IS_NULL, 0, JSEXN_TYPEERR, "Cannot set Response.finalURL when Response.url is null.")
|
||||
MSG_DEF(MSG_RESPONSE_HAS_VARY_STAR, 0, JSEXN_TYPEERR, "Invalid Response object with a 'Vary: *' header.")
|
||||
MSG_DEF(MSG_BAD_FORMDATA, 0, JSEXN_TYPEERR, "Could not parse content as FormData.")
|
||||
|
6
dom/cache/DBSchema.cpp
vendored
6
dom/cache/DBSchema.cpp
vendored
@ -944,9 +944,9 @@ DBSchema::MatchByVaryHeader(mozIStorageConnection* aConn,
|
||||
for (; token;
|
||||
token = nsCRT::strtok(rawBuffer, NS_HTTP_HEADER_SEPS, &rawBuffer)) {
|
||||
nsDependentCString header(token);
|
||||
if (header.EqualsLiteral("*")) {
|
||||
continue;
|
||||
}
|
||||
MOZ_ASSERT(!header.EqualsLiteral("*"),
|
||||
"We should have already caught this in "
|
||||
"TypeUtils::ToPCacheResponseWithoutBody()");
|
||||
|
||||
ErrorResult errorResult;
|
||||
nsAutoCString queryValue;
|
||||
|
12
dom/cache/FetchPut.cpp
vendored
12
dom/cache/FetchPut.cpp
vendored
@ -259,10 +259,10 @@ FetchPut::FetchComplete(FetchObserver* aObserver,
|
||||
ToPCacheResponseWithoutBody(mStateList[i].mPCacheResponse,
|
||||
*aInternalResponse, rv);
|
||||
if (rv.Failed()) {
|
||||
MaybeSetError(rv.ErrorCode());
|
||||
return;
|
||||
mResult = Move(rv);
|
||||
} else {
|
||||
aInternalResponse->GetBody(getter_AddRefs(mStateList[i].mResponseStream));
|
||||
}
|
||||
aInternalResponse->GetBody(getter_AddRefs(mStateList[i].mResponseStream));
|
||||
mStateList[i].mFetchObserver = nullptr;
|
||||
MOZ_ASSERT(mPendingCount > 0);
|
||||
mPendingCount -= 1;
|
||||
@ -377,9 +377,9 @@ FetchPut::MatchInPutList(const PCacheRequest& aRequest,
|
||||
for (; token;
|
||||
token = nsCRT::strtok(rawBuffer, NS_HTTP_HEADER_SEPS, &rawBuffer)) {
|
||||
nsDependentCString header(token);
|
||||
if (header.EqualsLiteral("*")) {
|
||||
continue;
|
||||
}
|
||||
MOZ_ASSERT(!header.EqualsLiteral("*"),
|
||||
"We should have already caught this in "
|
||||
"TypeUtils::ToPCacheResponseWithoutBody()");
|
||||
|
||||
ErrorResult headerRv;
|
||||
nsAutoCString value;
|
||||
|
32
dom/cache/TypeUtils.cpp
vendored
32
dom/cache/TypeUtils.cpp
vendored
@ -26,6 +26,8 @@
|
||||
#include "nsStreamUtils.h"
|
||||
#include "nsString.h"
|
||||
#include "nsURLParsers.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsHttp.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@ -104,6 +106,29 @@ ProcessURL(nsAString& aUrl, bool* aSchemeValidOut,
|
||||
*aUrlWithoutQueryOut = Substring(aUrl, 0, queryPos - 1);
|
||||
}
|
||||
|
||||
static bool
|
||||
HasVaryStar(mozilla::dom::InternalHeaders* aHeaders)
|
||||
{
|
||||
nsAutoTArray<nsCString, 16> varyHeaders;
|
||||
ErrorResult rv;
|
||||
aHeaders->GetAll(NS_LITERAL_CSTRING("vary"), varyHeaders, rv);
|
||||
MOZ_ALWAYS_TRUE(!rv.Failed());
|
||||
|
||||
for (uint32_t i = 0; i < varyHeaders.Length(); ++i) {
|
||||
nsAutoCString varyValue(varyHeaders[i]);
|
||||
char* rawBuffer = varyValue.BeginWriting();
|
||||
char* token = nsCRT::strtok(rawBuffer, NS_HTTP_HEADER_SEPS, &rawBuffer);
|
||||
for (; token;
|
||||
token = nsCRT::strtok(rawBuffer, NS_HTTP_HEADER_SEPS, &rawBuffer)) {
|
||||
nsDependentCString header(token);
|
||||
if (header.EqualsLiteral("*")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
SerializeNormalStream(nsIInputStream* aStream, PCacheReadStream& aReadStreamOut)
|
||||
{
|
||||
@ -266,6 +291,10 @@ TypeUtils::ToPCacheResponseWithoutBody(PCacheResponse& aOut,
|
||||
aOut.statusText() = aIn.GetStatusText();
|
||||
nsRefPtr<InternalHeaders> headers = aIn.UnfilteredHeaders();
|
||||
MOZ_ASSERT(headers);
|
||||
if (HasVaryStar(headers)) {
|
||||
aRv.ThrowTypeError(MSG_RESPONSE_HAS_VARY_STAR);
|
||||
return;
|
||||
}
|
||||
headers->GetPHeaders(aOut.headers());
|
||||
aOut.headersGuard() = headers->Guard();
|
||||
aOut.securityInfo() = aIn.GetSecurityInfo();
|
||||
@ -281,6 +310,9 @@ TypeUtils::ToPCacheResponse(PCacheResponse& aOut, Response& aIn, ErrorResult& aR
|
||||
|
||||
nsRefPtr<InternalResponse> ir = aIn.GetInternalResponse();
|
||||
ToPCacheResponseWithoutBody(aOut, *ir, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
aIn.GetBody(getter_AddRefs(stream));
|
||||
|
@ -107,15 +107,59 @@ function testBasicKeys() {
|
||||
}
|
||||
|
||||
function testStar() {
|
||||
function ensurePromiseRejected(promise) {
|
||||
return promise
|
||||
.then(function() {
|
||||
ok(false, "Promise should be rejected");
|
||||
}, function(err) {
|
||||
is(err.name, "TypeError", "Attempting to store a Response with a Vary:* header must fail");
|
||||
});
|
||||
}
|
||||
var test;
|
||||
return setupTest({"WhatToVary": "*", "Cookie": "foo=bar"})
|
||||
.then(function(t) {
|
||||
test = t;
|
||||
// Ensure that searching with a different Cookie header with Vary:* succeeds.
|
||||
return test.cache.match(new Request(requestURL, {headers: {"Cookie": "bar=baz"}}));
|
||||
}).then(function(r) {
|
||||
return checkResponse(r, test.response, test.responseText);
|
||||
return new Promise(function(resolve, reject) {
|
||||
var cache;
|
||||
caches.open(name).then(function(c) {
|
||||
cache = c;
|
||||
Promise.all([
|
||||
ensurePromiseRejected(
|
||||
cache.add(new Request(requestURL + "1", {headers: {"WhatToVary": "*"}}))),
|
||||
ensurePromiseRejected(
|
||||
cache.addAll([
|
||||
new Request(requestURL + "2", {headers: {"WhatToVary": "*"}}),
|
||||
requestURL + "3",
|
||||
])),
|
||||
ensurePromiseRejected(
|
||||
fetch(new Request(requestURL + "4", {headers: {"WhatToVary": "*"}}))
|
||||
.then(function(response) {
|
||||
return cache.put(requestURL + "4", response);
|
||||
})),
|
||||
ensurePromiseRejected(
|
||||
cache.add(new Request(requestURL + "5", {headers: {"WhatToVary": "*,User-Agent"}}))),
|
||||
ensurePromiseRejected(
|
||||
cache.addAll([
|
||||
new Request(requestURL + "6", {headers: {"WhatToVary": "*,User-Agent"}}),
|
||||
requestURL + "7",
|
||||
])),
|
||||
ensurePromiseRejected(
|
||||
fetch(new Request(requestURL + "8", {headers: {"WhatToVary": "*,User-Agent"}}))
|
||||
.then(function(response) {
|
||||
return cache.put(requestURL + "8", response);
|
||||
})),
|
||||
ensurePromiseRejected(
|
||||
cache.add(new Request(requestURL + "9", {headers: {"WhatToVary": "User-Agent,*"}}))),
|
||||
ensurePromiseRejected(
|
||||
cache.addAll([
|
||||
new Request(requestURL + "10", {headers: {"WhatToVary": "User-Agent,*"}}),
|
||||
requestURL + "10",
|
||||
])),
|
||||
ensurePromiseRejected(
|
||||
fetch(new Request(requestURL + "11", {headers: {"WhatToVary": "User-Agent,*"}}))
|
||||
.then(function(response) {
|
||||
return cache.put(requestURL + "11", response);
|
||||
})),
|
||||
]).then(reject, resolve);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testMatch() {
|
||||
@ -134,23 +178,6 @@ function testMatch() {
|
||||
});
|
||||
}
|
||||
|
||||
function testStarAndAnotherHeader() {
|
||||
var test;
|
||||
return setupTest({"WhatToVary": "*,User-Agent"})
|
||||
.then(function(t) {
|
||||
test = t;
|
||||
// Ensure that searching with a different User-Agent header fails.
|
||||
return test.cache.match(new Request(requestURL, {headers: {"User-Agent": "MyUA"}}));
|
||||
}).then(function(r) {
|
||||
is(typeof r, "undefined", "Searching for a request with a non-matching User-Agent header should not succeed");
|
||||
// Ensure that searching with a different User-Agent header but with ignoreVary succeeds.
|
||||
return test.cache.match(new Request(requestURL, {headers: {"User-Agent": "MyUA"}}),
|
||||
{ignoreVary: true});
|
||||
}).then(function(r) {
|
||||
return checkResponse(r, test.response, test.responseText);
|
||||
});
|
||||
}
|
||||
|
||||
function testInvalidHeaderName() {
|
||||
var test;
|
||||
return setupTest({"WhatToVary": "Foo/Bar, User-Agent"})
|
||||
@ -285,6 +312,8 @@ function testMultipleCacheEntries() {
|
||||
function step(testPromise) {
|
||||
return testPromise.then(function() {
|
||||
caches.delete(name);
|
||||
}, function() {
|
||||
caches.delete(name);
|
||||
});
|
||||
}
|
||||
|
||||
@ -294,8 +323,6 @@ step(testBasics()).then(function() {
|
||||
return step(testStar());
|
||||
}).then(function() {
|
||||
return step(testMatch());
|
||||
}).then(function() {
|
||||
return step(testStarAndAnotherHeader());
|
||||
}).then(function() {
|
||||
return step(testInvalidHeaderName());
|
||||
}).then(function() {
|
||||
|
Loading…
Reference in New Issue
Block a user