Esempio n. 1
0
// 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;
    }
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
    }
}
Esempio n. 6
0
	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;
	}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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;
            }
        }
    }
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
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);
}
Esempio n. 11
0
/* 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;
}
Esempio n. 12
0
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;
}
Esempio n. 13
0
// 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;
}
Esempio n. 14
0
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;
}