// Copyright 2017 The Fuchsia 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 <lib/fidl/coding.h>
#include <lib/fidl/cpp/features.h>
#include <lib/fidl/internal.h>
#include <lib/fidl/visitor.h>
#include <lib/fidl/walker.h>
#include <lib/utf-utils/utf-utils.h>
#include <stdalign.h>
#include <zircon/assert.h>
#include <zircon/compiler.h>
#include <zircon/fidl.h>

#include <cstdint>
#include <cstdlib>
#include <cstring>

#if __FIDL_SUPPORT_HANDLES
#include <zircon/syscalls.h>
#endif

// TODO(kulakowski) Design zx_status_t error values.

namespace {

template <typename Byte>
struct DecodingPosition {
  Byte* addr;
  DecodingPosition operator+(uint32_t size) const { return DecodingPosition{addr + size}; }
  DecodingPosition& operator+=(uint32_t size) {
    addr += size;
    return *this;
  }
  template <typename T, typename U = std::conditional_t<std::is_const<Byte>::value, const T, T>>
  constexpr U* Get() const {
    return reinterpret_cast<U*>(addr);
  }
};

struct EnvelopeCheckpoint {
  uint32_t num_bytes;
  uint32_t num_handles;
};

constexpr zx_rights_t subtract_rights(zx_rights_t minuend, zx_rights_t subtrahend) {
  return minuend & ~subtrahend;
}
static_assert(subtract_rights(0b011, 0b101) == 0b010, "ensure rights subtraction works correctly");

enum class Mode { Decode, Validate };

template <Mode mode, typename T, typename U>
void AssignInDecode(T* ptr, U value) {
  static_assert(mode == Mode::Decode, "only assign if decode");
  *ptr = value;
}

template <Mode mode, typename T, typename U>
void AssignInDecode(const T* ptr, U value) {
  static_assert(mode == Mode::Validate, "don't assign if validate");
  // nothing in validate mode
}

template <Mode mode>
zx_status_t DecodeProcessHandle(fidl_handle_t* handle, zx_obj_type_t obj_type, zx_rights_t rights,
                                uint32_t metadata_index, const void* metadata_array,
                                const char** error) {
  static_assert(mode == Mode::Decode, "process handles during decode");
  fidl_channel_handle_metadata_t v =
      reinterpret_cast<const fidl_channel_handle_metadata_t*>(metadata_array)[metadata_index];
  return FidlEnsureHandleRights(handle, v.obj_type, v.rights, obj_type, rights, error);
}

template <Mode mode>
zx_status_t DecodeProcessHandle(const fidl_handle_t* handle, zx_obj_type_t obj_type,
                                zx_rights_t rights, uint32_t metadata_index,
                                const void* metadata_array, const char** error) {
  static_assert(mode == Mode::Validate, "never used during validate");
  __builtin_unreachable();
}

void ConvertEnvelopeToDecodedRepresentation(const void* bytes_base_ptr,
                                            fidl_envelope_t envelope_copy,
                                            const fidl_envelope_t* envelope_ptr) {
  // No conversion is needed for v2 validate.
}
void ConvertEnvelopeToDecodedRepresentation(const void* bytes_base_ptr,
                                            fidl_envelope_t envelope_copy,
                                            fidl_envelope_t* envelope_ptr) {
  if ((envelope_copy.flags & FIDL_ENVELOPE_FLAGS_INLINING_MASK) != 0) {
    fidl_envelope_v2_unknown_data_t unknown_data_envelope = {
        .num_handles = envelope_copy.num_handles,
        .flags = envelope_copy.flags,
    };
    memcpy(unknown_data_envelope.inline_value, envelope_ptr->inline_value,
           sizeof(envelope_ptr->inline_value));
    memcpy(envelope_ptr, &unknown_data_envelope, sizeof(unknown_data_envelope));
    return;
  }

  uintptr_t data_ptr = *reinterpret_cast<uintptr_t*>(envelope_ptr);
  uintptr_t base_ptr = reinterpret_cast<uintptr_t>(bytes_base_ptr);
  uintptr_t offset = data_ptr - base_ptr;
  ZX_ASSERT(offset <= std::numeric_limits<uint16_t>::max());
  ZX_ASSERT(envelope_copy.num_bytes <= std::numeric_limits<uint16_t>::max());
  fidl_envelope_v2_unknown_data_t unknown_data_envelope = {
      .out_of_line =
          {
              .num_bytes = static_cast<uint16_t>(envelope_copy.num_bytes),
              .offset = static_cast<uint16_t>(offset),
          },
      .num_handles = envelope_copy.num_handles,
      .flags = envelope_copy.flags,
  };
  memcpy(envelope_ptr, &unknown_data_envelope, sizeof(unknown_data_envelope));
}

template <FidlWireFormatVersion WireFormatVersion, typename Byte>
using BaseVisitor =
    fidl::Visitor<WireFormatVersion,
                  std::conditional_t<std::is_const<Byte>::value, fidl::NonMutatingVisitorTrait,
                                     fidl::MutatingVisitorTrait>,
                  DecodingPosition<Byte>, EnvelopeCheckpoint>;

template <Mode mode, FidlWireFormatVersion WireFormatVersion, typename Byte>
class FidlDecoder final : public BaseVisitor<WireFormatVersion, Byte> {
 public:
  FidlDecoder(Byte* bytes, uint32_t num_bytes, const fidl_handle_t* handles,
              const void* handle_metadata, uint32_t num_handles, uint32_t next_out_of_line,
              const char** out_error_msg, bool hlcpp_mode)
      : bytes_(bytes),
        num_bytes_(num_bytes),
        handles_(handles),
        handle_metadata_(handle_metadata),
        num_handles_(num_handles),
        next_out_of_line_(next_out_of_line),
        out_error_msg_(out_error_msg),
        hlcpp_mode_(hlcpp_mode) {}
  using Position = typename BaseVisitor<WireFormatVersion, Byte>::Position;
  using Status = typename BaseVisitor<WireFormatVersion, Byte>::Status;
  using PointeeType = typename BaseVisitor<WireFormatVersion, Byte>::PointeeType;
  using ObjectPointerPointer = typename BaseVisitor<WireFormatVersion, Byte>::ObjectPointerPointer;
  using HandlePointer = typename BaseVisitor<WireFormatVersion, Byte>::HandlePointer;
  using CountPointer = typename BaseVisitor<WireFormatVersion, Byte>::CountPointer;
  using EnvelopeType = typename BaseVisitor<WireFormatVersion, Byte>::EnvelopeType;
  using EnvelopePointer = typename BaseVisitor<WireFormatVersion, Byte>::EnvelopePointer;

