mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1155898 - Expose fetch on JS sandbox. r=gabor, r=peterv
This commit is contained in:
parent
d5d271440b
commit
e6709a0bb7
@ -32,12 +32,16 @@
|
||||
#include "mozilla/dom/BlobBinding.h"
|
||||
#include "mozilla/dom/CSSBinding.h"
|
||||
#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
|
||||
#include "mozilla/dom/Fetch.h"
|
||||
#include "mozilla/dom/FileBinding.h"
|
||||
#include "mozilla/dom/PromiseBinding.h"
|
||||
#include "mozilla/dom/RequestBinding.h"
|
||||
#include "mozilla/dom/ResponseBinding.h"
|
||||
#include "mozilla/dom/RTCIdentityProviderRegistrar.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/dom/TextDecoderBinding.h"
|
||||
#include "mozilla/dom/TextEncoderBinding.h"
|
||||
#include "mozilla/dom/UnionConversions.h"
|
||||
#include "mozilla/dom/URLBinding.h"
|
||||
#include "mozilla/dom/URLSearchParamsBinding.h"
|
||||
|
||||
@ -236,6 +240,84 @@ SandboxCreateRTCIdentityProvider(JSContext* cx, JS::HandleObject obj)
|
||||
return JS_DefineProperty(cx, obj, "rtcIdentityProvider", wrapped, JSPROP_ENUMERATE);
|
||||
}
|
||||
|
||||
static bool
|
||||
SetFetchRequestFromValue(JSContext *cx, RequestOrUSVString& request,
|
||||
const MutableHandleValue& requestOrUrl)
|
||||
{
|
||||
RequestOrUSVStringArgument requestHolder(request);
|
||||
bool noMatch = true;
|
||||
if (requestOrUrl.isObject() &&
|
||||
!requestHolder.TrySetToRequest(cx, requestOrUrl, noMatch, false)) {
|
||||
return false;
|
||||
}
|
||||
if (noMatch &&
|
||||
!requestHolder.TrySetToUSVString(cx, requestOrUrl, noMatch)) {
|
||||
return false;
|
||||
}
|
||||
if (noMatch) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
SandboxFetch(JSContext* cx, JS::HandleObject scope, const CallArgs& args)
|
||||
{
|
||||
if (args.length() < 1) {
|
||||
JS_ReportError(cx, "fetch requires at least 1 argument");
|
||||
return false;
|
||||
}
|
||||
|
||||
RequestOrUSVString request;
|
||||
if (!SetFetchRequestFromValue(cx, request, args[0])) {
|
||||
JS_ReportError(cx, "fetch requires a string or Request in argument 1");
|
||||
return false;
|
||||
}
|
||||
RootedDictionary<dom::RequestInit> options(cx);
|
||||
if (!options.Init(cx, args.hasDefined(1) ? args[1] : JS::NullHandleValue,
|
||||
"Argument 2 of fetch", false)) {
|
||||
return false;
|
||||
}
|
||||
nsCOMPtr<nsIGlobalObject> global = xpc::NativeGlobal(scope);
|
||||
if (!global) {
|
||||
return false;
|
||||
}
|
||||
ErrorResult rv;
|
||||
nsRefPtr<dom::Promise> response =
|
||||
FetchRequest(global, Constify(request), Constify(options), rv);
|
||||
rv.WouldReportJSException();
|
||||
if (rv.Failed()) {
|
||||
return ThrowMethodFailedWithDetails(cx, rv, "Sandbox", "fetch");
|
||||
}
|
||||
if (!GetOrCreateDOMReflector(cx, scope, response, args.rval())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool SandboxFetchPromise(JSContext* cx, unsigned argc, jsval* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
RootedObject callee(cx, &args.callee());
|
||||
RootedObject scope(cx, JS::CurrentGlobalOrNull(cx));
|
||||
if (SandboxFetch(cx, scope, args)) {
|
||||
return true;
|
||||
}
|
||||
return ConvertExceptionToPromise(cx, scope, args.rval());
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
SandboxCreateFetch(JSContext* cx, HandleObject obj)
|
||||
{
|
||||
MOZ_ASSERT(JS_IsGlobalObject(obj));
|
||||
|
||||
return JS_DefineFunction(cx, obj, "fetch", SandboxFetchPromise, 2, 0) &&
|
||||
dom::RequestBinding::GetConstructorObject(cx, obj) &&
|
||||
dom::ResponseBinding::GetConstructorObject(cx, obj) &&
|
||||
dom::HeadersBinding::GetConstructorObject(cx, obj);
|
||||
}
|
||||
|
||||
static bool
|
||||
SandboxIsProxy(JSContext* cx, unsigned argc, jsval* vp)
|
||||
{
|
||||
@ -818,6 +900,8 @@ xpc::GlobalProperties::Parse(JSContext* cx, JS::HandleObject obj)
|
||||
crypto = true;
|
||||
} else if (!strcmp(name.ptr(), "rtcIdentityProvider")) {
|
||||
rtcIdentityProvider = true;
|
||||
} else if (!strcmp(name.ptr(), "fetch")) {
|
||||
fetch = true;
|
||||
} else {
|
||||
JS_ReportError(cx, "Unknown property name: %s", name.ptr());
|
||||
return false;
|
||||
@ -878,6 +962,9 @@ xpc::GlobalProperties::Define(JSContext* cx, JS::HandleObject obj)
|
||||
if (rtcIdentityProvider && !SandboxCreateRTCIdentityProvider(cx, obj))
|
||||
return false;
|
||||
|
||||
if (fetch && !SandboxCreateFetch(cx, obj))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3400,6 +3400,7 @@ struct GlobalProperties {
|
||||
bool File : 1;
|
||||
bool crypto : 1;
|
||||
bool rtcIdentityProvider : 1;
|
||||
bool fetch : 1;
|
||||
};
|
||||
|
||||
// Infallible.
|
||||
|
@ -105,3 +105,6 @@ skip-if= buildapp == 'mulet'
|
||||
skip-if = (debug == false || os == "android")
|
||||
[test_nac.xhtml]
|
||||
[test_sameOriginPolicy.html]
|
||||
[test_sandbox_fetch.html]
|
||||
support-files =
|
||||
../../../../dom/tests/mochitest/fetch/test_fetch_basic.js
|
||||
|
54
js/xpconnect/tests/mochitest/test_sandbox_fetch.html
Normal file
54
js/xpconnect/tests/mochitest/test_sandbox_fetch.html
Normal file
@ -0,0 +1,54 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Fetch in JS Sandbox</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"></link>
|
||||
<script src="test_fetch_basic.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function testHttpFetch(url) {
|
||||
info('fetch: ' + url);
|
||||
return fetch(new Request(url, { method: 'GET' }))
|
||||
.then(response => {
|
||||
is(response.status, 200, 'Response is 200');
|
||||
is(response.url, url, 'Response URL matches');
|
||||
});
|
||||
}
|
||||
|
||||
function runSandboxTest(testFunc, argString) {
|
||||
is(typeof testFunc, 'function');
|
||||
var resolvePromise;
|
||||
var testPromise = new Promise(r => resolvePromise = r);
|
||||
var finishFuncName = 'finish_' + testFunc.name;
|
||||
SpecialPowers.Cu.exportFunction(_ => resolvePromise(), sb,
|
||||
{ defineAs: finishFuncName });
|
||||
SpecialPowers.Cu.evalInSandbox('(' + testFunc.toSource() + ')' +
|
||||
'(' + argString + ')' +
|
||||
'.then(' + finishFuncName + ');', sb);
|
||||
return testPromise;
|
||||
}
|
||||
|
||||
var origin = 'https://example.com';
|
||||
var properties = ['fetch', 'Blob', 'URL'];
|
||||
var sb = new SpecialPowers.Cu.Sandbox(origin,
|
||||
{ wantGlobalProperties: properties });
|
||||
|
||||
sb.ok = SpecialPowers.Cu.exportFunction(ok, sb);
|
||||
sb.is = SpecialPowers.Cu.exportFunction(is, sb);
|
||||
sb.info = SpecialPowers.Cu.exportFunction(info, sb);
|
||||
|
||||
Promise.resolve()
|
||||
.then(_ => runSandboxTest(testHttpFetch, '"' + origin + window.location.pathname + '"'))
|
||||
.then(_ => runSandboxTest(testAboutURL))
|
||||
.then(_ => runSandboxTest(testDataURL))
|
||||
.then(_ => runSandboxTest(testSameOriginBlobURL))
|
||||
.then(_ => SimpleTest.finish());
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user