Exemple #1
0
JSBool report_ruby_error_in_js(JohnsonRuntime* runtime, int state, VALUE old_errinfo)
{
  JSContext * context = johnson_get_current_context(runtime);
  assert(state);
  switch (state)
  {
    case TAG_RAISE:
      {
        VALUE local_error = ruby_errinfo;
        jsval js_err;
        ruby_errinfo = old_errinfo;
        if (!convert_to_js(runtime, local_error, &js_err))
          return JS_FALSE;
        JS_SetPendingException(context, js_err);
        return JS_FALSE;
      }

    case TAG_THROW:
      // FIXME: This should be propagated to JS... as an exception?

    default:
      {
        JSString* str = JS_NewStringCopyZ(context, "Unexpected longjmp from ruby!");
        if (str)
          JS_SetPendingException(context, STRING_TO_JSVAL(str));
        return JS_FALSE;
      }
  }
}
Exemple #2
0
JSBool
gjs_move_exception(JSContext      *src_context,
                   JSContext      *dest_context)
{
    JSBool success;

    JS_BeginRequest(src_context);
    JS_BeginRequest(dest_context);

    /* NOTE: src and dest could be the same. */
    jsval exc;
    if (JS_GetPendingException(src_context, &exc)) {
        if (src_context != dest_context) {
            /* try to add the current stack of dest_context to the
             * stack trace of exc */
            try_to_chain_stack_trace(src_context, dest_context, exc);
            /* move the exception to dest_context */
            JS_SetPendingException(dest_context, exc);
            JS_ClearPendingException(src_context);
        }
        success = JS_TRUE;
    } else {
        success = JS_FALSE;
    }

    JS_EndRequest(dest_context);
    JS_EndRequest(src_context);

    return success;
}
/* void throwArg (); */
NS_IMETHODIMP
xpctestEcho::ThrowArg(void)
{
    GET_CALL_CONTEXT;
    if(NS_FAILED(rv) || !cc)
        return NS_ERROR_FAILURE;

    nsCOMPtr<nsISupports> callee;
    if(NS_FAILED(cc->GetCallee(getter_AddRefs(callee))) || 
       callee != static_cast<nsIEcho*>(this))
        return NS_ERROR_FAILURE;

    PRUint32 argc;
    if(NS_FAILED(cc->GetArgc(&argc)) || !argc)
        return NS_OK;

    jsval* argv;
    JSContext* cx;
    if(NS_FAILED(cc->GetArgvPtr(&argv)) ||
       NS_FAILED(cc->GetJSContext(&cx)))
        return NS_ERROR_FAILURE;

    JS_SetPendingException(cx, argv[0]);
    return NS_OK;
}
Exemple #4
0
JSBool report_ruby_error_in_js(JohnsonRuntime* runtime, int state, VALUE old_errinfo)
{
  JSContext * context = johnson_get_current_context(runtime);
  assert(state);
  switch (state)
  {
    case TAG_RAISE:
      {
        VALUE local_error = ruby_errinfo;
        ruby_errinfo = old_errinfo;

        local_error = rb_funcall(local_error, rb_intern("inspect"), 0);
        JS_ReportError(context, StringValuePtr(local_error));

        return JS_FALSE ;
      }

    case TAG_THROW:
      // FIXME: This should be propagated to JS... as an exception?

    default:
      {
        JSString* str = JS_NewStringCopyZ(context, "Unexpected longjmp from ruby!");
        if (str)
          JS_SetPendingException(context, STRING_TO_JSVAL(str));
        return JS_FALSE;
      }
  }
}
Exemple #5
0
/*
 * Common subroutine of generator_(next|send|throw|close) methods.
 */
