Bug 949940. Only enter the uncheckedObj compartment in a crossOriginGetter/Setter/Method around the UnwrapArg call that needs us to be in that compartment. r=peterv

This commit is contained in:
Boris Zbarsky 2013-12-17 17:09:05 -05:00
Родитель 82fad7a97f
Коммит b1af932dc3
3 изменённых файлов: 43 добавлений и 14 удалений

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

@ -2595,17 +2595,36 @@ class CastableObjectUnwrapper():
If isCallbackReturnValue is "JSImpl" and our descriptor is also
JS-implemented, fall back to just creating the right object if what we
have isn't one already.
If allowCrossOriginObj is True, then we'll first do an
UncheckedUnwrap and then operate on the result.
"""
def __init__(self, descriptor, source, target, codeOnFailure,
exceptionCode=None, isCallbackReturnValue=False):
exceptionCode=None, isCallbackReturnValue=False,
allowCrossOriginObj=False):
if not exceptionCode:
exceptionCode = codeOnFailure
self.substitution = { "type" : descriptor.nativeType,
"protoID" : "prototypes::id::" + descriptor.name,
"source" : source,
"target" : target,
"codeOnFailure" : CGIndenter(CGGeneric(codeOnFailure)).define(),
"exceptionCode" : CGIndenter(CGGeneric(exceptionCode), 4).define() }
if allowCrossOriginObj:
self.substitution["uncheckedObjDecl"] = (
"\n JS::Rooted<JSObject*> uncheckedObj(cx, js::UncheckedUnwrap(%s));" % source)
self.substitution["source"] = "uncheckedObj"
xpconnectUnwrap = (
"nsresult rv;\n"
"{ // Scope for the JSAutoCompartment, because we only\n"
" // want to be in that compartment for the UnwrapArg call.\n"
" JSAutoCompartment ac(cx, ${source});\n"
" rv = UnwrapArg<${type}>(cx, val, &objPtr, &objRef.ptr, &val);\n"
"}\n")
else:
self.substitution["uncheckedObjDecl"] = ""
self.substitution["source"] = source
xpconnectUnwrap = "nsresult rv = UnwrapArg<${type}>(cx, val, &objPtr, &objRef.ptr, &val);\n"
if descriptor.hasXPConnectImpls:
# We don't use xpc_qsUnwrapThis because it will always throw on
# unwrap failure, whereas we want to control whether we throw or
@ -2613,8 +2632,8 @@ class CastableObjectUnwrapper():
self.substitution["codeOnFailure"] = CGIndenter(CGGeneric(string.Template(
"${type} *objPtr;\n"
"SelfRef objRef;\n"
"JS::Rooted<JS::Value> val(cx, JS::ObjectValue(*${source}));\n"
"nsresult rv = UnwrapArg<${type}>(cx, val, &objPtr, &objRef.ptr, &val);\n"
"JS::Rooted<JS::Value> val(cx, JS::ObjectValue(*${source}));\n" +
xpconnectUnwrap +
"if (NS_FAILED(rv)) {\n"
"${codeOnFailure}\n"
"}\n"
@ -2647,7 +2666,7 @@ class CastableObjectUnwrapper():
def __str__(self):
codeOnFailure = self.substitution["codeOnFailure"] % {'securityError': 'rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO'}
return string.Template(
"""{
"""{${uncheckedObjDecl}
nsresult rv = UnwrapObject<${protoID}, ${type}>(${source}, ${target});
if (NS_FAILED(rv)) {
${codeOnFailure}
@ -5752,18 +5771,11 @@ class CGAbstractBindingMethod(CGAbstractStaticMethod):
CGGeneric("%s* self;" % self.descriptor.nativeType)
], "\n")
objName = "uncheckedObj" if self.allowCrossOriginThis else "obj"
unwrapThis = CGGeneric(
str(CastableObjectUnwrapper(
self.descriptor,
objName, "self", self.unwrapFailureCode)))
if self.allowCrossOriginThis:
unwrapThis = CGWrapper(
CGIndenter(unwrapThis),
pre=("{ // Scope for the uncheckedObj JSAutoCompartment\n"
" JS::Rooted<JSObject*> uncheckedObj(cx, js::UncheckedUnwrap(obj));\n"
" JSAutoCompartment ac(cx, uncheckedObj);\n"),
post="\n}")
"obj", "self", self.unwrapFailureCode,
allowCrossOriginObj=self.allowCrossOriginThis)))
return CGList([ CGIndenter(getThis), CGIndenter(unwrapThis),
self.generate_code() ], "\n").define()

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

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script>
function boom()
{
var frameWin = document.getElementById("f").contentWindow;
Object.create(frameWin).self;
}
</script>
</head>
<body onload="boom()">
<iframe id="f" src="data:text/html,3"></iframe>
</body>
</html>

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

@ -7,3 +7,4 @@ load 860551.html
load 862610.html
load 862092.html
load 869038.html
load 949940.html