зеркало из https://github.com/mozilla/gecko-dev.git
Back out bug 386635; it broke restoring sessions in the browser.
This commit is contained in:
Родитель
8e8284090f
Коммит
db38a1aa8a
|
@ -123,7 +123,7 @@ interface nsIXPCComponents_utils_Sandbox : nsISupports
|
|||
/**
|
||||
* interface of Components.utils
|
||||
*/
|
||||
[scriptable, uuid(5ab4708a-ee92-4ab2-a230-9e638d04d3b0)]
|
||||
[scriptable, uuid(da2267f2-d4cc-448f-9d70-1c7fe134d2fe)]
|
||||
interface nsIXPCComponents_Utils : nsISupports
|
||||
{
|
||||
|
||||
|
@ -170,17 +170,6 @@ interface nsIXPCComponents_Utils : nsISupports
|
|||
*/
|
||||
void evalInSandbox(in AString source/*, obj */);
|
||||
|
||||
/*
|
||||
* importIntoSandbox must be called only from JavaScript.
|
||||
*
|
||||
* importIntoSandbox imports a function into a sandbox so that it
|
||||
* appears that the function was originally declared in the sandbox.
|
||||
* The imported function can then do privileged things (e.g. use
|
||||
* Components.classes) and return the result (which must be a
|
||||
* primitive value) to the caller.
|
||||
*/
|
||||
void importIntoSandbox(/* JSObject *aSandbox, JSObject *aFunction,
|
||||
[string aName]*/);
|
||||
|
||||
/*
|
||||
* import is designed to be called from JavaScript only.
|
||||
|
|
|
@ -3008,15 +3008,6 @@ JS_STATIC_DLL_CALLBACK(JSBool)
|
|||
SandboxFunForwarder(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
jsval *rval)
|
||||
{
|
||||
// Iterate through the arguments, converting them to safe JSObject
|
||||
// wrappers, if necessary.
|
||||
for (uintN i = 0; i < argc; ++i) {
|
||||
if (!JSVAL_IS_PRIMITIVE(argv[i]) &&
|
||||
!XPC_SJOW_Construct(cx, nsnull, 1, &argv[i], &argv[i])) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
jsval v;
|
||||
if (!JS_GetReservedSlot(cx, JSVAL_TO_OBJECT(argv[-2]), 0, &v) ||
|
||||
!JS_CallFunctionValue(cx, obj, v, argc, argv, rval)) {
|
||||
|
@ -3025,11 +3016,77 @@ SandboxFunForwarder(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
|
||||
if (JSVAL_IS_PRIMITIVE(*rval))
|
||||
return JS_TRUE; // nothing more to do.
|
||||
|
||||
|
||||
XPCThrower::Throw(NS_ERROR_NOT_IMPLEMENTED, cx);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(JSBool)
|
||||
SandboxImport(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
jsval *rval)
|
||||
{
|
||||
if (argc < 1) {
|
||||
XPCThrower::Throw(NS_ERROR_INVALID_ARG, cx);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JSFunction *fun = JS_ValueToFunction(cx, argv[0]);
|
||||
if (!fun) {
|
||||
XPCThrower::Throw(NS_ERROR_INVALID_ARG, cx);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JSString *funname;
|
||||
if (argc > 1) {
|
||||
// Use the second parameter as the function name.
|
||||
funname = JS_ValueToString(cx, argv[1]);
|
||||
if (!funname)
|
||||
return JS_FALSE;
|
||||
argv[1] = STRING_TO_JSVAL(funname);
|
||||
} else {
|
||||
// Use the actual function name as the name.
|
||||
funname = JS_GetFunctionId(fun);
|
||||
if (!funname) {
|
||||
XPCThrower::Throw(NS_ERROR_INVALID_ARG, cx);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
JSObject *oldfunobj = JS_GetFunctionObject(fun);
|
||||
nsXPConnect *xpc = nsXPConnect::GetXPConnect();
|
||||
|
||||
if (xpc && oldfunobj) {
|
||||
nsIXPCSecurityManager *secman = xpc->GetDefaultSecurityManager();
|
||||
if (secman) {
|
||||
rv = secman->CanAccess(nsIXPCSecurityManager::ACCESS_CALL_METHOD,
|
||||
nsnull, cx, oldfunobj, nsnull, nsnull,
|
||||
STRING_TO_JSVAL(funname), nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
if (rv == NS_ERROR_FAILURE)
|
||||
XPCThrower::Throw(NS_ERROR_XPC_SECURITY_MANAGER_VETO, cx);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JSFunction *newfun = JS_DefineUCFunction(cx, obj,
|
||||
JS_GetStringChars(funname), JS_GetStringLength(funname),
|
||||
SandboxFunForwarder, JS_GetFunctionArity(fun), 0);
|
||||
|
||||
if (!newfun)
|
||||
return JS_FALSE;
|
||||
|
||||
JSObject *newfunobj = JS_GetFunctionObject(newfun);
|
||||
if (!newfunobj)
|
||||
return JS_FALSE;
|
||||
|
||||
// Functions come with two extra reserved slots on them. Use the 0-th slot
|
||||
// to communicate the wrapped function to our forwarder.
|
||||
return JS_SetReservedSlot(cx, newfunobj, 0, argv[0]);
|
||||
}
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(JSBool)
|
||||
sandbox_enumerate(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
|
@ -3062,92 +3119,10 @@ static JSClass SandboxClass = {
|
|||
static JSFunctionSpec SandboxFunctions[] = {
|
||||
{"dump", SandboxDump, 1,0,0},
|
||||
{"debug", SandboxDebug, 1,0,0},
|
||||
{"importFunction", SandboxImport, 1,0,0},
|
||||
{nsnull,nsnull,0,0,0}
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Utils::ImportIntoSandbox()
|
||||
{
|
||||
XPCPerThreadData *tls = XPCPerThreadData::GetData();
|
||||
if (!tls) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
XPCCallContext *cc = tls->GetCallContext();
|
||||
if (!cc || !cc->IsValid() || cc->GetCallerLanguage() != JS_CALLER) {
|
||||
NS_ERROR("Don't use importIntoSandbox from native code");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
JSContext *cx = cc->GetJSContext();
|
||||
|
||||
// get place for return value
|
||||
jsval *rval = cc->GetRetVal();
|
||||
if (!rval) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// get argc and argv and verify arg count
|
||||
PRUint32 argc = cc->GetArgc();
|
||||
jsval *argv = cc->GetArgv();
|
||||
if (argc < 2) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// The first argument is the sandbox object. It is required.
|
||||
if (JSVAL_IS_PRIMITIVE(argv[0])) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
JSObject *sandbox = XPC_SJOW_GetUnsafeObject(cx, JSVAL_TO_OBJECT(argv[0]));
|
||||
if (!sandbox || JS_GET_CLASS(cx, sandbox) != &SandboxClass) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// The second argument is the function.
|
||||
JSFunction *fun = JS_ValueToFunction(cx, argv[1]);
|
||||
if (!fun) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
JSString *funname;
|
||||
if (argc > 2) {
|
||||
// Use the third parameter as the function name.
|
||||
funname = JS_ValueToString(cx, argv[2]);
|
||||
if (!funname) {
|
||||
cc->SetExceptionWasThrown(PR_TRUE);
|
||||
return NS_OK;
|
||||
}
|
||||
argv[2] = STRING_TO_JSVAL(funname);
|
||||
} else {
|
||||
// Use the actual function name as the name.
|
||||
funname = JS_GetFunctionId(fun);
|
||||
if (!funname) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
JSFunction *newfun = JS_DefineUCFunction(cx, sandbox,
|
||||
JS_GetStringChars(funname), JS_GetStringLength(funname),
|
||||
SandboxFunForwarder, JS_GetFunctionArity(fun), 0);
|
||||
|
||||
if (!newfun) {
|
||||
cc->SetExceptionWasThrown(PR_TRUE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
JSObject *newfunobj = JS_GetFunctionObject(newfun);
|
||||
if (!newfunobj) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// Functions come with two extra reserved slots on them. Use the 0-th slot
|
||||
// to communicate the wrapped function to our forwarder.
|
||||
return JS_SetReservedSlot(cx, newfunobj, 0, argv[1])
|
||||
? NS_OK
|
||||
: NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
#endif /* !XPCONNECT_STANDALONE */
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -3240,11 +3215,9 @@ xpc_CreateSandboxObject(JSContext * cx, jsval * vp, nsISupports *prinOrSop)
|
|||
if (NS_FAILED(rv))
|
||||
return NS_ERROR_XPC_UNEXPECTED;
|
||||
|
||||
if (vp) {
|
||||
if (vp)
|
||||
*vp = OBJECT_TO_JSVAL(sandbox);
|
||||
if (!XPC_SJOW_Construct(cx, nsnull, 1, vp, vp))
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
#endif /* !XPCONNECT_STANDALONE */
|
||||
|
@ -3505,9 +3478,7 @@ nsresult
|
|||
xpc_EvalInSandbox(JSContext *cx, JSObject *sandbox, const nsAString& source,
|
||||
const char *filename, PRInt32 lineNo, jsval *rval)
|
||||
{
|
||||
// |sandbox| will be an XPCSafeJSObjectWrapper.
|
||||
sandbox = XPC_SJOW_GetUnsafeObject(cx, sandbox);
|
||||
if (!sandbox || JS_GetClass(cx, sandbox) != &SandboxClass)
|
||||
if (JS_GetClass(cx, sandbox) != &SandboxClass)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsIScriptObjectPrincipal *sop =
|
||||
|
@ -3561,12 +3532,7 @@ xpc_EvalInSandbox(JSContext *cx, JSObject *sandbox, const nsAString& source,
|
|||
AutoJSSuspendRequestWithNoCallContext sus(sandcx->GetJSContext());
|
||||
AutoJSRequestWithNoCallContext cxreq(cx);
|
||||
|
||||
// Wrap the exception in a safe JSObject wrapper if the sandbox had
|
||||
// been wrapped, to prevent evil exceptions from leaking out.
|
||||
if (JSVAL_IS_PRIMITIVE(exn) ||
|
||||
XPC_SJOW_Construct(cx, nsnull, 1, &exn, &exn)) {
|
||||
JS_SetPendingException(cx, exn);
|
||||
}
|
||||
JS_SetPendingException(cx, exn);
|
||||
} else {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -3578,14 +3544,6 @@ xpc_EvalInSandbox(JSContext *cx, JSObject *sandbox, const nsAString& source,
|
|||
|
||||
JSPRINCIPALS_DROP(cx, jsPrincipals);
|
||||
|
||||
// Wrap the return value in an XPCSafeJSObjectWrapper if the
|
||||
// sandbox was originally wrapped.
|
||||
if (NS_SUCCEEDED(rv) &&
|
||||
!JSVAL_IS_PRIMITIVE(*rval) &&
|
||||
!XPC_SJOW_Construct(cx, nsnull, 1, rval, rval)) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif /* !XPCONNECT_STANDALONE */
|
||||
|
|
|
@ -78,12 +78,17 @@ nsProxyAutoConfig.prototype = {
|
|||
Components.utils.evalInSandbox(pacUtils, this._sandBox);
|
||||
|
||||
// add predefined functions to pac
|
||||
Components.utils.importIntoSandbox(this._sandBox, myIpAddress);
|
||||
Components.utils.importIntoSandbox(this._sandBox, dnsResolve);
|
||||
Components.utils.importIntoSandbox(this._sandBox, proxyAlert, "alert");
|
||||
this._sandBox.importFunction(myIpAddress);
|
||||
this._sandBox.importFunction(dnsResolve);
|
||||
this._sandBox.importFunction(proxyAlert, "alert");
|
||||
|
||||
// evaluate loaded js file
|
||||
Components.utils.evalInSandbox(pacText, this._sandBox);
|
||||
|
||||
// We can no longer trust this._sandBox. Touching it directly can
|
||||
// cause all sorts of pain, so wrap it in an XPCSafeJSObjectWrapper
|
||||
// and do all of our work through there.
|
||||
this._sandBox = new XPCSafeJSObjectWrapper(this._sandBox);
|
||||
},
|
||||
|
||||
getProxyForURI: function(testURI, testHost) {
|
||||
|
@ -97,6 +102,10 @@ nsProxyAutoConfig.prototype = {
|
|||
}
|
||||
|
||||
function proxyAlert(msg) {
|
||||
// Ensure that we have a string.
|
||||
if (typeof msg != "string")
|
||||
msg = new XPCSafeJSObjectWrapper(msg).toString();
|
||||
|
||||
try {
|
||||
// It would appear that the console service is threadsafe.
|
||||
var cns = Components.classes["@mozilla.org/consoleservice;1"]
|
||||
|
@ -118,6 +127,9 @@ function myIpAddress() {
|
|||
|
||||
// wrapper for resolving hostnames called by PAC file
|
||||
function dnsResolve(host) {
|
||||
if (typeof host != "string")
|
||||
host = new XPCSafeJSObjectWrapper(host).toString();
|
||||
|
||||
try {
|
||||
return dns.resolve(host, 0).getNextAddrAsString();
|
||||
} catch (e) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче