/* |callee| requires a usage string provided by JS_DefineFunctionsWithHelp. */ void js::ReportUsageError(JSContext *cx, HandleObject callee, const char *msg) { const char *usageStr = "usage"; PropertyName *usageAtom = Atomize(cx, usageStr, strlen(usageStr))->asPropertyName(); RootedId id(cx, NameToId(usageAtom)); DebugOnly<Shape *> shape = static_cast<Shape *>(callee->as<NativeObject>().lookup(cx, id)); MOZ_ASSERT(!shape->configurable()); MOZ_ASSERT(!shape->writable()); MOZ_ASSERT(shape->hasDefaultGetter()); RootedValue usage(cx); if (!JS_LookupProperty(cx, callee, "usage", &usage)) return; if (usage.isUndefined()) { JS_ReportError(cx, "%s", msg); } else { JSString *str = usage.toString(); if (!str->ensureFlat(cx)) return; AutoStableStringChars chars(cx); if (!chars.initTwoByte(cx, str)) return; JS_ReportError(cx, "%s. Usage: %hs", msg, chars.twoByteRange().start().get()); } }
bool SecurityWrapper<Base>::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id, MutableHandle<PropertyDescriptor> desc) const { if (desc.getter() || desc.setter()) { JSString *str = IdToString(cx, id); AutoStableStringChars chars(cx); const jschar *prop = nullptr; if (str->ensureFlat(cx) && chars.initTwoByte(cx, str)) prop = chars.twoByteChars(); JS_ReportErrorNumberUC(cx, js_GetErrorMessage, nullptr, JSMSG_ACCESSOR_DEF_DENIED, prop); return false; } return Base::defineProperty(cx, wrapper, id, desc); }
void js::AutoEnterPolicy::reportErrorIfExceptionIsNotPending(JSContext *cx, jsid id) { if (JS_IsExceptionPending(cx)) return; if (JSID_IS_VOID(id)) { JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_OBJECT_ACCESS_DENIED); } else { JSString *str = IdToString(cx, id); AutoStableStringChars chars(cx); const char16_t *prop = nullptr; if (str->ensureFlat(cx) && chars.initTwoByte(cx, str)) prop = chars.twoByteChars(); JS_ReportErrorNumberUC(cx, js_GetErrorMessage, nullptr, JSMSG_PROPERTY_ACCESS_DENIED, prop); } }
bool SecurityWrapper<Base>::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id, MutableHandle<PropertyDescriptor> desc, ObjectOpResult &result) const { if (desc.getter() || desc.setter()) { RootedValue idVal(cx, IdToValue(id)); JSString *str = ValueToSource(cx, idVal); if (!str) return false; AutoStableStringChars chars(cx); const char16_t *prop = nullptr; if (str->ensureFlat(cx) && chars.initTwoByte(cx, str)) prop = chars.twoByteChars(); JS_ReportErrorNumberUC(cx, GetErrorMessage, nullptr, JSMSG_ACCESSOR_DEF_DENIED, prop); return false; } return Base::defineProperty(cx, wrapper, id, desc, result); }
void js::AutoEnterPolicy::reportErrorIfExceptionIsNotPending(JSContext* cx, jsid id) { if (JS_IsExceptionPending(cx)) return; if (JSID_IS_VOID(id)) { ReportAccessDenied(cx); } else { RootedValue idVal(cx, IdToValue(id)); JSString* str = ValueToSource(cx, idVal); if (!str) { return; } AutoStableStringChars chars(cx); const char16_t* prop = nullptr; if (str->ensureFlat(cx) && chars.initTwoByte(cx, str)) prop = chars.twoByteChars(); JS_ReportErrorNumberUC(cx, GetErrorMessage, nullptr, JSMSG_PROPERTY_ACCESS_DENIED, prop); } }
static bool InvokeInterruptCallback(JSContext* cx) { MOZ_ASSERT(cx->runtime()->requestDepth >= 1); cx->runtime()->gc.gcIfRequested(); // A worker thread may have requested an interrupt after finishing an Ion // compilation. jit::AttachFinishedCompilations(cx); // Important: Additional callbacks can occur inside the callback handler // if it re-enters the JS engine. The embedding must ensure that the // callback is disconnected before attempting such re-entry. JSInterruptCallback cb = cx->runtime()->interruptCallback; if (!cb) return true; if (cb(cx)) { // Debugger treats invoking the interrupt callback as a "step", so // invoke the onStep handler. if (cx->compartment()->isDebuggee()) { ScriptFrameIter iter(cx); if (!iter.done() && iter.script()->stepModeEnabled()) { RootedValue rval(cx); switch (Debugger::onSingleStep(cx, &rval)) { case JSTRAP_ERROR: return false; case JSTRAP_CONTINUE: return true; case JSTRAP_RETURN: // See note in Debugger::propagateForcedReturn. Debugger::propagateForcedReturn(cx, iter.abstractFramePtr(), rval); return false; case JSTRAP_THROW: cx->setPendingException(rval); return false; default:; } } } return true; } // No need to set aside any pending exception here: ComputeStackString // already does that. JSString* stack = ComputeStackString(cx); JSFlatString* flat = stack ? stack->ensureFlat(cx) : nullptr; const char16_t* chars; AutoStableStringChars stableChars(cx); if (flat && stableChars.initTwoByte(cx, flat)) chars = stableChars.twoByteRange().start().get(); else chars = MOZ_UTF16("(stack not available)"); JS_ReportErrorFlagsAndNumberUC(cx, JSREPORT_WARNING, GetErrorMessage, nullptr, JSMSG_TERMINATED, chars); return false; }