static JSBool
generator_op(JSContext *cx, JSGeneratorOp op, jsval *vp, uintN argc)
{
    JSObject *obj;
    JSGenerator *gen;
    jsval arg;

    obj = JS_THIS_OBJECT(cx, vp);
    if (!JS_InstanceOf(cx, obj, &js_GeneratorClass, vp + 2))
        return JS_FALSE;

    gen = (JSGenerator *) JS_GetPrivate(cx, obj);
    if (gen == NULL) {
        /* This happens when obj is the generator prototype. See bug 352885. */
        goto closed_generator;
    }

    if (gen->state == JSGEN_NEWBORN) {
        switch (op) {
          case JSGENOP_NEXT:
          case JSGENOP_THROW:
            break;

          case JSGENOP_SEND:
            if (argc >= 1 && !JSVAL_IS_VOID(vp[2])) {
                js_ReportValueError(cx, JSMSG_BAD_GENERATOR_SEND,
                                    JSDVG_SEARCH_STACK, vp[2], NULL);
                return JS_FALSE;
            }
            break;

          default:
            JS_ASSERT(op == JSGENOP_CLOSE);
            gen->state = JSGEN_CLOSED;
            return JS_TRUE;
        }
    } else if (gen->state == JSGEN_CLOSED) {
      closed_generator:
        switch (op) {
          case JSGENOP_NEXT:
          case JSGENOP_SEND:
            return js_ThrowStopIteration(cx);
          case JSGENOP_THROW:
            JS_SetPendingException(cx, argc >= 1 ? vp[2] : JSVAL_VOID);
            return JS_FALSE;
          default:
            JS_ASSERT(op == JSGENOP_CLOSE);
            return JS_TRUE;
        }
    }

    arg = ((op == JSGENOP_SEND || op == JSGENOP_THROW) && argc != 0)
          ? vp[2]
          : JSVAL_VOID;
    if (!SendToGenerator(cx, op, obj, gen, arg))
        return JS_FALSE;
    *vp = gen->frame.rval;
    return JS_TRUE;
}
// static
JSBool
XPCThrower::ThrowExceptionObject(JSContext* cx, nsIException* e)
{
    JSBool success = JS_FALSE;
    if(e)
    {
        nsCOMPtr<nsIXPCException> xpcEx;
        jsval thrown;
        nsXPConnect* xpc;

        // If we stored the original thrown JS value in the exception
        // (see XPCConvert::ConstructException) and we are in a web
        // context (i.e., not chrome), rethrow the original value.
        if(!IsCallerChrome(cx) &&
           (xpcEx = do_QueryInterface(e)) &&
           NS_SUCCEEDED(xpcEx->StealJSVal(&thrown)))
        {
            if (!JS_WrapValue(cx, &thrown))
                return JS_FALSE;
            JS_SetPendingException(cx, thrown);
            success = JS_TRUE;
        }
        else if((xpc = nsXPConnect::GetXPConnect()))
        {
            JSObject* glob = JS_GetScopeChain(cx);
            if(!glob)
                return JS_FALSE;
            glob = JS_GetGlobalForObject(cx, glob);

            nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
            nsresult rv = xpc->WrapNative(cx, glob, e,
                                          NS_GET_IID(nsIException),
                                          getter_AddRefs(holder));
            if(NS_SUCCEEDED(rv) && holder)
            {
                JSObject* obj;
                if(NS_SUCCEEDED(holder->GetJSObject(&obj)))
                {
                    JS_SetPendingException(cx, OBJECT_TO_JSVAL(obj));
                    success = JS_TRUE;
                }
            }
        }
    }
    return success;
}
Exemple #7
0
/*
 * Class:     com_google_gwt_dev_shell_moz_LowLevelMoz
 * Method:    _raiseJavaScriptException
 * Signature: ()Z
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_moz_LowLevelMoz__1raiseJavaScriptException
(JNIEnv* env, jclass)
{
    Tracer tracer("LowLevelMoz._raiseJavaScriptException");
    JS_SetPendingException(JsRootedValue::currentContext(), JSVAL_NULL);
    return JNI_TRUE;
}
void
AutoJSAPI::ReportException()
{
  MOZ_ASSERT(OwnsErrorReporting(), "This is not our exception to report!");
  if (!HasException()) {
    return;
  }

  // AutoJSAPI uses a JSAutoNullableCompartment, and may be in a null
  // compartment when the destructor is called. However, the JS engine
  // requires us to be in a compartment when we fetch the pending exception.
  // In this case, we enter the privileged junk scope and don't dispatch any
  // error events.
  JS::Rooted<JSObject*> errorGlobal(cx(), JS::CurrentGlobalOrNull(cx()));
  if (!errorGlobal) {
    if (mIsMainThread) {
      errorGlobal = xpc::PrivilegedJunkScope();
    } else {
      errorGlobal = workers::GetCurrentThreadWorkerGlobal();
    }
  }
  JSAutoCompartment ac(cx(), errorGlobal);
  JS::Rooted<JS::Value> exn(cx());
  js::ErrorReport jsReport(cx());
  if (StealException(&exn) && jsReport.init(cx(), exn)) {
    if (mIsMainThread) {
      RefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();
      RefPtr<nsGlobalWindow> win = xpc::WindowGlobalOrNull(errorGlobal);
      nsPIDOMWindowInner* inner = win ? win->AsInner() : nullptr;
      xpcReport->Init(jsReport.report(), jsReport.message(),
                      nsContentUtils::IsCallerChrome(),
                      inner ? inner->WindowID() : 0);
      if (inner) {
        DispatchScriptErrorEvent(inner, JS_GetRuntime(cx()), xpcReport, exn);
      } else {
        xpcReport->LogToConsole();
      }
    } else {
      // On a worker, we just use the worker error reporting mechanism and don't
      // bother with xpc::ErrorReport.  This will ensure that all the right
      // events (which are a lot more complicated than in the window case) get
      // fired.
      workers::WorkerPrivate* worker = workers::GetCurrentThreadWorkerPrivate();
      MOZ_ASSERT(worker);
      MOZ_ASSERT(worker->GetJSContext() == cx());
      // Before invoking ReportError, put the exception back on the context,
      // because it may want to put it in its error events and has no other way
      // to get hold of it.  After we invoke ReportError, clear the exception on
      // cx(), just in case ReportError didn't.
      JS_SetPendingException(cx(), exn);
      worker->ReportError(cx(), jsReport.message(), jsReport.report());
      ClearException();
    }
  } else {
    NS_WARNING("OOMed while acquiring uncaught exception from JSAPI");
    ClearException();
  }
}
Exemple #9
0
JSBool
js_ThrowStopIteration(JSContext *cx)
{
    jsval v;

    JS_ASSERT(!JS_IsExceptionPending(cx));
    if (js_FindClassObject(cx, NULL, INT_TO_JSID(JSProto_StopIteration), &v))
        JS_SetPendingException(cx, v);
    return JS_FALSE;
}
Exemple #10
0
void
ThrowDOMExceptionForNSResult(JSContext* aCx, nsresult aNSResult)
{
  JSObject* exception = DOMException::Create(aCx, aNSResult);
  if (!exception) {
    return;
  }

  JS_SetPendingException(aCx, OBJECT_TO_JSVAL(exception));
}
Exemple #11
0
static JSBool DriverManager_getConnection(JSContext *cx, unsigned argc, jsval *vp)
{
	jsval drivers;
	JS_LookupProperty(cx, JS_THIS_OBJECT(cx, vp), "drivers", &drivers);
	// FIXME check return code; check that drivers is an array
	JSObject *obj = JSVAL_TO_OBJECT(drivers);

	uint32_t len, i;
	JS_GetArrayLength(cx, obj, &len);


	jsval connect_argv[2] = {JS_ARGV(cx, vp)[0]};
	if (argc == 2) {
		/* Caller passed "info" object, so we forward it as-is */
		connect_argv[1] = JS_ARGV(cx, vp)[1];
	} else {
		JSObject *info = JS_NewObject(cx, NULL, NULL, NULL); // FIXME root it to avoid GC
		if (argc > 1)
			JS_DefineProperty(cx, info, "user", JS_ARGV(cx, vp)[1], NULL, NULL, JSPROP_ENUMERATE);
		if (argc > 2)
			JS_DefineProperty(cx, info, "password", JS_ARGV(cx, vp)[2], NULL, NULL, JSPROP_ENUMERATE);

		connect_argv[1] = OBJECT_TO_JSVAL(info);
	};

	jsval reason = JSVAL_NULL;
	for (i = 0; i < len; i++) {
		jsval driver, rval;
		JS_GetElement(cx, obj, i, &driver);

		if (!JS_CallFunctionName(cx, JSVAL_TO_OBJECT(driver), "connect", 2, &connect_argv[0], &rval)) {
			if (JSVAL_IS_NULL(reason))
				JS_GetPendingException(cx, &reason);
			continue;
		}
		if (JSVAL_IS_NULL(rval))
			continue;
		JS_SET_RVAL(cx, vp, rval);
		return JS_TRUE;
	}

	if (JSVAL_IS_NULL(reason)) {
		JSString *url_str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
		// FIXME check return value
		// FIXME root url_str (protect from GC) -> https://developer.mozilla.org/en-US/docs/SpiderMonkey/JSAPI_Reference/JS_ValueToString
		char *url = JS_EncodeString(cx, url_str);
		JS_ReportError(cx, "No suitable driver found for %s", url);
		JS_free(cx, url);
	} else
		JS_SetPendingException(cx, reason);

	JS_SET_RVAL(cx, vp, JSVAL_NULL);
	return JS_FALSE;
}
Exemple #12
0
void ScriptInterface::ReportError(const char* msg)
{
	// JS_ReportError by itself doesn't seem to set a JS-style exception, and so
	// script callers will be unable to catch anything. So use JS_SetPendingException
	// to make sure there really is a script-level exception. But just set it to undefined
	// because there's not much value yet in throwing a real exception object.
	JS_SetPendingException(m->m_cx, JSVAL_VOID);
	// And report the actual error
	JS_ReportError(m->m_cx, "%s", msg);

	// TODO: Why doesn't JS_ReportPendingException(m->m_cx); work?
}
Exemple #13
0
static void
js_txn_deadlock(JSContext *cx, js_db_t *jd)
{
    if(JS_IsExceptionPending(cx))
        return;

    if(jd->jd_debug)
        TRACE(TRACE_DEBUG, "JS", "Raising deadlock exception");

    JSObject *obj = JS_NewObjectWithGivenProto(cx, &db_deadlock_exn, NULL, NULL);
    JS_SetPendingException(cx, OBJECT_TO_JSVAL(obj));
}
Exemple #14
0
/**
 * Calls a method on a Java object and returns a two-element JS array, with
 * the first element being a boolean flag indicating an exception was thrown,
 * and the second element is the actual return value or exception.
 */
