// static void XPCThrower::Verbosify(XPCCallContext& ccx, char** psz, PRBool own) { char* sz = nsnull; if(ccx.HasInterfaceAndMember()) { XPCNativeInterface* iface = ccx.GetInterface(); jsid id = ccx.GetMember()->GetName(); JSAutoByteString bytes; const char *name = JSID_IS_VOID(id) ? "Unknown" : bytes.encode(ccx, JSID_TO_STRING(id)); if(!name) { name = ""; } sz = JS_smprintf("%s [%s.%s]", *psz, iface->GetNameString(), name); } if(sz) { if(own) JS_smprintf_free(*psz); *psz = sz; } }
static JSBool rpmfc_enumerate(JSContext *cx, JSObject *obj, JSIterateOp op, jsval *statep, jsid *idp) { _ENUMERATE_DEBUG_ENTRY(_debug < 0); switch (op) { case JSENUMERATE_INIT: case JSENUMERATE_INIT_ALL: *statep = JSVAL_VOID; if (idp) *idp = JSVAL_ZERO; break; case JSENUMERATE_NEXT: *statep = JSVAL_VOID; if (!JSID_IS_VOID(*idp)) break; /*@fallthrough@*/ case JSENUMERATE_DESTROY: *statep = JSVAL_NULL; break; } return JS_TRUE; }
static JSBool rpmps_enumerate(JSContext *cx, JSObject *obj, JSIterateOp op, jsval *statep, jsid *idp) { _ENUMERATE_DEBUG_ENTRY(_debug); #ifdef DYING switch (op) { case JSENUMERATE_INIT: case JSENUMERATE_INIT_ALL: if ((iterator = JS_NewPropertyIterator(cx, obj)) == NULL) goto exit; *statep = OBJECT_TO_JSVAL(iterator); if (idp) *idp = JSVAL_ZERO; break; case JSENUMERATE_NEXT: iterator = (JSObject *) JSVAL_TO_OBJECT(*statep); if (!JS_NextProperty(cx, iterator, idp)) goto exit; if (!JSID_IS_VOID(*idp)) break; /*@fallthrough@*/ case JSENUMERATE_DESTROY: /* Allow our iterator object to be GC'd. */ *statep = JSVAL_NULL; break; } #else { static const char hex[] = "0123456789abcdef"; const char * s; char name[2]; JSString * valstr; char value[5]; for (s = "AaBbCc"; *s != '\0'; s++) { name[0] = s[0]; name[1] = '\0'; value[0] = '0'; value[1] = 'x'; value[2] = hex[(name[0] >> 4) & 0xf]; value[3] = hex[(name[0] ) & 0xf]; value[4] = '\0'; if ((valstr = JS_NewStringCopyZ(cx, value)) == NULL || !JS_DefineProperty(cx, obj, name, STRING_TO_JSVAL(valstr), NULL, NULL, JSPROP_ENUMERATE)) goto exit; } } #endif exit: return JS_TRUE; }
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; }
// static void XPCThrower::Verbosify(XPCCallContext& ccx, char** psz, PRBool own) { char* sz = nsnull; if(ccx.HasInterfaceAndMember()) { XPCNativeInterface* iface = ccx.GetInterface(); jsid id = JSID_VOID; #ifdef XPC_IDISPATCH_SUPPORT NS_ASSERTION(ccx.GetIDispatchMember() == nsnull || ccx.GetMember() == nsnull, "Both IDispatch member and regular XPCOM member " "were set in XPCCallContext"); if(ccx.GetIDispatchMember()) { XPCDispInterface::Member * member = reinterpret_cast<XPCDispInterface::Member*>(ccx.GetIDispatchMember()); if(member && JSID_IS_STRING(member->GetName())) { id = member->GetName(); } } else #endif { id = ccx.GetMember()->GetName(); } JSAutoByteString bytes; const char *name = JSID_IS_VOID(id) ? "Unknown" : bytes.encode(ccx, JSID_TO_STRING(id)); if(!name) { name = ""; } sz = JS_smprintf("%s [%s.%s]", *psz, iface->GetNameString(), name); } if(sz) { if(own) JS_smprintf_free(*psz); *psz = sz; } }
JSBool JsGlobal::event_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, jsval *statep, jsid *idp) { static log4cplus::Logger log = log4cplus::Logger::getInstance("fsm.JsContext.enumerate"); JSObject *iterator; //fsm::env::Js::ToString objString(cx,OBJECT_TO_JSVAL(obj)); LOG4CPLUS_ERROR(log,"[_event] enumerate."); switch (enum_op) { case JSENUMERATE_INIT: case JSENUMERATE_INIT_ALL: LOG4CPLUS_TRACE(log, "enumerate [_event] Init properties."); iterator = JS_NewPropertyIterator(cx, obj); if (!iterator) return JS_FALSE; *statep = OBJECT_TO_JSVAL(iterator); if (idp) *idp = INT_TO_JSID(0); break; case JSENUMERATE_NEXT: /*if (its_enum_fail) { JS_ReportError(cx, "its enumeration failed"); return JS_FALSE; }*/ LOG4CPLUS_TRACE(log, "enumerate [_event] next properties."); iterator = (JSObject *) JSVAL_TO_OBJECT(*statep); if (!JS_NextProperty(cx, iterator, idp)) return JS_FALSE; if (!JSID_IS_VOID(*idp)) break; /* Fall through. */ case JSENUMERATE_DESTROY: /* Allow our iterator object to be GC'd. */ LOG4CPLUS_TRACE(log, "enumerate [_event] destroy properties."); *statep = JSVAL_NULL; break; } return JS_TRUE; }
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 void load_module_elements(JSContext *context, JSObject *in_object, ImporterIterator *iter, const char *init_path) { JSObject *module_obj; JSObject *jsiter; module_obj = load_module_init(context, in_object, init_path); if (module_obj != NULL) { jsid idp; jsiter = JS_NewPropertyIterator(context, module_obj); if (jsiter == NULL) { return; } if (!JS_NextProperty(context, jsiter, &idp)) { return; } while (!JSID_IS_VOID(idp)) { char *name; if (!gjs_get_string_id(context, idp, &name)) { continue; } /* Pass ownership of name */ g_ptr_array_add(iter->elements, name); if (!JS_NextProperty(context, jsiter, &idp)) { break; } } } }
JSBool CheckFilename(JSContext *cx, jsid id, JSStackFrame *fp) { const char *filename; if (fp && (filename = fp->getScript()->filename) && !strncmp(filename, prefix, NS_ARRAY_LENGTH(prefix) - 1)) { return JS_TRUE; } if (JSID_IS_VOID(id)) { ThrowException(NS_ERROR_XPC_SECURITY_MANAGER_VETO, cx); } else { jsval idval; JSString *str; if (JS_IdToValue(cx, id, &idval) && (str = JS_ValueToString(cx, idval))) { JS_ReportError(cx, "Permission denied to access property '%hs' from a non-chrome context", JS_GetStringChars(str)); } } return JS_FALSE; }
void XPCCallContext::Init(XPCContext::LangType callerLanguage, JSBool callBeginRequest, JSObject* obj, JSObject* funobj, WrapperInitOptions wrapperInitOptions, jsid name, uintN argc, jsval *argv, jsval *rval) { if (!mXPC) return; mThreadData = XPCPerThreadData::GetData(mJSContext); if (!mThreadData) return; XPCJSContextStack* stack = mThreadData->GetJSContextStack(); JSContext* topJSContext; if (!stack || NS_FAILED(stack->Peek(&topJSContext))) { // If we don't have a stack we're probably in shutdown. NS_ASSERTION(!stack, "Bad, Peek failed!"); mJSContext = nsnull; return; } if (!mJSContext) { // This is slightly questionable. If called without an explicit // JSContext (generally a call to a wrappedJS) we will use the JSContext // on the top of the JSContext stack - if there is one - *before* // falling back on the safe JSContext. // This is good AND bad because it makes calls from JS -> native -> JS // have JS stack 'continuity' for purposes of stack traces etc. // Note: this *is* what the pre-XPCCallContext xpconnect did too. if (topJSContext) mJSContext = topJSContext; else if (NS_FAILED(stack->GetSafeJSContext(&mJSContext)) || !mJSContext) return; } if (topJSContext != mJSContext) { if (NS_FAILED(stack->Push(mJSContext))) { NS_ERROR("bad!"); return; } mContextPopRequired = true; } // Get into the request as early as we can to avoid problems with scanning // callcontexts on other threads from within the gc callbacks. NS_ASSERTION(!callBeginRequest || mCallerLanguage == NATIVE_CALLER, "Don't call JS_BeginRequest unless the caller is native."); if (callBeginRequest) JS_BeginRequest(mJSContext); mXPCContext = XPCContext::GetXPCContext(mJSContext); mPrevCallerLanguage = mXPCContext->SetCallingLangType(mCallerLanguage); // hook into call context chain for our thread mPrevCallContext = mThreadData->SetCallContext(this); // We only need to addref xpconnect once so only do it if this is the first // context in the chain. if (!mPrevCallContext) NS_ADDREF(mXPC); mState = HAVE_CONTEXT; if (!obj) return; mScopeForNewJSObjects = obj; mState = HAVE_SCOPE; mMethodIndex = 0xDEAD; mState = HAVE_OBJECT; mTearOff = nsnull; if (wrapperInitOptions == INIT_SHOULD_LOOKUP_WRAPPER) { mWrapper = XPCWrappedNative::GetWrappedNativeOfJSObject(mJSContext, obj, funobj, &mFlattenedJSObject, &mTearOff); if (mWrapper) { DEBUG_CheckWrapperThreadSafety(mWrapper); mFlattenedJSObject = mWrapper->GetFlatJSObject(); if (mTearOff) mScriptableInfo = nsnull; else mScriptableInfo = mWrapper->GetScriptableInfo(); } else { NS_ABORT_IF_FALSE(!mFlattenedJSObject || IS_SLIM_WRAPPER(mFlattenedJSObject), "should have a slim wrapper"); } } if (!JSID_IS_VOID(name)) SetName(name); if (argc != NO_ARGS) SetArgsAndResultPtr(argc, argv, rval); CHECK_STATE(HAVE_OBJECT); }
/* Initialize a newly created Boxed from an object that is a "hash" of * properties to set as fieds of the object. We don't require that every field * of the object be set. */ static JSBool boxed_init_from_props(JSContext *context, JSObject *obj, Boxed *priv, jsval props_value) { JSObject *props; JSObject *iter; jsid prop_id; GHashTable *field_map; gboolean success; success = FALSE; if (!JSVAL_IS_OBJECT(props_value)) { gjs_throw(context, "argument should be a hash with fields to set"); return JS_FALSE; } props = JSVAL_TO_OBJECT(props_value); iter = JS_NewPropertyIterator(context, props); if (iter == NULL) { gjs_throw(context, "Failed to create property iterator for fields hash"); return JS_FALSE; } field_map = get_field_map(priv->info); prop_id = JSID_VOID; if (!JS_NextProperty(context, iter, &prop_id)) goto out; while (!JSID_IS_VOID(prop_id)) { GIFieldInfo *field_info; char *name; jsval value; if (!gjs_get_string_id(context, prop_id, &name)) goto out; field_info = g_hash_table_lookup(field_map, name); if (field_info == NULL) { gjs_throw(context, "No field %s on boxed type %s", name, g_base_info_get_name((GIBaseInfo *)priv->info)); g_free(name); goto out; } if (!gjs_object_require_property(context, props, "property list", name, &value)) { g_free(name); goto out; } g_free(name); if (!boxed_set_field_from_value(context, priv, field_info, value)) goto out; prop_id = JSID_VOID; if (!JS_NextProperty(context, iter, &prop_id)) goto out; } success = TRUE; out: g_hash_table_destroy(field_map); return success; }
nsresult leakmonJSObjectInfo::Init(leakmonObjectsInReportTable &aObjectsInReport) { mIsInitialized = PR_TRUE; JSContext *cx = leakmonService::GetJSContext(); NS_ENSURE_TRUE(cx, NS_ERROR_UNEXPECTED); JSAutoRequest ar(cx); if (!JSVAL_IS_PRIMITIVE(mJSValue)) { JSObject *obj = JSVAL_TO_OBJECT(mJSValue); // All of the objects in obj's prototype chain, and all // objects reachable from JS_NewPropertyIterator should // (I think?) be in the same compartment. JSAutoEnterCompartment ac; if (!ac.enter(cx, obj)) { return NS_ERROR_FAILURE; } JSObject *p; for (p = obj; p; p = JS_GetPrototype(cx, p)) { // Stack-scanning protects newly-created objects // (etor) from GC. (And protecting |etor| // should in turn protect |id|.) // JS_NewPropertyIterator has the nice property that it // avoids JS_Enumerate on native objects (where it can // execute code) and uses the scope properties, but doesn't // require this code to use the unstable OBJ_IS_NATIVE API. JSObject *etor = JS_NewPropertyIterator(cx, p); if (!etor) return NS_ERROR_OUT_OF_MEMORY; jsid id; while (JS_NextProperty(cx, etor, &id) && !JSID_IS_VOID(id)) { nsresult rv = AppendProperty(id, cx, aObjectsInReport); NS_ENSURE_SUCCESS(rv, rv); } } if (JS_ObjectIsFunction(cx, obj)) { JSFunction *fun = JS_ValueToFunction(cx, mJSValue); NS_ENSURE_TRUE(fun, NS_ERROR_UNEXPECTED); JSScript *script = JS_GetFunctionScript(cx, fun); if (script) { // null for native code const char *fname = JS_GetScriptFilename(cx, script); // XXX Do we know the encoding of this file name? mFileName = NS_ConvertUTF8toUTF16(fname); mLineStart = JS_GetScriptBaseLineNumber(cx, script); mLineEnd = mLineStart + JS_GetScriptLineExtent(cx, script) - 1; } } } ValueToString(cx, mJSValue, mString); return NS_OK; }
// If you change this code, change also nsContentUtils::CanAccessNativeAnon()! JSBool AllowedToAct(JSContext *cx, jsid id) { // TODO bug 508928: Refactor this with the XOW security checking code. nsIScriptSecurityManager *ssm = GetSecurityManager(); if (!ssm) { return JS_TRUE; } JSStackFrame *fp; nsIPrincipal *principal = ssm->GetCxSubjectPrincipalAndFrame(cx, &fp); if (!principal) { return ThrowException(NS_ERROR_UNEXPECTED, cx); } if (!fp) { if (!JS_FrameIterator(cx, &fp)) { // No code at all is running. So we must be arriving here as the result // of C++ code asking us to do something. Allow access. return JS_TRUE; } // Some code is running, we can't make the assumption, as above, but we // can't use a native frame, so clear fp. fp = nsnull; } else if (!fp->hasScript()) { fp = nsnull; } PRBool privileged; if (NS_SUCCEEDED(ssm->IsSystemPrincipal(principal, &privileged)) && privileged) { // Chrome things are allowed to touch us. return JS_TRUE; } // XXX HACK EWW! Allow chrome://global/ access to these things, even // if they've been cloned into less privileged contexts. const char *filename; if (fp && (filename = fp->getScript()->filename) && !strncmp(filename, prefix, NS_ARRAY_LENGTH(prefix) - 1)) { return JS_TRUE; } // Before we throw, check for UniversalXPConnect. nsresult rv = ssm->IsCapabilityEnabled("UniversalXPConnect", &privileged); if (NS_SUCCEEDED(rv) && privileged) { return JS_TRUE; } if (JSID_IS_VOID(id)) { ThrowException(NS_ERROR_XPC_SECURITY_MANAGER_VETO, cx); } else { // TODO Localize me? jsval idval; JSString *str; if (JS_IdToValue(cx, id, &idval) && (str = JS_ValueToString(cx, idval))) { JS_ReportError(cx, "Permission denied to access property '%hs' from a non-chrome context", JS_GetStringChars(str)); } } return JS_FALSE; }
static JSBool rpmxar_enumerate(JSContext *cx, JSObject *obj, JSIterateOp op, jsval *statep, jsid *idp) { void * ptr = JS_GetInstancePrivate(cx, obj, &rpmxarClass, NULL); rpmxar xar = ptr; int ix = 0; _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 xar %p\n", xar); break; case JSENUMERATE_NEXT: ix = JSVAL_TO_INT(*statep); if (!rpmxarNext(xar)) { const char * path = rpmxarPath(xar); struct stat * st = xmalloc(sizeof(*st)); JSObject * arr = JS_NewArrayObject(cx, 0, NULL); JSBool ok = JS_AddRoot(cx, &arr); JSObject * o; jsval v; v = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, path)); ok = JS_SetElement(cx, arr, 0, &v); if (!rpmxarStat(xar, st) && (o = JS_NewObject(cx, &rpmstClass, NULL, NULL)) != NULL && JS_SetPrivate(cx, o, (void *)st)) v = OBJECT_TO_JSVAL(o); else { st = _free(st); v = JSVAL_NULL; } ok = JS_SetElement(cx, arr, 1, &v); v = OBJECT_TO_JSVAL(arr); ok = JS_DefineElement(cx, obj, ix, v, NULL, NULL, JSPROP_ENUMERATE); (void) JS_RemoveRoot(cx, &arr); if (_debug) fprintf(stderr, "\tNEXT xar %p[%u] \"%s\"\n", xar, ix, path); path = _free(path); JS_ValueToId(cx, *statep, idp); *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 xar %p[%u]\n", xar, ix); *statep = JSVAL_NULL; break; } return JS_TRUE; }