// 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 "media/gpu/buffer_validation.h"

#include <algorithm>
#include <cstdint>

#include "base/logging.h"
#include "base/numerics/checked_math.h"
#include "base/numerics/safe_conversions.h"
#include "build/build_config.h"
#include "media/base/video_frame.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/gpu_memory_buffer.h"

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#include <sys/types.h>
#include <unistd.h>
#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)

namespace media {

bool GetFileSize(const int fd, size_t* size) {
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
  if (fd < 0) {
    VLOG(1) << "Invalid file descriptor";
    return false;
  }

  off_t fd_size = lseek(fd, 0, SEEK_END);
  lseek(fd, 0, SEEK_SET);
  if (fd_size < 0u) {
    VPLOG(1) << "Fail to find the size of fd";
    return false;
  }

  if (!base::IsValueInRangeForNumericType<size_t>(fd_size)) {
    VLOG(1) << "fd_size is out of range of size_t"
            << ", size=" << size
            << ", size_t max=" << std::numeric_limits<size_t>::max()
            << ", size_t min=" << std::numeric_limits<size_t>::min();
    return false;
  }

  *size = static_cast<size_t>(fd_size);
  return true;
#else
  NOTIMPLEMENTED();
  return false;
#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
}

bool VerifyGpuMemoryBufferHandle(
    media::VideoPixelFormat pixel_format,
    const gfx::Size& coded_size,
    const gfx::GpuMemoryBufferHandle& gmb_handle,
    GetFileSizeCBForTesting file_size_cb_for_testing) {
  if (gmb_handle.type != gfx::NATIVE_PIXMAP) {
    VLOG(1) << "Unexpected GpuMemoryBufferType: " << gmb_handle.type;
    return false;
  }
  if (!media::VideoFrame::IsValidCodedSize(coded_size)) {
    VLOG(1) << "Coded size is beyond allowed dimensions: "
            << coded_size.ToString();
    return false;
  }
  // YV12 is used by ARC++ on MTK8173. Consider removing it.
  if (pixel_format != PIXEL_FORMAT_I420 && pixel_format != PIXEL_FORMAT_YV12 &&
      pixel_format != PIXEL_FORMAT_NV12 &&
      pixel_format != PIXEL_FORMAT_P016LE) {
    VLOG(1) << "Unsupported: " << pixel_format;
    return false;
  }
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
  const size_t num_planes = media::VideoFrame::NumPlanes(pixel_format);
  if (num_planes != gmb_handle.native_pixmap_handle.planes.size() ||
      num_planes == 0) {
    VLOG(1) << "Invalid number of dmabuf planes passed: "
            << gmb_handle.native_pixmap_handle.planes.size()
            << ", expected: " << num_planes;
    return false;
  }

  // Strides monotonically decrease.
  for (size_t i = 1; i < num_planes; i++) {
    if (gmb_handle.native_pixmap_handle.planes[i - 1].stride <
        gmb_handle.native_pixmap_handle.planes[i].stride) {
      return false;
    }
  }

  for (size_t i = 0; i < num_planes; i++) {
    const auto& plane = gmb_handle.native_pixmap_handle.planes[i];
    DVLOG(4) << "Plane " << i << ", offset: " << plane.offset
             << ", stride: " << plane.stride;

    size_t file_size_in_bytes;
    if (file_size_cb_for_testing) {
      file_size_in_bytes = file_size_cb_for_testing.Run();
    } else if (!plane.fd.is_valid() ||
               !GetFileSize(plane.fd.get(), &file_size_in_bytes)) {
      return false;
    }
    size_t plane_height =
        media::VideoFrame::Rows(i, pixel_format, coded_size.height());
    base::CheckedNumeric<size_t> min_plane_size =
        base::CheckMul(base::strict_cast<size_t>(plane.stride), plane_height);
    size_t plane_pixel_width =
        media::VideoFrame::RowBytes(i, pixel_format, coded_size.width());
    if (!min_plane_size.IsValid<uint64_t>() ||
        min_plane_size.ValueOrDie<uint64_t>() > plane.size ||
        base::strict_cast<size_t>(plane.stride) < plane_pixel_width) {
      VLOG(1) << "Invalid strides/sizes";
      return false;
    }

    // Check |offset| + (the size of a plane) on each plane is not larger than
    // |file_size_in_bytes|. This ensures we don't access out of a buffer
    // referred by |fd|.
    base::CheckedNumeric<uint64_t> min_buffer_size =
        base::CheckAdd(plane.offset, plane.size);
    if (!min_buffer_size.IsValid() ||
        min_buffer_size.ValueOrDie() >
            base::strict_cast<uint64_t>(file_size_in_bytes)) {
      VLOG(1) << "Invalid strides/offsets";
      return false;
    }
  }
  return true;
#else
  NOTIMPLEMENTED();
  return false;
#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
}

}  // namespace media