JSBool JavaObject::invokeJava(JSContext* ctx, SessionData* data,
    const gwt::Value& javaThis, int dispId, int numArgs, const jsval* jsargs,
    jsval* rval) {
  HostChannel* channel = data->getHostChannel();
  SessionHandler* handler = data->getSessionHandler();
  scoped_array<gwt::Value> args(new gwt::Value[numArgs]);
  for (int i = 0; i < numArgs; ++i) {
    data->makeValueFromJsval(args[i], ctx, jsargs[i]);
  }

  bool isException = false;
  gwt::Value returnValue;
  if (!InvokeMessage::send(*channel, javaThis, dispId, numArgs, args.get())) {
    Debug::log(Debug::Debugging) << "JavaObject::call failed to send invoke message" << Debug::flush;
  } else {
    Debug::log(Debug::Spam) << " return from invoke" << Debug::flush;
    scoped_ptr<ReturnMessage> retMsg(channel->reactToMessagesWhileWaitingForReturn(handler));
    if (!retMsg.get()) {
      Debug::log(Debug::Debugging) << "JavaObject::call failed to get return value" << Debug::flush;
    } else {
      isException = retMsg->isException();
      returnValue = retMsg->getReturnValue();
    }
  }
  // Since we can set exceptions normally, we always return false to the
  // wrapper function and set the exception ourselves if one occurs.
  // TODO: cleanup exception case
  jsval retvalArray[] = {JSVAL_FALSE, JSVAL_VOID};
  JSObject* retval = JS_NewArrayObject(ctx, 2, retvalArray);
  *rval = OBJECT_TO_JSVAL(retval);
  jsval retJsVal;
  Debug::log(Debug::Spam) << "  result is " << returnValue << Debug::flush;
  data->makeJsvalFromValue(retJsVal, ctx, returnValue);
  if (isException) {
    JS::MutableHandleValue argHandle = JS::MutableHandleValue::fromMarkedLocation(&retJsVal);
    JS_SetPendingException(ctx, argHandle);
    return false;
  }
#if GECKO_VERSION >= 26000
        JS::Rooted<JS::Value> tmp(ctx);
        tmp = retJsVal;
#else
        jsval tmp = retJsVal;
#endif
  if (!JS_SetElement(ctx, retval, 1, &tmp)) {
    Debug::log(Debug::Error) << "Error setting return value element in array"
        << Debug::flush;
    return false;
  }
  return true;
}
Exemple #15
0
JSBool
jsd_SetException(JSDContext* jsdc, JSDThreadState* jsdthreadstate, 
                 JSDValue* jsdval)
{
    JSContext* cx;

    if(!(cx = _getContextForThreadState(jsdc, jsdthreadstate)))
        return JS_FALSE;

    if(jsdval)
        JS_SetPendingException(cx, JSD_GetValueWrappedJSVal(jsdc, jsdval));
    else
        JS_ClearPendingException(cx);
    return JS_TRUE;
}
Exemple #16
0
/* void CanAccess (in PRUint32 aAction, in nsIXPCNativeCallContext aCallContext, in JSContextPtr aJSContext, in JSObjectPtr aJSObject, in nsISupports aObj, in nsIClassInfo aClassInfo, in jsid aName, inout voidPtr aPolicy); */
NS_IMETHODIMP 
MySecMan::CanAccess(PRUint32 aAction, nsAXPCNativeCallContext *aCallContext, JSContext * aJSContext, JSObject * aJSObject, nsISupports *aObj, nsIClassInfo *aClassInfo, jsid aName, void * *aPolicy)
{
    switch(mMode)
    {
        case OK_ALL:
            return NS_OK;
        case VETO_ALL:
            JS_SetPendingException(aJSContext,
                STRING_TO_JSVAL(JS_NewStringCopyZ(aJSContext,
                    "security exception")));
            return NS_ERROR_FAILURE;
        default:
            NS_ERROR("bad case");
            return NS_OK;
    }
}
Exemple #17
0
NS_IMETHODIMP
MySecMan::CanGetService(JSContext * aJSContext, const nsCID & aCID)
{
    switch(mMode)
    {
        case OK_ALL:
            return NS_OK;
        case VETO_ALL:
            JS_SetPendingException(aJSContext,
                STRING_TO_JSVAL(JS_NewStringCopyZ(aJSContext,
                    "security exception")));
            return NS_ERROR_FAILURE;
        default:
            NS_ERROR("bad case");
            return NS_OK;
    }
}
Exemple #18
0
NS_IMETHODIMP
MySecMan::CanCreateWrapper(JSContext * aJSContext, const nsIID & aIID, nsISupports *aObj, nsIClassInfo *aClassInfo, void * *aPolicy)
{
    switch(mMode)
    {
        case OK_ALL:
            return NS_OK;
        case VETO_ALL:
            JS_SetPendingException(aJSContext,
                STRING_TO_JSVAL(JS_NewStringCopyZ(aJSContext,
                    "security exception")));
            return NS_ERROR_FAILURE;
        default:
            NS_ERROR("bad case");
            return NS_OK;
    }
}
Exemple #19
0
/**
 * gjs_throw_g_error:
 *
 * Convert a GError into a JavaScript Exception, and
 * frees the GError. Differently from gjs_throw(), it
 * will overwrite an existing exception, as it is used
 * to report errors from C functions.
 */
