Example #1
0
static bool
IsVectorObject(HandleValue v)
{
    if (!v.isObject())
        return false;

    JSObject &obj = v.toObject();
    if (!obj.is<TypedObject>())
        return false;

    TypeDescr &typeRepr = obj.as<TypedObject>().typeDescr();
    if (typeRepr.kind() != TypeDescr::X4)
        return false;

    return typeRepr.as<X4TypeDescr>().type() == V::type;
}
bool
JS::detail::CallMethodIfWrapped(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
                                const CallArgs& args)
{
    HandleValue thisv = args.thisv();
    MOZ_ASSERT(!test(thisv));

    if (thisv.isObject()) {
        JSObject& thisObj = args.thisv().toObject();
        if (thisObj.is<ProxyObject>())
            return Proxy::nativeCall(cx, test, impl, args);
    }

    ReportIncompatible(cx, args);
    return false;
}
Example #3
0
static Elem
TypedObjectMemory(HandleValue v)
{
    TypedObject &obj = v.toObject().as<TypedObject>();
    MOZ_ASSERT(!obj.owner().isNeutered());
    return reinterpret_cast<Elem>(obj.typedMem());
}
Example #4
0
static bool
CheckVectorObject(HandleValue v, X4TypeDescr::Type expectedType)
{
    if (!v.isObject())
        return false;

    JSObject &obj = v.toObject();
    if (!obj.is<TypedObject>())
        return false;

    TypeDescr &typeRepr = obj.as<TypedObject>().typeDescr();
    if (typeRepr.kind() != type::X4)
        return false;

    return typeRepr.as<X4TypeDescr>().type() == expectedType;
}
Example #5
0
/*
 * ES6 21.2.3.2.2.  Because this function only ever returns |obj| in the spec,
 * provided by the user, we omit it and just return the usual success/failure.
 */