  static constexpr bool kOnlyWalkResources = false;
  static constexpr bool kContinueAfterConstraintViolation = false;
  static constexpr bool kValidateEnvelopeInlineBit = true;

  Status VisitAbsentPointerInNonNullableCollection(ObjectPointerPointer object_ptr_ptr) {
    SetError("absent pointer disallowed in non-nullable collection");
    return Status::kConstraintViolationError;
  }

  Status VisitPointer(Position ptr_position, PointeeType pointee_type,
                      ObjectPointerPointer object_ptr_ptr, uint32_t inline_size,
                      Position* out_position) {
    if (unlikely(pointee_type != PointeeType::kEnvelope &&
                 reinterpret_cast<uintptr_t>(*object_ptr_ptr) != FIDL_ALLOC_PRESENT)) {
      SetError("invalid presence marker");
      return Status::kMemoryError;
    }
    uint32_t new_offset;
    if (unlikely(!FidlAddOutOfLine(next_out_of_line_, inline_size, &new_offset))) {
      SetError("overflow updating out-of-line offset");
      return Status::kMemoryError;
    }
    if (unlikely(new_offset > num_bytes_)) {
      SetError("message tried to access more than provided number of bytes");
      return Status::kMemoryError;
    }
    {
      if (inline_size % FIDL_ALIGNMENT != 0) {
        // Validate the last 8-byte block.
        const uint64_t* block_end = reinterpret_cast<const uint64_t*>(&bytes_[new_offset]) - 1;
        uint64_t padding_len = new_offset - next_out_of_line_ - inline_size;
        uint64_t padding_mask = ~0ull << (64 - 8 * padding_len);
        auto status = ValidatePadding(block_end, padding_mask);
        if (status != Status::kSuccess) {
          return status;
        }
      }
    }
    if (unlikely(pointee_type == PointeeType::kString)) {
      bool valid = utfutils_is_valid_utf8(reinterpret_cast<const char*>(&bytes_[next_out_of_line_]),
                                          inline_size);
      if (!valid) {
        SetError("encountered invalid UTF8 string");
        return Status::kConstraintViolationError;
      }
    }
    *out_position = Position{bytes_ + next_out_of_line_};
    AssignInDecode<mode>(
        object_ptr_ptr,
        reinterpret_cast<std::remove_pointer_t<ObjectPointerPointer>>(&bytes_[next_out_of_line_]));

    next_out_of_line_ = new_offset;
    return Status::kSuccess;
  }

