NS_IMETHODIMP TimeZoneSettingObserver::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData) { if (strcmp(aTopic, MOZSETTINGS_CHANGED) != 0) { return NS_OK; } // Note that this function gets called for any and all settings changes, // so we need to carefully check if we have the one we're interested in. // // The string that we're interested in will be a JSON string that looks like: // {"key":"time.timezone","value":"America/Chicago"} // Get the safe JS context. nsCOMPtr<nsIThreadJSContextStack> stack = do_GetService("@mozilla.org/js/xpc/ContextStack;1"); if (!stack) { ERR("Failed to get JSContextStack"); return NS_OK; } JSContext *cx = stack->GetSafeJSContext(); if (!cx) { ERR("Failed to GetSafeJSContext"); return NS_OK; } // Parse the JSON value. nsDependentString dataStr(aData); JS::Value val; if (!JS_ParseJSON(cx, dataStr.get(), dataStr.Length(), &val) || !val.isObject()) { return NS_OK; } // Get the key, which should be the JS string "time.timezone". JSObject &obj(val.toObject()); JS::Value key; if (!JS_GetProperty(cx, &obj, "key", &key) || !key.isString()) { return NS_OK; } JSBool match; if (!JS_StringEqualsAscii(cx, key.toString(), TIME_TIMEZONE, &match) || match != JS_TRUE) { return NS_OK; } // Get the value, which should be a JS string like "America/Chicago". JS::Value value; if (!JS_GetProperty(cx, &obj, "value", &value) || !value.isString()) { return NS_OK; } // Set the system timezone. return SetTimeZone(value, cx); }
void nsGeolocationService::HandleMozsettingChanged(const PRUnichar* aData) { // The string that we're interested in will be a JSON string that looks like: // {"key":"gelocation.enabled","value":true} SafeAutoJSContext cx; nsDependentString dataStr(aData); JS::Value val; if (!JS_ParseJSON(cx, dataStr.get(), dataStr.Length(), &val) || !val.isObject()) { return; } JSObject &obj(val.toObject()); JS::Value key; if (!JS_GetProperty(cx, &obj, "key", &key) || !key.isString()) { return; } JSBool match; if (!JS_StringEqualsAscii(cx, key.toString(), GEO_SETINGS_ENABLED, &match) || (match != JS_TRUE)) { return; } JS::Value value; if (!JS_GetProperty(cx, &obj, "value", &value) || !value.isBoolean()) { return; } HandleMozsettingValue(value.toBoolean()); }
NS_IMETHODIMP TCPSocketChild::Send(const JS::Value& aData, uint32_t aByteOffset, uint32_t aByteLength, JSContext* aCx) { if (aData.isString()) { JSString* jsstr = aData.toString(); nsDependentJSString str; bool ok = str.init(aCx, jsstr); NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE); SendData(str); } else { NS_ENSURE_TRUE(aData.isObject(), NS_ERROR_FAILURE); JS::Rooted<JSObject*> obj(aCx, &aData.toObject()); NS_ENSURE_TRUE(JS_IsArrayBufferObject(obj), NS_ERROR_FAILURE); uint32_t buflen = JS_GetArrayBufferByteLength(obj); aByteOffset = std::min(buflen, aByteOffset); uint32_t nbytes = std::min(buflen - aByteOffset, aByteLength); uint8_t* data = JS_GetArrayBufferData(obj); if (!data) { return NS_ERROR_OUT_OF_MEMORY; } FallibleTArray<uint8_t> fallibleArr; if (!fallibleArr.InsertElementsAt(0, data, nbytes)) { return NS_ERROR_OUT_OF_MEMORY; } InfallibleTArray<uint8_t> arr; arr.SwapElements(fallibleArr); SendData(arr); } return NS_OK; }
bool gjs_string_to_utf8 (JSContext *context, const JS::Value value, char **utf8_string_p) { gsize len; char *bytes; JS_BeginRequest(context); if (!value.isString()) { gjs_throw(context, "Value is not a string, cannot convert to UTF-8"); JS_EndRequest(context); return false; } JS::RootedString str(context, value.toString()); len = JS_GetStringEncodingLength(context, str); if (len == (gsize)(-1)) { JS_EndRequest(context); return false; } if (utf8_string_p) { bytes = JS_EncodeStringToUTF8(context, str); *utf8_string_p = bytes; } JS_EndRequest(context); return true; }
/** * gjs_string_get_char16_data: * @context: js context * @value: a JS::Value * @data_p: address to return allocated data buffer * @len_p: address to return length of data (number of 16-bit characters) * * Get the binary data (as a sequence of 16-bit characters) in the JSString * contained in @value. * Throws a JS exception if value is not a string. * * Returns: false if exception thrown **/ bool gjs_string_get_char16_data(JSContext *context, JS::Value value, char16_t **data_p, size_t *len_p) { const char16_t *js_data; bool retval = false; JS_BeginRequest(context); if (!value.isString()) { gjs_throw(context, "Value is not a string, can't return binary data from it"); goto out; } js_data = JS_GetStringCharsAndLength(context, value.toString(), len_p); if (js_data == NULL) goto out; *data_p = (char16_t *) g_memdup(js_data, sizeof(*js_data) * (*len_p)); retval = true; out: JS_EndRequest(context); return retval; }
NS_IMETHODIMP SmsManager::Send(const JS::Value& aNumber, const nsAString& aMessage, JS::Value* aReturn) { nsresult rv; nsIScriptContext* sc = GetContextForEventHandlers(&rv); NS_ENSURE_STATE(sc); AutoPushJSContext cx(sc->GetNativeContext()); NS_ASSERTION(cx, "Failed to get a context!"); if (!aNumber.isString() && !(aNumber.isObject() && JS_IsArrayObject(cx, &aNumber.toObject()))) { return NS_ERROR_INVALID_ARG; } JSObject* global = sc->GetNativeGlobal(); NS_ASSERTION(global, "Failed to get global object!"); JSAutoRequest ar(cx); JSAutoCompartment ac(cx, global); if (aNumber.isString()) { return Send(cx, global, aNumber.toString(), aMessage, aReturn); } // Must be an array then. JSObject& numbers = aNumber.toObject(); uint32_t size; JS_ALWAYS_TRUE(JS_GetArrayLength(cx, &numbers, &size)); JS::Value* requests = new JS::Value[size]; for (uint32_t i=0; i<size; ++i) { JS::Value number; if (!JS_GetElement(cx, &numbers, i, &number)) { return NS_ERROR_INVALID_ARG; } nsresult rv = Send(cx, global, number.toString(), aMessage, &requests[i]); NS_ENSURE_SUCCESS(rv, rv); } aReturn->setObjectOrNull(JS_NewArrayObject(cx, size, requests)); NS_ENSURE_TRUE(aReturn->isObject(), NS_ERROR_FAILURE); return NS_OK; }
bool JSCompartment::putWrapper(const CrossCompartmentKey &wrapped, const js::Value &wrapper) { JS_ASSERT(wrapped.wrapped); JS_ASSERT_IF(wrapped.kind == CrossCompartmentKey::StringWrapper, wrapper.isString()); JS_ASSERT_IF(wrapped.kind != CrossCompartmentKey::StringWrapper, wrapper.isObject()); // todo: uncomment when bug 815999 is fixed: // JS_ASSERT(!wrapped.wrapped->isMarked(gc::GRAY)); return crossCompartmentWrappers.put(wrapped, wrapper); }
static bool VerifyJSValueIsString( JSContext *cx, const JS::Value &value, const char *string) { JSBool match; if (!value.isString() || !JS_StringEqualsAscii(cx, value.toString(), string, &match) || (match != JS_TRUE)) { return false; } return true; }
bool JSCompartment::putWrapper(const CrossCompartmentKey &wrapped, const js::Value &wrapper) { JS_ASSERT(wrapped.wrapped); JS_ASSERT(!IsPoisonedPtr(wrapped.wrapped)); JS_ASSERT(!IsPoisonedPtr(wrapped.debugger)); JS_ASSERT(!IsPoisonedPtr(wrapper.toGCThing())); JS_ASSERT_IF(wrapped.kind == CrossCompartmentKey::StringWrapper, wrapper.isString()); JS_ASSERT_IF(wrapped.kind != CrossCompartmentKey::StringWrapper, wrapper.isObject()); return crossCompartmentWrappers.put(wrapped, wrapper); }
NS_IMETHODIMP AutoMounterSetting::Observe(nsISupports* aSubject, const char* aTopic, const PRUnichar* aData) { if (strcmp(aTopic, MOZSETTINGS_CHANGED) != 0) { return NS_OK; } // Note that this function gets called for any and all settings changes, // so we need to carefully check if we have the one we're interested in. // // The string that we're interested in will be a JSON string that looks like: // {"key":"ums.autoMount","value":true} nsCOMPtr<nsIThreadJSContextStack> stack = do_GetService("@mozilla.org/js/xpc/ContextStack;1"); if (!stack) { ERR("Failed to get JSContextStack"); return NS_OK; } JSContext* cx = stack->GetSafeJSContext(); if (!cx) { ERR("Failed to GetSafeJSContext"); return NS_OK; } nsDependentString dataStr(aData); JS::Value val; if (!JS_ParseJSON(cx, dataStr.get(), dataStr.Length(), &val) || !val.isObject()) { return NS_OK; } JSObject& obj(val.toObject()); JS::Value key; if (!JS_GetProperty(cx, &obj, "key", &key) || !key.isString()) { return NS_OK; } JSBool match; if (!JS_StringEqualsAscii(cx, key.toString(), UMS_MODE, &match) || (match != JS_TRUE)) { return NS_OK; } JS::Value value; if (!JS_GetProperty(cx, &obj, "value", &value) || !value.isInt32()) { return NS_OK; } int32_t mode = value.toInt32(); SetAutoMounterMode(mode); return NS_OK; }
bool JSCompartment::putWrapper(JSContext* cx, const CrossCompartmentKey& wrapped, const js::Value& wrapper) { MOZ_ASSERT(wrapped.is<JSString*>() == wrapper.isString()); MOZ_ASSERT_IF(!wrapped.is<JSString*>(), wrapper.isObject()); if (!crossCompartmentWrappers.put(wrapped, wrapper)) { ReportOutOfMemory(cx); return false; } return true; }
/** * gjs_string_to_utf8: * @cx: JSContext * @value: a JS::Value containing a string * @utf8_string_p: return location for a unique JS chars pointer * * Converts the JSString in @value to UTF-8 and puts it in @utf8_string_p. * * This function is a convenience wrapper around JS_EncodeStringToUTF8() that * typechecks the JS::Value and throws an exception if it's the wrong type. * Don't use this function if you already have a JS::RootedString, or if you * know the value already holds a string; use JS_EncodeStringToUTF8() instead. */ bool gjs_string_to_utf8(JSContext *cx, const JS::Value value, GjsAutoJSChar *utf8_string_p) { JSAutoRequest ar(cx); if (!value.isString()) { gjs_throw(cx, "Value is not a string, cannot convert to UTF-8"); return false; } JS::RootedString str(cx, value.toString()); utf8_string_p->reset(JS_EncodeStringToUTF8(cx, str)); return !!*utf8_string_p; }
nsresult ProxyAutoConfig::GetProxyForURI(const nsCString &aTestURI, const nsCString &aTestHost, nsACString &result) { if (mJSNeedsSetup) SetupJS(); if (!mJSRuntime || !mJSRuntime->IsOK()) return NS_ERROR_NOT_AVAILABLE; JSContext *cx = mJSRuntime->Context(); JSAutoRequest ar(cx); // the sRunning flag keeps a new PAC file from being installed // while the event loop is spinning on a DNS function. Don't early return. sRunning = this; mRunningHost = aTestHost; nsresult rv = NS_ERROR_FAILURE; JS::RootedString uriString(cx, JS_NewStringCopyZ(cx, aTestURI.get())); JS::RootedString hostString(cx, JS_NewStringCopyZ(cx, aTestHost.get())); if (uriString && hostString) { JS::RootedValue uriValue(cx, STRING_TO_JSVAL(uriString)); JS::RootedValue hostValue(cx, STRING_TO_JSVAL(hostString)); JS::Value argv[2] = { uriValue, hostValue }; JS::Value rval; JSBool ok = JS_CallFunctionName(cx, mJSRuntime->Global(), "FindProxyForURL", 2, argv, &rval); if (ok && rval.isString()) { nsDependentJSString pacString; if (pacString.init(cx, rval.toString())) { CopyUTF16toUTF8(pacString, result); rv = NS_OK; } } } mRunningHost.Truncate(); sRunning = nullptr; return rv; }
bool JSCompartment::putWrapper(JSContext* cx, const CrossCompartmentKey& wrapped, const js::Value& wrapper) { MOZ_ASSERT(wrapped.wrapped); MOZ_ASSERT_IF(wrapped.kind == CrossCompartmentKey::StringWrapper, wrapper.isString()); MOZ_ASSERT_IF(wrapped.kind != CrossCompartmentKey::StringWrapper, wrapper.isObject()); bool success = crossCompartmentWrappers.put(wrapped, ReadBarriered<Value>(wrapper)); /* There's no point allocating wrappers in the nursery since we will tenure them anyway. */ MOZ_ASSERT(!IsInsideNursery(static_cast<gc::Cell*>(wrapper.toGCThing()))); if (success && (IsInsideNursery(wrapped.wrapped) || IsInsideNursery(wrapped.debugger))) { WrapperMapRef ref(&crossCompartmentWrappers, wrapped); cx->runtime()->gc.storeBuffer.putGeneric(ref); } return success; }
std::string gjs_debug_value(JS::Value v) { std::ostringstream out; if (v.isNull()) return "null"; if (v.isUndefined()) return "undefined"; if (v.isInt32()) { out << v.toInt32(); return out.str(); } if (v.isDouble()) { out << v.toDouble(); return out.str(); } if (v.isString()) { out << gjs_debug_string(v.toString()); return out.str(); } if (v.isSymbol()) { out << gjs_debug_symbol(v.toSymbol()); return out.str(); } if (v.isObject() && js::IsFunctionObject(&v.toObject())) { JSFunction* fun = JS_GetObjectFunction(&v.toObject()); JSString *display_name = JS_GetFunctionDisplayId(fun); if (display_name) out << "<function " << gjs_debug_string(display_name); else out << "<unnamed function"; out << " at " << fun << '>'; return out.str(); } if (v.isObject()) { out << gjs_debug_object(&v.toObject()); return out.str(); } if (v.isBoolean()) return (v.toBoolean() ? "true" : "false"); if (v.isMagic()) return "<magic>"; return "unexpected value"; }
NS_IMETHODIMP SmsFilter::SetNumbers(JSContext* aCx, const JS::Value& aNumbers) { if (aNumbers == JSVAL_NULL) { mData.numbers().Clear(); return NS_OK; } if (!aNumbers.isObject()) { return NS_ERROR_INVALID_ARG; } JSObject& obj = aNumbers.toObject(); if (!JS_IsArrayObject(aCx, &obj)) { return NS_ERROR_INVALID_ARG; } uint32_t size; JS_ALWAYS_TRUE(JS_GetArrayLength(aCx, &obj, &size)); nsTArray<nsString> numbers; for (uint32_t i=0; i<size; ++i) { JS::Value jsNumber; if (!JS_GetElement(aCx, &obj, i, &jsNumber)) { return NS_ERROR_INVALID_ARG; } if (!jsNumber.isString()) { return NS_ERROR_INVALID_ARG; } nsDependentJSString number; number.init(aCx, jsNumber.toString()); numbers.AppendElement(number); } mData.numbers().Clear(); mData.numbers().AppendElements(numbers); return NS_OK; }
NS_IMETHODIMP GonkGPSGeolocationProvider::Handle(const nsAString& aName, const JS::Value& aResult) { if (aName.EqualsLiteral("ril.supl.apn")) { JSContext *cx = nsContentUtils::GetCurrentJSContext(); NS_ENSURE_TRUE(cx, NS_OK); JSAutoRequest ar(cx); JSAutoCompartment ac(cx, JSVAL_TO_OBJECT(aResult)); // When we get the APN, we attempt to call data_call_open of AGPS. if (aResult.isString()) { nsDependentJSString apn; apn.init(cx, aResult.toString()); if (!apn.IsEmpty()) { SetAGpsDataConn(apn); } } } return NS_OK; }
NS_IMETHODIMP GonkGPSGeolocationProvider::Handle(const nsAString& aName, const JS::Value& aResult) { if (aName.EqualsLiteral("ril.supl.apn")) { JSContext *cx = nsContentUtils::GetCurrentJSContext(); NS_ENSURE_TRUE(cx, NS_OK); // When we get the APN, we attempt to call data_call_open of AGPS. if (aResult.isString()) { // NB: No need to enter a compartment to read the contents of a string. nsDependentJSString apn; apn.init(cx, aResult.toString()); if (!apn.IsEmpty()) { SetAGpsDataConn(apn); } } } return NS_OK; }
nsresult HTMLCanvasElement::ParseParams(JSContext* aCx, const nsAString& aType, const JS::Value& aEncoderOptions, nsAString& aParams, bool* usingCustomParseOptions) { // Quality parameter is only valid for the image/jpeg MIME type if (aType.EqualsLiteral("image/jpeg")) { if (aEncoderOptions.isNumber()) { double quality = aEncoderOptions.toNumber(); // Quality must be between 0.0 and 1.0, inclusive if (quality >= 0.0 && quality <= 1.0) { aParams.AppendLiteral("quality="); aParams.AppendInt(NS_lround(quality * 100.0)); } } } // If we haven't parsed the aParams check for proprietary options. // The proprietary option -moz-parse-options will take a image lib encoder // parse options string as is and pass it to the encoder. *usingCustomParseOptions = false; if (aParams.Length() == 0 && aEncoderOptions.isString()) { NS_NAMED_LITERAL_STRING(mozParseOptions, "-moz-parse-options:"); nsAutoJSString paramString; if (!paramString.init(aCx, aEncoderOptions.toString())) { return NS_ERROR_FAILURE; } if (StringBeginsWith(paramString, mozParseOptions)) { nsDependentSubstring parseOptions = Substring(paramString, mozParseOptions.Length(), paramString.Length() - mozParseOptions.Length()); aParams.Append(parseOptions); *usingCustomParseOptions = true; } } return NS_OK; }
bool JSCompartment::putWrapper(JSContext* cx, const CrossCompartmentKey& wrapped, const js::Value& wrapper) { MOZ_ASSERT(wrapped.is<JSString*>() == wrapper.isString()); MOZ_ASSERT_IF(!wrapped.is<JSString*>(), wrapper.isObject()); /* There's no point allocating wrappers in the nursery since we will tenure them anyway. */ MOZ_ASSERT(!IsInsideNursery(static_cast<gc::Cell*>(wrapper.toGCThing()))); if (!crossCompartmentWrappers.put(wrapped, ReadBarriered<Value>(wrapper))) { ReportOutOfMemory(cx); return false; } if (const_cast<CrossCompartmentKey&>(wrapped).applyToWrapped(IsInsideNurseryFunctor()) || const_cast<CrossCompartmentKey&>(wrapped).applyToDebugger(IsInsideNurseryFunctor())) { WrapperMapRef ref(&crossCompartmentWrappers, wrapped); cx->runtime()->gc.storeBuffer.putGeneric(ref); } return true; }
bool JSCompartment::putWrapper(JSContext *cx, const CrossCompartmentKey &wrapped, const js::Value &wrapper) { JS_ASSERT(wrapped.wrapped); JS_ASSERT(!IsPoisonedPtr(wrapped.wrapped)); JS_ASSERT(!IsPoisonedPtr(wrapped.debugger)); JS_ASSERT(!IsPoisonedPtr(wrapper.toGCThing())); JS_ASSERT_IF(wrapped.kind == CrossCompartmentKey::StringWrapper, wrapper.isString()); JS_ASSERT_IF(wrapped.kind != CrossCompartmentKey::StringWrapper, wrapper.isObject()); bool success = crossCompartmentWrappers.put(wrapped, wrapper); #ifdef JSGC_GENERATIONAL /* There's no point allocating wrappers in the nursery since we will tenure them anyway. */ Nursery &nursery = cx->nursery(); JS_ASSERT(!nursery.isInside(wrapper.toGCThing())); if (success && (nursery.isInside(wrapped.wrapped) || nursery.isInside(wrapped.debugger))) { WrapperMapRef ref(&crossCompartmentWrappers, wrapped); cx->runtime()->gcStoreBuffer.putGeneric(ref); } #endif return success; }
nsresult BluetoothService::HandleSettingsChanged(const nsAString& aData) { MOZ_ASSERT(NS_IsMainThread()); // The string that we're interested in will be a JSON string that looks like: // {"key":"bluetooth.enabled","value":true} JSContext* cx = nsContentUtils::GetSafeJSContext(); if (!cx) { return NS_OK; } JS::Value val; if (!JS_ParseJSON(cx, aData.BeginReading(), aData.Length(), &val)) { return JS_ReportPendingException(cx) ? NS_OK : NS_ERROR_OUT_OF_MEMORY; } if (!val.isObject()) { return NS_OK; } JSObject& obj(val.toObject()); JS::Value key; if (!JS_GetProperty(cx, &obj, "key", &key)) { MOZ_ASSERT(!JS_IsExceptionPending(cx)); return NS_ERROR_OUT_OF_MEMORY; } if (!key.isString()) { return NS_OK; } JSBool match; if (!JS_StringEqualsAscii(cx, key.toString(), BLUETOOTH_ENABLED_SETTING, &match)) { MOZ_ASSERT(!JS_IsExceptionPending(cx)); return NS_ERROR_OUT_OF_MEMORY; } if (!match) { return NS_OK; } JS::Value value; if (!JS_GetProperty(cx, &obj, "value", &value)) { MOZ_ASSERT(!JS_IsExceptionPending(cx)); return NS_ERROR_OUT_OF_MEMORY; } if (!value.isBoolean()) { MOZ_ASSERT(false, "Expecting a boolean for 'bluetooth.enabled'!"); return NS_ERROR_UNEXPECTED; } if (value.toBoolean() == IsEnabled()) { // Nothing to do here. return NS_OK; } nsresult rv; if (IsEnabled()) { rv = Stop(); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; } rv = Start(); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; }
NS_IMETHODIMP TCPSocketParent::SendCallback(const nsAString& aType, const JS::Value& aDataVal, const nsAString& aReadyState, uint32_t aBuffered, JSContext* aCx) { if (!mIPCOpen) { NS_WARNING("Dropping callback due to no IPC connection"); return NS_OK; } CallbackData data; if (aDataVal.isString()) { JSString* jsstr = aDataVal.toString(); nsDependentJSString str; if (!str.init(aCx, jsstr)) { FireInteralError(this, __LINE__); return NS_ERROR_OUT_OF_MEMORY; } data = str; } else if (aDataVal.isUndefined() || aDataVal.isNull()) { data = mozilla::void_t(); } else if (aDataVal.isObject()) { JSObject* obj = &aDataVal.toObject(); if (JS_IsTypedArrayObject(obj)) { NS_ENSURE_TRUE(JS_IsUint8Array(obj), NS_ERROR_FAILURE); uint32_t nbytes = JS_GetTypedArrayByteLength(obj); uint8_t* buffer = JS_GetUint8ArrayData(obj); if (!buffer) { FireInteralError(this, __LINE__); return NS_ERROR_OUT_OF_MEMORY; } FallibleTArray<uint8_t> fallibleArr; if (!fallibleArr.InsertElementsAt(0, buffer, nbytes)) { FireInteralError(this, __LINE__); return NS_ERROR_OUT_OF_MEMORY; } InfallibleTArray<uint8_t> arr; arr.SwapElements(fallibleArr); data = SendableData(arr); } else { nsDependentJSString message, filename; uint32_t lineNumber = 0; uint32_t columnNumber = 0; jsval val; if (!JS_GetProperty(aCx, obj, "message", &val)) { NS_ERROR("No message property on supposed error object"); } else if (JSVAL_IS_STRING(val)) { if (!message.init(aCx, JSVAL_TO_STRING(val))) { NS_WARNING("couldn't initialize string"); } } if (!JS_GetProperty(aCx, obj, "fileName", &val)) { NS_ERROR("No fileName property on supposed error object"); } else if (JSVAL_IS_STRING(val)) { if (!filename.init(aCx, JSVAL_TO_STRING(val))) { NS_WARNING("couldn't initialize string"); } } if (!JS_GetProperty(aCx, obj, "lineNumber", &val)) { NS_ERROR("No lineNumber property on supposed error object"); } else if (JSVAL_IS_INT(val)) { lineNumber = JSVAL_TO_INT(val); } if (!JS_GetProperty(aCx, obj, "columnNumber", &val)) { NS_ERROR("No columnNumber property on supposed error object"); } else if (JSVAL_IS_INT(val)) { columnNumber = JSVAL_TO_INT(val); } data = JSError(message, filename, lineNumber, columnNumber); } } else { NS_ERROR("Unexpected JS value encountered"); FireInteralError(this, __LINE__); return NS_ERROR_FAILURE; } mozilla::unused << PTCPSocketParent::SendCallback(nsString(aType), data, nsString(aReadyState), aBuffered); return NS_OK; }
nsresult BluetoothManager::HandleMozsettingChanged(const PRUnichar* aData) { // The string that we're interested in will be a JSON string that looks like: // {"key":"bluetooth.enabled","value":true} nsresult rv; nsIScriptContext* sc = GetContextForEventHandlers(&rv); if (NS_FAILED(rv)) { return NS_ERROR_UNEXPECTED; } JSContext *cx = sc->GetNativeContext(); if (!cx) { return NS_OK; } // In the following [if] blocks, NS_OK will be returned even if JS_* functions // return false. That's because this function gets called whenever mozSettings // changes, so that we'll receive signals we're not interested in and it would // be one of the reasons for making JS_* functions return false. nsDependentString dataStr(aData); JS::Value val; if (!JS_ParseJSON(cx, dataStr.get(), dataStr.Length(), &val)) { return NS_OK; } if (!val.isObject()) { return NS_OK; } JSObject &obj(val.toObject()); JS::Value key; if (!JS_GetProperty(cx, &obj, "key", &key)) { return NS_OK; } if (!key.isString()) { return NS_OK; } JSBool match; if (!JS_StringEqualsAscii(cx, key.toString(), "bluetooth.enabled", &match)) { return NS_OK; } if (!match) { return NS_OK; } JS::Value value; if (!JS_GetProperty(cx, &obj, "value", &value)) { return NS_OK; } if (!value.isBoolean()) { return NS_OK; } BluetoothService* bs = BluetoothService::Get(); if (!bs) { NS_WARNING("BluetoothService not available!"); return NS_ERROR_FAILURE; } bool enabled = value.toBoolean(); nsCOMPtr<nsIRunnable> resultTask = new ToggleBtResultTask(this, enabled); if (enabled) { if (NS_FAILED(bs->Start(resultTask))) { return NS_ERROR_FAILURE; } } else { if (NS_FAILED(bs->Stop(resultTask))) { return NS_ERROR_FAILURE; } } return NS_OK; }
nsresult BluetoothHfpManager::HandleVolumeChanged(const nsAString& aData) { MOZ_ASSERT(NS_IsMainThread()); if (GetConnectionStatus() != SocketConnectionStatus::SOCKET_CONNECTED) { return NS_OK; } // The string that we're interested in will be a JSON string that looks like: // {"key":"volumeup", "value":1.0} // {"key":"volumedown", "value":0.2} JSContext* cx = nsContentUtils::GetSafeJSContext(); if (!cx) { return NS_OK; } JS::Value val; if (!JS_ParseJSON(cx, aData.BeginReading(), aData.Length(), &val)) { return JS_ReportPendingException(cx) ? NS_OK : NS_ERROR_OUT_OF_MEMORY; } if (!val.isObject()) { return NS_OK; } JSObject& obj(val.toObject()); JS::Value key; if (!JS_GetProperty(cx, &obj, "key", &key)) { MOZ_ASSERT(!JS_IsExceptionPending(cx)); return NS_ERROR_OUT_OF_MEMORY; } if (!key.isString()) { return NS_OK; } JSBool match; if (!JS_StringEqualsAscii(cx, key.toString(), AUDIO_VOLUME_MASTER, &match)) { MOZ_ASSERT(!JS_IsExceptionPending(cx)); return NS_ERROR_OUT_OF_MEMORY; } if (!match) { return NS_OK; } JS::Value value; if (!JS_GetProperty(cx, &obj, "value", &value)) { MOZ_ASSERT(!JS_IsExceptionPending(cx)); return NS_ERROR_OUT_OF_MEMORY; } if (!value.isNumber()) { return NS_ERROR_UNEXPECTED; } // AG volume range: [0.0, 1.0] // HS volume range: [0, 15] float volume = value.toNumber(); mCurrentVgs = ceil(volume * 15); SendCommand("+VGS: ", mCurrentVgs); return NS_OK; }
/*! @brief Fill a bottle with the contents of an object. @param[in] jct The %JavaScript engine context. @param[in,out] aBottle The bottle to be filled. @param[in] theData The value to be sent. @param[in] topLevel @c true if this is the outermost list of an object. */ static void fillBottleFromValue(JSContext * jct, yarp::os::Bottle & aBottle, JS::Value theData, const bool topLevel) { ODL_ENTER(); //#### ODL_P2("jct = ", jct, "aBottle = ", &aBottle); //#### ODL_B1("topLevel = ", topLevel); //#### JS::RootedValue asRootedValue(jct); asRootedValue = theData; if (theData.isBoolean()) { aBottle.addInt(JS::ToBoolean(asRootedValue) ? 1 : 0); } else if (theData.isDouble()) { double aValue; if (JS::ToNumber(jct, asRootedValue, &aValue)) { aBottle.addDouble(aValue); } } else if (theData.isInt32()) { int32_t aValue; if (JS::ToInt32(jct, asRootedValue, &aValue)) { aBottle.addInt(aValue); } } else if (theData.isString()) { JSString * asString = theData.toString(); char * asChars = JS_EncodeString(jct, asString); aBottle.addString(asChars); JS_free(jct, asChars); } else if (theData.isObject()) { JS::RootedObject asObject(jct); if (JS_ValueToObject(jct, asRootedValue, &asObject)) { bool processed = false; #if (47 <= MOZJS_MAJOR_VERSION) bool isArray; #endif // 47 <= MOZJS_MAJOR_VERSION #if (47 <= MOZJS_MAJOR_VERSION) if (JS_IsArrayObject(jct, asObject, &isArray)) #else // 47 > MOZJS_MAJOR_VERSION if (JS_IsArrayObject(jct, asObject)) #endif // 47 > MOZJS_MAJOR_VERSION { uint32_t arrayLength; if (JS_GetArrayLength(jct, asObject, &arrayLength)) { // Treat as a list if (topLevel) { for (uint32_t ii = 0; arrayLength > ii; ++ii) { JS::RootedValue anElement(jct); if (JS_GetElement(jct, asObject, ii, &anElement)) { fillBottleFromValue(jct, aBottle, anElement, false); } } } else { yarp::os::Bottle & innerList(aBottle.addList()); for (uint32_t ii = 0; arrayLength > ii; ++ii) { JS::RootedValue anElement(jct); if (JS_GetElement(jct, asObject, ii, &anElement)) { fillBottleFromValue(jct, innerList, anElement, false); } } } processed = true; } } if (! processed) { // Treat as a dictionary yarp::os::Property & innerDict(aBottle.addDict()); #if (47 <= MOZJS_MAJOR_VERSION) JS::Rooted<JS::IdVector> ids(jct, JS::IdVector(jct)); #else // 47 > MOZJS_MAJOR_VERSION JS::AutoIdArray ids(jct, JS_Enumerate(jct, asObject)); #endif // 47 > MOZJS_MAJOR_VERSION #if (47 <= MOZJS_MAJOR_VERSION) if (JS_Enumerate(jct, asObject, &ids)) #else // 47 > MOZJS_MAJOR_VERSION // Note that only operator! is defined, so we need to do a 'double-negative'. if (!! ids) #endif // 47 > MOZJS_MAJOR_VERSION { for (size_t ii = 0, len = ids.length(); len > ii; ++ii) { JS::RootedValue key(jct); if (JS_IdToValue(jct, ids[ii], &key)) { JS::RootedValue key(jct); JS::RootedValue result(jct); JS::RootedId aRootedId(jct); aRootedId = ids[ii]; if (JS_IdToValue(jct, ids[ii], &key) && JS_GetPropertyById(jct, asObject, aRootedId, &result)) { JSString * keyString = key.toString(); char * keyAsChars = JS_EncodeString(jct, keyString); YarpString keyToUse(keyAsChars); yarp::os::Bottle convertedResult; JS_free(jct, keyAsChars); fillBottleFromValue(jct, convertedResult, result, false); if (1 == convertedResult.size()) { yarp::os::Value anElement(convertedResult.get(0)); if (anElement.isInt()) { innerDict.put(keyToUse, anElement.asInt()); } else if (anElement.isDouble()) { innerDict.put(keyToUse, anElement.asDouble()); } else if (anElement.isString()) { innerDict.put(keyToUse, anElement.asString()); } else { innerDict.put(keyToUse, anElement); } } } } } } } } } ODL_EXIT(); //#### } // fillBottleFromValue
NS_IMETHODIMP TCPSocketParent::SendCallback(const nsAString& aType, const JS::Value& aDataVal, const nsAString& aReadyState, uint32_t aBuffered, JSContext* aCx) { if (!mIPCOpen) { NS_WARNING("Dropping callback due to no IPC connection"); return NS_OK; } CallbackData data; if (aDataVal.isString()) { JSString* jsstr = aDataVal.toString(); nsDependentJSString str; if (!str.init(aCx, jsstr)) { FireInteralError(this, __LINE__); return NS_ERROR_OUT_OF_MEMORY; } data = SendableData(str); } else if (aDataVal.isUndefined() || aDataVal.isNull()) { data = mozilla::void_t(); } else if (aDataVal.isObject()) { JSObject* obj = &aDataVal.toObject(); if (JS_IsArrayBufferObject(obj)) { uint32_t nbytes = JS_GetArrayBufferByteLength(obj); uint8_t* buffer = JS_GetArrayBufferData(obj); if (!buffer) { FireInteralError(this, __LINE__); return NS_ERROR_OUT_OF_MEMORY; } FallibleTArray<uint8_t> fallibleArr; if (!fallibleArr.InsertElementsAt(0, buffer, nbytes)) { FireInteralError(this, __LINE__); return NS_ERROR_OUT_OF_MEMORY; } InfallibleTArray<uint8_t> arr; arr.SwapElements(fallibleArr); data = SendableData(arr); } else { nsDependentJSString name; JS::Rooted<JS::Value> val(aCx); if (!JS_GetProperty(aCx, obj, "name", val.address())) { NS_ERROR("No name property on supposed error object"); } else if (JSVAL_IS_STRING(val)) { if (!name.init(aCx, JSVAL_TO_STRING(val))) { NS_WARNING("couldn't initialize string"); } } data = TCPError(name); } } else { NS_ERROR("Unexpected JS value encountered"); FireInteralError(this, __LINE__); return NS_ERROR_FAILURE; } mozilla::unused << PTCPSocketParent::SendCallback(nsString(aType), data, nsString(aReadyState), aBuffered); return NS_OK; }
nsresult BluetoothHfpManager::HandleVolumeChanged(const nsAString& aData) { MOZ_ASSERT(NS_IsMainThread()); // The string that we're interested in will be a JSON string that looks like: // {"key":"volumeup", "value":1.0} // {"key":"volumedown", "value":0.2} JSContext* cx = nsContentUtils::GetSafeJSContext(); if (!cx) { return NS_OK; } JS::Value val; if (!JS_ParseJSON(cx, aData.BeginReading(), aData.Length(), &val)) { return JS_ReportPendingException(cx) ? NS_OK : NS_ERROR_OUT_OF_MEMORY; } if (!val.isObject()) { return NS_OK; } JSObject& obj(val.toObject()); JS::Value key; if (!JS_GetProperty(cx, &obj, "key", &key)) { MOZ_ASSERT(!JS_IsExceptionPending(cx)); return NS_ERROR_OUT_OF_MEMORY; } if (!key.isString()) { return NS_OK; } JSBool match; if (!JS_StringEqualsAscii(cx, key.toString(), AUDIO_VOLUME_MASTER, &match)) { MOZ_ASSERT(!JS_IsExceptionPending(cx)); return NS_ERROR_OUT_OF_MEMORY; } if (!match) { return NS_OK; } JS::Value value; if (!JS_GetProperty(cx, &obj, "value", &value)) { MOZ_ASSERT(!JS_IsExceptionPending(cx)); return NS_ERROR_OUT_OF_MEMORY; } if (!value.isNumber()) { return NS_ERROR_UNEXPECTED; } // AG volume range: [0.0, 1.0] float volume = value.toNumber(); // HS volume range: [0, 15] mCurrentVgs = ceil(volume * 15); nsDiscriminatedUnion du; du.mType = 0; du.u.mInt8Value = mCurrentVgs; nsCString vgs; if (NS_FAILED(nsVariant::ConvertToACString(du, vgs))) { NS_WARNING("Failed to convert volume to string"); return NS_ERROR_FAILURE; } nsAutoCString newVgs; newVgs += "+VGS: "; newVgs += vgs; SendLine(newVgs.get()); return NS_OK; }
nsresult nsDOMMultipartFile::InitBlob(JSContext* aCx, uint32_t aArgc, JS::Value* aArgv, UnwrapFuncPtr aUnwrapFunc) { bool nativeEOL = false; if (aArgc > 1) { if (NS_IsMainThread()) { BlobPropertyBag d; if (!d.Init(aCx, JS::NullPtr(), aArgv[1])) { return NS_ERROR_TYPE_ERR; } mContentType = d.mType; nativeEOL = d.mEndings == EndingTypesValues::Native; } else { BlobPropertyBagWorkers d; if (!d.Init(aCx, JS::NullPtr(), aArgv[1])) { return NS_ERROR_TYPE_ERR; } mContentType = d.mType; nativeEOL = d.mEndings == EndingTypesValues::Native; } } if (aArgc > 0) { if (!aArgv[0].isObject()) { return NS_ERROR_TYPE_ERR; // We're not interested } JSObject& obj = aArgv[0].toObject(); if (!JS_IsArrayObject(aCx, &obj)) { return NS_ERROR_TYPE_ERR; // We're not interested } BlobSet blobSet; uint32_t length; JS_ALWAYS_TRUE(JS_GetArrayLength(aCx, &obj, &length)); for (uint32_t i = 0; i < length; ++i) { JS::Value element; if (!JS_GetElement(aCx, &obj, i, &element)) return NS_ERROR_TYPE_ERR; if (element.isObject()) { JSObject& obj = element.toObject(); nsCOMPtr<nsIDOMBlob> blob = aUnwrapFunc(aCx, &obj); if (blob) { // Flatten so that multipart blobs will never nest nsDOMFileBase* file = static_cast<nsDOMFileBase*>( static_cast<nsIDOMBlob*>(blob)); const nsTArray<nsCOMPtr<nsIDOMBlob> >* subBlobs = file->GetSubBlobs(); if (subBlobs) { blobSet.AppendBlobs(*subBlobs); } else { blobSet.AppendBlob(blob); } continue; } if (JS_IsArrayBufferViewObject(&obj)) { blobSet.AppendVoidPtr(JS_GetArrayBufferViewData(&obj), JS_GetArrayBufferViewByteLength(&obj)); continue; } if (JS_IsArrayBufferObject(&obj)) { blobSet.AppendArrayBuffer(&obj); continue; } // neither Blob nor ArrayBuffer(View) } else if (element.isString()) { blobSet.AppendString(element.toString(), nativeEOL, aCx); continue; } // coerce it to a string JSString* str = JS_ValueToString(aCx, element); NS_ENSURE_TRUE(str, NS_ERROR_TYPE_ERR); blobSet.AppendString(str, nativeEOL, aCx); } mBlobs = blobSet.GetBlobs(); } return NS_OK; }