void Promise::CreateWrapper(JS::Handle<JSObject*> aDesiredProto, ErrorResult& aRv) { AutoJSAPI jsapi; if (!jsapi.Init(mGlobal)) { aRv.Throw(NS_ERROR_UNEXPECTED); return; } JSContext* cx = jsapi.cx(); JSFunction* doNothingFunc = JS_NewFunction(cx, DoNothingPromiseExecutor, /* nargs = */ 2, /* flags = */ 0, nullptr); if (!doNothingFunc) { JS_ClearPendingException(cx); aRv.Throw(NS_ERROR_OUT_OF_MEMORY); return; } JS::Rooted<JSObject*> doNothingObj(cx, JS_GetFunctionObject(doNothingFunc)); mPromiseObj = JS::NewPromiseObject(cx, doNothingObj, aDesiredProto); if (!mPromiseObj) { JS_ClearPendingException(cx); aRv.Throw(NS_ERROR_OUT_OF_MEMORY); return; } }
void FetchStreamReader::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) { if (mStreamClosed) { return; } // This promise should be resolved with { done: boolean, value: something }, // "value" is interesting only if done is false. // We don't want to play with JS api, let's WebIDL bindings doing it for us. // FetchReadableStreamReadDataDone is a dictionary with just a boolean, if the // parsing succeeded, we can proceed with the parsing of the "value", which it // must be a Uint8Array. FetchReadableStreamReadDataDone valueDone; if (!valueDone.Init(aCx, aValue)) { JS_ClearPendingException(aCx); CloseAndRelease(aCx, NS_ERROR_DOM_INVALID_STATE_ERR); return; } if (valueDone.mDone) { // Stream is completed. CloseAndRelease(aCx, NS_BASE_STREAM_CLOSED); return; } UniquePtr<FetchReadableStreamReadDataArray> value( new FetchReadableStreamReadDataArray); if (!value->Init(aCx, aValue) || !value->mValue.WasPassed()) { JS_ClearPendingException(aCx); CloseAndRelease(aCx, NS_ERROR_DOM_INVALID_STATE_ERR); return; } Uint8Array& array = value->mValue.Value(); array.ComputeLengthAndData(); uint32_t len = array.Length(); if (len == 0) { // If there is nothing to read, let's do another reading. OnOutputStreamReady(mPipeOut); return; } MOZ_DIAGNOSTIC_ASSERT(!mBuffer); mBuffer = Move(value); mBufferOffset = 0; mBufferRemaining = len; nsresult rv = WriteBuffer(); if (NS_FAILED(rv)) { // DOMException only understands errors from domerr.msg, so we normalize to // identifying an abort if the write fails. CloseAndRelease(aCx, NS_ERROR_DOM_ABORT_ERR); } }
void FileReader::OnLoadEndArrayBuffer() { AutoJSAPI jsapi; if (!jsapi.Init(GetParentObject())) { FreeDataAndDispatchError(NS_ERROR_FAILURE); return; } RootResultArrayBuffer(); JSContext* cx = jsapi.cx(); mResultArrayBuffer = JS_NewArrayBufferWithContents(cx, mDataLen, mFileData); if (mResultArrayBuffer) { mFileData = nullptr; // Transfer ownership FreeDataAndDispatchSuccess(); return; } // Let's handle the error status. JS::Rooted<JS::Value> exceptionValue(cx); if (!JS_GetPendingException(cx, &exceptionValue) || // This should not really happen, exception should always be an object. !exceptionValue.isObject()) { JS_ClearPendingException(jsapi.cx()); FreeDataAndDispatchError(NS_ERROR_OUT_OF_MEMORY); return; } JS_ClearPendingException(jsapi.cx()); JS::Rooted<JSObject*> exceptionObject(cx, &exceptionValue.toObject()); JSErrorReport* er = JS_ErrorFromException(cx, exceptionObject); if (!er || er->message()) { FreeDataAndDispatchError(NS_ERROR_OUT_OF_MEMORY); return; } nsAutoString errorName; JSFlatString* name = js::GetErrorTypeName(cx, er->exnType); if (name) { AssignJSFlatString(errorName, name); } nsAutoCString errorMsg(er->message().c_str()); nsAutoCString errorNameC = NS_LossyConvertUTF16toASCII(errorName); // XXX Code selected arbitrarily mError = new DOMException(NS_ERROR_DOM_INVALID_STATE_ERR, errorMsg, errorNameC, DOMException_Binding::INVALID_STATE_ERR); FreeDataAndDispatchError(); }
std::string ScriptInterface::StringifyJSON(jsval obj, bool indent) { Stringifier str; if (!JS_Stringify(m->m_cx, &obj, NULL, indent ? INT_TO_JSVAL(2) : JSVAL_VOID, &Stringifier::callback, &str)) { JS_ClearPendingException(m->m_cx); LOGERROR(L"StringifyJSON failed"); JS_ClearPendingException(m->m_cx); return std::string(); } return str.stream.str(); }
nsresult MobileConnectionCallback::NotifySendCancelMmiSuccessWithStrings(const nsAString& aServiceCode, const nsAString& aStatusMessage, uint32_t aCount, const char16_t** aAdditionalInformation) { AutoJSAPI jsapi; if (NS_WARN_IF(!jsapi.Init(mWindow))) { return NS_ERROR_FAILURE; } JSContext* cx = jsapi.cx(); RootedDictionary<MozMMIResult> result(cx); result.mServiceCode.Assign(aServiceCode); result.mStatusMessage.Assign(aStatusMessage); nsTArray<nsString> additionalInformation; for (uint32_t i = 0; i < aCount; i++) { additionalInformation.AppendElement(nsDependentString(aAdditionalInformation[i])); } JS::Rooted<JS::Value> jsAdditionalInformation(cx); if (!ToJSValue(cx, additionalInformation, &jsAdditionalInformation)) { JS_ClearPendingException(cx); return NS_ERROR_TYPE_ERR; } result.mAdditionalInformation.Construct().SetAsObject() = &jsAdditionalInformation.toObject(); return NotifySendCancelMmiSuccess(result); }
NS_IMETHODIMP MobileConnectionCallback::NotifyGetNetworksSuccess(uint32_t aCount, nsIMobileNetworkInfo** aNetworks) { nsTArray<nsRefPtr<MobileNetworkInfo>> results; for (uint32_t i = 0; i < aCount; i++) { nsRefPtr<MobileNetworkInfo> networkInfo = new MobileNetworkInfo(mWindow); networkInfo->Update(aNetworks[i]); results.AppendElement(networkInfo); } AutoJSAPI jsapi; if (NS_WARN_IF(!jsapi.Init(mWindow))) { return NS_ERROR_FAILURE; } JSContext* cx = jsapi.cx(); JS::Rooted<JS::Value> jsResult(cx); if (!ToJSValue(cx, results, &jsResult)) { JS_ClearPendingException(cx); return NS_ERROR_TYPE_ERR; } return NotifySuccess(jsResult); }
void JSWindowActor::QueryHandler::ResolvedCallback( JSContext* aCx, JS::Handle<JS::Value> aValue) { if (!mActor) { return; } ipc::StructuredCloneData data; data.InitScope(JS::StructuredCloneScope::DifferentProcess); IgnoredErrorResult error; data.Write(aCx, aValue, error); if (NS_WARN_IF(error.Failed())) { // We failed to serialize the message over IPC. Report this error to the // console, and send a reject reply. nsAutoString msg; msg.Append(mActor->Name()); msg.Append(':'); msg.Append(mMessageName); msg.Append(NS_LITERAL_STRING(": message reply cannot be cloned.")); nsContentUtils::LogSimpleConsoleError(msg, "chrome", false, true); JS_ClearPendingException(aCx); SendReply(aCx, JSWindowActorMessageKind::QueryReject, ipc::StructuredCloneData()); return; } SendReply(aCx, JSWindowActorMessageKind::QueryResolve, std::move(data)); }
bool ScriptInterface::ParseJSON(const std::string& string_utf8, JS::MutableHandleValue out) { JSAutoRequest rq(m->m_cx); std::wstring attrsW = wstring_from_utf8(string_utf8); utf16string string(attrsW.begin(), attrsW.end()); if (JS_ParseJSON(m->m_cx, reinterpret_cast<const jschar*>(string.c_str()), (u32)string.size(), out)) return true; LOGERROR("JS_ParseJSON failed!"); if (!JS_IsExceptionPending(m->m_cx)) return false; JS::RootedValue exc(m->m_cx); if (!JS_GetPendingException(m->m_cx, &exc)) return false; JS_ClearPendingException(m->m_cx); // We expect an object of type SyntaxError if (!exc.isObject()) return false; JS::RootedValue rval(m->m_cx); JS::RootedObject excObj(m->m_cx, &exc.toObject()); if (!JS_CallFunctionName(m->m_cx, excObj, "toString", JS::HandleValueArray::empty(), &rval)) return false; std::wstring error; ScriptInterface::FromJSVal(m->m_cx, rval, error); LOGERROR("%s", utf8_from_wstring(error)); return false; }
static void error_reporter(JSContext *ctx, const char *message, JSErrorReport *report) { unsigned char *strict, *exception, *warning, *error; struct string msg; if (!init_string(&msg)) goto reported; strict = JSREPORT_IS_STRICT(report->flags) ? " strict" : ""; exception = JSREPORT_IS_EXCEPTION(report->flags) ? " exception" : ""; warning = JSREPORT_IS_WARNING(report->flags) ? " warning" : ""; error = !report->flags ? " error" : ""; add_format_to_string(&msg, "A client script raised the following%s%s%s%s", strict, exception, warning, error); add_to_string(&msg, ":\n\n"); add_to_string(&msg, message); if (report->linebuf && report->tokenptr) { int pos = report->tokenptr - report->linebuf; add_format_to_string(&msg, "\n\n%s\n.%*s^%*s.", report->linebuf, pos - 2, " ", strlen(report->linebuf) - pos - 1, " "); } alert_smjs_error(msg.source); done_string(&msg); reported: JS_ClearPendingException(ctx); }
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 Promise::ReportRejectedPromise(JSContext* aCx, JS::HandleObject aPromise) { MOZ_ASSERT(!js::IsWrapper(aPromise)); MOZ_ASSERT(JS::GetPromiseState(aPromise) == JS::PromiseState::Rejected); JS::Rooted<JS::Value> result(aCx, JS::GetPromiseResult(aPromise)); js::ErrorReport report(aCx); if (!report.init(aCx, result, js::ErrorReport::NoSideEffects)) { JS_ClearPendingException(aCx); return; } RefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport(); bool isMainThread = MOZ_LIKELY(NS_IsMainThread()); bool isChrome = isMainThread ? nsContentUtils::IsSystemPrincipal(nsContentUtils::ObjectPrincipal(aPromise)) : GetCurrentThreadWorkerPrivate()->IsChromeWorker(); nsGlobalWindow* win = isMainThread ? xpc::WindowGlobalOrNull(aPromise) : nullptr; xpcReport->Init(report.report(), report.toStringResult().c_str(), isChrome, win ? win->AsInner()->WindowID() : 0); // Now post an event to do the real reporting async NS_DispatchToMainThread(new AsyncErrorReporter(xpcReport)); }
virtual bool MainThreadRun() override { AssertIsOnMainThread(); // Initialise an AutoJSAPI with the target window. AutoJSAPI jsapi; if (NS_WARN_IF(!jsapi.Init(mBackingStore->GetParentObject()))) { mRv.Throw(NS_ERROR_UNEXPECTED); return true; } JSContext* cx = jsapi.cx(); JS::Rooted<JS::Value> value(cx); if (!mObjBuffer.read(cx, &value)) { JS_ClearPendingException(cx); mRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR); return true; } nsRefPtr<Promise> promise = mBackingStore->Add(cx, value, mId, mRevisionId, mRv); promise->AppendNativeHandler(mPromiseWorkerProxy); return true; }
std::string CThreadDebugger::StringifyCyclicJSON(jsval obj, bool indent) { CyclicRefWorkaround::Stringifier str; CyclicRefWorkaround::g_ProcessedObjects.clear(); CyclicRefWorkaround::g_LastKey = JSVAL_VOID; JSObject* pGlob = JSVAL_TO_OBJECT(m->m_pScriptInterface->GetGlobalObject()); JSFunction* fun = JS_DefineFunction(m->m_pScriptInterface->GetContext(), pGlob, "replacer", CyclicRefWorkaround::replacer, 0, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); JSObject* replacer = JS_GetFunctionObject(fun); if (!JS_Stringify(m->m_pScriptInterface->GetContext(), &obj, replacer, indent ? INT_TO_JSVAL(2) : JSVAL_VOID, &CyclicRefWorkaround::Stringifier::callback, &str)) { LOGERROR(L"StringifyJSON failed"); jsval exec; jsval execString; if (JS_GetPendingException(m->m_pScriptInterface->GetContext(), &exec)) { if (JSVAL_IS_OBJECT(exec)) { JS_GetProperty(m->m_pScriptInterface->GetContext(), JSVAL_TO_OBJECT(exec), "message", &execString); if (JSVAL_IS_STRING(execString)) { std::string strExec = JS_EncodeString(m->m_pScriptInterface->GetContext(), JSVAL_TO_STRING(execString)); LOGERROR(L"Error: %hs", strExec.c_str()); } } } JS_ClearPendingException(m->m_pScriptInterface->GetContext()); return ""; } return str.stream.str(); }
std::wstring ScriptInterface::ToString(jsval obj, bool pretty) { if (JSVAL_IS_VOID(obj)) return L"(void 0)"; // Try to stringify as JSON if possible // (TODO: this is maybe a bad idea since it'll drop 'undefined' values silently) if (pretty) { StringifierW str; // Temporary disable the error reporter, so we don't print complaints about cyclic values JSErrorReporter er = JS_SetErrorReporter(m->m_cx, NULL); bool ok = JS_Stringify(m->m_cx, &obj, NULL, INT_TO_JSVAL(2), &StringifierW::callback, &str) == JS_TRUE; // Restore error reporter JS_SetErrorReporter(m->m_cx, er); if (ok) return str.stream.str(); // Clear the exception set when Stringify failed JS_ClearPendingException(m->m_cx); } // Caller didn't want pretty output, or JSON conversion failed (e.g. due to cycles), // so fall back to obj.toSource() std::wstring source = L"(error)"; CallFunction(obj, "toSource", source); return source; }
static JSString * ValueToShortSource(JSContext *cx, jsval v) { JSString *str; /* Avoid toSource bloat and fallibility for object types. */ if (JSVAL_IS_PRIMITIVE(v)) { str = js_ValueToSource(cx, v); } else if (VALUE_IS_FUNCTION(cx, v)) { /* * XXX Avoid function decompilation bloat for now. */ str = JS_GetFunctionId(JS_ValueToFunction(cx, v)); if (!str && !(str = js_ValueToSource(cx, v))) { /* * Continue to soldier on if the function couldn't be * converted into a string. */ JS_ClearPendingException(cx); str = JS_NewStringCopyZ(cx, "[unknown function]"); } } else { /* * XXX Avoid toString on objects, it takes too long and uses too much * memory, for too many classes (see Mozilla bug 166743). */ char buf[100]; JS_snprintf(buf, sizeof buf, "[object %s]", OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v))->name); str = JS_NewStringCopyZ(cx, buf); } return str; }
static void ReportException(JSContext *cx) { if (JS_IsExceptionPending(cx)) { if (!JS_ReportPendingException(cx)) { JS_ClearPendingException(cx); } } }
static JSBool jsd_DebugErrorHook(JSContext *cx, const char *message, JSErrorReport *report, void *closure) { JSDContext* jsdc = (JSDContext*) closure; JSD_ErrorReporter errorReporter; void* errorReporterData; if( ! jsdc ) { JS_ASSERT(0); return JS_TRUE; } if( JSD_IS_DANGEROUS_THREAD(jsdc) ) return JS_TRUE; /* local in case hook gets cleared on another thread */ JSD_LOCK(); errorReporter = jsdc->errorReporter; errorReporterData = jsdc->errorReporterData; JSD_UNLOCK(); if(!errorReporter) return JS_TRUE; switch(errorReporter(jsdc, cx, message, report, errorReporterData)) { case JSD_ERROR_REPORTER_PASS_ALONG: return JS_TRUE; case JSD_ERROR_REPORTER_RETURN: return JS_FALSE; case JSD_ERROR_REPORTER_DEBUG: { jsval rval; JSD_ExecutionHookProc hook; void* hookData; /* local in case hook gets cleared on another thread */ JSD_LOCK(); hook = jsdc->debugBreakHook; hookData = jsdc->debugBreakHookData; JSD_UNLOCK(); jsd_CallExecutionHook(jsdc, cx, JSD_HOOK_DEBUG_REQUESTED, hook, hookData, &rval); /* XXX Should make this dependent on ExecutionHook retval */ return JS_TRUE; } case JSD_ERROR_REPORTER_CLEAR_RETURN: if(report && JSREPORT_IS_EXCEPTION(report->flags)) JS_ClearPendingException(cx); return JS_FALSE; default: JS_ASSERT(0); break; } return JS_TRUE; }
bool AutoJSAPI::StealException(JS::MutableHandle<JS::Value> aVal) { if (!PeekException(aVal)) { return false; } JS_ClearPendingException(cx()); return true; }
void AutoEntryScript::DocshellEntryMonitor::Entry(JSContext* aCx, JSFunction* aFunction, JSScript* aScript, JS::Handle<JS::Value> aAsyncStack, JS::Handle<JSString*> aAsyncCause) { JS::Rooted<JSFunction*> rootedFunction(aCx); if (aFunction) { rootedFunction = aFunction; } JS::Rooted<JSScript*> rootedScript(aCx); if (aScript) { rootedScript = aScript; } nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(xpc::NativeGlobal(JS::CurrentGlobalOrNull(aCx))); if (!window || !window->GetDocShell() || !window->GetDocShell()->GetRecordProfileTimelineMarkers()) { return; } nsCOMPtr<nsIDocShell> docShellForJSRunToCompletion = window->GetDocShell(); nsString filename; uint32_t lineNumber = 0; js::AutoStableStringChars functionName(aCx); if (rootedFunction) { JS::Rooted<JSString*> displayId(aCx, JS_GetFunctionDisplayId(rootedFunction)); if (displayId) { if (!functionName.initTwoByte(aCx, displayId)) { JS_ClearPendingException(aCx); return; } } } if (!rootedScript) { rootedScript = JS_GetFunctionScript(aCx, rootedFunction); } if (rootedScript) { filename = NS_ConvertUTF8toUTF16(JS_GetScriptFilename(rootedScript)); lineNumber = JS_GetScriptBaseLineNumber(aCx, rootedScript); } if (!filename.IsEmpty() || functionName.isTwoByte()) { const char16_t* functionNameChars = functionName.isTwoByte() ? functionName.twoByteChars() : nullptr; JS::Rooted<JS::Value> asyncCauseValue(aCx, aAsyncCause ? StringValue(aAsyncCause) : JS::NullValue()); docShellForJSRunToCompletion->NotifyJSRunToCompletionStart(mReason, functionNameChars, filename.BeginReading(), lineNumber, aAsyncStack, asyncCauseValue); } }
RuntimeContext::~RuntimeContext() { JS_SetContextThread(_context); JS_ClearNewbornRoots(_context); JS_ClearRegExpStatics(_context); JS_ClearPendingException(_context); JS_MaybeGC(_context); JS_DestroyContext(_context); }
~AutoPACErrorReporter() { if (!JS_IsExceptionPending(mCx)) { return; } JS::RootedValue exn(mCx); if (!JS_GetPendingException(mCx, &exn)) { return; } JS_ClearPendingException(mCx); js::ErrorReport report(mCx); if (!report.init(mCx, exn, js::ErrorReport::WithSideEffects)) { JS_ClearPendingException(mCx); return; } PACLogErrorOrWarning(NS_LITERAL_STRING("Error"), report.report()); }
NS_IMETHODIMP MobileConnectionCallback::NotifyGetCallForwardingSuccess(uint32_t aCount, nsIMobileCallForwardingOptions** aResults) { nsTArray<MozCallForwardingOptions> results; for (uint32_t i = 0; i < aCount; i++) { MozCallForwardingOptions result; int16_t pShort; nsString pString; bool pBool; aResults[i]->GetActive(&pBool); result.mActive.Construct(pBool); aResults[i]->GetAction(&pShort); if (pShort != nsIMobileConnection::CALL_FORWARD_ACTION_UNKNOWN) { result.mAction.Construct(pShort); } aResults[i]->GetReason(&pShort); if (pShort != nsIMobileConnection::CALL_FORWARD_REASON_UNKNOWN) { result.mReason.Construct(pShort); } aResults[i]->GetNumber(pString); result.mNumber.Construct(pString.get()); aResults[i]->GetTimeSeconds(&pShort); if (pShort >= 0) { result.mTimeSeconds.Construct(pShort); } aResults[i]->GetServiceClass(&pShort); if (pShort != nsIMobileConnection::ICC_SERVICE_CLASS_NONE) { result.mServiceClass.Construct(pShort); } results.AppendElement(result); } AutoJSAPI jsapi; if (NS_WARN_IF(!jsapi.Init(mWindow))) { return NS_ERROR_FAILURE; } JSContext* cx = jsapi.cx(); JS::Rooted<JS::Value> jsResult(cx); if (!ToJSValue(cx, results, &jsResult)) { JS_ClearPendingException(cx); return NS_ERROR_TYPE_ERR; } return NotifySuccess(jsResult); }
void Promise::HandleException(JSContext* aCx) { JS::Rooted<JS::Value> exn(aCx); if (JS_GetPendingException(aCx, &exn)) { JS_ClearPendingException(aCx); // This is only called from MaybeSomething, so it's OK to MaybeReject here. MaybeReject(aCx, exn); } }
template<size_t N> inline bool Error(JSContext *cx, const char (&input)[N]) { AutoInflatedString str(cx); jsval dummy; str = input; CHECK(!JS_ParseJSON(cx, str.chars(), str.length(), &dummy)); JS_ClearPendingException(cx); return true; }
// PD_TRACE_DECLARE_FUNCTION ( SDB_SCOPE_EVALUATE2, "Scope::evaluate2" ) INT32 Scope::evaluate2 ( const CHAR *code, UINT32 len, UINT32 lineno, jsval *rval, CHAR **errMsg, INT32 printFlag ) { PD_TRACE_ENTRY ( SDB_SCOPE_EVALUATE2 ); INT32 rc = SDB_OK ; jsval exception = JSVAL_VOID ; CHAR *cstrException = NULL ; SDB_ASSERT ( _context && _global, "this scope has not been initilized" ) ; SDB_ASSERT ( code , "Invalid arguments" ) ; // set error report sdbSetPrintError( ( printFlag & SPT_EVAL_FLAG_PRINT ) ? TRUE : FALSE ) ; sdbSetNeedClearErrorInfo( TRUE ) ; if ( ! JS_EvaluateScript ( _context, _global, code, len, NULL, lineno, rval ) ) { rc = sdbGetErrno() ? sdbGetErrno() : SDB_SPT_EVAL_FAIL ; goto error ; } // clear return error if ( sdbIsNeedClearErrorInfo() && !JS_IsExceptionPending( _context ) ) { sdbClearErrorInfo() ; } done: PD_TRACE_EXITRC ( SDB_SCOPE_EVALUATE2, rc ); return rc ; error: if ( JS_IsExceptionPending( _context ) && JS_GetPendingException ( _context , &exception ) ) { cstrException = convertJsvalToString ( _context , exception ) ; if ( cstrException ) { if ( printFlag & SPT_EVAL_FLAG_PRINT ) { ossPrintf ( "Uncaught exception: %s\n" , cstrException ) ; } /// what to do when oom? *errMsg = ossStrdup( cstrException ) ; SAFE_JS_FREE ( _context , cstrException ) ; } else { JS_ClearPendingException ( _context ) ; } } goto done ; }
bool AccessCheck::isCrossOriginAccessPermitted(JSContext* cx, HandleObject wrapper, HandleId id, Wrapper::Action act) { if (act == Wrapper::CALL) return false; if (act == Wrapper::ENUMERATE) return true; // For the case of getting a property descriptor, we allow if either GET or SET // is allowed, and rely on FilteringWrapper to filter out any disallowed accessors. if (act == Wrapper::GET_PROPERTY_DESCRIPTOR) { return isCrossOriginAccessPermitted(cx, wrapper, id, Wrapper::GET) || isCrossOriginAccessPermitted(cx, wrapper, id, Wrapper::SET); } RootedObject obj(cx, js::UncheckedUnwrap(wrapper, /* stopAtOuter = */ false)); CrossOriginObjectType type = IdentifyCrossOriginObject(obj); if (JSID_IS_STRING(id)) { if (IsPermitted(type, JSID_TO_FLAT_STRING(id), act == Wrapper::SET)) return true; } if (act != Wrapper::GET) return false; // Check for frame IDs. If we're resolving named frames, make sure to only // resolve ones that don't shadow native properties. See bug 860494. if (type == CrossOriginWindow) { if (JSID_IS_STRING(id)) { bool wouldShadow = false; if (!XrayUtils::HasNativeProperty(cx, wrapper, id, &wouldShadow) || wouldShadow) { // If the named subframe matches the name of a DOM constructor, // the global resolve triggered by the HasNativeProperty call // above will try to perform a CheckedUnwrap on |wrapper|, and // throw a security error if it fails. That exception isn't // really useful for our callers, so we silence it and just // deny access to the property (since it matched a builtin). // // Note that this would be a problem if the resolve code ever // tried to CheckedUnwrap the wrapper _before_ concluding that // the name corresponds to a builtin global property, since it // would mean that we'd never permit cross-origin named subframe // access (something we regrettably need to support). JS_ClearPendingException(cx); return false; } } return IsFrameId(cx, obj, id); } return false; }
bool ToJSValue(JSContext* aCx, ErrorResult& aArgument, JS::MutableHandle<JS::Value> aValue) { MOZ_ASSERT(aArgument.Failed()); MOZ_ASSERT( !aArgument.IsUncatchableException(), "Doesn't make sense to convert uncatchable exception to a JS value!"); MOZ_ALWAYS_TRUE(aArgument.MaybeSetPendingException(aCx)); MOZ_ALWAYS_TRUE(JS_GetPendingException(aCx, aValue)); JS_ClearPendingException(aCx); return true; }
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; } }
void Promise::MaybeReject(JSContext* aCx, JS::Handle<JS::Value> aValue) { NS_ASSERT_OWNINGTHREAD(Promise); JS::Rooted<JSObject*> p(aCx, PromiseObj()); if (!JS::RejectPromise(aCx, p, aValue)) { // Now what? There's nothing sane to do here. JS_ClearPendingException(aCx); } }
bool AutoJSAPI::StealException(JS::MutableHandle<JS::Value> aVal) { MOZ_ASSERT(CxPusherIsStackTop()); MOZ_ASSERT(HasException()); MOZ_ASSERT(js::GetContextCompartment(cx())); if (!JS_GetPendingException(cx(), aVal)) { return false; } JS_ClearPendingException(cx()); return true; }