JSTrapStatus ScriptDebugPrologue(JSContext *cx, StackFrame *fp) { JS_ASSERT(fp == cx->fp()); if (fp->isFramePushedByExecute()) { if (JSInterpreterHook hook = cx->debugHooks->executeHook) fp->setHookData(hook(cx, Jsvalify(fp), true, 0, cx->debugHooks->executeHookData)); } else { if (JSInterpreterHook hook = cx->debugHooks->callHook) fp->setHookData(hook(cx, Jsvalify(fp), true, 0, cx->debugHooks->callHookData)); } Value rval; JSTrapStatus status = Debugger::onEnterFrame(cx, &rval); switch (status) { case JSTRAP_CONTINUE: break; case JSTRAP_THROW: cx->setPendingException(rval); break; case JSTRAP_ERROR: cx->clearPendingException(); break; case JSTRAP_RETURN: fp->setReturnValue(rval); break; default: JS_NOT_REACHED("bad Debugger::onEnterFrame JSTrapStatus value"); } return status; }
JSObject* newKey() { static const js::Class keyClass = { "keyWithDelgate", JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(1), nullptr, /* addProperty */ nullptr, /* delProperty */ nullptr, /* getProperty */ nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ nullptr, /* mayResolve */ nullptr, /* finalize */ nullptr, /* call */ nullptr, /* hasInstance */ nullptr, /* construct */ nullptr, /* trace */ JS_NULL_CLASS_SPEC, { nullptr, nullptr, false, GetKeyDelegate }, JS_NULL_OBJECT_OPS }; JS::RootedObject key(cx, JS_NewObject(cx, Jsvalify(&keyClass))); if (!key) return nullptr; return key; }
static bool IterClassConstructor(JSContext *cx, unsigned argc, jsval *vp) { JSObject *obj = JS_NewObjectForConstructor(cx, Jsvalify(&HasCustomIterClass), vp); if (!obj) return false; JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj)); return true; }
bool ScriptDebugEpilogue(JSContext *cx, StackFrame *fp, bool okArg) { JS_ASSERT(fp == cx->fp()); JSBool ok = okArg; if (void *hookData = fp->maybeHookData()) { if (fp->isFramePushedByExecute()) { if (JSInterpreterHook hook = cx->runtime->debugHooks.executeHook) hook(cx, Jsvalify(fp), false, &ok, hookData); } else { if (JSInterpreterHook hook = cx->runtime->debugHooks.callHook) hook(cx, Jsvalify(fp), false, &ok, hookData); } } return Debugger::onLeaveFrame(cx, ok); }
CrossOriginObjectType IdentifyCrossOriginObject(JSObject* obj) { obj = js::UncheckedUnwrap(obj, /* stopAtOuter = */ false); const js::Class* clasp = js::GetObjectClass(obj); MOZ_ASSERT(!XrayUtils::IsXPCWNHolderClass(Jsvalify(clasp)), "shouldn't have a holder here"); if (clasp->name[0] == 'L' && !strcmp(clasp->name, "Location")) return CrossOriginLocation; if (clasp->name[0] == 'W' && !strcmp(clasp->name, "Window")) return CrossOriginWindow; return CrossOriginOpaque; }
JSObject* newDelegate() { static const js::Class delegateClass = { "delegate", JSCLASS_GLOBAL_FLAGS | JSCLASS_HAS_RESERVED_SLOTS(1), nullptr, /* addProperty */ nullptr, /* delProperty */ nullptr, /* getProperty */ nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ nullptr, /* mayResolve */ nullptr, /* convert */ nullptr, /* finalize */ nullptr, /* call */ nullptr, /* hasInstance */ nullptr, /* construct */ JS_GlobalObjectTraceHook, JS_NULL_CLASS_SPEC, { nullptr, nullptr, false, nullptr, DelegateObjectMoved }, JS_NULL_OBJECT_OPS }; /* Create the global object. */ JS::CompartmentOptions options; options.setVersion(JSVERSION_LATEST); JS::RootedObject global(cx); global = JS_NewGlobalObject(cx, Jsvalify(&delegateClass), nullptr, JS::FireOnNewGlobalHook, options); JS_SetReservedSlot(global, 0, JS::Int32Value(42)); return global; }
bool AccessCheck::isCrossOriginAccessPermitted(JSContext *cx, HandleObject wrapper, HandleId id, Wrapper::Action act) { if (act == Wrapper::CALL) return false; if (act == Wrapper::ENUMERATE) return true; // For the case of getting a property descriptor, we allow if either GET or SET // is allowed, and rely on FilteringWrapper to filter out any disallowed accessors. if (act == Wrapper::GET_PROPERTY_DESCRIPTOR) { return isCrossOriginAccessPermitted(cx, wrapper, id, Wrapper::GET) || isCrossOriginAccessPermitted(cx, wrapper, id, Wrapper::SET); } RootedObject obj(cx, Wrapper::wrappedObject(wrapper)); const char *name; const js::Class *clasp = js::GetObjectClass(obj); MOZ_ASSERT(!XrayUtils::IsXPCWNHolderClass(Jsvalify(clasp)), "shouldn't have a holder here"); if (clasp->ext.innerObject) name = "Window"; else name = clasp->name; if (JSID_IS_STRING(id)) { if (IsPermitted(name, JSID_TO_FLAT_STRING(id), act == Wrapper::SET)) return true; } if (act != Wrapper::GET) return false; // Check for frame IDs. If we're resolving named frames, make sure to only // resolve ones that don't shadow native properties. See bug 860494. if (IsWindow(name)) { if (JSID_IS_STRING(id) && !XrayUtils::IsXrayResolving(cx, wrapper, id)) { bool wouldShadow = false; if (!XrayUtils::HasNativeProperty(cx, wrapper, id, &wouldShadow) || wouldShadow) { // If the named subframe matches the name of a DOM constructor, // the global resolve triggered by the HasNativeProperty call // above will try to perform a CheckedUnwrap on |wrapper|, and // throw a security error if it fails. That exception isn't // really useful for our callers, so we silence it and just // deny access to the property (since it matched a builtin). // // Note that this would be a problem if the resolve code ever // tried to CheckedUnwrap the wrapper _before_ concluding that // the name corresponds to a builtin global property, since it // would mean that we'd never permit cross-origin named subframe // access (something we regrettably need to support). JS_ClearPendingException(cx); return false; } } return IsFrameId(cx, obj, id); } return false; }