  Status VisitHandle(Position handle_position, HandlePointer handle,
                     zx_rights_t required_handle_rights, zx_obj_type_t required_handle_subtype) {
    if (unlikely(*handle != FIDL_HANDLE_PRESENT)) {
      SetError("message tried to decode a garbage handle");
      return Status::kConstraintViolationError;
    }
    if (unlikely(handle_idx_ == num_handles_)) {
      SetError("message decoded too many handles");
      return Status::kConstraintViolationError;
    }

    if (mode == Mode::Validate) {
      handle_idx_++;
      return Status::kSuccess;
    }

    if (unlikely(handles_[handle_idx_] == ZX_HANDLE_INVALID)) {
      SetError("invalid handle detected in handle table");
      return Status::kConstraintViolationError;
    }
    if (mode == Mode::Decode) {
      AssignInDecode<mode>(handle, handles_[handle_idx_]);

      const char* error;
      zx_status_t status =
          DecodeProcessHandle<mode>(handle, required_handle_subtype, required_handle_rights,
                                    handle_idx_, handle_metadata_, &error);
      if (status != ZX_OK) {
        SetError(error);
        return Status::kConstraintViolationError;
      }
    }
    handle_idx_++;
    return Status::kSuccess;
  }

  Status VisitVectorOrStringCount(CountPointer ptr) { return Status::kSuccess; }

  template <typename MaskType>
  Status VisitInternalPadding(Position padding_position, MaskType mask) {
    return ValidatePadding(padding_position.template Get<const MaskType>(), mask);
  }

  EnvelopeCheckpoint EnterEnvelope() {
    return {
        .num_bytes = next_out_of_line_,
        .num_handles = handle_idx_,
    };
  }

  Status LeaveEnvelope(EnvelopeType in_envelope, EnvelopePointer out_envelope,
                       EnvelopeCheckpoint prev_checkpoint) {
    // Now that the envelope has been consumed, check the correctness of the envelope header.
    uint32_t num_bytes = next_out_of_line_ - prev_checkpoint.num_bytes;
    uint32_t num_handles = handle_idx_ - prev_checkpoint.num_handles;
    if (unlikely(in_envelope.num_bytes != num_bytes)) {
      SetError("Envelope num_bytes was mis-sized");
      return Status::kConstraintViolationError;
    }
    if (unlikely(in_envelope.num_handles != num_handles)) {
      SetError("Envelope num_handles was mis-sized");
      return Status::kConstraintViolationError;
    }
    return Status::kSuccess;
  }