void
gjs_throw_g_error (JSContext       *context,
                   GError          *error)
{
    JSObject *err_obj;

    if (error == NULL)
        return;

    JS_BeginRequest(context);

    err_obj = gjs_error_from_gerror(context, error, TRUE);
    if (err_obj)
        JS_SetPendingException(context, OBJECT_TO_JSVAL(err_obj));

    JS_EndRequest(context);
}
Exemple #20
0
void propagate2JS(
    pTHX_
    PJS_Context *pcx,
    JSObject *obj
) {
    JSContext *cx = PJS_getJScx(pcx);
    if(PJS_getFlag(pcx, "ReflectExceptions")) {
	jsval rval;
	SV* cp = newSVsv(ERRSV);
	if(!PJS_ReflectPerl2JS(aTHX_ cx, obj, cp, &rval)) 
	    croak("Can't convert perl error into JSVAL");
	JS_SetPendingException(cx, rval);
	sv_setsv(ERRSV, &PL_sv_undef);            
	sv_free(cp);
    } else {
	JS_ClearPendingException(cx);
    }
}
Exemple #21
0
	END_FUNCTION_SPEC

END_CLASS



NEVER_INLINE bool FASTCALL
ThrowIoErrorArg( JSContext *cx, PRErrorCode errorCode, PRInt32 osError ) {

	JS::RootedObject error(cx, jl::newObjectWithGivenProto( cx, JL_CLASS(IoError), JL_CLASS_PROTOTYPE(cx, IoError)));
	JS::RootedValue tmp(cx);
	JL_ASSERT_ALLOC( error );
	tmp.setObject(*error);
	JS_SetPendingException( cx, tmp );

	tmp.setInt32(errorCode);
	JL_CHK( JL_SetReservedSlot( error, 0, tmp ) );
	tmp.setInt32(osError);
	JL_CHK( JL_SetReservedSlot( error, 1, tmp ) );
	JL_SAFE( jl::addScriptLocation(cx, &error) );
	JL_BAD;
}
Exemple #22
0
JSBool
js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp)
{
    JSErrNum errorNumber;
    const JSErrorFormatString *errorString;
    JSExnType exn;
    jsval tv[4];
    JSTempValueRooter tvr;
    JSBool ok;
    JSObject *errProto, *errObject;
    JSString *messageStr, *filenameStr;

    /*
     * Tell our caller to report immediately if cx has no active frames, or if
     * this report is just a warning.
     */
    JS_ASSERT(reportp);
    if (!cx->fp || JSREPORT_IS_WARNING(reportp->flags))
        return JS_FALSE;

    /* Find the exception index associated with this error. */
    errorNumber = (JSErrNum) reportp->errorNumber;
    errorString = js_GetLocalizedErrorMessage(cx, NULL, NULL, errorNumber);
    exn = errorString ? (JSExnType) errorString->exnType : JSEXN_NONE;
    JS_ASSERT(exn < JSEXN_LIMIT);

#if defined( DEBUG_mccabe ) && defined ( PRINTNAMES )
    /* Print the error name and the associated exception name to stderr */
    fprintf(stderr, "%s\t%s\n",
            errortoexnname[errorNumber].name,
            errortoexnname[errorNumber].exception);
#endif

    /*
     * Return false (no exception raised) if no exception is associated
     * with the given error number.
     */
    if (exn == JSEXN_NONE)
        return JS_FALSE;

    /*
     * Prevent runaway recursion, via cx->generatingError.  If an out-of-memory
     * error occurs, no exception object will be created, but we don't assume
     * that OOM is the only kind of error that subroutines of this function
     * called below might raise.
     */
    if (cx->generatingError)
        return JS_FALSE;

    /* After this point the control must flow through the label out. */
    cx->generatingError = JS_TRUE;

    /* Protect the newly-created strings below from nesting GCs. */
    memset(tv, 0, sizeof tv);
    JS_PUSH_TEMP_ROOT(cx, JS_ARRAY_LENGTH(tv), tv, &tvr);

    /*
     * Try to get an appropriate prototype by looking up the corresponding
     * exception constructor name in the scope chain of the current context's
     * top stack frame, or in the global object if no frame is active.
     */
    ok = js_GetClassPrototype(cx, NULL, INT_TO_JSID(exceptions[exn].key),
                              &errProto);
    if (!ok)
        goto out;
    tv[0] = OBJECT_TO_JSVAL(errProto);

    errObject = js_NewObject(cx, &js_ErrorClass, errProto, NULL, 0);
    if (!errObject) {
        ok = JS_FALSE;
        goto out;
    }
    tv[1] = OBJECT_TO_JSVAL(errObject);

    messageStr = JS_NewStringCopyZ(cx, message);
    if (!messageStr) {
        ok = JS_FALSE;
        goto out;
    }
    tv[2] = STRING_TO_JSVAL(messageStr);

    filenameStr = JS_NewStringCopyZ(cx, reportp->filename);
    if (!filenameStr) {
        ok = JS_FALSE;
        goto out;
    }
    tv[3] = STRING_TO_JSVAL(filenameStr);

    ok = InitExnPrivate(cx, errObject, messageStr, filenameStr,
                        reportp->lineno, reportp);
    if (!ok)
        goto out;

    JS_SetPendingException(cx, OBJECT_TO_JSVAL(errObject));

    /* Flag the error report passed in to indicate an exception was raised. */
    reportp->flags |= JSREPORT_EXCEPTION;

out:
    JS_POP_TEMP_ROOT(cx, &tvr);
    cx->generatingError = JS_FALSE;
    return ok;
}
Exemple #23
0
void
gjstest_test_func_gjs_jsapi_util_error_throw(void)
{
    GjsUnitTestFixture fixture;
    JSContext *context;
    jsval exc, value, previous;
    char *s = NULL;
    int strcmp_result;

    _gjs_unit_test_fixture_begin(&fixture);
    context = fixture.context;

    /* Test that we can throw */

    gjs_throw(context, "This is an exception %d", 42);

    g_assert(JS_IsExceptionPending(context));

    exc = JSVAL_VOID;
    JS_GetPendingException(context, &exc);
    g_assert(!JSVAL_IS_VOID(exc));

    value = JSVAL_VOID;
    JS_GetProperty(context, JSVAL_TO_OBJECT(exc), "message",
                   &value);

    g_assert(JSVAL_IS_STRING(value));

    gjs_string_get_binary_data (context, value, &s, NULL);
    g_assert(s != NULL);
    strcmp_result = strcmp(s, "This is an exception 42");
    free(s);
    if (strcmp_result != 0)
        g_error("Exception has wrong message '%s'", s);

    /* keep this around before we clear it */
    previous = exc;
    JS_AddValueRoot(context, &previous);

    JS_ClearPendingException(context);

    g_assert(!JS_IsExceptionPending(context));

    /* Check that we don't overwrite a pending exception */
    JS_SetPendingException(context, previous);

    g_assert(JS_IsExceptionPending(context));

    gjs_throw(context, "Second different exception %s", "foo");

    g_assert(JS_IsExceptionPending(context));

    exc = JSVAL_VOID;
    JS_GetPendingException(context, &exc);
    g_assert(!JSVAL_IS_VOID(exc));
    g_assert(exc == previous);

    JS_RemoveValueRoot(context, &previous);

    _gjs_unit_test_fixture_finish(&fixture);
}
Exemple #24
0
JSBool js_destroy(JSContext *context) {
    JS_SetPendingException(context, STRING_TO_JSVAL(JS_NewStringCopyZ(context, "timeout")));
    return JS_FALSE;
}
Exemple #25
0
JSBool
js_ReportUncaughtException(JSContext *cx)
{
    jsval exn;
    JSObject *exnObject;
    jsval roots[5];
    JSTempValueRooter tvr;
    JSErrorReport *reportp, report;
    JSString *str;
    const char *bytes;
    JSBool ok;

    if (!JS_IsExceptionPending(cx))
        return JS_TRUE;

    if (!JS_GetPendingException(cx, &exn))
        return JS_FALSE;

    memset(roots, 0, sizeof roots);
    JS_PUSH_TEMP_ROOT(cx, JS_ARRAY_LENGTH(roots), roots, &tvr);

    /*
     * Because js_ValueToString below could error and an exception object
     * could become unrooted, we must root exnObject.  Later, if exnObject is
     * non-null, we need to root other intermediates, so allocate an operand
     * stack segment to protect all of these values.
     */
    if (JSVAL_IS_PRIMITIVE(exn)) {
        exnObject = NULL;
    } else {
        exnObject = JSVAL_TO_OBJECT(exn);
        roots[0] = exn;
    }

    JS_ClearPendingException(cx);
    reportp = js_ErrorFromException(cx, exn);

    /* XXX L10N angels cry once again (see also jsemit.c, /L10N gaffes/) */
    str = js_ValueToString(cx, exn);
    if (!str) {
        bytes = "unknown (can't convert to string)";
    } else {
        roots[1] = STRING_TO_JSVAL(str);
        bytes = js_GetStringBytes(cx, str);
        if (!bytes) {
            ok = JS_FALSE;
            goto out;
        }
    }
    ok = JS_TRUE;

    if (!reportp &&
        exnObject &&
        OBJ_GET_CLASS(cx, exnObject) == &js_ErrorClass) {
        const char *filename;
        uint32 lineno;

        ok = JS_GetProperty(cx, exnObject, js_message_str, &roots[2]);
        if (!ok)
            goto out;
        if (JSVAL_IS_STRING(roots[2])) {
            bytes = js_GetStringBytes(cx, JSVAL_TO_STRING(roots[2]));
            if (!bytes) {
                ok = JS_FALSE;
                goto out;
            }
        }

        ok = JS_GetProperty(cx, exnObject, js_fileName_str, &roots[3]);
        if (!ok)
            goto out;
        str = js_ValueToString(cx, roots[3]);
        if (!str) {
            ok = JS_FALSE;
            goto out;
        }
        filename = StringToFilename(cx, str);
        if (!filename) {
            ok = JS_FALSE;
            goto out;
        }

        ok = JS_GetProperty(cx, exnObject, js_lineNumber_str, &roots[4]);
        if (!ok)
            goto out;
        lineno = js_ValueToECMAUint32 (cx, &roots[4]);
        ok = !JSVAL_IS_NULL(roots[4]);
        if (!ok)
            goto out;

        reportp = &report;
        memset(&report, 0, sizeof report);
        report.filename = filename;
        report.lineno = (uintN) lineno;
    }

    if (!reportp) {
        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                             JSMSG_UNCAUGHT_EXCEPTION, bytes);
    } else {
        /* Flag the error as an exception. */
        reportp->flags |= JSREPORT_EXCEPTION;

        /* Pass the exception object. */
        JS_SetPendingException(cx, exn);
        js_ReportErrorAgain(cx, bytes, reportp);
        JS_ClearPendingException(cx);
    }

