// Copyright 2019 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 <stddef.h>
#include <stdint.h>
#include <string.h>
#include <va/va.h>

#include <algorithm>

#include "base/callback_helpers.h"
#include "base/cxx17_backports.h"
#include "base/logging.h"
#include "base/no_destructor.h"
#include "base/numerics/safe_conversions.h"
#include "media/gpu/vaapi/fuzzers/jpeg_decoder/jpeg_decoder_fuzzer_input.pb.h"
#include "media/gpu/vaapi/vaapi_jpeg_decoder.h"
#include "media/gpu/vaapi/vaapi_utils.h"
#include "media/gpu/vaapi/vaapi_wrapper.h"
#include "media/parsers/jpeg_parser.h"
#include "testing/libfuzzer/proto/lpm_interface.h"
#include "ui/gfx/geometry/size.h"

// This file defines a fuzzer test for the JPEG decoding functionality of the
// VA-API. To do the fuzzing, we re-use code from media::VaapiJpegDecoder: we
// poke at its internals to get past the parsing and image support validation.
// That way, we can inject a large variety of data into the VA-API driver and
// exercise more paths than if we just pass raw data to the
// media::VaapiJpegDecoder using its public API.
//
// The VA-API does not take raw JPEG data. Instead, it expects that some
// pre-parsing was done. Therefore, we feed the data as a
// media::JpegParseResult. To generate the fuzzing inputs, we use
// libprotobuf-mutator, so we define a protobuf that mirrors the structure of
// media::JpegParseResult.
//
// This fuzzer should be run on a real device that supports the VA-API.
// Additionally, libva and the backend user-space VA-API driver (plus its
// dependencies) should be instrumented for fuzzing.