  Status LeaveInlinedEnvelope(EnvelopeType in_envelope, EnvelopePointer out_envelope,
                              EnvelopeCheckpoint prev_checkpoint) {
    // Now that the envelope has been consumed, check the correctness of the envelope header.
    uint32_t num_handles = handle_idx_ - prev_checkpoint.num_handles;
    if (unlikely(in_envelope.num_handles != num_handles)) {
      SetError("Envelope num_handles was mis-sized");
      return Status::kConstraintViolationError;
    }
    return Status::kSuccess;
  }

  Status VisitUnknownEnvelope(EnvelopeType envelope_copy, EnvelopePointer envelope_ptr,
                              FidlIsResource is_resource) {
    if (mode == Mode::Validate) {
      handle_idx_ += envelope_copy.num_handles;
      return Status::kSuccess;
    }

    if (hlcpp_mode_) {
      ConvertEnvelopeToDecodedRepresentation(bytes_, envelope_copy, envelope_ptr);
    }

    // If we do not have the coding table for this payload,
    // treat it as unknown and close its contained handles
    if (unlikely(envelope_copy.num_handles > 0)) {
      uint32_t total_unknown_handles;
      if (add_overflow(unknown_handle_idx_, envelope_copy.num_handles, &total_unknown_handles)) {
        SetError("number of unknown handles overflows");
        return Status::kConstraintViolationError;
      }
      if (total_unknown_handles > ZX_CHANNEL_MAX_MSG_HANDLES) {
        SetError("number of unknown handles exceeds unknown handle array size");
        return Status::kConstraintViolationError;
      }
      uint32_t end_incoming_handle;
      if (add_overflow(handle_idx_, envelope_copy.num_handles, &end_incoming_handle)) {
        SetError("number of incoming handles overflows");
        return Status::kConstraintViolationError;
      }
      if (end_incoming_handle > num_handles_) {
        SetError("number of incoming handles exceeds incoming handle array size");
        return Status::kConstraintViolationError;
      }
      // If hlcpp_mode_ is true, leave the unknown handles intact
      // for something else to process (e.g. HLCPP Decode)
      if (hlcpp_mode_ && is_resource == kFidlIsResource_Resource) {
        handle_idx_ += envelope_copy.num_handles;
        return Status::kSuccess;
      }
      memcpy(&unknown_handles_[unknown_handle_idx_], &handles_[handle_idx_],
             envelope_copy.num_handles * sizeof(fidl_handle_t));
      handle_idx_ = end_incoming_handle;
      unknown_handle_idx_ = total_unknown_handles;
    }
    return Status::kSuccess;
  }

  void OnError(const char* error) { SetError(error); }

  zx_status_t status() const { return status_; }

  bool DidConsumeAllBytes() const { return next_out_of_line_ == num_bytes_; }

  bool DidConsumeAllHandles() const { return handle_idx_ == num_handles_; }

  uint32_t unknown_handle_idx() const { return unknown_handle_idx_; }

  const fidl_handle_t* unknown_handles() const { return unknown_handles_; }

 private:
  void SetError(const char* error) {
    if (status_ != ZX_OK) {
      return;
    }
    status_ = ZX_ERR_INVALID_ARGS;
    if (!out_error_msg_) {
      return;
    }
    *out_error_msg_ = error;
  }

  template <typename MaskType>
  Status ValidatePadding(const MaskType* padding_ptr, MaskType mask) {
    if ((*padding_ptr & mask) != 0) {
      SetError("non-zero padding bytes detected");
      return Status::kConstraintViolationError;
    }
    return Status::kSuccess;
  }

  // Message state passed in to the constructor.
  Byte* const bytes_;
  const uint32_t num_bytes_;
  const fidl_handle_t* handles_;
  const void* handle_metadata_;
  const uint32_t num_handles_;
  uint32_t next_out_of_line_;
  const char** const out_error_msg_;
  // HLCPP first uses FidlDecoder to do an in-place decode, then extracts data
  // out into domain objects. Since HLCPP stores unknown handles
  // (and LLCPP does not), this field allows HLCPP to use the decoder while
  // keeping unknown handles in flexible resource unions intact.
  bool hlcpp_mode_;

