// Copyright 2015 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 "mojo/public/cpp/bindings/lib/validation_util.h"

#include <stdint.h>

#include <limits>

#include "base/strings/stringprintf.h"
#include "mojo/public/cpp/bindings/lib/message_internal.h"
#include "mojo/public/cpp/bindings/lib/serialization_util.h"
#include "mojo/public/cpp/bindings/lib/validation_errors.h"

namespace mojo {
namespace internal {

void ReportNonNullableValidationError(ValidationContext* validation_context,
                                      ValidationError error,
                                      int field_index) {
  const char* null_or_invalid =
      error == VALIDATION_ERROR_UNEXPECTED_NULL_POINTER ? "null" : "invalid";

  std::string error_message =
      base::StringPrintf("%s field %d", null_or_invalid, field_index);
  ReportValidationError(validation_context, error, error_message.c_str());
}

bool ValidateStructHeaderAndClaimMemory(const void* data,
                                        ValidationContext* validation_context) {
  if (!IsAligned(data)) {
    ReportValidationError(validation_context,
                          VALIDATION_ERROR_MISALIGNED_OBJECT);
    return false;
  }
  if (!validation_context->IsValidRange(data, sizeof(StructHeader))) {
    ReportValidationError(validation_context,
                          VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE);
    return false;
  }

  const StructHeader* header = static_cast<const StructHeader*>(data);

  if (header->num_bytes < sizeof(StructHeader)) {
    ReportValidationError(validation_context,
                          VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER);
    return false;
  }

  if (!validation_context->ClaimMemory(data, header->num_bytes)) {
    ReportValidationError(validation_context,
                          VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE);
    return false;
  }

  return true;
}

bool ValidateNonInlinedUnionHeaderAndClaimMemory(
    const void* data,
    ValidationContext* validation_context) {
  if (!IsAligned(data)) {
    ReportValidationError(validation_context,
                          VALIDATION_ERROR_MISALIGNED_OBJECT);
    return false;
  }

  if (!validation_context->ClaimMemory(data, kUnionDataSize) ||
      *static_cast<const uint32_t*>(data) != kUnionDataSize) {
    ReportValidationError(validation_context,
                          VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE);
    return false;
  }

  return true;
}

bool ValidateMessageIsRequestWithoutResponse(
    const Message* message,
    ValidationContext* validation_context) {
  if (message->has_flag(Message::kFlagIsResponse) ||
      message->has_flag(Message::kFlagExpectsResponse)) {
    ReportValidationError(validation_context,
                          VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS);
    return false;
  }
  return true;
}

bool ValidateMessageIsRequestExpectingResponse(
    const Message* message,
    ValidationContext* validation_context) {
  if (message->has_flag(Message::kFlagIsResponse) ||
      !message->has_flag(Message::kFlagExpectsResponse)) {
    ReportValidationError(validation_context,
                          VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS);
    return false;
  }
  return true;
}

bool ValidateMessageIsResponse(const Message* message,
                               ValidationContext* validation_context) {
  if (message->has_flag(Message::kFlagExpectsResponse) ||
      !message->has_flag(Message::kFlagIsResponse)) {
    ReportValidationError(validation_context,
                          VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS);
    return false;
  }
  return true;
}

bool IsHandleOrInterfaceValid(const AssociatedInterface_Data& input) {
  return input.handle.is_valid();
}

bool IsHandleOrInterfaceValid(const AssociatedEndpointHandle_Data& input) {
  return input.is_valid();
}

bool IsHandleOrInterfaceValid(const Interface_Data& input) {
  return input.handle.is_valid();
}

bool IsHandleOrInterfaceValid(const Handle_Data& input) {
  return input.is_valid();
}

bool ValidateHandleOrInterfaceNonNullable(
    const AssociatedInterface_Data& input,
    int field_index,
    ValidationContext* validation_context) {
  if (IsHandleOrInterfaceValid(input))
    return true;

  ReportNonNullableValidationError(
      validation_context, VALIDATION_ERROR_UNEXPECTED_INVALID_INTERFACE_ID,
      field_index);
  return false;
}

bool ValidateHandleOrInterfaceNonNullable(
    const AssociatedEndpointHandle_Data& input,
    int field_index,
    ValidationContext* validation_context) {
  if (IsHandleOrInterfaceValid(input))
    return true;

  ReportNonNullableValidationError(
      validation_context, VALIDATION_ERROR_UNEXPECTED_INVALID_INTERFACE_ID,
      field_index);
  return false;
}

bool ValidateHandleOrInterfaceNonNullable(
    const Interface_Data& input,
    int field_index,
    ValidationContext* validation_context) {
  if (IsHandleOrInterfaceValid(input))
    return true;

  ReportNonNullableValidationError(validation_context,
                                   VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
                                   field_index);
  return false;
}

bool ValidateHandleOrInterfaceNonNullable(
    const Handle_Data& input,
    int field_index,
    ValidationContext* validation_context) {
  if (IsHandleOrInterfaceValid(input))
    return true;

  ReportNonNullableValidationError(validation_context,
                                   VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
                                   field_index);
  return false;
}

bool ValidateHandleOrInterface(const AssociatedInterface_Data& input,
                               ValidationContext* validation_context) {
  if (validation_context->ClaimAssociatedEndpointHandle(input.handle))
    return true;

  ReportValidationError(validation_context,
                        VALIDATION_ERROR_ILLEGAL_INTERFACE_ID);
  return false;
}

bool ValidateHandleOrInterface(const AssociatedEndpointHandle_Data& input,
                               ValidationContext* validation_context) {
  if (validation_context->ClaimAssociatedEndpointHandle(input))
    return true;

  ReportValidationError(validation_context,
                        VALIDATION_ERROR_ILLEGAL_INTERFACE_ID);
  return false;
}

bool ValidateHandleOrInterface(const Interface_Data& input,
                               ValidationContext* validation_context) {
  if (validation_context->ClaimHandle(input.handle))
    return true;

  ReportValidationError(validation_context, VALIDATION_ERROR_ILLEGAL_HANDLE);
  return false;
}

bool ValidateHandleOrInterface(const Handle_Data& input,
                               ValidationContext* validation_context) {
  if (validation_context->ClaimHandle(input))
    return true;

  ReportValidationError(validation_context, VALIDATION_ERROR_ILLEGAL_HANDLE);
  return false;
}

}  // namespace internal
}  // namespace mojo
