bool ChromeObjectWrapper::get(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) { assertEnteredPolicy(cx, wrapper, id); vp.setUndefined(); JSPropertyDescriptor desc; // Only call through to the get trap on the underlying object if we're // allowed to see the property, and if what we'll find is not on a standard // prototype. if (AllowedByBase(cx, wrapper, id, js::Wrapper::GET) && !PropIsFromStandardPrototype(cx, wrapper, id)) { // Call the get trap. if (!ChromeObjectWrapperBase::get(cx, wrapper, receiver, id, vp)) return false; // If we found something, we're done. if (!vp.isUndefined()) return true; } // If we have no proto, we're done. JSObject *wrapperProto; if (!JS_GetPrototype(cx, wrapper, &wrapperProto)) return false; if (!wrapperProto) return true; // Try the prototype. MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx)); return js::GetGeneric(cx, wrapperProto, receiver, id, vp.address()); }
nsresult XBL_DeserializeFunction(nsIObjectInputStream* aStream, JS::MutableHandle<JSObject*> aFunctionObjectp) { AssertInCompilationScope(); AutoJSContext cx; return nsContentUtils::XPConnect()->ReadFunction(aStream, cx, aFunctionObjectp.address()); }
bool CallbackInterface::GetCallableProperty(JSContext* cx, const char* aPropName, JS::MutableHandle<JS::Value> aCallable) { if (!JS_GetProperty(cx, mCallback, aPropName, aCallable.address())) { return false; } if (!aCallable.isObject() || !JS_ObjectIsCallable(cx, &aCallable.toObject())) { nsPrintfCString description("Property '%s'", aPropName); ThrowErrorMessage(cx, MSG_NOT_CALLABLE, description.get()); return false; } return true; }
// Define a shadowing property on |this| for the XBL field defined by the // contents of the callee's reserved slots. If the property was defined, // *installed will be true, and idp will be set to the property name that was // defined. static bool InstallXBLField(JSContext* cx, JS::Handle<JSObject*> callee, JS::Handle<JSObject*> thisObj, JS::MutableHandle<jsid> idp, bool* installed) { *installed = false; // First ensure |this| is a reasonable XBL bound node. // // FieldAccessorGuard already determined whether |thisObj| was acceptable as // |this| in terms of not throwing a TypeError. Assert this for good measure. MOZ_ASSERT(ValueHasISupportsPrivate(JS::ObjectValue(*thisObj))); // But there are some cases where we must accept |thisObj| but not install a // property on it, or otherwise touch it. Hence this split of |this|-vetting // duties. nsISupports* native = nsContentUtils::XPConnect()->GetNativeOfWrapper(cx, thisObj); if (!native) { // Looks like whatever |thisObj| is it's not our nsIContent. It might well // be the proto our binding installed, however, where the private is the // nsXBLDocumentInfo, so just baul out quietly. Do NOT throw an exception // here. // // We could make this stricter by checking the class maybe, but whatever. return true; } nsCOMPtr<nsIContent> xblNode = do_QueryInterface(native); if (!xblNode) { xpc::Throw(cx, NS_ERROR_UNEXPECTED); return false; } // Now that |this| is okay, actually install the field. // Because of the possibility (due to XBL binding inheritance, because each // XBL binding lives in its own global object) that |this| might be in a // different compartment from the callee (not to mention that this method can // be called with an arbitrary |this| regardless of how insane XBL is), and // because in this method we've entered |this|'s compartment (see in // Field[GS]etter where we attempt a cross-compartment call), we must enter // the callee's compartment to access its reserved slots. nsXBLPrototypeBinding* protoBinding; nsDependentJSString fieldName; { JSAutoCompartment ac(cx, callee); JS::Rooted<JSObject*> xblProto(cx); xblProto = &js::GetFunctionNativeReserved(callee, XBLPROTO_SLOT).toObject(); JS::Rooted<JS::Value> name(cx, js::GetFunctionNativeReserved(callee, FIELD_SLOT)); JSFlatString* fieldStr = JS_ASSERT_STRING_IS_FLAT(name.toString()); fieldName.init(fieldStr); MOZ_ALWAYS_TRUE(JS_ValueToId(cx, name, idp.address())); // If a separate XBL scope is being used, the callee is not same-compartment // with the xbl prototype, and the object is a cross-compartment wrapper. xblProto = js::UncheckedUnwrap(xblProto); JSAutoCompartment ac2(cx, xblProto); JS::Value slotVal = ::JS_GetReservedSlot(xblProto, 0); protoBinding = static_cast<nsXBLPrototypeBinding*>(slotVal.toPrivate()); MOZ_ASSERT(protoBinding); } nsXBLProtoImplField* field = protoBinding->FindField(fieldName); MOZ_ASSERT(field); // This mirrors code in nsXBLProtoImpl::InstallImplementation nsCOMPtr<nsIScriptGlobalObject> global = do_QueryInterface(xblNode->OwnerDoc()->GetWindow()); if (!global) { return true; } nsCOMPtr<nsIScriptContext> context = global->GetContext(); if (!context) { return true; } nsresult rv = field->InstallField(context, thisObj, protoBinding->DocURI(), installed); if (NS_SUCCEEDED(rv)) { return true; } if (!::JS_IsExceptionPending(cx)) { xpc::Throw(cx, rv); } return false; }
nsresult nsJSON::DecodeInternal(JSContext* cx, nsIInputStream *aStream, int32_t aContentLength, bool aNeedsConverter, JS::MutableHandle<JS::Value> aRetval) { // Consume the stream nsCOMPtr<nsIChannel> jsonChannel; if (!mURI) { NS_NewURI(getter_AddRefs(mURI), NS_LITERAL_CSTRING("about:blank"), 0, 0 ); if (!mURI) return NS_ERROR_OUT_OF_MEMORY; } nsresult rv = NS_NewInputStreamChannel(getter_AddRefs(jsonChannel), mURI, aStream, NS_LITERAL_CSTRING("application/json")); if (!jsonChannel || NS_FAILED(rv)) return NS_ERROR_FAILURE; nsRefPtr<nsJSONListener> jsonListener = new nsJSONListener(cx, aRetval.address(), aNeedsConverter); //XXX this stream pattern should be consolidated in netwerk rv = jsonListener->OnStartRequest(jsonChannel, nullptr); if (NS_FAILED(rv)) { jsonChannel->Cancel(rv); return rv; } nsresult status; jsonChannel->GetStatus(&status); uint64_t offset = 0; while (NS_SUCCEEDED(status)) { uint64_t available; rv = aStream->Available(&available); if (rv == NS_BASE_STREAM_CLOSED) { rv = NS_OK; break; } if (NS_FAILED(rv)) { jsonChannel->Cancel(rv); break; } if (!available) break; // blocking input stream has none available when done if (available > UINT32_MAX) available = UINT32_MAX; rv = jsonListener->OnDataAvailable(jsonChannel, nullptr, aStream, offset, (uint32_t)available); if (NS_FAILED(rv)) { jsonChannel->Cancel(rv); break; } offset += available; jsonChannel->GetStatus(&status); } NS_ENSURE_SUCCESS(rv, rv); rv = jsonListener->OnStopRequest(jsonChannel, nullptr, status); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; }
nsresult nsJSON::DecodeInternal(JSContext* cx, nsIInputStream *aStream, int32_t aContentLength, bool aNeedsConverter, JS::MutableHandle<JS::Value> aRetval) { // Consume the stream nsCOMPtr<nsIChannel> jsonChannel; if (!mURI) { NS_NewURI(getter_AddRefs(mURI), NS_LITERAL_CSTRING("about:blank"), 0, 0 ); if (!mURI) return NS_ERROR_OUT_OF_MEMORY; } nsresult rv; nsCOMPtr<nsIPrincipal> nullPrincipal = nsNullPrincipal::Create(); // The ::Decode function is deprecated [Bug 675797] and the following // channel is never openend, so it does not matter what securityFlags // we pass to NS_NewInputStreamChannel here. rv = NS_NewInputStreamChannel(getter_AddRefs(jsonChannel), mURI, aStream, nullPrincipal, nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED, nsIContentPolicy::TYPE_OTHER, NS_LITERAL_CSTRING("application/json")); if (!jsonChannel || NS_FAILED(rv)) return NS_ERROR_FAILURE; RefPtr<nsJSONListener> jsonListener = new nsJSONListener(cx, aRetval.address(), aNeedsConverter); //XXX this stream pattern should be consolidated in netwerk rv = jsonListener->OnStartRequest(jsonChannel, nullptr); if (NS_FAILED(rv)) { jsonChannel->Cancel(rv); return rv; } nsresult status; jsonChannel->GetStatus(&status); uint64_t offset = 0; while (NS_SUCCEEDED(status)) { uint64_t available; rv = aStream->Available(&available); if (rv == NS_BASE_STREAM_CLOSED) { rv = NS_OK; break; } if (NS_FAILED(rv)) { jsonChannel->Cancel(rv); break; } if (!available) break; // blocking input stream has none available when done if (available > UINT32_MAX) available = UINT32_MAX; rv = jsonListener->OnDataAvailable(jsonChannel, nullptr, aStream, offset, (uint32_t)available); if (NS_FAILED(rv)) { jsonChannel->Cancel(rv); break; } offset += available; jsonChannel->GetStatus(&status); } NS_ENSURE_SUCCESS(rv, rv); rv = jsonListener->OnStopRequest(jsonChannel, nullptr, status); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; }
NS_IMETHODIMP MobileMessageManager::Send(JS::Handle<JS::Value> aNumber, const nsAString& aMessage, JS::Handle<JS::Value> aSendParams, JSContext* aCx, uint8_t aArgc, JS::MutableHandle<JS::Value> aReturn) { if (!aNumber.isString() && !(aNumber.isObject() && JS_IsArrayObject(aCx, &aNumber.toObject()))) { return NS_ERROR_INVALID_ARG; } nsresult rv; nsIScriptContext* sc = GetContextForEventHandlers(&rv); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_STATE(sc); JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx)); mozilla::Maybe<JSAutoCompartment> ac; if (!global) { global = sc->GetWindowProxy(); ac.construct(aCx, global); } nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID); NS_ENSURE_TRUE(smsService, NS_ERROR_FAILURE); // Use the default one unless |aSendParams.serviceId| is available. uint32_t serviceId; rv = smsService->GetSmsDefaultServiceId(&serviceId); NS_ENSURE_SUCCESS(rv, rv); if (aArgc == 3) { JS::Rooted<JS::Value> param(aCx, aSendParams); RootedDictionary<SmsSendParameters> sendParams(aCx); if (!sendParams.Init(aCx, param)) { return NS_ERROR_TYPE_ERR; } if (sendParams.mServiceId.WasPassed()) { serviceId = sendParams.mServiceId.Value(); } } if (aNumber.isString()) { JS::Rooted<JSString*> str(aCx, aNumber.toString()); return Send(aCx, global, serviceId, str, aMessage, aReturn.address()); } // Must be an array then. JS::Rooted<JSObject*> numbers(aCx, &aNumber.toObject()); uint32_t size; if (!JS_GetArrayLength(aCx, numbers, &size)) { return NS_ERROR_FAILURE; } JS::AutoValueVector requests(aCx); if (!requests.resize(size)) { return NS_ERROR_FAILURE; } JS::Rooted<JS::Value> number(aCx); JS::Rooted<JSString*> str(aCx); for (uint32_t i = 0; i < size; ++i) { if (!JS_GetElement(aCx, numbers, i, &number)) { return NS_ERROR_INVALID_ARG; } str = JS::ToString(aCx, number); if (!str) { return NS_ERROR_FAILURE; } nsresult rv = Send(aCx, global, serviceId, str, aMessage, &requests[i]); NS_ENSURE_SUCCESS(rv, rv); } JS::Rooted<JSObject*> obj(aCx); obj = JS_NewArrayObject(aCx, requests.length(), requests.begin()); if (!obj) { return NS_ERROR_FAILURE; } aReturn.setObject(*obj); return NS_OK; }