// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "extensions/renderer/messaging_util.h"

#include <string>

#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/stringprintf.h"
#include "components/crx_file/id_util.h"
#include "extensions/common/api/messaging/message.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest.h"
#include "extensions/common/manifest_handlers/background_info.h"
#include "extensions/renderer/get_script_context.h"
#include "extensions/renderer/script_context.h"
#include "gin/converter.h"
#include "gin/dictionary.h"
#include "third_party/blink/public/web/web_user_gesture_indicator.h"

namespace extensions {
namespace messaging_util {

namespace {

constexpr char kExtensionIdRequiredErrorTemplate[] =
    "chrome.%s() called from a webpage must specify an "
    "Extension ID (string) for its first argument.";

constexpr char kErrorCouldNotSerialize[] = "Could not serialize message.";

}  // namespace

const char kSendMessageChannel[] = "chrome.runtime.sendMessage";
const char kSendRequestChannel[] = "chrome.extension.sendRequest";

const char kOnMessageEvent[] = "runtime.onMessage";
const char kOnMessageExternalEvent[] = "runtime.onMessageExternal";
const char kOnRequestEvent[] = "extension.onRequest";
const char kOnRequestExternalEvent[] = "extension.onRequestExternal";
const char kOnConnectEvent[] = "runtime.onConnect";
const char kOnConnectExternalEvent[] = "runtime.onConnectExternal";

const int kNoFrameId = -1;

std::unique_ptr<Message> MessageFromV8(v8::Local<v8::Context> context,
                                       v8::Local<v8::Value> value,
                                       std::string* error_out) {
  DCHECK(!value.IsEmpty());
  v8::Isolate* isolate = context->GetIsolate();
  v8::Context::Scope context_scope(context);

  // TODO(devlin): For some reason, we don't use the signature for
  // Port.postMessage when evaluating the parameters. We probably should, but
  // we don't know how many extensions that may break. It would be good to
  // investigate, and, ideally, use the signature.

  if (value->IsUndefined()) {
    // JSON.stringify won't serialized undefined (it returns undefined), but it
    // will serialized null. We've always converted undefined to null in JS
    // bindings, so preserve this behavior for now.
    value = v8::Null(isolate);
  }

  bool success = false;
  v8::Local<v8::String> stringified;
  {
    v8::TryCatch try_catch(isolate);
    success = v8::JSON::Stringify(context, value).ToLocal(&stringified);
  }

  if (!success) {
    *error_out = kErrorCouldNotSerialize;
    return nullptr;
  }

  ScriptContext* script_context = GetScriptContextFromV8Context(context);
  blink::WebLocalFrame* web_frame =
      script_context ? script_context->web_frame() : nullptr;
  return MessageFromJSONString(isolate, stringified, error_out, web_frame);
}

std::unique_ptr<Message> MessageFromJSONString(
    v8::Isolate* isolate,
    v8::Local<v8::String> json,
    std::string* error_out,
    blink::WebLocalFrame* web_frame) {
  std::string message;
  message = gin::V8ToString(isolate, json);
  // JSON.stringify can fail to produce a string value in one of two ways: it
  // can throw an exception (as with unserializable objects), or it can return
  // `undefined` (as with e.g. passing a function). If JSON.stringify returns
  // `undefined`, the v8 API then coerces it to the string value "undefined".
  // Check for this, and consider it a failure (since we didn't properly
  // serialize a value).
  if (message == "undefined") {
    *error_out = kErrorCouldNotSerialize;
    return nullptr;
  }

  size_t message_length = message.length();

  // Max bucket at 512 MB - anything over that, and we don't care.
  static constexpr int kMaxUmaLength = 1024 * 1024 * 512;
  static constexpr int kMinUmaLength = 1;
  static constexpr int kBucketCount = 50;
  UMA_HISTOGRAM_CUSTOM_COUNTS("Extensions.Messaging.MessageSize",
                              message_length, kMinUmaLength, kMaxUmaLength,
                              kBucketCount);

  // IPC messages will fail at > 128 MB. Restrict extension messages to 64 MB.
  // A 64 MB JSON-ifiable object is scary enough as is.
  static constexpr size_t kMaxMessageLength = 1024 * 1024 * 64;
  if (message_length > kMaxMessageLength) {
    *error_out = "Message length exceeded maximum allowed length.";
    return nullptr;
  }

  return std::make_unique<Message>(
      message,
      blink::WebUserGestureIndicator::IsProcessingUserGesture(web_frame));
}

v8::Local<v8::Value> MessageToV8(v8::Local<v8::Context> context,
                                 const Message& message) {
  v8::Isolate* isolate = context->GetIsolate();
  v8::Context::Scope context_scope(context);

  v8::Local<v8::String> v8_message_string =
      gin::StringToV8(isolate, message.data);
  v8::Local<v8::Value> parsed_message;
  v8::TryCatch try_catch(isolate);
  if (!v8::JSON::Parse(context, v8_message_string).ToLocal(&parsed_message)) {
    NOTREACHED();
    return v8::Local<v8::Value>();
  }
  return parsed_message;
}

int ExtractIntegerId(v8::Local<v8::Value> value) {
  if (value->IsInt32())
    return value.As<v8::Int32>()->Value();

  // Account for -0, which is a valid integer, but is stored as a number in v8.
  DCHECK(value->IsNumber() && value.As<v8::Number>()->Value() == 0.0);
  return 0;
}

MessageOptions ParseMessageOptions(v8::Local<v8::Context> context,
                                   v8::Local<v8::Object> v8_options,
                                   int flags) {
  DCHECK(!v8_options.IsEmpty());
  DCHECK(!v8_options->IsNull());

  v8::Isolate* isolate = context->GetIsolate();

  MessageOptions options;

  gin::Dictionary options_dict(isolate, v8_options);
  if ((flags & PARSE_CHANNEL_NAME) != 0) {
    v8::Local<v8::Value> v8_channel_name;
    bool success = options_dict.Get("name", &v8_channel_name);
    DCHECK(success);

    if (!v8_channel_name->IsUndefined()) {
      DCHECK(v8_channel_name->IsString());
      options.channel_name = gin::V8ToString(isolate, v8_channel_name);
    }
  }

  if ((flags & PARSE_INCLUDE_TLS_CHANNEL_ID) != 0) {
    v8::Local<v8::Value> v8_include_tls_channel_id;
    bool success =
        options_dict.Get("includeTlsChannelId", &v8_include_tls_channel_id);
    DCHECK(success);

    if (!v8_include_tls_channel_id->IsUndefined()) {
      DCHECK(v8_include_tls_channel_id->IsBoolean());
      options.include_tls_channel_id =
          v8_include_tls_channel_id.As<v8::Boolean>()->Value();
    }
  }

  if ((flags & PARSE_FRAME_ID) != 0) {
    v8::Local<v8::Value> v8_frame_id;
    bool success = options_dict.Get("frameId", &v8_frame_id);
    DCHECK(success);

    if (!v8_frame_id->IsUndefined()) {
      DCHECK(v8_frame_id->IsInt32());
      int frame_id = v8_frame_id.As<v8::Int32>()->Value();
      // NOTE(devlin): JS bindings coerce any negative value to -1. For
      // backwards compatibility, we do the same here.
      options.frame_id = frame_id < 0 ? -1 : frame_id;
    }
  }

  return options;
}

bool GetTargetExtensionId(ScriptContext* script_context,
                          v8::Local<v8::Value> v8_target_id,
                          const char* method_name,
                          std::string* target_out,
                          std::string* error_out) {
  DCHECK(!v8_target_id.IsEmpty());
  // Argument parsing should guarantee this is null or a string before we reach
  // this point.
  DCHECK(v8_target_id->IsNull() || v8_target_id->IsString());

  std::string target_id;
  // If omitted, we use the extension associated with the context.
  // Note: we deliberately treat the empty string as omitting the id, even
  // though it's not strictly correct. See https://crbug.com/823577.
  if (v8_target_id->IsNull() ||
      (v8_target_id->IsString() &&
       v8_target_id.As<v8::String>()->Length() == 0)) {
    if (!script_context->extension()) {
      *error_out =
          base::StringPrintf(kExtensionIdRequiredErrorTemplate, method_name);
      return false;
    }

    target_id = script_context->extension()->id();
    // An extension should never have an invalid id.
    DCHECK(crx_file::id_util::IdIsValid(target_id));
  } else {
    DCHECK(v8_target_id->IsString());
    target_id = gin::V8ToString(script_context->isolate(), v8_target_id);
    // NOTE(devlin): JS bindings only validate that the extension id is present,
    // rather than validating its content. This seems better. Let's see how this
    // goes.
    if (!crx_file::id_util::IdIsValid(target_id)) {
      *error_out =
          base::StringPrintf("Invalid extension id: '%s'", target_id.c_str());
      return false;
    }
  }

  *target_out = std::move(target_id);
  return true;
}

void MassageSendMessageArguments(
    v8::Isolate* isolate,
    bool allow_options_argument,
    std::vector<v8::Local<v8::Value>>* arguments_out) {
  base::span<const v8::Local<v8::Value>> arguments = *arguments_out;
  size_t max_size = allow_options_argument ? 4u : 3u;
  if (arguments.empty() || arguments.size() > max_size)
    return;

  v8::Local<v8::Value> target_id = v8::Null(isolate);
  v8::Local<v8::Value> message = v8::Null(isolate);
  v8::Local<v8::Value> options;
  if (allow_options_argument)
    options = v8::Null(isolate);
  v8::Local<v8::Value> response_callback = v8::Null(isolate);

  // If the last argument is a function, it is the response callback.
  // Ignore it for the purposes of further argument parsing.
  if ((*arguments.rbegin())->IsFunction()) {
    response_callback = *arguments.rbegin();
    arguments = arguments.first(arguments.size() - 1);
  }

  // Re-check for too many arguments after looking for the callback. If there
  // are, early-out and rely on normal signature parsing to report the error.
  if (arguments.size() >= max_size)
    return;

  switch (arguments.size()) {
    case 0:
      // Required argument (message) is missing.
      // Early-out and rely on normal signature parsing to report this error.
      return;
    case 1:
      // Argument must be the message.
      message = arguments[0];
      break;
    case 2: {
      // Assume the first argument is the ID if we don't expect options, or if
      // the argument could match the ID parameter.
      // ID could be either a string, or null/undefined (since it's optional).
      bool could_match_id =
          arguments[0]->IsString() || arguments[0]->IsNullOrUndefined();
      if (!allow_options_argument || could_match_id) {
        target_id = arguments[0];
        message = arguments[1];
      } else {  // Otherwise, the meaning is (message, options).
        message = arguments[0];
        options = arguments[1];
      }
      break;
    }
    case 3:
      DCHECK(allow_options_argument);
      // The meaning in this case is unambiguous.
      target_id = arguments[0];
      message = arguments[1];
      options = arguments[2];
      break;
    default:
      NOTREACHED();
  }

  if (allow_options_argument)
    *arguments_out = {target_id, message, options, response_callback};
  else
    *arguments_out = {target_id, message, response_callback};
}

bool IsSendRequestDisabled(ScriptContext* script_context) {
  const Extension* extension = script_context->extension();
  return extension && Manifest::IsUnpackedLocation(extension->location()) &&
         BackgroundInfo::HasLazyBackgroundPage(extension);
}

}  // namespace messaging_util
}  // namespace extensions