namespace {

// Converts |proto_huffman_table| to a media::JpegHuffmanTable which can be used
// to populate the Huffman table fields of a media::JpegParseResult.
media::JpegHuffmanTable ConvertToJpegHuffmanTable(
    const media::fuzzing::JpegHuffmanTable& proto_huffman_table) {
  media::JpegHuffmanTable huffman_table{};
  huffman_table.valid = proto_huffman_table.valid();
  memcpy(huffman_table.code_length, proto_huffman_table.code_length().data(),
         std::min(base::size(huffman_table.code_length),
                  proto_huffman_table.code_length().size()));
  memcpy(huffman_table.code_value, proto_huffman_table.code_value().data(),
         std::min(base::size(huffman_table.code_value),
                  proto_huffman_table.code_value().size()));
  return huffman_table;
}

// Converts |proto_parse_result| to a media::JpegParseResult that can be used as
// the input for VaapiJpegDecoder::SubmitBuffers(). The data field of the return
// value will point to the same memory as |proto_parse_result|.data().data(), so
// we assume |proto_parse_result| will live for as long as that data needs to be
// used.
media::JpegParseResult ConvertToJpegParseResult(
    const media::fuzzing::JpegParseResult& proto_parse_result) {
  media::JpegParseResult parse_result{};

  // Convert the frame header.
  parse_result.frame_header.visible_width =
      proto_parse_result.frame_header().visible_width() & 0xFFFF;
  parse_result.frame_header.visible_height =
      proto_parse_result.frame_header().visible_height() & 0xFFFF;
  parse_result.frame_header.coded_width =
      proto_parse_result.frame_header().coded_width() & 0xFFFF;
  parse_result.frame_header.coded_height =
      proto_parse_result.frame_header().coded_height() & 0xFFFF;

  const size_t frame_header_num_components =
      std::min(base::size(parse_result.frame_header.components),
               base::checked_cast<size_t>(
                   proto_parse_result.frame_header().components_size()));
  for (size_t i = 0; i < frame_header_num_components; i++) {
    const auto& input_jpeg_component =
        proto_parse_result.frame_header().components()[i];
    parse_result.frame_header.components[i].id =
        input_jpeg_component.id() & 0xFF;
    parse_result.frame_header.components[i].horizontal_sampling_factor =
        input_jpeg_component.horizontal_sampling_factor() & 0xFF;
    parse_result.frame_header.components[i].vertical_sampling_factor =
        input_jpeg_component.vertical_sampling_factor() & 0xFF;
    parse_result.frame_header.components[i].quantization_table_selector =
        input_jpeg_component.quantization_table_selector() & 0xFF;
  }
  parse_result.frame_header.num_components =
      static_cast<uint8_t>(frame_header_num_components);

  // Convert the DC/AC Huffman tables.
  const size_t num_dc_tables =
      std::min(base::size(parse_result.dc_table),
               base::checked_cast<size_t>(proto_parse_result.dc_table_size()));
  for (size_t i = 0; i < num_dc_tables; i++) {
    parse_result.dc_table[i] =
        ConvertToJpegHuffmanTable(proto_parse_result.dc_table()[i]);
  }
  const size_t num_ac_tables =
      std::min(base::size(parse_result.ac_table),
               base::checked_cast<size_t>(proto_parse_result.ac_table_size()));
  for (size_t i = 0; i < num_ac_tables; i++) {
    parse_result.ac_table[i] =
        ConvertToJpegHuffmanTable(proto_parse_result.ac_table()[i]);
  }

  // Convert the quantization tables.
  const size_t num_q_tables =
      std::min(base::size(parse_result.q_table),
               base::checked_cast<size_t>(proto_parse_result.q_table_size()));
  for (size_t i = 0; i < num_q_tables; i++) {
    const media::fuzzing::JpegQuantizationTable& input_q_table =
        proto_parse_result.q_table()[i];
    parse_result.q_table[i].valid = input_q_table.valid();
    memcpy(parse_result.q_table[i].value, input_q_table.value().data(),
           std::min(base::size(parse_result.q_table[i].value),
                    input_q_table.value().size()));
  }

  // Convert the scan header.
  const size_t scan_num_components = std::min(
      base::size(parse_result.scan.components),
      base::checked_cast<size_t>(proto_parse_result.scan().components_size()));
  for (size_t i = 0; i < scan_num_components; i++) {
    const media::fuzzing::JpegScanHeader::Component& input_component =
        proto_parse_result.scan().components()[i];
    parse_result.scan.components[i].component_selector =
        input_component.component_selector() & 0xFF;
    parse_result.scan.components[i].dc_selector =
        input_component.dc_selector() & 0xFF;
    parse_result.scan.components[i].ac_selector =
        input_component.ac_selector() & 0xFF;
  }
  parse_result.scan.num_components = static_cast<uint8_t>(scan_num_components);

  // Convert the coded data. Note that we don't do a deep copy, so we assume
  // that |proto_parse_result| will live for as long as |parse_result|.data is
  // needed.
  parse_result.data = proto_parse_result.data().data();
  parse_result.data_size = proto_parse_result.data().size();

  // Convert the rest of the fields.
  parse_result.restart_interval =
      proto_parse_result.restart_interval() & 0xFFFF;
  parse_result.image_size =
      base::strict_cast<size_t>(proto_parse_result.image_size());

  return parse_result;
}

unsigned int ConvertToVARTFormat(
    media::fuzzing::VARTFormat proto_picture_va_rt_format) {
  switch (proto_picture_va_rt_format) {
    case media::fuzzing::VARTFormat::INVALID:
      return media::kInvalidVaRtFormat;
    case media::fuzzing::VARTFormat::YUV420:
      return VA_RT_FORMAT_YUV420;
    case media::fuzzing::VARTFormat::YUV422:
      return VA_RT_FORMAT_YUV422;
    case media::fuzzing::VARTFormat::YUV444:
      return VA_RT_FORMAT_YUV444;
    case media::fuzzing::VARTFormat::YUV411:
      return VA_RT_FORMAT_YUV411;
    case media::fuzzing::VARTFormat::YUV400:
      return VA_RT_FORMAT_YUV400;
    case media::fuzzing::VARTFormat::YUV420_10:
      return VA_RT_FORMAT_YUV420_10;
    case media::fuzzing::VARTFormat::YUV422_10:
      return VA_RT_FORMAT_YUV422_10;
    case media::fuzzing::VARTFormat::YUV444_10:
      return VA_RT_FORMAT_YUV444_10;
    case media::fuzzing::VARTFormat::YUV420_12:
      return VA_RT_FORMAT_YUV420_12;
    case media::fuzzing::VARTFormat::YUV422_12:
      return VA_RT_FORMAT_YUV422_12;
    case media::fuzzing::VARTFormat::YUV444_12:
      return VA_RT_FORMAT_YUV444_12;
    case media::fuzzing::VARTFormat::RGB16:
      return VA_RT_FORMAT_RGB16;
    case media::fuzzing::VARTFormat::RGB32:
      return VA_RT_FORMAT_RGB32;
    case media::fuzzing::VARTFormat::RGBP:
      return VA_RT_FORMAT_RGBP;
    case media::fuzzing::VARTFormat::RGB32_10:
      return VA_RT_FORMAT_RGB32_10;
    case media::fuzzing::VARTFormat::PROTECTED:
      return VA_RT_FORMAT_PROTECTED;
  }
}

}  // namespace