out:
    JS_POP_TEMP_ROOT(cx, &tvr);
    return ok;
}
Exemple #26
0
/*
 * This is a wrapper around JS_ReportError(), useful when an error condition
 * is the result of a JVM failure or exception condition.  It appends the
 * message associated with the pending Java exception to the passed in
 * printf-style format string and arguments.
 */
static void
vreport_java_error(JSContext *cx, JNIEnv *jEnv, const char *format, va_list ap)
{
    jobject java_obj;
    jclass java_class;
    JavaClassDescriptor *class_descriptor;
    jthrowable java_exception;
    JSType wrapped_exception_type;
    jsval js_exception;
       
    java_obj = NULL;
    class_descriptor = NULL;

    /* Get the exception out of the java environment. */
    java_exception = (*jEnv)->ExceptionOccurred(jEnv);
    if (!java_exception) {
        JSString *err_jsstr;
        char *err = JS_vsmprintf(format, ap);
        if (!err)
            return;
        err_jsstr = JS_NewString(cx, err, strlen(err));
        if (!err_jsstr)
            return;
        JS_SetPendingException(cx, STRING_TO_JSVAL(err_jsstr));
        return;
    }

    
    (*jEnv)->ExceptionClear(jEnv);
    
    /* Check for JSException */
    if (njJSException && 
        (*jEnv)->IsInstanceOf(jEnv, java_exception, njJSException)) {
        
        wrapped_exception_type = 
            (*jEnv)->GetIntField(jEnv, java_exception,
            njJSException_wrappedExceptionType);
        
        /* (int) to suppress warning */
        if ((int)wrapped_exception_type != JSTYPE_EMPTY) {
            java_obj = 
                (*jEnv)->GetObjectField(jEnv, java_exception, 
                njJSException_wrappedException);
            
            if ((java_obj == NULL) && 
                (wrapped_exception_type == JSTYPE_OBJECT)) {
                js_exception = JSVAL_NULL;
            } else { 
                java_class = (*jEnv)->GetObjectClass(jEnv, java_obj); 
                class_descriptor = jsj_GetJavaClassDescriptor(cx, jEnv, java_class);
                /* OK to delete ref, since above call adds global ref */
                (*jEnv)->DeleteLocalRef(jEnv, java_class);  
                
                /* Convert native JS values back to native types. */
                switch(wrapped_exception_type) {
                case JSTYPE_NUMBER:
                    if (!jsj_ConvertJavaObjectToJSNumber(cx, jEnv,
                        class_descriptor,
                        java_obj, 
                        &js_exception))
                        goto error;
                    break;
                case JSTYPE_BOOLEAN:
                    if (!jsj_ConvertJavaObjectToJSBoolean(cx, jEnv,
                        class_descriptor,
                        java_obj, 
                        &js_exception))
                        goto error;
                    break;
                case JSTYPE_STRING:
                    if (!jsj_ConvertJavaObjectToJSString(cx, jEnv,
                        class_descriptor,
                        java_obj, 
                        &js_exception))
                        goto error;
                    break;
                case JSTYPE_VOID:
                    js_exception = JSVAL_VOID;
                    break;
                case JSTYPE_OBJECT:
                case JSTYPE_FUNCTION:
                default:
                    if ((*jEnv)->IsInstanceOf(jEnv, java_obj, njJSObject)) {
                        js_exception = OBJECT_TO_JSVAL(jsj_UnwrapJSObjectWrapper(jEnv, java_obj));
                        if (!js_exception)
                            goto error;                        
                    } else {
                        if (!jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_obj, 
                            &js_exception)) 
                            goto error;
                    }
                }
            }
        }
        /* Check for internal exception */
    } else {
        if (!JSJ_ConvertJavaObjectToJSValue(cx, java_exception,
            &js_exception)) {
            goto error;
        }
    }
    
    /* Set pending JS exception and clear the java exception. */
    JS_SetPendingException(cx, js_exception);                        
    goto done;

