// Helper for weighted regions.
nsresult
CameraControlImpl::Set(JSContext* aCx, uint32_t aKey, const JS::Value& aValue, uint32_t aLimit)
{
  if (aLimit == 0) {
    DOM_CAMERA_LOGI("%s:%d : aLimit = 0, nothing to do\n", __func__, __LINE__);
    return NS_OK;
  }

  if (!aValue.isObject()) {
    return NS_ERROR_INVALID_ARG;
  }

  uint32_t length = 0;

  JSObject* regions = &aValue.toObject();
  if (!JS_GetArrayLength(aCx, regions, &length)) {
    return NS_ERROR_FAILURE;
  }

  DOM_CAMERA_LOGI("%s:%d : got %d regions (limited to %d)\n", __func__, __LINE__, length, aLimit);
  if (length > aLimit) {
    length = aLimit;
  }

  nsTArray<CameraRegion> regionArray;
  regionArray.SetCapacity(length);

  for (uint32_t i = 0; i < length; ++i) {
    JS::Value v;

    if (!JS_GetElement(aCx, regions, i, &v)) {
      return NS_ERROR_FAILURE;
    }

    CameraRegion* r = regionArray.AppendElement();
    /**
     * These are the default values.  We can remove these when the xpidl
     * dictionary parser gains the ability to grok default values.
     */
    r->top = -1000;
    r->left = -1000;
    r->bottom = 1000;
    r->right = 1000;
    r->weight = 1000;

    nsresult rv = r->Init(aCx, &v);
    NS_ENSURE_SUCCESS(rv, rv);

    DOM_CAMERA_LOGI("region %d: top=%d, left=%d, bottom=%d, right=%d, weight=%d\n",
      i,
      r->top,
      r->left,
      r->bottom,
      r->right,
      r->weight
    );
  }
  SetParameter(aKey, regionArray);
  return NS_OK;
}
Beispiel #2
0
JSScript *createScriptViaXDR(JSPrincipals *prin, JSPrincipals *orig, int testCase)
{
    const char src[] =
        "function f() { return 1; }\n"
        "f;\n";

    js::RootedObject global(cx, JS_GetGlobalObject(cx));
    JSScript *script = CompileScriptForPrincipalsVersionOrigin(cx, global, prin, orig,
                                                               src, strlen(src), "test", 1,
                                                               JSVERSION_DEFAULT);
    if (!script)
        return NULL;

    if (testCase == TEST_SCRIPT || testCase == TEST_SERIALIZED_FUNCTION) {
        script = FreezeThaw(cx, script);
        if (!script)
            return NULL;
        if (testCase == TEST_SCRIPT)
            return script;
    }

    JS::Value v;
    JSBool ok = JS_ExecuteScript(cx, global, script, &v);
    if (!ok || !v.isObject())
        return NULL;
    js::RootedObject funobj(cx, &v.toObject());
    if (testCase == TEST_FUNCTION) {
        funobj = FreezeThaw(cx, funobj);
        if (!funobj)
            return NULL;
    }
    return GetScript(cx, funobj);
}
// static
JSObject*
DOMProxyHandler::GetAndClearExpandoObject(JSObject* obj)
{
    MOZ_ASSERT(IsDOMProxy(obj), "expected a DOM proxy object");
    JS::Value v = js::GetProxyExtra(obj, JSPROXYSLOT_EXPANDO);
    if (v.isUndefined()) {
        return nullptr;
    }

    if (v.isObject()) {
        js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO, UndefinedValue());
        xpc::GetObjectScope(obj)->RemoveDOMExpandoObject(obj);
    } else {
        js::ExpandoAndGeneration* expandoAndGeneration =
            static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
        v = expandoAndGeneration->expando;
        if (v.isUndefined()) {
            return nullptr;
        }
        expandoAndGeneration->expando = UndefinedValue();
    }


    return &v.toObject();
}
Beispiel #4
0
NS_IMETHODIMP
MobileMessageManager::Delete(const JS::Value& aParam, nsIDOMDOMRequest** aRequest)
{
  if (aParam.isInt32()) {
    return Delete(aParam.toInt32(), aRequest);
  }

  if (!aParam.isObject()) {
    return NS_ERROR_INVALID_ARG;
  }

  nsresult rv;
  nsIScriptContext* sc = GetContextForEventHandlers(&rv);
  AutoPushJSContext cx(sc->GetNativeContext());
  NS_ENSURE_STATE(sc);

  int32_t id;
  nsCOMPtr<nsIDOMMozSmsMessage> smsMessage =
    do_QueryInterface(nsContentUtils::XPConnect()->GetNativeOfWrapper(cx, &aParam.toObject()));
  if (smsMessage) {
    smsMessage->GetId(&id);
  } else {
    nsCOMPtr<nsIDOMMozMmsMessage> mmsMessage =
      do_QueryInterface(nsContentUtils::XPConnect()->GetNativeOfWrapper(cx, &aParam.toObject()));
    if (mmsMessage) {
      mmsMessage->GetId(&id);
    } else {
      return NS_ERROR_INVALID_ARG;
    }
  }

  return Delete(id, aRequest);
}
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;
}
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());
}
nsresult xpcJSWeakReference::Init(JSContext* cx, const JS::Value& object)
{
    if (!object.isObject())
        return NS_OK;

    JS::RootedObject obj(cx, &object.toObject());

    XPCCallContext ccx(NATIVE_CALLER, cx);

    // See if the object is a wrapped native that supports weak references.
    nsISupports* supports =
        nsXPConnect::XPConnect()->GetNativeOfWrapper(cx, obj);
    nsCOMPtr<nsISupportsWeakReference> supportsWeakRef =
        do_QueryInterface(supports);
    if (supportsWeakRef) {
        supportsWeakRef->GetWeakReference(getter_AddRefs(mReferent));
        if (mReferent) {
            return NS_OK;
        }
    }
    // If it's not a wrapped native, or it is a wrapped native that does not
    // support weak references, fall back to getting a weak ref to the object.

    // See if object is a wrapped JSObject.
    nsRefPtr<nsXPCWrappedJS> wrapped;
    nsresult rv = nsXPCWrappedJS::GetNewOrUsed(obj,
                                               NS_GET_IID(nsISupports),
                                               getter_AddRefs(wrapped));
    if (!wrapped) {
        NS_ERROR("can't get nsISupportsWeakReference wrapper for obj");
        return rv;
    }

    return wrapped->GetWeakReference(getter_AddRefs(mReferent));
}
Beispiel #8
0
NS_IMETHODIMP
TCPSocketParent::InitJS(const JS::Value& aIntermediary, JSContext* aCx)
{
  MOZ_ASSERT(aIntermediary.isObject());
  mIntermediaryObj = &aIntermediary.toObject();
  return NS_OK;
}
js::DOMProxyShadowsResult
DOMProxyShadows(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id)
{
  JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
  JS::Value v = js::GetProxyExtra(proxy, JSPROXYSLOT_EXPANDO);
  bool isOverrideBuiltins = !v.isObject() && !v.isUndefined();
  if (expando) {
    bool hasOwn;
    if (!JS_AlreadyHasOwnPropertyById(cx, expando, id, &hasOwn))
      return js::ShadowCheckFailed;

    if (hasOwn) {
      return isOverrideBuiltins ?
        js::ShadowsViaIndirectExpando : js::ShadowsViaDirectExpando;
    }
  }

  if (!isOverrideBuiltins) {
    // Our expando, if any, didn't shadow, so we're not shadowing at all.
    return js::DoesntShadow;
  }

  bool hasOwn;
  if (!GetProxyHandler(proxy)->hasOwn(cx, proxy, id, &hasOwn))
    return js::ShadowCheckFailed;

  return hasOwn ? js::Shadows : js::DoesntShadowUnique;
}
Beispiel #10
0
/* [implicit_jscontext] void getPreviewStream (in jsval aOptions, in nsICameraPreviewStreamCallback onSuccess, [optional] in nsICameraErrorCallback onError); */
NS_IMETHODIMP
nsCameraControl::GetPreviewStream(const JS::Value & aOptions, nsICameraPreviewStreamCallback *onSuccess, nsICameraErrorCallback *onError, JSContext* cx)
{
  /* 0 means not specified, use default value */
  PRUint32 width = 0;
  PRUint32 height = 0;

  NS_ENSURE_TRUE(onSuccess, NS_ERROR_INVALID_ARG);

  if (aOptions.isObject()) {
    JSObject *options = JSVAL_TO_OBJECT(aOptions);
    jsval v;

    if (JS_GetProperty(cx, options, "width", &v)) {
      if (JSVAL_IS_INT(v)) {
        width = JSVAL_TO_INT(v);
      }
    }
    if (JS_GetProperty(cx, options, "height", &v)) {
      if (JSVAL_IS_INT(v)) {
        height = JSVAL_TO_INT(v);
      }
    }
  }

  nsCOMPtr<nsIRunnable> getPreviewStreamTask = new GetPreviewStreamTask(this, width, height, onSuccess, onError);
  mCameraThread->Dispatch(getPreviewStreamTask, NS_DISPATCH_NORMAL);

  return NS_OK;
}
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);
}
Beispiel #12
0
nsresult
nsJSON::EncodeInternal(JSContext* cx, const JS::Value& aValue,
                       nsJSONWriter* writer)
{
  JSAutoRequest ar(cx);

  // Backward compatibility:
  // nsIJSON does not allow to serialize anything other than objects
  if (!aValue.isObject()) {
    return NS_ERROR_INVALID_ARG;
  }

  JSObject* obj = &aValue.toObject();

  JS::Value val = aValue;

  /* Backward compatibility:
   * Manually call toJSON if implemented by the object and check that
   * the result is still an object
   * Note: It is perfectly fine to not implement toJSON, so it is
   * perfectly fine for GetMethod to fail
   */
  JS::Value toJSON;
  if (JS_GetMethod(cx, obj, "toJSON", NULL, &toJSON) &&
      !JSVAL_IS_PRIMITIVE(toJSON) &&
      JS_ObjectIsCallable(cx, JSVAL_TO_OBJECT(toJSON))) {
    // If toJSON is implemented, it must not throw
    if (!JS_CallFunctionValue(cx, obj, toJSON, 0, NULL, &val)) {
      if (JS_IsExceptionPending(cx))
        // passing NS_OK will throw the pending exception
        return NS_OK;

      // No exception, but still failed
      return NS_ERROR_FAILURE;
    }

    // Backward compatibility:
    // nsIJSON does not allow to serialize anything other than objects
    if (JSVAL_IS_PRIMITIVE(val))
      return NS_ERROR_INVALID_ARG;
  }
  // GetMethod may have thrown
  else if (JS_IsExceptionPending(cx))
    // passing NS_OK will throw the pending exception
    return NS_OK;

  // Backward compatibility:
  // function shall not pass, just "plain" objects and arrays
  JSType type = JS_TypeOfValue(cx, val);
  if (type == JSTYPE_FUNCTION)
    return NS_ERROR_INVALID_ARG;

  // We're good now; try to stringify
  if (!JS_Stringify(cx, &val, NULL, JSVAL_NULL, WriteCallback, writer))
    return NS_ERROR_FAILURE;

  return NS_OK;
}
NS_IMETHODIMP
nsScreen::MozLockOrientation(const JS::Value& aOrientation, JSContext* aCx,
                             bool* aReturn)
{
  if (aOrientation.isObject()) {
    JS::Rooted<JSObject*> seq(aCx, &aOrientation.toObject());
    if (IsArrayLike(aCx, seq)) {
      uint32_t length;
      // JS_GetArrayLength actually works on all objects
      if (!JS_GetArrayLength(aCx, seq, &length)) {
        return NS_ERROR_FAILURE;
      }

      Sequence<nsString> orientations;
      if (!orientations.SetCapacity(length)) {
        return NS_ERROR_OUT_OF_MEMORY;
      }

      for (uint32_t i = 0; i < length; ++i) {
        JS::Rooted<JS::Value> temp(aCx);
        if (!JS_GetElement(aCx, seq, i, &temp)) {
          return NS_ERROR_FAILURE;
        }

        JS::RootedString jsString(aCx, JS_ValueToString(aCx, temp));
        if (!jsString) {
          return NS_ERROR_FAILURE;
        }

        nsDependentJSString str;
        if (!str.init(aCx, jsString)) {
          return NS_ERROR_FAILURE;
        }

        *orientations.AppendElement() = str;
      }

      ErrorResult rv;
      *aReturn = MozLockOrientation(orientations, rv);
      return rv.ErrorCode();
    }
  }

  JS::RootedString jsString(aCx, JS_ValueToString(aCx, aOrientation));
  if (!jsString) {
    return NS_ERROR_FAILURE;
  }

  nsDependentJSString orientation;
  if (!orientation.init(aCx, jsString)) {
    return NS_ERROR_FAILURE;
  }

  ErrorResult rv;
  *aReturn = MozLockOrientation(orientation, rv);
  return rv.ErrorCode();
}
Beispiel #14
0
// JS-to-native helpers
// Setter for weighted regions: { top, bottom, left, right, weight }
nsresult
nsDOMCameraControl::Set(JSContext* aCx, uint32_t aKey, const JS::Value& aValue, uint32_t aLimit)
{
  if (aLimit == 0) {
    DOM_CAMERA_LOGI("%s:%d : aLimit = 0, nothing to do\n", __func__, __LINE__);
    return NS_OK;
  }

  if (!aValue.isObject()) {
    return NS_ERROR_INVALID_ARG;
  }

  uint32_t length = 0;

  JS::Rooted<JSObject*> regions(aCx, &aValue.toObject());
  if (!JS_GetArrayLength(aCx, regions, &length)) {
    return NS_ERROR_FAILURE;
  }

  DOM_CAMERA_LOGI("%s:%d : got %d regions (limited to %d)\n", __func__, __LINE__, length, aLimit);
  if (length > aLimit) {
    length = aLimit;
  }

  nsTArray<ICameraControl::Region> regionArray;
  regionArray.SetCapacity(length);

  for (uint32_t i = 0; i < length; ++i) {
    JS::Rooted<JS::Value> v(aCx);

    if (!JS_GetElement(aCx, regions, i, &v)) {
      return NS_ERROR_FAILURE;
    }

    CameraRegion region;
    if (!region.Init(aCx, v)) {
      return NS_ERROR_FAILURE;
    }

    ICameraControl::Region* r = regionArray.AppendElement();
    r->top = region.mTop;
    r->left = region.mLeft;
    r->bottom = region.mBottom;
    r->right = region.mRight;
    r->weight = region.mWeight;

    DOM_CAMERA_LOGI("region %d: top=%d, left=%d, bottom=%d, right=%d, weight=%u\n",
      i,
      r->top,
      r->left,
      r->bottom,
      r->right,
      r->weight
    );
  }
  return mCameraControl->Set(aKey, regionArray);
}
Beispiel #15
0
NS_IMETHODIMP
nsHTMLAudioElement::MozWriteAudio(const JS::Value& aData, JSContext* aCx, uint32_t* aRetVal)
{
  if (!mAudioStream) {
    return NS_ERROR_DOM_INVALID_STATE_ERR;
  }

  if (!aData.isObject()) {
    return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
  }

  JSObject* darray = &aData.toObject();
  JS::AutoObjectRooter tvr(aCx);
  JSObject* tsrc = NULL;

  // Allow either Float32Array or plain JS Array
  if (JS_IsFloat32Array(darray)) {
    tsrc = darray;
  } else if (JS_IsArrayObject(aCx, darray)) {
    JSObject* nobj = JS_NewFloat32ArrayFromArray(aCx, darray);
    if (!nobj) {
      return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
    }
    tsrc = nobj;
  } else {
    return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
  }
  tvr.setObject(tsrc);

  uint32_t dataLength = JS_GetTypedArrayLength(tsrc);

  // Make sure that we are going to write the correct amount of data based
  // on number of channels.
  if (dataLength % mChannels != 0) {
    return NS_ERROR_DOM_INDEX_SIZE_ERR;
  }

  // Don't write more than can be written without blocking.
  uint32_t writeLen = std::min(mAudioStream->Available(), dataLength / mChannels);

  float* frames = JS_GetFloat32ArrayData(tsrc);
  // Convert the samples back to integers as we are using fixed point audio in
  // the AudioStream.
  // This could be optimized to avoid allocation and memcpy when
  // AudioDataValue is 'float', but it's not worth it for this deprecated API.
  nsAutoArrayPtr<AudioDataValue> audioData(new AudioDataValue[writeLen * mChannels]);
  ConvertAudioSamples(frames, audioData.get(), writeLen * mChannels);
  nsresult rv = mAudioStream->Write(audioData.get(), writeLen);

  if (NS_FAILED(rv)) {
    return rv;
  }

  // Return the actual amount written.
  *aRetVal = writeLen * mChannels;
  return rv;
}
Beispiel #16
0
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";
}
Beispiel #17
0
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);
}
nsresult
nsJSON::EncodeInternal(JSContext* cx, const JS::Value& aValue,
                       nsJSONWriter* writer)
{
    // Backward compatibility:
    // nsIJSON does not allow to serialize anything other than objects
    if (!aValue.isObject()) {
        return NS_ERROR_INVALID_ARG;
    }
    JS::Rooted<JSObject*> obj(cx, &aValue.toObject());

    /* Backward compatibility:
     * Manually call toJSON if implemented by the object and check that
     * the result is still an object
     * Note: It is perfectly fine to not implement toJSON, so it is
     * perfectly fine for GetMethod to fail
     */
    JS::Rooted<JS::Value> val(cx, aValue);
    JS::Rooted<JS::Value> toJSON(cx);
    if (JS_GetProperty(cx, obj, "toJSON", &toJSON) &&
            toJSON.isObject() &&
            JS_ObjectIsCallable(cx, &toJSON.toObject())) {
        // If toJSON is implemented, it must not throw
        if (!JS_CallFunctionValue(cx, obj, toJSON, JS::HandleValueArray::empty(), &val)) {
            if (JS_IsExceptionPending(cx))
                // passing NS_OK will throw the pending exception
                return NS_OK;

            // No exception, but still failed
            return NS_ERROR_FAILURE;
        }

        // Backward compatibility:
        // nsIJSON does not allow to serialize anything other than objects
        if (val.isPrimitive())
            return NS_ERROR_INVALID_ARG;
    }
    // GetMethod may have thrown
    else if (JS_IsExceptionPending(cx))
        // passing NS_OK will throw the pending exception
        return NS_OK;

    // Backward compatibility:
    // function shall not pass, just "plain" objects and arrays
    JSType type = JS_TypeOfValue(cx, val);
    if (type == JSTYPE_FUNCTION)
        return NS_ERROR_INVALID_ARG;

    // We're good now; try to stringify
    if (!JS_Stringify(cx, &val, JS::NullPtr(), JS::NullHandleValue, WriteCallback, writer))
        return NS_ERROR_FAILURE;

    return NS_OK;
}
Beispiel #19
0
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);
}
Beispiel #20
0
Promise*
GetPromise(JSContext* aCx, JS::Handle<JSObject*> aFunc)
{
  JS::Value promiseVal = js::GetFunctionNativeReserved(aFunc, SLOT_PROMISE);

  MOZ_ASSERT(promiseVal.isObject());

  Promise* promise;
  UNWRAP_OBJECT(Promise, &promiseVal.toObject(), promise);
  return promise;
}
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;
}
nsresult
DOMEventTargetHelper::SetEventHandler(nsIAtom* aType,
                                      JSContext* aCx,
                                      const JS::Value& aValue)
{
  RefPtr<EventHandlerNonNull> handler;
  JS::Rooted<JSObject*> callable(aCx);
  if (aValue.isObject() && JS::IsCallable(callable = &aValue.toObject())) {
    handler = new EventHandlerNonNull(aCx, callable, dom::GetIncumbentGlobal());
  }
  SetEventHandler(aType, EmptyString(), handler);
  return NS_OK;
}
NS_IMETHODIMP
TCPSocketChild::SetSocketAndWindow(nsITCPSocketInternal *aSocket,
                          const JS::Value& aWindowObj,
                          JSContext* aCx)
{
  mSocket = aSocket;
  MOZ_ASSERT(aWindowObj.isObject());
  mWindowObj = js::CheckedUnwrap(&aWindowObj.toObject());
  if (!mWindowObj) {
    return NS_ERROR_FAILURE;
  }
  return NS_OK;
}
Beispiel #24
0
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;
}
void
nsGeolocationSettings::HandleGeolocationAlwaysPreciseChange(const JS::Value& aVal)
{
  if (!aVal.isObject()) {
    return;
  }

  // clear the list of apps that are always precise
  mAlwaysPreciseApps.Clear();

  // root the object and get the global
  JS::Rooted<JSObject*> obj(nsContentUtils::RootingCx(), &aVal.toObject());
  MOZ_ASSERT(obj);
  nsIGlobalObject* global = xpc::NativeGlobal(obj);
  NS_ENSURE_TRUE_VOID(global && global->GetGlobalJSObject());

  // the spec requires calling getters when accessing array by index
  AutoEntryScript aes(global, "geolocation.always_precise indexing");
  aes.TakeOwnershipOfErrorReporting();
  JSContext *cx = aes.cx();

  if (!JS_IsArrayObject(cx, obj)) {
    return;
  }

  uint32_t length;
  if (!JS_GetArrayLength(cx, obj, &length)) {
    return;
  }

  // process the list of apps...
  for (uint32_t i = 0; i < length; ++i) {
    JS::RootedValue value(cx);

    if (!JS_GetElement(cx, obj, i, &value) || !value.isString()) {
      continue;
    }

    nsAutoJSString origin;
    if (!origin.init(cx, value)) {
      continue;
    }

    GPSLOG("adding always precise for %s", NS_ConvertUTF16toUTF8(origin).get());

    // add the origin to the list of apps that will always receive
    // precise location information
    mAlwaysPreciseApps.AppendElement(origin);
  }
}
Beispiel #26
0
NS_IMETHODIMP
nsHTMLAudioElement::MozWriteAudio(const JS::Value& aData, JSContext* aCx, PRUint32* aRetVal)
{
    if (!mAudioStream) {
        return NS_ERROR_DOM_INVALID_STATE_ERR;
    }

    if (!aData.isObject()) {
        return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
    }

    JSObject* darray = &aData.toObject();
    JS::AutoObjectRooter tvr(aCx);
    JSObject* tsrc = NULL;

    // Allow either Float32Array or plain JS Array
    if (JS_IsFloat32Array(darray, aCx)) {
        tsrc = darray;
    } else if (JS_IsArrayObject(aCx, darray)) {
        JSObject* nobj = JS_NewFloat32ArrayFromArray(aCx, darray);
        if (!nobj) {
            return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
        }
        tsrc = nobj;
    } else {
        return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
    }
    tvr.setObject(tsrc);

    PRUint32 dataLength = JS_GetTypedArrayLength(tsrc, aCx);

    // Make sure that we are going to write the correct amount of data based
    // on number of channels.
    if (dataLength % mChannels != 0) {
        return NS_ERROR_DOM_INDEX_SIZE_ERR;
    }

    // Don't write more than can be written without blocking.
    PRUint32 writeLen = NS_MIN(mAudioStream->Available(), dataLength / mChannels);

    nsresult rv = mAudioStream->Write(JS_GetFloat32ArrayData(tsrc, aCx), writeLen);
    if (NS_FAILED(rv)) {
        return rv;
    }

    // Return the actual amount written.
    *aRetVal = writeLen * mChannels;
    return rv;
}
Beispiel #27
0
bool
GetSendMmsMessageRequestFromParams(uint32_t aServiceId,
                                   const JS::Value& aParam,
                                   SendMmsMessageRequest& request) {
  if (aParam.isUndefined() || aParam.isNull() || !aParam.isObject()) {
    return false;
  }

  mozilla::AutoJSContext cx;
  JS::Rooted<JS::Value> param(cx, aParam);
  RootedDictionary<MmsParameters> params(cx);
  if (!params.Init(cx, param)) {
    return false;
  }

  // SendMobileMessageRequest.receivers
  if (!params.mReceivers.WasPassed()) {
    return false;
  }
  request.receivers().AppendElements(params.mReceivers.Value());

  // SendMobileMessageRequest.attachments
  mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton();

  if (!params.mAttachments.WasPassed()) {
    return false;
  }

  for (uint32_t i = 0; i < params.mAttachments.Value().Length(); i++) {
    mozilla::dom::MmsAttachment& attachment = params.mAttachments.Value()[i];
    MmsAttachmentData mmsAttachment;
    mmsAttachment.id().Assign(attachment.mId);
    mmsAttachment.location().Assign(attachment.mLocation);
    mmsAttachment.contentChild() = cc->GetOrCreateActorForBlob(attachment.mContent);
    if (!mmsAttachment.contentChild()) {
      return false;
    }
    request.attachments().AppendElement(mmsAttachment);
  }

  request.smil() = params.mSmil;
  request.subject() = params.mSubject;

  // Set service ID.
  request.serviceId() = aServiceId;

  return true;
}
NS_IMETHODIMP
WebVTTListener::OnCue(const JS::Value &aCue, JSContext* aCx)
{
  if (!aCue.isObject()) {
    return NS_ERROR_FAILURE;
  }

  TextTrackCue* cue;
  nsresult rv = UNWRAP_OBJECT(VTTCue, aCx, &aCue.toObject(), cue);
  NS_ENSURE_SUCCESS(rv, rv);

  cue->SetTrackElement(mElement);
  mElement->mTrack->AddCue(*cue);

  return NS_OK;
}
NS_IMETHODIMP
WebVTTListener::OnRegion(const JS::Value &aRegion, JSContext* aCx)
{
  if (!aRegion.isObject()) {
    return NS_ERROR_FAILURE;
  }

  TextTrackRegion* region;
  nsresult rv = UNWRAP_OBJECT(VTTRegion, aCx, &aRegion.toObject(),
                              region);
  NS_ENSURE_SUCCESS(rv, rv);

  mElement->mTrack->AddRegion(*region);

  return NS_OK;
}
Beispiel #30
0
void ShadowingDOMProxyHandler::trace(JSTracer* trc, JSObject* proxy) const {
  DOMProxyHandler::trace(trc, proxy);

  MOZ_ASSERT(IsDOMProxy(proxy), "expected a DOM proxy object");
  JS::Value v = js::GetProxyPrivate(proxy);
  MOZ_ASSERT(!v.isObject(), "Should not have expando object directly!");

  // The proxy's private slot is set when we allocate the proxy,
  // so it cannot be |undefined|.
  MOZ_ASSERT(!v.isUndefined());

  js::ExpandoAndGeneration* expandoAndGeneration =
      static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
  JS::TraceEdge(trc, &expandoAndGeneration->expando,
                "Shadowing DOM proxy expando");
}