namespace media {
namespace fuzzing {

// This wrapper lets us poke at the internals of a media::VaapiJpegDecoder. It
// somewhat mirrors the way media::VaapiImageDecoder drives a VaapiJpegDecoder.
class VaapiJpegDecoderWrapper {
 public:
  VaapiJpegDecoderWrapper() = default;
  ~VaapiJpegDecoderWrapper() = default;

  bool Initialize() { return decoder_.Initialize(base::DoNothing()); }

  bool MaybeCreateSurface(unsigned int picture_va_rt_format,
                          const gfx::Size& new_coded_size,
                          const gfx::Size& new_visible_size) {
    if (!decoder_.MaybeCreateSurface(picture_va_rt_format, new_coded_size,
                                     new_visible_size)) {
      decoder_.scoped_va_context_and_surface_.reset();
      return false;
    }
    return true;
  }

  bool SubmitBuffers(const media::JpegParseResult& parse_result) {
    if (!decoder_.SubmitBuffers(parse_result)) {
      decoder_.scoped_va_context_and_surface_.reset();
      return false;
    }
    return true;
  }

  bool ExecuteAndDestroyPendingBuffers() {
    if (!decoder_.vaapi_wrapper_->ExecuteAndDestroyPendingBuffers(
            decoder_.scoped_va_context_and_surface_->id())) {
      decoder_.scoped_va_context_and_surface_.reset();
      return false;
    }
    return true;
  }

 private:
  VaapiJpegDecoder decoder_;
};

struct Environment {
  Environment() { VaapiWrapper::PreSandboxInitialization(); }
};

DEFINE_PROTO_FUZZER(const JpegImageList& image_list) {
  static const Environment env;
  VaapiJpegDecoderWrapper decoder_wrapper;
  if (!decoder_wrapper.Initialize()) {
    LOG(ERROR) << "Cannot initialize the VaapiJpegDecoder";
    abort();
  }
  for (const auto& jpeg_image : image_list.images()) {
    if (!decoder_wrapper.MaybeCreateSurface(
            ConvertToVARTFormat(jpeg_image.picture_va_rt_format()),
            gfx::Size(
                base::strict_cast<int>(jpeg_image.surface_coded_width()),
                base::strict_cast<int>(jpeg_image.surface_coded_height())),
            gfx::Size(
                base::strict_cast<int>(jpeg_image.surface_visible_width()),
                base::strict_cast<int>(jpeg_image.surface_visible_height())))) {
      continue;
    }
    if (!decoder_wrapper.SubmitBuffers(
            ConvertToJpegParseResult(jpeg_image.parse_result()))) {
      continue;
    }
    if (!decoder_wrapper.ExecuteAndDestroyPendingBuffers())
      continue;
    // TODO(crbug.com/1034357): for decodes that succeeded, it would be good to
    // get the result as a dma-buf, map it, and read it to make sure that doing
    // so does not lead us into an invalid state.
  }
}

}  // namespace fuzzing
}  // namespace media