error:
    
    JS_ASSERT(0);
    jsj_LogError("Out of memory while attempting to throw JSException\n");
    
done:
    if (class_descriptor)
        jsj_ReleaseJavaClassDescriptor(cx, jEnv, class_descriptor);
    if (java_obj)
        (*jEnv)->DeleteLocalRef(jEnv, java_obj);
    if (java_exception)
        (*jEnv)->DeleteLocalRef(jEnv, java_exception);
}
Exemple #27
0
   void _sptInvoker::_reportError( JSContext *cx,
                                   INT32 rc,
                                   const bson::BSONObj &detail )
   {
      sdbSetErrno( rc ) ;

      if ( SDB_OK != rc )
      {
         stringstream ss ;
         BSONObjIterator itr( detail) ;
         INT32 fieldNum = detail.nFields() ;
         INT32 count = 0 ;
         while ( itr.more() )
         {
            if ( count > 0 )
            {
               ss << ", " ;
            }
            BSONElement e = itr.next() ;
            if ( fieldNum > 1 ||
                 0 != ossStrcmp( SPT_ERR, e.fieldName() ) )
            {
               ss << e.fieldName() << ": " ;
            }

            if ( String == e.type() )
            {
               ss << e.valuestr() ;
            }
            else if ( NumberInt == e.type() )
            {
               ss << e.numberInt() ;
            }
            else if ( NumberLong == e.type() )
            {
               ss << e.numberLong() ;
            }
            else if ( NumberDouble == e.type() )
            {
               ss << e.numberDouble() ;
            }
            else if ( Bool == e.type() )
            {
               ss << ( e.boolean() ? "true" : "false" ) ;
            }
            else
            {
               ss << e.toString( false, false ) ;
            }
            ++count ;
         }
         sdbSetErrMsg( ss.str().c_str() ) ;

         if ( sdbIsErrMsgEmpty() )
         {
            sdbSetErrMsg( getErrDesp( rc ) ) ;
         }

         JS_SetPendingException( cx , INT_TO_JSVAL( rc ) ) ;
      }
      else
      {
         sdbSetErrMsg( NULL ) ;
      }

      return ;
   }
