/* @bookmark_class.setProperty */ static JSBool bookmark_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp) { struct bookmark *bookmark; jsid tmp; unsigned char *title = NULL; unsigned char *url = NULL; int ok; /* This can be called if @obj if not itself an instance of the * appropriate class but has one in its prototype chain. Fail * such calls. */ if (!JS_InstanceOf(ctx, obj, (JSClass *) &bookmark_class, NULL)) return JS_FALSE; bookmark = JS_GetInstancePrivate(ctx, obj, (JSClass *) &bookmark_class, NULL); if (!bookmark) return JS_FALSE; if (!JSID_IS_INT(id)) return JS_FALSE; switch (JSID_TO_INT(id)) { case BOOKMARK_TITLE: if (!JS_ValueToId(ctx, *vp, &tmp)) return JS_FALSE; if (!jsval_to_bookmark_string(ctx, tmp, &title)) return JS_FALSE; break; case BOOKMARK_URL: if (!JS_ValueToId(ctx, *vp, &tmp)) return JS_FALSE; if (!jsval_to_bookmark_string(ctx, tmp, &url)) return JS_FALSE; break; default: /* Unrecognized integer property ID; someone is using * the object as an array. SMJS builtin classes (e.g. * js_RegExpClass) just return JS_TRUE in this case. * Do the same here. */ return JS_TRUE; } ok = update_bookmark(bookmark, get_cp_index("UTF-8"), title, url); mem_free_if(title); mem_free_if(url); return ok ? JS_TRUE : JS_FALSE; }
JSBool JavaStringToId(JSContext *cx, JNIEnv *jEnv, jstring jstr, jsid *idp) { const jschar *ucs2; JSString *jsstr; jsize ucs2_len; jsval val; ucs2 = (*jEnv)->GetStringChars(jEnv, jstr, 0); if (!ucs2) { jsj_UnexpectedJavaError(cx, jEnv, "Couldn't obtain Unicode characters" "from Java string"); return JS_FALSE; } ucs2_len = (*jEnv)->GetStringLength(jEnv, jstr); jsstr = JS_InternUCStringN(cx, ucs2, ucs2_len); (*jEnv)->ReleaseStringChars(jEnv, jstr, ucs2); if (!jsstr) return JS_FALSE; val = STRING_TO_JSVAL(jsstr); JS_ValueToId(cx, STRING_TO_JSVAL(jsstr), idp); return JS_TRUE; }
void BSONInfo::enumerate(JSContext* cx, JS::HandleObject obj, JS::AutoIdVector& properties) { auto holder = getHolder(obj); if (!holder) return; BSONObjIterator i(holder->_obj); ObjectWrapper o(cx, obj); JS::RootedValue val(cx); JS::RootedId id(cx); while (i.more()) { BSONElement e = i.next(); // TODO: when we get heterogenous set lookup, switch to StringData // rather than involving the temporary string if (holder->_removed.count(e.fieldName())) continue; ValueReader(cx, &val).fromStringData(e.fieldNameStringData()); if (!JS_ValueToId(cx, val, &id)) uasserted(ErrorCodes::JSInterpreterFailure, "Failed to invoke JS_ValueToId"); properties.append(id); } }
static JSBool XPC_COW_NewResolve(JSContext *cx, JSObject *obj, jsval idval, uintN flags, JSObject **objp) { obj = GetWrapper(obj); JSObject *wrappedObj = GetWrappedObject(cx, obj); if (!wrappedObj) { // No wrappedObj means that this is probably the prototype. *objp = nsnull; return JS_TRUE; } XPCCallContext ccx(JS_CALLER, cx); if (!ccx.IsValid()) { return ThrowException(NS_ERROR_FAILURE, cx); } jsid id; JSBool canTouch; if (!JS_ValueToId(cx, idval, &id) || !CanTouchProperty(cx, obj, id, (flags & JSRESOLVE_ASSIGNING) != 0, &canTouch)) { return JS_FALSE; } if (!canTouch) { return ThrowException(NS_ERROR_XPC_SECURITY_MANAGER_VETO, cx); } return XPCWrapper::NewResolve(cx, obj, JS_TRUE, wrappedObj, id, flags, objp); }
NS_IMETHODIMP nsJetpack::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, jsval id, PRUint32 flags, JSObject * *objp, PRBool *_retval) { if (JSVAL_IS_STRING(id) && strncmp(JS_GetStringBytes(JSVAL_TO_STRING(id)), "get", 3) == 0) { JSFunction *get = JS_NewFunction(cx, getEndpoint, 0, 0, JS_GetParent(cx, obj), "get"); if (!get) { JS_ReportOutOfMemory(cx); *_retval = PR_FALSE; return NS_OK; } JSObject *getObj = JS_GetFunctionObject(get); jsid idid; *objp = obj; *_retval = (JS_ValueToId(cx, id, &idid) && JS_DefinePropertyById(cx, obj, idid, OBJECT_TO_JSVAL(getObj), nsnull, nsnull, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)); return NS_OK; } *objp = nsnull; *_retval = PR_TRUE; return NS_OK; }
/* static */ bool DOMProxyHandler::AppendNamedPropertyIds(JSContext* cx, JS::Handle<JSObject*> proxy, nsTArray<nsString>& names, bool shadowPrototypeProperties, DOMProxyHandler* handler, JS::AutoIdVector& props) { for (uint32_t i = 0; i < names.Length(); ++i) { JS::Rooted<JS::Value> v(cx); if (!xpc::NonVoidStringToJsval(cx, names[i], v.address())) { return false; } JS::Rooted<jsid> id(cx); if (!JS_ValueToId(cx, v, id.address())) { return false; } if (shadowPrototypeProperties || !HasPropertyOnPrototype(cx, proxy, handler, id)) { if (!props.append(id)) { return false; } } } return true; }
bool DOMProxyHandler::AppendNamedPropertyIds(JSContext* cx, JSObject* proxy, nsTArray<nsString>& names, JS::AutoIdVector& props) { for (uint32_t i = 0; i < names.Length(); ++i) { JS::Value v; if (!xpc::NonVoidStringToJsval(cx, names[i], &v)) { return false; } jsid id; if (!JS_ValueToId(cx, v, &id)) { return false; } if (!HasPropertyOnPrototype(cx, proxy, this, id)) { if (!props.append(id)) { return false; } } } return true; }
static JSBool stringToId(JSContext *cx, const char *s, jsid *idp) { JSString *str = JS_NewStringCopyZ(cx, s); if (!str) return false; return JS_ValueToId(cx, STRING_TO_JSVAL(str), idp); }
static JSBool XPC_COW_GetOrSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp, JSBool isSet) { obj = GetWrapper(obj); if (!obj) { return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx); } XPCCallContext ccx(JS_CALLER, cx); if (!ccx.IsValid()) { return ThrowException(NS_ERROR_FAILURE, cx); } AUTO_MARK_JSVAL(ccx, vp); JSObject *wrappedObj = GetWrappedObject(cx, obj); if (!wrappedObj) { return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx); } jsid interned_id; if (!JS_ValueToId(cx, id, &interned_id)) { return JS_FALSE; } if (interned_id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_PROTO) || interned_id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_PARENT) || interned_id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_EXPOSEDPROPS)) { // No getting or setting __proto__ or __parent__ on my object. return ThrowException(NS_ERROR_INVALID_ARG, cx); // XXX better error message } JSBool canTouch; if (!CanTouchProperty(cx, obj, interned_id, isSet, &canTouch)) { return JS_FALSE; } if (!canTouch) { return ThrowException(NS_ERROR_XPC_SECURITY_MANAGER_VETO, cx); } if (!XPC_COW_RewrapForChrome(cx, obj, vp)) { return JS_FALSE; } JSBool ok = isSet ? JS_SetPropertyById(cx, wrappedObj, interned_id, vp) : JS_GetPropertyById(cx, wrappedObj, interned_id, vp); if (!ok) { return JS_FALSE; } return XPC_COW_RewrapForContent(cx, obj, vp); }
static JSBool rpmhdr_enumerate(JSContext *cx, JSObject *obj, JSIterateOp op, jsval *statep, jsid *idp) { void * ptr = JS_GetInstancePrivate(cx, obj, &rpmhdrClass, NULL); Header h = ptr; HeaderIterator hi = NULL; HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); JSObject *ho = NULL; JSBool ok = JS_FALSE; _ENUMERATE_DEBUG_ENTRY(_debug); switch (op) { case JSENUMERATE_INIT: if ((ho = JS_NewObject(cx, &rpmhiClass, NULL, obj)) == NULL) goto exit; if ((hi = headerInit(h)) == NULL) goto exit; if (!JS_SetPrivate(cx, ho, (void *)hi)) { hi = headerFini(hi); goto exit; } *statep = OBJECT_TO_JSVAL(ho); if (idp) *idp = JSVAL_ZERO; if (_debug) fprintf(stderr, "\tINIT ho %p hi %p\n", ho, hi); break; case JSENUMERATE_NEXT: ho = (JSObject *) JSVAL_TO_OBJECT(*statep); hi = JS_GetInstancePrivate(cx, ho, &rpmhiClass, NULL); if (_debug) fprintf(stderr, "\tNEXT ho %p hi %p\n", ho, hi); if (headerNext(hi, he, 0)) { JS_ValueToId(cx, INT_TO_JSVAL(he->tag), idp); he->p.ptr = _free(he->p.ptr); } else *idp = JSVAL_VOID; if (*idp != JSVAL_VOID) break; /*@fallthrough@*/ case JSENUMERATE_DESTROY: ho = (JSObject *) JSVAL_TO_OBJECT(*statep); hi = JS_GetInstancePrivate(cx, ho, &rpmhiClass, NULL); if (_debug) fprintf(stderr, "\tFINI ho %p hi %p\n", ho, hi); /* Allow our iterator object to be GC'd. */ *statep = JSVAL_NULL; break; } ok = JS_TRUE; exit: return ok; }
static JSBool XPC_SJOW_GetOrSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp, JSBool aIsSet) { // We resolve toString to a function in our resolve hook. if (id == GetRTStringByIndex(cx, XPCJSRuntime::IDX_TO_STRING)) { return JS_TRUE; } obj = FindSafeObject(obj); NS_ASSERTION(obj != nsnull, "FindSafeObject() returned null in class hook!"); JSObject *unsafeObj = GetUnsafeObject(obj); if (!unsafeObj) { return ThrowException(NS_ERROR_UNEXPECTED, cx); } // Check that the caller can access the unsafe object. if (!CanCallerAccess(cx, unsafeObj)) { // CanCallerAccess() already threw for us. return JS_FALSE; } JSObject *scopeFun = GetScopeFunction(cx, obj); if (!scopeFun) { return JS_FALSE; } { SafeCallGuard guard(cx, FindObjectPrincipals(cx, obj, unsafeObj)); if (!guard.ready()) { return JS_FALSE; } jsid interned_id; if (!JS_ValueToId(cx, id, &interned_id)) { return JS_FALSE; } if (aIsSet) { *vp = UnwrapJSValue(*vp); } JSBool ok = aIsSet ? js_SetPropertyByIdWithFakeFrame(cx, unsafeObj, scopeFun, interned_id, vp) : js_GetPropertyByIdWithFakeFrame(cx, unsafeObj, scopeFun, interned_id, vp); if (!ok) { return JS_FALSE; } } return WrapJSValue(cx, obj, *vp, vp); }
static JSBool enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, jsval *statep, jsid *idp) { JSObject *iterator; switch (enum_op) { case JSENUMERATE_INIT: if (resolverHasMethod(cx, obj, "enumerate")) { if (!delegateToResolver(cx, obj, "enumerate", 0, NULL, statep)) return JS_FALSE; if (!JSVAL_IS_OBJECT(*statep)) { JS_ReportError(cx, "Expected enumerate() to return an iterator."); return JS_FALSE; } *idp = JSVAL_ZERO; JS_AddRoot(cx, statep); return JS_TRUE; } // TODO: Default behavior? JS_ReportError(cx, "Enumeration is not implemented on this object."); return JS_FALSE; case JSENUMERATE_NEXT: jsval rval; iterator = JSVAL_TO_OBJECT(*statep); if (!JS_CallFunctionName(cx, iterator, "next", 0, NULL, &rval)) { if (JS_IsExceptionPending(cx)) { jsval exception; if (!JS_GetPendingException(cx, &exception)) return JS_FALSE; if (!JSVAL_IS_OBJECT(exception)) return JS_FALSE; JSClass *clasp = JS_GET_CLASS(cx, JSVAL_TO_OBJECT(exception)); if (clasp && JSCLASS_CACHED_PROTO_KEY(clasp) == JSProto_StopIteration) { JS_ClearPendingException(cx); *statep = JSVAL_NULL; JS_RemoveRoot(cx, statep); return JS_TRUE; } } return JS_FALSE; } if (!JS_ValueToId(cx, rval, idp)) return JS_FALSE; return JS_TRUE; case JSENUMERATE_DESTROY: JS_RemoveRoot(cx, statep); return JS_TRUE; default: JS_ReportError(cx, "Unknown enum_op"); return JS_FALSE; } }
static JSBool rpmts_enumerate(JSContext *cx, JSObject *obj, JSIterateOp op, jsval *statep, jsid *idp) { void * ptr = JS_GetInstancePrivate(cx, obj, &rpmtsClass, NULL); rpmts ts = ptr; rpmtsi tsi; JSObject *tsio = NULL; JSBool ok = JS_FALSE; _ENUMERATE_DEBUG_ENTRY(_debug); switch (op) { case JSENUMERATE_INIT: if ((tsio = JS_NewObject(cx, &rpmtsiClass, NULL, obj)) == NULL) goto exit; if ((tsi = rpmtsiInit(ts)) == NULL) goto exit; if (!JS_SetPrivate(cx, tsio, (void *)tsi)) { tsi = rpmtsiFree(tsi); goto exit; } *statep = OBJECT_TO_JSVAL(tsio); if (idp) *idp = JSVAL_ZERO; if (_debug) fprintf(stderr, "\tINIT tsio %p tsi %p\n", tsio, tsi); break; case JSENUMERATE_NEXT: tsio = (JSObject *) JSVAL_TO_OBJECT(*statep); tsi = JS_GetInstancePrivate(cx, tsio, &rpmtsiClass, NULL); if (rpmtsiNext(tsi, 0) != NULL) { int oc = rpmtsiOc(tsi); if (_debug) fprintf(stderr, "\tNEXT tsio %p tsi %p[%d]\n", tsio, tsi, oc); JS_ValueToId(cx, INT_TO_JSVAL(oc), idp); } else *idp = JSVAL_VOID; if (*idp != JSVAL_VOID) break; /*@fallthrough@*/ case JSENUMERATE_DESTROY: tsio = (JSObject *) JSVAL_TO_OBJECT(*statep); tsi = JS_GetInstancePrivate(cx, tsio, &rpmtsiClass, NULL); if (_debug) fprintf(stderr, "\tFINI tsio %p tsi %p\n", tsio, tsi); /* Allow our iterator object to be GC'd. */ *statep = JSVAL_NULL; break; } ok = JS_TRUE; exit: return ok; }
static JSBool XPC_COW_CheckAccess(JSContext *cx, JSObject *obj, jsval prop, JSAccessMode mode, jsval *vp) { // Simply forward checkAccess to our wrapped object. It's already expecting // untrusted things to ask it about accesses. uintN junk; jsid id; return JS_ValueToId(cx, prop, &id) && JS_CheckAccess(cx, GetWrappedObject(cx, obj), id, mode, vp, &junk); }
JSBool resolve(JSContext* jscx, JSObject* jsobj, jsval key) { Context* pycx = NULL; PyObject* pykey = NULL; jsid pid; JSBool ret = JS_FALSE; pycx = (Context*) JS_GetContextPrivate(jscx); if(pycx == NULL) { JS_ReportError(jscx, "Failed to get Python context."); goto done; } // Bail if there's no registered global handler. if(pycx->global == NULL) { ret = JS_TRUE; goto done; } pykey = js2py(pycx, key); if(pykey == NULL) goto done; if(Context_has_access(pycx, jscx, pycx->global, pykey) <= 0) goto done; if(!PyMapping_HasKey(pycx->global, pykey)) { ret = JS_TRUE; goto done; } if(!JS_ValueToId(jscx, key, &pid)) { JS_ReportError(jscx, "Failed to convert property id."); goto done; } if(!js_DefineProperty(jscx, pycx->root, pid, JSVAL_VOID, NULL, NULL, JSPROP_SHARED, NULL)) { JS_ReportError(jscx, "Failed to define property."); goto done; } ret = JS_TRUE; done: Py_XDECREF(pykey); return ret; }
static JSBool rpmmg_enumerate(JSContext *cx, JSObject *obj, JSIterateOp op, jsval *statep, jsid *idp) { #ifdef NOTYET void * ptr = JS_GetInstancePrivate(cx, obj, &rpmmgClass, NULL); rpmmg mg = ptr; struct dirent * dp; unsigned int ix = 0; #endif _ENUMERATE_DEBUG_ENTRY(_debug < 0); #ifdef NOTYET switch (op) { case JSENUMERATE_INIT: if (idp) *idp = JSVAL_ZERO; *statep = INT_TO_JSVAL(ix); if (_debug) fprintf(stderr, "\tINIT mg %p\n", mg); break; case JSENUMERATE_NEXT: ix = JSVAL_TO_INT(*statep); if ((dp = Readdir(dir)) != NULL) { (void) JS_DefineElement(cx, obj, ix, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, dp->d_name)), NULL, NULL, JSPROP_ENUMERATE); JS_ValueToId(cx, *statep, idp); if (_debug) fprintf(stderr, "\tNEXT mg %p[%u] dirent %p \"%s\"\n", mg, ix, dp, dp->d_name); *statep = INT_TO_JSVAL(ix+1); } else *idp = JSVAL_VOID; if (*idp != JSVAL_VOID) break; /*@fallthrough@*/ case JSENUMERATE_DESTROY: ix = JSVAL_TO_INT(*statep); (void) JS_DefineProperty(cx, obj, "length", INT_TO_JSVAL(ix), NULL, NULL, JSPROP_ENUMERATE); if (_debug) fprintf(stderr, "\tFINI mg %p[%u]\n", mg, ix); *statep = JSVAL_NULL; break; } #else *statep = JSVAL_NULL; #endif return JS_TRUE; }
jsval to_js_object(ErlNifEnv* env, JSContext* cx, ERL_NIF_TERM list) { JSObject* ret; jsval kval; jsval vval; jsid idp; ERL_NIF_TERM head; ERL_NIF_TERM tail; const ERL_NIF_TERM* pair; int arity; ret = JS_NewObject(cx, NULL, NULL, NULL); if(ret == NULL) return JSVAL_VOID; if(enif_is_empty_list(env, list)) { return OBJECT_TO_JSVAL(ret); } if(!enif_get_list_cell(env, list, &head, &tail)) { return JSVAL_VOID; } do { if(!enif_get_tuple(env, head, &arity, &pair)) { return JSVAL_VOID; } if(arity != 2) { return JSVAL_VOID; } kval = to_js_key(env, cx, pair[0]); if(kval == JSVAL_VOID) return JSVAL_VOID; if(!JS_ValueToId(cx, kval, &idp)) return JSVAL_VOID; vval = to_js(env, cx, pair[1]); if(vval == JSVAL_VOID) return JSVAL_VOID; if(!JS_SetPropertyById(cx, ret, idp, &vval)) { return JSVAL_VOID; } } while(enif_get_list_cell(env, tail, &head, &tail)); return OBJECT_TO_JSVAL(ret); }
static JSBool rpmdir_enumerate(JSContext *cx, JSObject *obj, JSIterateOp op, jsval *statep, jsid *idp) { void * ptr = JS_GetInstancePrivate(cx, obj, &rpmdirClass, NULL); DIR * dir = ptr; struct dirent * dp; unsigned int ix = 0; /* XXX VG: JS_Enumerate (jsobj.c:4211) doesn't initialize some fields. */ _ENUMERATE_DEBUG_ENTRY(_debug < 0); switch (op) { case JSENUMERATE_INIT: case JSENUMERATE_INIT_ALL: if (idp) *idp = JSVAL_ZERO; *statep = INT_TO_JSVAL(ix); if (_debug) fprintf(stderr, "\tINIT dir %p\n", dir); break; case JSENUMERATE_NEXT: ix = JSVAL_TO_INT(*statep); if ((dp = Readdir(dir)) != NULL) { (void) JS_DefineElement(cx, obj, ix, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, dp->d_name)), NULL, NULL, JSPROP_ENUMERATE); JS_ValueToId(cx, *statep, idp); if (_debug) fprintf(stderr, "\tNEXT dir %p[%u] dirent %p \"%s\"\n", dir, ix, dp, dp->d_name); *statep = INT_TO_JSVAL(ix+1); } else *idp = JSVAL_VOID; if (!JSID_IS_VOID(*idp)) break; /*@fallthrough@*/ case JSENUMERATE_DESTROY: ix = JSVAL_TO_INT(*statep); (void) JS_DefineProperty(cx, obj, "length", INT_TO_JSVAL(ix), NULL, NULL, JSPROP_ENUMERATE); if (_debug) fprintf(stderr, "\tFINI dir %p[%u]\n", dir, ix); *statep = JSVAL_NULL; break; } return JS_TRUE; }
JSBool XPCJSRuntime::GenerateStringIDs(JSContext* cx) { NS_PRECONDITION(!mStrIDs[0],"string ids generated twice!"); for(uintN i = 0; i < IDX_TOTAL_COUNT; i++) { JSString* str = JS_InternString(cx, mStrings[i]); if(!str || !JS_ValueToId(cx, STRING_TO_JSVAL(str), &mStrIDs[i])) { mStrIDs[0] = 0; return JS_FALSE; } mStrJSVals[i] = STRING_TO_JSVAL(str); } return JS_TRUE; }
PyObject* Context_rem_global(Context* self, PyObject* args, PyObject* kwargs) { PyObject* pykey = NULL; PyObject* ret = NULL; jsval jsk; jsid kid; jsval jsv; JS_BeginRequest(self->cx); if(!PyArg_ParseTuple(args, "O", &pykey)) goto error; jsk = py2js(self, pykey); if(jsk == JSVAL_VOID) goto error; if(!JS_ValueToId(self->cx, jsk, &kid)) { PyErr_SetString(JSError, "Failed to create key id."); } if(!js_GetProperty(self->cx, self->root, kid, &jsv)) { PyErr_SetString(JSError, "Failed to get global property."); goto error; } ret = js2py(self, jsv); if(ret == NULL) goto error; if(!js_DeleteProperty(self->cx, self->root, kid, &jsv)) { PyErr_SetString(JSError, "Failed to remove global property."); goto error; } JS_MaybeGC(self->cx); goto success; error: success: JS_EndRequest(self->cx); return ret; }
static JSBool DefineGetterOrSetter(JSContext *cx, uintN argc, JSBool wantGetter, jsval *vp) { uintN attrs; JSBool found; JSPropertyOp getter, setter; JSObject *obj2; jsval v; jsid interned_id; XPC_QS_ASSERT_CONTEXT_OK(cx); JSObject *obj = JS_THIS_OBJECT(cx, vp); if (!obj) return JS_FALSE; JSFastNative forward = wantGetter ? js_obj_defineGetter : js_obj_defineSetter; jsval id = (argc >= 1) ? JS_ARGV(cx, vp)[0] : JSVAL_VOID; if(!JSVAL_IS_STRING(id)) return forward(cx, argc, vp); JSString *str = JSVAL_TO_STRING(id); const char *name = JS_GetStringBytes(str); if(!JS_ValueToId(cx, id, &interned_id) || !JS_LookupPropertyWithFlagsById(cx, obj, interned_id, JSRESOLVE_QUALIFIED, &obj2, &v) || (obj2 && !JS_GetPropertyAttrsGetterAndSetterById(cx, obj2, interned_id, &attrs, &found, &getter, &setter))) return JS_FALSE; // The property didn't exist, already has a getter or setter, or is not // our property, then just forward now. if(!obj2 || (attrs & (JSPROP_GETTER | JSPROP_SETTER)) || !(getter || setter) || !IS_PROTO_CLASS(STOBJ_GET_CLASS(obj2))) return forward(cx, argc, vp); // Reify the getter and setter... if(!ReifyPropertyOps(cx, obj, id, interned_id, name, getter, setter, nsnull, nsnull)) return JS_FALSE; return forward(cx, argc, vp); }
static JSBool perlarray_enumerate( JSContext *cx, JSObject *obj, JSIterateOp enum_op, jsval *statep, jsid *idp ) { dTHX; SV *ref = (SV *)JS_GetPrivate(cx, obj); AV *av = (AV *)SvRV(ref); PJS_ARRAY_CHECK if(enum_op == JSENUMERATE_INIT) { SV *cc = newSViv(0); *statep = PRIVATE_TO_JSVAL(cc); if(idp) { I32 alen = av_len(av); *idp = INT_TO_JSVAL(alen + 1); } return JS_TRUE; } if(enum_op == JSENUMERATE_NEXT) { SV *cc = (SV *)JSVAL_TO_PRIVATE(*statep); I32 alen = av_len(av); I32 curr; if(!SvIOK(cc)) { JS_ReportError(cx, "Wrong Array iterator"); return JS_FALSE; } curr = (I32)SvIVX(cc); if(curr > alen) { // At end *statep = JSVAL_NULL; sv_free(cc); } else { jsval key = INT_TO_JSVAL(curr); SvIV_set(cc, (IV)(curr+1)); return JS_ValueToId(cx, key, idp); } } return JS_TRUE; }
JSBool JavaObject::enumerate(JSContext* ctx, JSObject* obj, JSIterateOp op, jsval* statep, jsid* idp) { int objectId = JavaObject::getObjectId(ctx, obj); switch (op) { case JSENUMERATE_INIT: Debug::log(Debug::Spam) << "JavaObject::enumerate(oid=" << objectId << ", INIT)" << Debug::flush; *statep = JSVAL_ZERO; if (idp) { *idp = INT_TO_JSID(NUM_PROPERTY_NAMES); } break; case JSENUMERATE_NEXT: { int idNum = JSVAL_TO_INT(*statep); Debug::log(Debug::Spam) << "JavaObject::enumerate(oid=" << objectId << ", NEXT " << idNum << ")" << Debug::flush; *statep = INT_TO_JSVAL(idNum + 1); if (idNum >= NUM_PROPERTY_NAMES) { *statep = JSVAL_NULL; #if GECKO_VERSION < 2000 //TODO(jat): do we need to do this? *idp = JSVAL_NULL; #endif //GECKO_VERSION } else { const char* propName = propertyNames[idNum]; JSString* str = JS_NewStringCopyZ(ctx, propName); return JS_ValueToId(ctx, STRING_TO_JSVAL(str), idp); } break; } case JSENUMERATE_DESTROY: Debug::log(Debug::Spam) << "JavaObject::enumerate(oid=" << objectId << ", DESTROY)" << Debug::flush; *statep = JSVAL_NULL; break; default: Debug::log(Debug::Error) << "Unknown Enumerate op " << static_cast<int>(op) << Debug::flush; return JS_FALSE; } return JS_TRUE; }
static JSBool XPC_COW_AddProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { obj = GetWrapper(obj); jsval resolving; if (!JS_GetReservedSlot(cx, obj, XPCWrapper::sFlagsSlot, &resolving)) { return JS_FALSE; } if (HAS_FLAGS(resolving, FLAG_RESOLVING)) { // Allow us to define a property on ourselves. return JS_TRUE; } // Someone's adding a property to us. We need to protect ourselves from // getters and setters. JSObject *wrappedObj = GetWrappedObject(cx, obj); if (!wrappedObj) { return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx); } jsid interned_id; JSPropertyDescriptor desc; if (!JS_ValueToId(cx, id, &interned_id) || !XPCWrapper::GetPropertyAttrs(cx, obj, interned_id, JSRESOLVE_QUALIFIED, JS_TRUE, &desc)) { return JS_FALSE; } NS_ASSERTION(desc.obj == obj, "The JS engine lies!"); if (desc.attrs & (JSPROP_GETTER | JSPROP_SETTER)) { // Only chrome is allowed to add getters or setters to our object. if (!AllowedToAct(cx, id)) { return JS_FALSE; } } return XPC_COW_RewrapForChrome(cx, obj, vp) && JS_DefinePropertyById(cx, wrappedObj, interned_id, *vp, desc.getter, desc.setter, desc.attrs); }
JSBool XPCJSRuntime::OnJSContextNew(JSContext *cx) { NS_TIME_FUNCTION; // if it is our first context then we need to generate our string ids JSBool ok = JS_TRUE; if(JSID_IS_VOID(mStrIDs[0])) { JS_SetGCParameterForThread(cx, JSGC_MAX_CODE_CACHE_BYTES, 16 * 1024 * 1024); JSAutoRequest ar(cx); for(uintN i = 0; i < IDX_TOTAL_COUNT; i++) { JSString* str = JS_InternString(cx, mStrings[i]); if(!str || !JS_ValueToId(cx, STRING_TO_JSVAL(str), &mStrIDs[i])) { mStrIDs[0] = JSID_VOID; ok = JS_FALSE; break; } mStrJSVals[i] = STRING_TO_JSVAL(str); } } if (!ok) return JS_FALSE; XPCPerThreadData* tls = XPCPerThreadData::GetData(cx); if(!tls) return JS_FALSE; XPCContext* xpc = new XPCContext(this, cx); if (!xpc) return JS_FALSE; JS_SetNativeStackQuota(cx, 128 * sizeof(size_t) * 1024); JS_SetScriptStackQuota(cx, 25 * sizeof(size_t) * 1024 * 1024); // we want to mark the global object ourselves since we use a different color JS_ToggleOptions(cx, JSOPTION_UNROOTED_GLOBAL); return JS_TRUE; }
static JSBool LookupGetterOrSetter(JSContext *cx, JSBool wantGetter, uintN argc, jsval *vp) { XPC_QS_ASSERT_CONTEXT_OK(cx); if(argc == 0) { JS_SET_RVAL(cx, vp, JSVAL_VOID); return JS_TRUE; } JSObject *obj = JS_THIS_OBJECT(cx, vp); if(!obj) return JS_FALSE; jsval idval = JS_ARGV(cx, vp)[0]; jsid interned_id; JSPropertyDescriptor desc; if(!JS_ValueToId(cx, idval, &interned_id) || !JS_GetPropertyDescriptorById(cx, obj, interned_id, JSRESOLVE_QUALIFIED, &desc)) return JS_FALSE; // No property at all means no getters or setters possible. if(!desc.obj) { JS_SET_RVAL(cx, vp, JSVAL_VOID); return JS_TRUE; } // Inline obj_lookup[GS]etter here. if(wantGetter) { if(desc.attrs & JSPROP_GETTER) { JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(JS_FUNC_TO_DATA_PTR(JSObject *, desc.getter))); return JS_TRUE; } }
PyObject* Context_add_global(Context* self, PyObject* args, PyObject* kwargs) { PyObject* pykey = NULL; PyObject* pyval = NULL; jsval jsk; jsid kid; jsval jsv; JS_BeginRequest(self->cx); if(!PyArg_ParseTuple(args, "OO", &pykey, &pyval)) goto error; jsk = py2js(self, pykey); if(jsk == JSVAL_VOID) goto error; if(!JS_ValueToId(self->cx, jsk, &kid)) { PyErr_SetString(PyExc_AttributeError, "Failed to create key id."); goto error; } jsv = py2js(self, pyval); if(jsv == JSVAL_VOID) goto error; if(!js_SetProperty(self->cx, self->root, kid, &jsv)) { PyErr_SetString(PyExc_AttributeError, "Failed to set global property."); goto error; } goto success; error: success: JS_EndRequest(self->cx); Py_RETURN_NONE; }
JSBool XPCJSRuntime::OnJSContextNew(JSContext *cx) { NS_TIME_FUNCTION; // if it is our first context then we need to generate our string ids JSBool ok = JS_TRUE; if(!mStrIDs[0]) { JS_SetGCParameterForThread(cx, JSGC_MAX_CODE_CACHE_BYTES, 16 * 1024 * 1024); JSAutoRequest ar(cx); for(uintN i = 0; i < IDX_TOTAL_COUNT; i++) { JSString* str = JS_InternString(cx, mStrings[i]); if(!str || !JS_ValueToId(cx, STRING_TO_JSVAL(str), &mStrIDs[i])) { mStrIDs[0] = 0; ok = JS_FALSE; break; } mStrJSVals[i] = STRING_TO_JSVAL(str); } } if (!ok) return JS_FALSE; XPCPerThreadData* tls = XPCPerThreadData::GetData(cx); if(!tls) return JS_FALSE; XPCContext* xpc = new XPCContext(this, cx); if (!xpc) return JS_FALSE; JS_SetNativeStackQuota(cx, 512 * 1024); JS_SetScriptStackQuota(cx, 100 * 1024 * 1024); return JS_TRUE; }
/* PRBool resolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in JSVal id); */ NS_IMETHODIMP nsJSIID::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, jsval id, PRUint32 flags, JSObject * *objp, PRBool *_retval) { XPCCallContext ccx(JS_CALLER, cx); AutoMarkingNativeInterfacePtr iface(ccx); const nsIID* iid; mInfo->GetIIDShared(&iid); iface = XPCNativeInterface::GetNewOrUsed(ccx, iid); if(!iface) return NS_OK; XPCNativeMember* member = iface->FindMember(id); if(member && member->IsConstant()) { jsval val; if(!member->GetConstantValue(ccx, iface, &val)) return NS_ERROR_OUT_OF_MEMORY; jsid idid; if(!JS_ValueToId(cx, id, &idid)) return NS_ERROR_OUT_OF_MEMORY; *objp = obj; *_retval = JS_DefinePropertyById(cx, obj, idid, val, nsnull, nsnull, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); } return NS_OK; }
JSDProperty* jsd_GetValueProperty(JSDContext* jsdc, JSDValue* jsdval, JSString* name) { JSContext* cx = jsdc->dumbContext; JSDProperty* jsdprop; JSDProperty* iter = NULL; JSObject* obj; uintN attrs = 0; JSBool found; JSPropertyDesc pd; const jschar * nameChars; size_t nameLen; jsval val, nameval; jsid nameid; JSCrossCompartmentCall *call = NULL; if(!jsd_IsValueObject(jsdc, jsdval)) return NULL; /* If we already have the prop, then return it */ while(NULL != (jsdprop = jsd_IterateProperties(jsdc, jsdval, &iter))) { JSString* propName = jsd_GetValueString(jsdc, jsdprop->name); if(propName) { intN result; if (JS_CompareStrings(cx, propName, name, &result) && !result) return jsdprop; } JSD_DropProperty(jsdc, jsdprop); } /* Not found in property list, look it up explicitly */ if(!(obj = JSVAL_TO_OBJECT(jsdval->val))) return NULL; if (!(nameChars = JS_GetStringCharsZAndLength(cx, name, &nameLen))) return NULL; JS_BeginRequest(cx); call = JS_EnterCrossCompartmentCall(cx, obj); if(!call) { JS_EndRequest(cx); return NULL; } JS_GetUCPropertyAttributes(cx, obj, nameChars, nameLen, &attrs, &found); if (!found) { JS_LeaveCrossCompartmentCall(call); JS_EndRequest(cx); return NULL; } JS_ClearPendingException(cx); if(!JS_GetUCProperty(cx, obj, nameChars, nameLen, &val)) { if (JS_IsExceptionPending(cx)) { if (!JS_GetPendingException(cx, &pd.value)) { JS_LeaveCrossCompartmentCall(call); JS_EndRequest(cx); return NULL; } pd.flags = JSPD_EXCEPTION; } else { pd.flags = JSPD_ERROR; pd.value = JSVAL_VOID; } } else { pd.value = val; } JS_LeaveCrossCompartmentCall(call); JS_EndRequest(cx); nameval = STRING_TO_JSVAL(name); if (!JS_ValueToId(cx, nameval, &nameid) || !JS_IdToValue(cx, nameid, &pd.id)) { return NULL; } pd.slot = pd.spare = 0; pd.alias = JSVAL_NULL; pd.flags |= (attrs & JSPROP_ENUMERATE) ? JSPD_ENUMERATE : 0 | (attrs & JSPROP_READONLY) ? JSPD_READONLY : 0 | (attrs & JSPROP_PERMANENT) ? JSPD_PERMANENT : 0; return _newProperty(jsdc, &pd, JSDPD_HINTED); }