Beispiel #1
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;
}
Beispiel #2
0
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, 0, nullptr, val.address())) {
      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;
}
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;
}
bool
CallbackInterface::GetCallableProperty(JSContext* cx, JS::Handle<jsid> aPropId,
                                       JS::MutableHandle<JS::Value> aCallable)
{
  if (!JS_GetPropertyById(cx, CallbackPreserveColor(), aPropId, aCallable)) {
    return false;
  }
  if (!aCallable.isObject() ||
      !JS_ObjectIsCallable(cx, &aCallable.toObject())) {
    char* propName =
      JS_EncodeString(cx, JS_FORGET_STRING_FLATNESS(JSID_TO_FLAT_STRING(aPropId)));
    nsPrintfCString description("Property '%s'", propName);
    JS_free(cx, propName);
    ThrowErrorMessage(cx, MSG_NOT_CALLABLE, description.get());
    return false;
  }

  return true;
}
Beispiel #5
0
JSBool
jsd_IsValueFunction(JSDContext* jsdc, JSDValue* jsdval)
{
    return !JSVAL_IS_PRIMITIVE(jsdval->val) &&
           JS_ObjectIsCallable(jsdc->dumbContext, JSVAL_TO_OBJECT(jsdval->val));
}