Exemple #28
0
JSBool
js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp)
{
    JSErrNum errorNumber;
    JSExnType exn;
    JSBool ok;
    JSObject *errProto, *errObject;
    JSString *messageStr, *filenameStr;
    uintN lineno;
    JSExnPrivate *privateData;

    /* Find the exception index associated with this error. */
    JS_ASSERT(reportp);
    if (JSREPORT_IS_WARNING(reportp->flags))
        return JS_FALSE;
    errorNumber = (JSErrNum) reportp->errorNumber;
    exn = errorToExceptionNum[errorNumber];
    JS_ASSERT(exn < JSEXN_LIMIT);

#if defined( DEBUG_mccabe ) && defined ( PRINTNAMES )
    /* Print the error name and the associated exception name to stderr */
    fprintf(stderr, "%s\t%s\n",
            errortoexnname[errorNumber].name,
            errortoexnname[errorNumber].exception);
#endif

    /*
     * Return false (no exception raised) if no exception is associated
     * with the given error number.
     */
    if (exn == JSEXN_NONE)
        return JS_FALSE;

    /*
     * Prevent runaway recursion, just as the Exception native constructor
     * must do, via cx->creatingException.  If an out-of-memory error occurs,
     * no exception object will be created, but we don't assume that OOM is
     * the only kind of error that subroutines of this function called below
     * might raise.
     */
    if (cx->creatingException)
        return JS_FALSE;
    cx->creatingException = JS_TRUE;

    /*
     * Try to get an appropriate prototype by looking up the corresponding
     * exception constructor name in the scope chain of the current context's
     * top stack frame, or in the global object if no frame is active.
     *
     * XXXbe hack around JSCLASS_NEW_RESOLVE code in js_LookupProperty that
     *       checks cx->fp, cx->fp->pc, and js_CodeSpec[*cx->fp->pc] in order
     *       to compute resolve flags such as JSRESOLVE_ASSIGNING.  The bug
     *       is that this "internal" js_GetClassPrototype call may trigger a
     *       resolve of exceptions[exn].name if the global object uses a lazy
     *       standard class resolver (see JS_ResolveStandardClass), but the
     *       current frame and bytecode end up affecting the resolve flags.
     */
    {
        JSStackFrame *fp = cx->fp;
        jsbytecode *pc = NULL;

        if (fp) {
            pc = fp->pc;
            fp->pc = NULL;
        }
        ok = js_GetClassPrototype(cx, exceptions[exn].name, &errProto);
        if (pc)
            fp->pc = pc;
        if (!ok)
            goto out;
    }

    errObject = js_NewObject(cx, &ExceptionClass, errProto, NULL);
    if (!errObject) {
        ok = JS_FALSE;
        goto out;
    }

    messageStr = JS_NewStringCopyZ(cx, message);
    if (!messageStr) {
        ok = JS_FALSE;
        goto out;
    }

    if (reportp) {
        filenameStr = JS_NewStringCopyZ(cx, reportp->filename);
        if (!filenameStr) {
            ok = JS_FALSE;
            goto out;
        }
        lineno = reportp->lineno;
    } else {
        filenameStr = cx->runtime->emptyString;
        lineno = 0;
    }
    ok = InitExceptionObject(cx, errObject, messageStr, filenameStr, lineno);
    if (!ok)
        goto out;

    /*
     * Construct a new copy of the error report struct, and store it in the
     * exception object's private data.  We can't use the error report struct
     * that was passed in, because it's stack-allocated, and also because it
     * may point to transient data in the JSTokenStream.
     */
    privateData = exn_newPrivate(cx, reportp);
    if (!privateData) {
        ok = JS_FALSE;
        goto out;
    }
    OBJ_SET_SLOT(cx, errObject, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(privateData));

    /* Set the generated Exception object as the current exception. */
    JS_SetPendingException(cx, OBJECT_TO_JSVAL(errObject));

    /* Flag the error report passed in to indicate an exception was raised. */
    reportp->flags |= JSREPORT_EXCEPTION;

out:
    cx->creatingException = JS_FALSE;
    return ok;
}
Exemple #29
0
/*
 * See:
 * https://bugzilla.mozilla.org/show_bug.cgi?id=166436
 * https://bugzilla.mozilla.org/show_bug.cgi?id=215173
 *
 * Very surprisingly, jsapi.h lacks any way to "throw new Error()"
 *
 * So here is an awful hack inspired by
 * http://egachine.berlios.de/embedding-sm-best-practice/embedding-sm-best-practice.html#error-handling
 */
