Back out bug 386635; it broke restoring sessions in the browser.

This commit is contained in:
jwalden@mit.edu 2007-07-12 12:11:45 -07:00
Родитель 8e8284090f
Коммит db38a1aa8a
3 изменённых файлов: 88 добавлений и 129 удалений

Просмотреть файл

@ -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) {