  // Decoder state
  zx_status_t status_ = ZX_OK;
  uint32_t handle_idx_ = 0;
  uint32_t unknown_handle_idx_ = 0;
  fidl_handle_t unknown_handles_[ZX_CHANNEL_MAX_MSG_HANDLES];
};

}  // namespace

namespace {
template <FidlWireFormatVersion WireFormatVersion>
zx_status_t fidl_decode_impl(const fidl_type_t* type, void* bytes, uint32_t num_bytes,
                             const fidl_handle_t* handles, const void* handle_metadata,
                             uint32_t num_handles, const char** out_error_msg, bool hlcpp_mode) {
  auto drop_all_handles = [&]() { FidlHandleCloseMany(handles, num_handles); };
  auto set_error = [&out_error_msg](const char* msg) {
    if (out_error_msg)
      *out_error_msg = msg;
  };
  if (unlikely(type == nullptr)) {
    set_error("fidl type cannot be null");
    return ZX_ERR_INVALID_ARGS;
  }
  if (unlikely(handles == nullptr && num_handles != 0)) {
    set_error("Cannot provide non-zero handle count and null handle pointer");
    return ZX_ERR_INVALID_ARGS;
  }
  if (unlikely(bytes == nullptr)) {
    set_error("Cannot decode null bytes");
    drop_all_handles();
    return ZX_ERR_INVALID_ARGS;
  }
  if (unlikely(!FidlIsAligned(reinterpret_cast<uint8_t*>(bytes)))) {
    set_error("Bytes must be aligned to FIDL_ALIGNMENT");
    drop_all_handles();
    return ZX_ERR_INVALID_ARGS;
  }

  zx_status_t status;
  uint32_t primary_size;
  uint32_t next_out_of_line;
  if (unlikely((status = fidl::PrimaryObjectSize<WireFormatVersion>(
                    type, num_bytes, &primary_size, &next_out_of_line, out_error_msg)) != ZX_OK)) {
    drop_all_handles();
    return status;
  }

  uint8_t* b = reinterpret_cast<uint8_t*>(bytes);
  for (uint32_t i = primary_size; i < next_out_of_line; i++) {
    if (b[i] != 0) {
      set_error("non-zero padding bytes detected");
      drop_all_handles();
      return ZX_ERR_INVALID_ARGS;
    }
  }

  FidlDecoder<Mode::Decode, WireFormatVersion, uint8_t> decoder(
      b, num_bytes, handles, handle_metadata, num_handles, next_out_of_line, out_error_msg,
      hlcpp_mode);
  fidl::Walk<WireFormatVersion>(decoder, type, DecodingPosition<uint8_t>{b});

  if (unlikely(decoder.status() != ZX_OK)) {
    drop_all_handles();
    return decoder.status();
  }
  if (unlikely(!decoder.DidConsumeAllBytes())) {
    set_error("message did not decode all provided bytes");
    drop_all_handles();
    return ZX_ERR_INVALID_ARGS;
  }
  if (unlikely(!decoder.DidConsumeAllHandles())) {
    set_error("message did not decode all provided handles");
    drop_all_handles();
    return ZX_ERR_INVALID_ARGS;
  }

  (void)FidlHandleCloseMany(decoder.unknown_handles(), decoder.unknown_handle_idx());
  return ZX_OK;
}

template <FidlWireFormatVersion WireFormatVersion>
zx_status_t fidl_decode_impl_handle_info(const fidl_type_t* type, void* bytes, uint32_t num_bytes,
                                         const zx_handle_info_t* handle_infos, uint32_t num_handles,
                                         const char** out_error_msg, bool hlcpp_mode) {
  if (!handle_infos) {
    return fidl_decode_impl<WireFormatVersion>(type, bytes, num_bytes, nullptr, nullptr,
                                               num_handles, out_error_msg, hlcpp_mode);
  }
  fidl_handle_t handles[ZX_CHANNEL_MAX_MSG_HANDLES];
  fidl_channel_handle_metadata_t handle_metadata[ZX_CHANNEL_MAX_MSG_HANDLES];
  for (uint32_t i = 0; i < num_handles; i++) {
    handles[i] = handle_infos[i].handle;
    handle_metadata[i] = {
        .obj_type = handle_infos[i].type,
        .rights = handle_infos[i].rights,
    };
  }
  return fidl_decode_impl<WireFormatVersion>(type, bytes, num_bytes, handles, handle_metadata,
                                             num_handles, out_error_msg, hlcpp_mode);
}
}  // namespace