static void
gjs_throw_valist(JSContext       *context,
                 const char      *error_class,
                 const char      *format,
                 va_list          args)
{
    char *s;
    JSBool result;
    jsval v_constructor, v_message;
    JSObject *err_obj;

    s = g_strdup_vprintf(format, args);

    JS_BeginRequest(context);

    if (JS_IsExceptionPending(context)) {
        /* Often it's unclear whether a given jsapi.h function
         * will throw an exception, so we will throw ourselves
         * "just in case"; in those cases, we don't want to
         * overwrite an exception that already exists.
         * (Do log in case our second exception adds more info,
         * but don't log as topic ERROR because if the exception is
         * caught we don't want an ERROR in the logs.)
         */
        gjs_debug(GJS_DEBUG_CONTEXT,
                  "Ignoring second exception: '%s'",
                  s);
        g_free(s);
        JS_EndRequest(context);
        return;
    }

    result = JS_FALSE;

    (void)JS_EnterLocalRootScope(context);

    if (!gjs_string_from_utf8(context, s, -1, &v_message)) {
        JS_ReportError(context, "Failed to copy exception string");
        goto out;
    }

    if (!gjs_object_get_property(context, JS_GetGlobalObject(context),
                                 error_class, &v_constructor)) {
        JS_ReportError(context, "??? Missing Error constructor in global object?");
        goto out;
    }

    /* throw new Error(message) */
    err_obj = JS_New(context, JSVAL_TO_OBJECT(v_constructor), 1, &v_message);
    JS_SetPendingException(context, OBJECT_TO_JSVAL(err_obj));

    result = JS_TRUE;

 out:

    JS_LeaveLocalRootScope(context);

    if (!result) {
        /* try just reporting it to error handler? should not
         * happen though pretty much
         */
        JS_ReportError(context,
                       "Failed to throw exception '%s'",
                       s);
    }
    g_free(s);

    JS_EndRequest(context);
}
Exemple #30
0
static JSBool
log_and_maybe_keep_exception(JSContext  *context,
                             char      **message_p,
                             gboolean    keep)
{
    jsval exc = JSVAL_VOID;
    JSString *s;
    char *message;
    JSBool retval = JS_FALSE;

    JS_BeginRequest(context);

    if (message_p)
        *message_p = NULL;

    JS_AddRoot(context, &exc);
    if (!JS_GetPendingException(context, &exc))
        goto out;

    JS_ClearPendingException(context);

    s = JS_ValueToString(context, exc);

    if (s == NULL) {
        gjs_debug(GJS_DEBUG_ERROR,
                  "Failed to convert exception to string");
        goto out; /* Exception should be thrown already */
    }

    if (!gjs_string_to_utf8(context, STRING_TO_JSVAL(s), &message)) {
        gjs_debug(GJS_DEBUG_ERROR,
                  "Failed to convert exception string to UTF-8");
        goto out; /* Error already set */
    }

    gjs_debug(GJS_DEBUG_ERROR,
              "Exception was: %s",
              message);

    if (message_p) {
        *message_p = message;
    } else {
        g_free(message);
    }

    gjs_log_exception_props(context, exc);

    /* We clear above and then set it back so any exceptions
     * from the logging process don't overwrite the original
     */
    if (keep)
        JS_SetPendingException(context, exc);

    retval = JS_TRUE;

 out:
    JS_RemoveRoot(context, &exc);

    JS_EndRequest(context);

    return retval;
}