static bool
RegExpInitialize(JSContext* cx, Handle<RegExpObject*> obj, HandleValue patternValue,
                 HandleValue flagsValue, RegExpStaticsUse staticsUse)
{
    RootedAtom pattern(cx);
    if (patternValue.isUndefined()) {
        /* Step 1. */
        pattern = cx->runtime()->emptyString;
    } else {
        /* Steps 2-3. */
        pattern = ToAtom<CanGC>(cx, patternValue);
        if (!pattern)
            return false;
    }

    /* Step 4. */
    RegExpFlag flags = RegExpFlag(0);
    if (!flagsValue.isUndefined()) {
        /* Steps 5-6. */
        RootedString flagStr(cx, ToString<CanGC>(cx, flagsValue));
        if (!flagStr)
            return false;
        /* Step 7. */
        if (!ParseRegExpFlags(cx, flagStr, &flags))
            return false;
    }

    /* Steps 9-10. */
    CompileOptions options(cx);
    frontend::TokenStream dummyTokenStream(cx, options, nullptr, 0, nullptr);
    if (!irregexp::ParsePatternSyntax(dummyTokenStream, cx->tempLifoAlloc(), pattern))
        return false;

    if (staticsUse == UseRegExpStatics) {
        RegExpStatics* res = cx->global()->getRegExpStatics(cx);
        if (!res)
            return false;
        flags = RegExpFlag(flags | res->getFlags());
    }

    /* Steps 11-15. */
    if (!RegExpObject::initFromAtom(cx, obj, pattern, flags))
        return false;

    /* Step 16. */
    return true;
}
Example #6
0
NS_IMETHODIMP
nsJSIID::HasInstance(nsIXPConnectWrappedNative* wrapper,
                     JSContext* cx, JSObject * /* unused */,
                     HandleValue val, bool* bp, bool* _retval)
{
    *bp = false;

    if (val.isPrimitive())
        return NS_OK;

    // we have a JSObject
    RootedObject obj(cx, &val.toObject());

    const nsIID* iid;
    mInfo->GetIIDShared(&iid);
    return xpc::HasInstance(cx, obj, iid, bp);
}
Example #7
0
MOZ_ALWAYS_INLINE bool
bool_toSource_impl(JSContext *cx, CallArgs args)
{
    HandleValue thisv = args.thisv();
    JS_ASSERT(IsBoolean(thisv));

    bool b = thisv.isBoolean() ? thisv.toBoolean() : thisv.toObject().as<BooleanObject>().unbox();

    StringBuffer sb(cx);
    if (!sb.append("(new Boolean(") || !BooleanToStringBuffer(b, sb) || !sb.append("))"))
        return false;

    JSString *str = sb.finishString();
    if (!str)
        return false;
    args.rval().setString(str);
    return true;
}
Example #8
0
bool
AccessCheck::checkPassToPrivilegedCode(JSContext* cx, HandleObject wrapper, HandleValue v)
{
    // Primitives are fine.
    if (!v.isObject())
        return true;
    RootedObject obj(cx, &v.toObject());

    // Non-wrappers are fine.
    if (!js::IsWrapper(obj))
        return true;

    // CPOWs use COWs (in the unprivileged junk scope) for all child->parent
    // references. Without this test, the child process wouldn't be able to
    // pass any objects at all to CPOWs.
    if (mozilla::jsipc::IsWrappedCPOW(obj) &&
        js::GetObjectCompartment(wrapper) == js::GetObjectCompartment(xpc::UnprivilegedJunkScope()) &&
        XRE_IsParentProcess())
    {
        return true;
    }

    // COWs are fine to pass to chrome if and only if they have __exposedProps__,
    // since presumably content should never have a reason to pass an opaque
    // object back to chrome.
    if (AccessCheck::isChrome(js::UncheckedUnwrap(wrapper)) && WrapperFactory::IsCOW(obj)) {
        RootedObject target(cx, js::UncheckedUnwrap(obj));
        JSAutoCompartment ac(cx, target);
        RootedId id(cx, GetRTIdByIndex(cx, XPCJSRuntime::IDX_EXPOSEDPROPS));
        bool found = false;
        if (!JS_HasPropertyById(cx, target, id, &found))
            return false;
        if (found)
            return true;
    }

    // Same-origin wrappers are fine.
    if (AccessCheck::wrapperSubsumes(obj))
        return true;

    // Badness.
    JS_ReportError(cx, "Permission denied to pass object to privileged code");
    return false;
}
static bool
ProtoGetterImpl(JSContext *cx, CallArgs args)
{
    JS_ASSERT(TestProtoGetterThis(args.thisv()));

    HandleValue thisv = args.thisv();
    if (thisv.isPrimitive() && !BoxNonStrictThis(cx, args))
        return false;

    unsigned dummy;
    RootedObject obj(cx, &args.thisv().toObject());
    RootedId nid(cx, NameToId(cx->names().proto));
    RootedValue v(cx);
    if (!CheckAccess(cx, obj, nid, JSACC_PROTO, &v, &dummy))
        return false;

    args.rval().set(v);
    return true;
}
Example #10
0
static bool
ProtoGetter(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    HandleValue thisv = args.thisv();
    if (thisv.isNullOrUndefined()) {
        ReportIncompatible(cx, args);
        return false;
    }
    if (thisv.isPrimitive() && !BoxNonStrictThis(cx, args))
        return false;

    RootedObject obj(cx, &args.thisv().toObject());
    RootedObject proto(cx);
    if (!GetPrototype(cx, obj, &proto))
        return false;
    args.rval().setObjectOrNull(proto);
    return true;
}
Example #11
0
bool
CreateObjectIn(JSContext *cx, HandleValue vobj, CreateObjectInOptions &options,
               MutableHandleValue rval)
{
    if (!vobj.isObject()) {
        JS_ReportError(cx, "Expected an object as the target scope");
        return false;
    }

    RootedObject scope(cx, js::CheckedUnwrap(&vobj.toObject()));
    if (!scope) {
        JS_ReportError(cx, "Permission denied to create object in the target scope");
        return false;
    }

    bool define = !JSID_IS_VOID(options.defineAs);

    if (define && js::IsScriptedProxy(scope)) {
        JS_ReportError(cx, "Defining property on proxy object is not allowed");
        return false;
    }

    RootedObject obj(cx);
    {
        JSAutoCompartment ac(cx, scope);
        obj = JS_NewObject(cx, nullptr, JS::NullPtr(), scope);
        if (!obj)
            return false;

        if (define) {
            if (!JS_DefinePropertyById(cx, scope, options.defineAs, obj, JSPROP_ENUMERATE,
                                       JS_PropertyStub, JS_StrictPropertyStub))
                return false;
        }
    }

    rval.setObject(*obj);
    if (!WrapperFactory::WaiveXrayAndWrap(cx, rval))
        return false;

    return true;
}
Example #12
0
bool
WrapperOwner::DOMQI(JSContext* cx, JS::HandleObject proxy, JS::CallArgs& args)
{
    // Someone's calling us, handle nsISupports specially to avoid unnecessary
    // CPOW traffic.
    HandleValue id = args[0];
    if (id.isObject()) {
        RootedObject idobj(cx, &id.toObject());
        nsCOMPtr<nsIJSID> jsid;

        nsresult rv = UnwrapArg<nsIJSID>(cx, idobj, getter_AddRefs(jsid));
        if (NS_SUCCEEDED(rv)) {
            MOZ_ASSERT(jsid, "bad wrapJS");
            const nsID* idptr = jsid->GetID();
            if (idptr->Equals(NS_GET_IID(nsISupports))) {
                args.rval().set(args.thisv());
                return true;
            }

            // Webidl-implemented DOM objects never have nsIClassInfo.
            if (idptr->Equals(NS_GET_IID(nsIClassInfo)))
                return Throw(cx, NS_ERROR_NO_INTERFACE);
        }
    }

    // It wasn't nsISupports, call into the other process to do the QI for us
    // (since we don't know what other interfaces our object supports). Note
    // that we have to use JS_GetPropertyDescriptor here to avoid infinite
    // recursion back into CPOWDOMQI via WrapperOwner::get().
    // We could stash the actual QI function on our own function object to avoid
    // if we're called multiple times, but since we're transient, there's no
    // point right now.
    JS::Rooted<PropertyDescriptor> propDesc(cx);
    if (!JS_GetPropertyDescriptor(cx, proxy, "QueryInterface", &propDesc))
        return false;

    if (!propDesc.value().isObject()) {
        MOZ_ASSERT_UNREACHABLE("We didn't get QueryInterface off a node");
        return Throw(cx, NS_ERROR_UNEXPECTED);
    }
    return JS_CallFunctionValue(cx, proxy, propDesc.value(), args, args.rval());
}
Example #13
0
static bool
ProtoSetter(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    // Do this here, rather than after the this-check so even likely-buggy
    // use of the __proto__ setter on unacceptable values, where no subsequent
    // use occurs on an acceptable value, will trigger a warning.
    RootedObject callee(cx, &args.callee());
    if (!GlobalObject::warnOnceAboutPrototypeMutation(cx, callee))
       return false;

    HandleValue thisv = args.thisv();
    if (thisv.isNullOrUndefined()) {
        ReportIncompatible(cx, args);
        return false;
    }
    if (thisv.isPrimitive()) {
        // Mutating a boxed primitive's [[Prototype]] has no side effects.
        args.rval().setUndefined();
        return true;
    }

    if (!cx->runningWithTrustedPrincipals())
        ++sSetProtoCalled;

    Rooted<JSObject*> obj(cx, &args.thisv().toObject());

    /* Do nothing if __proto__ isn't being set to an object or null. */
    if (args.length() == 0 || !args[0].isObjectOrNull()) {
        args.rval().setUndefined();
        return true;
    }

    Rooted<JSObject*> newProto(cx, args[0].toObjectOrNull());
    if (!SetPrototype(cx, obj, newProto))
        return false;

    args.rval().setUndefined();
    return true;
}
Example #14
0
bool
js::ToSimdConstant(JSContext* cx, HandleValue v, jit::SimdConstant* out)
{
    typedef typename V::Elem Elem;
    Rooted<TypeDescr*> typeDescr(cx, &V::GetTypeDescr(*cx->global()));
    if (!IsVectorObject<V>(v))
        return ErrorWrongTypeArg(cx, 1, typeDescr);

    Elem* mem = reinterpret_cast<Elem*>(v.toObject().as<TypedObject>().typedMem());
    *out = jit::SimdConstant::CreateX4(mem);
    return true;
}
Example #15
0
static bool
GetDataProperty(JSContext *cx, HandleValue objVal, HandlePropertyName field, MutableHandleValue v)
{
    if (!objVal.isObject())
        return LinkFail(cx, "accessing property of non-object");

    Rooted<JSPropertyDescriptor> desc(cx);
    RootedObject obj(cx, &objVal.toObject());
    RootedId id(cx, NameToId(field));
    if (!JS_GetPropertyDescriptorById(cx, obj, id, 0, &desc))
        return false;

    if (!desc.object())
        return LinkFail(cx, "property not present on object");

    if (desc.hasGetterOrSetterObject())
        return LinkFail(cx, "property is not a data property");

    v.set(desc.value());
    return true;
}
Example #16
0
// ES6 rev 25 (2014 May 22) 19.4.2.7
bool
SymbolObject::keyFor(JSContext *cx, unsigned argc, Value *vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    // step 1
    HandleValue arg = args.get(0);
    if (!arg.isSymbol()) {
        js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK,
                                 arg, js::NullPtr(), "not a symbol", nullptr);
        return false;
    }

    // step 2
    if (arg.toSymbol()->code() == JS::SymbolCode::InSymbolRegistry) {
#ifdef DEBUG
        RootedString desc(cx, arg.toSymbol()->description());
        MOZ_ASSERT(Symbol::for_(cx, desc) == arg.toSymbol());
#endif
        args.rval().setString(arg.toSymbol()->description());
        return true;
    }

    // step 3: omitted
    // step 4
    args.rval().setUndefined();
    return true;
}
Example #17
0
MOZ_ALWAYS_INLINE bool
Proxy::setInternal(JSContext* cx, HandleObject proxy, HandleId id, HandleValue v,
                   HandleValue receiver, ObjectOpResult& result)
{
    MOZ_ASSERT_IF(receiver.isObject(), !IsWindow(&receiver.toObject()));

    if (!CheckRecursionLimit(cx))
        return false;
    const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();
    AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::SET, true);
    if (!policy.allowed()) {
        if (!policy.returnValue())
            return false;
        return result.succeed();
    }

    // Special case. See the comment on BaseProxyHandler::mHasPrototype.
    if (handler->hasPrototype())
        return handler->BaseProxyHandler::set(cx, proxy, id, v, receiver, result);

    return handler->set(cx, proxy, id, v, receiver, result);
}
Example #18
0
bool
xpc_qsJsvalToCharStr(JSContext *cx, HandleValue v, JSAutoByteString *bytes)
{
    MOZ_ASSERT(!bytes->ptr());

    if (v.isNullOrUndefined())
      return true;

    JSString *str = ToString(cx, v);
    if (!str)
      return false;
    return !!bytes->encodeLatin1(cx, str);
}
bool
js::GeneratorThrowOrClose(JSContext* cx, AbstractFramePtr frame, Handle<GeneratorObject*> genObj,
                          HandleValue arg, uint32_t resumeKind)
{
    if (resumeKind == GeneratorObject::THROW) {
        cx->setPendingException(arg);
        genObj->setRunning();
    } else {
        MOZ_ASSERT(resumeKind == GeneratorObject::CLOSE);

        if (genObj->is<StarGeneratorObject>()) {
            MOZ_ASSERT(arg.isObject());
            frame.setReturnValue(arg);
        } else {
            MOZ_ASSERT(arg.isUndefined());
        }

        cx->setPendingException(MagicValue(JS_GENERATOR_CLOSING));
        genObj->setClosing();
    }
    return false;
}
Example #20
0
static bool
ProtoSetterImpl(JSContext *cx, CallArgs args)
{
    JS_ASSERT(TestProtoThis(args.thisv()));

    HandleValue thisv = args.thisv();
    if (thisv.isPrimitive()) {
        JS_ASSERT(!thisv.isNullOrUndefined());

        // Mutating a boxed primitive's [[Prototype]] has no side effects.
        args.rval().setUndefined();
        return true;
    }

    if (!cx->runningWithTrustedPrincipals())
        ++sSetProtoCalled;

    Rooted<JSObject*> obj(cx, &args.thisv().toObject());

    /* Do nothing if __proto__ isn't being set to an object or null. */
    if (args.length() == 0 || !args[0].isObjectOrNull()) {
        args.rval().setUndefined();
        return true;
    }

    Rooted<JSObject*> newProto(cx, args[0].toObjectOrNull());

    bool success;
    if (!JSObject::setProto(cx, obj, newProto, &success))
        return false;

    if (!success) {
        js_ReportValueError(cx, JSMSG_SETPROTOTYPEOF_FAIL, JSDVG_IGNORE_STACK, thisv, js::NullPtr());
        return false;
    }

    args.rval().setUndefined();
    return true;
}
Example #21
0
bool
js::ToSimdConstant(JSContext *cx, HandleValue v, jit::SimdConstant *out)
{
    typedef typename V::Elem Elem;
    if (!IsVectorObject<V>(v)) {
        JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_SIMD_NOT_A_VECTOR);
        return false;
    }

    Elem *mem = reinterpret_cast<Elem *>(v.toObject().as<TypedObject>().typedMem());
    *out = jit::SimdConstant::CreateX4(mem);
    return true;
}
Example #22
0
static bool
HasPureCoercion(JSContext *cx, HandleValue v)
{
    if (IsVectorObject<Int32x4>(v) || IsVectorObject<Float32x4>(v))
        return true;

    // Ideally, we'd reject all non-SIMD non-primitives, but Emscripten has a
    // bug that generates code that passes functions for some imports. To avoid
    // breaking all the code that contains this bug, we make an exception for
    // functions that don't have user-defined valueOf or toString, for their
    // coercions are not observable and coercion via ToNumber/ToInt32
    // definitely produces NaN/0. We should remove this special case later once
    // most apps have been built with newer Emscripten.
    jsid toString = NameToId(cx->names().toString);
    if (v.toObject().is<JSFunction>() &&
            HasObjectValueOf(&v.toObject(), cx) &&
            ClassMethodIsNative(cx, &v.toObject().as<JSFunction>(), &JSFunction::class_, toString, fun_toString))
    {
        return true;
    }

    return false;
}
Example #23
0
static MOZ_ALWAYS_INLINE bool
SetWeakMapEntryInternal(JSContext* cx, Handle<WeakMapObject*> mapObj,
                        HandleObject key, HandleValue value)
{
    ObjectValueMap* map = mapObj->getMap();
    if (!map) {
        AutoInitGCManagedObject<ObjectValueMap> newMap(
            cx->make_unique<ObjectValueMap>(cx, mapObj.get()));
        if (!newMap)
            return false;
        if (!newMap->init()) {
            JS_ReportOutOfMemory(cx);
            return false;
        }
        map = newMap.release();
        mapObj->setPrivate(map);
    }

    // Preserve wrapped native keys to prevent wrapper optimization.
    if (!TryPreserveReflector(cx, key))
        return false;

    if (JSWeakmapKeyDelegateOp op = key->getClass()->ext.weakmapKeyDelegateOp) {
        RootedObject delegate(cx, op(key));
        if (delegate && !TryPreserveReflector(cx, delegate))
            return false;
    }

    MOZ_ASSERT(key->compartment() == mapObj->compartment());
    MOZ_ASSERT_IF(value.isObject(), value.toObject().compartment() == mapObj->compartment());
    if (!map->put(key, value)) {
        JS_ReportOutOfMemory(cx);
        return false;
    }
    WeakMapPostWriteBarrier(cx->runtime(), map, key.get());
    return true;
}
Example #24
0
static bool
ReadCustomFloat32NaNObject(JSContext* cx, HandleValue v, float* ret)
{
    RootedObject obj(cx, &v.toObject());
    RootedValue val(cx);

    int32_t i32;
    if (!JS_GetProperty(cx, obj, "nan_low", &val))
        return false;
    if (!ToInt32(cx, val, &i32))
        return false;

    BitwiseCast(i32, ret);
    return true;
}
Example #25
0
Node::Node(HandleValue value)
{
    if (value.isObject())
        construct(&value.toObject());
    else if (value.isString())
        construct(value.toString());
    else if (value.isSymbol())
        construct(value.toSymbol());
    else
        construct<void>(nullptr);
}
Example #26
0
bool
js::IsSharedArrayBuffer(HandleValue v)
{
    return v.isObject() && v.toObject().is<SharedArrayBufferObject>();
}
Example #27
0
bool
js::DirectEvalStringFromIon(JSContext *cx,
                            HandleObject scopeobj, HandleScript callerScript,
                            HandleValue thisValue, HandleString str,
                            jsbytecode *pc, MutableHandleValue vp)
{
    AssertInnerizedScopeChain(cx, *scopeobj);

    Rooted<GlobalObject*> scopeObjGlobal(cx, &scopeobj->global());
    if (!GlobalObject::isRuntimeCodeGenEnabled(cx, scopeObjGlobal)) {
        JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CSP_BLOCKED_EVAL);
        return false;
    }

    // ES5 15.1.2.1 steps 2-8.

    unsigned staticLevel = callerScript->staticLevel() + 1;

    Rooted<JSFlatString*> flatStr(cx, str->ensureFlat(cx));
    if (!flatStr)
        return false;

    EvalJSONResult ejr = TryEvalJSON(cx, callerScript, flatStr, vp);
    if (ejr != EvalJSON_NotJSON)
        return ejr == EvalJSON_Success;

    EvalScriptGuard esg(cx);

    esg.lookupInEvalCache(flatStr, callerScript, pc);

    if (!esg.foundScript()) {
        RootedScript maybeScript(cx);
        const char *filename;
        unsigned lineno;
        JSPrincipals *originPrincipals;
        uint32_t pcOffset;
        DescribeScriptedCallerForCompilation(cx, &maybeScript, &filename, &lineno, &pcOffset,
                                              &originPrincipals, CALLED_FROM_JSOP_EVAL);

        const char *introducerFilename = filename;
        if (maybeScript && maybeScript->scriptSource()->introducerFilename())
            introducerFilename = maybeScript->scriptSource()->introducerFilename();

        CompileOptions options(cx);
        options.setFileAndLine(filename, 1)
               .setCompileAndGo(true)
               .setForEval(true)
               .setNoScriptRval(false)
               .setOriginPrincipals(originPrincipals)
               .setIntroductionInfo(introducerFilename, "eval", lineno, maybeScript, pcOffset);

        AutoStableStringChars flatChars(cx);
        if (!flatChars.initTwoByte(cx, flatStr))
            return false;

        const char16_t *chars = flatChars.twoByteRange().start().get();
        SourceBufferHolder::Ownership ownership = flatChars.maybeGiveOwnershipToCaller()
                                                  ? SourceBufferHolder::GiveOwnership
                                                  : SourceBufferHolder::NoOwnership;
        SourceBufferHolder srcBuf(chars, flatStr->length(), ownership);
        JSScript *compiled = frontend::CompileScript(cx, &cx->tempLifoAlloc(),
                                                     scopeobj, callerScript, options,
                                                     srcBuf, flatStr, staticLevel);
        if (!compiled)
            return false;

        esg.setNewScript(compiled);
    }

    // Primitive 'this' values should have been filtered out by Ion. If boxed,
    // the calling frame cannot be updated to store the new object.
    JS_ASSERT(thisValue.isObject() || thisValue.isUndefined() || thisValue.isNull());

    return ExecuteKernel(cx, esg.script(), *scopeobj, thisValue, ExecuteType(DIRECT_EVAL),
                         NullFramePtr() /* evalInFrame */, vp.address());
}
Example #28
0
/* static */ bool
ModuleObject::isInstance(HandleValue value)
{
    return value.isObject() && value.toObject().is<ModuleObject>();
}
Example #29
0
MOZ_ALWAYS_INLINE bool
IsBoolean(HandleValue v)
{
    return v.isBoolean() || (v.isObject() && v.toObject().is<BooleanObject>());
}
Example #30
0
/* static */ bool
ImportEntryObject::isInstance(HandleValue value)
{
    return value.isObject() && value.toObject().is<ImportEntryObject>();
}