zx_status_t internal__fidl_decode_etc_hlcpp__v2__may_break(const fidl_type_t* type, void* bytes,
                                                           uint32_t num_bytes,
                                                           const zx_handle_info_t* handle_infos,
                                                           uint32_t num_handle_infos,
                                                           const char** error_msg_out) {
  return fidl_decode_impl_handle_info<FIDL_WIRE_FORMAT_VERSION_V2>(
      type, bytes, num_bytes, handle_infos, num_handle_infos, error_msg_out, true);
}

template <FidlWireFormatVersion WireFormatVersion>
zx_status_t fidl_validate_impl(const fidl_type_t* type, const void* bytes, uint32_t num_bytes,
                               uint32_t num_handles, const char** out_error_msg) {
  auto set_error = [&out_error_msg](const char* msg) {
    if (out_error_msg)
      *out_error_msg = msg;
  };
  if (unlikely(type == nullptr)) {
    set_error("fidl type cannot be null");
    return ZX_ERR_INVALID_ARGS;
  }
  if (bytes == nullptr) {
    set_error("Cannot validate null bytes");
    return ZX_ERR_INVALID_ARGS;
  }
  if (unlikely(!FidlIsAligned(reinterpret_cast<const uint8_t*>(bytes)))) {
    set_error("Bytes must be aligned to FIDL_ALIGNMENT");
    return ZX_ERR_INVALID_ARGS;
  }

  zx_status_t status;
  uint32_t primary_size;
  uint32_t next_out_of_line;
  if (unlikely((status = fidl::PrimaryObjectSize<WireFormatVersion>(
                    type, num_bytes, &primary_size, &next_out_of_line, out_error_msg)) != ZX_OK)) {
    return status;
  }

  const uint8_t* b = reinterpret_cast<const uint8_t*>(bytes);
  for (uint32_t i = primary_size; i < next_out_of_line; i++) {
    if (b[i] != 0) {
      set_error("non-zero padding bytes detected");
      return ZX_ERR_INVALID_ARGS;
    }
  }

  FidlDecoder<Mode::Validate, WireFormatVersion, const uint8_t> validator(
      b, num_bytes, nullptr, nullptr, num_handles, next_out_of_line, out_error_msg, false);
  fidl::Walk<WireFormatVersion>(validator, type, DecodingPosition<const uint8_t>{b});

  if (validator.status() == ZX_OK) {
    if (!validator.DidConsumeAllBytes()) {
      set_error("message did not consume all provided bytes");
      return ZX_ERR_INVALID_ARGS;
    }
    if (!validator.DidConsumeAllHandles()) {
      set_error("message did not reference all provided handles");
      return ZX_ERR_INVALID_ARGS;
    }
  }

  return validator.status();
}

zx_status_t internal__fidl_validate__v2__may_break(const fidl_type_t* type, const void* bytes,
                                                   uint32_t num_bytes, uint32_t num_handles,
                                                   const char** out_error_msg) {
  return fidl_validate_impl<FIDL_WIRE_FORMAT_VERSION_V2>(type, bytes, num_bytes, num_handles,
                                                         out_error_msg);
}
