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

#include "ui/base/x/x11_cursor_loader.h"

#include <dlfcn.h>

#include <limits>
#include <string>
#include <string_view>
#include <utility>

#include "base/compiler_specific.h"
#include "base/containers/fixed_flat_map.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/containers/span.h"
#include "base/environment.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/memory/ref_counted_memory.h"
#include "base/memory/scoped_refptr.h"
#include "base/no_destructor.h"
#include "base/numerics/byte_conversions.h"
#include "base/numerics/checked_math.h"
#include "base/sequence_checker.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/time/time.h"
#include "ui/base/x/x11_util.h"
#include "ui/gfx/x/atom_cache.h"
#include "ui/gfx/x/connection.h"
#include "ui/gfx/x/xproto.h"

#if BUILDFLAG(IS_LINUX)
#include "ui/linux/linux_ui.h"
#endif

extern "C" {
const char* XcursorLibraryPath(void);
}

namespace ui {

namespace {

using ThemeAndCursorName = std::pair<std::string, std::string>;

// Track the addition of an object to a set, removing it automatically when
// the ScopedSetInsertion goes out of scope.
class ScopedSetInsertion {
 public:
  ScopedSetInsertion(base::flat_set<ThemeAndCursorName>* org_set,
                     const ThemeAndCursorName& elem)
      : set_(org_set), elem_(elem) {
    set_->insert(elem);
  }
  ScopedSetInsertion(const ScopedSetInsertion&) = delete;
  ScopedSetInsertion& operator=(const ScopedSetInsertion&) = delete;
  ~ScopedSetInsertion() { set_->erase(elem_); }

 private:
  const raw_ptr<base::flat_set<ThemeAndCursorName>> set_;
  const ThemeAndCursorName elem_;
};

std::string GetEnv(const std::string& var) {
  return base::Environment::Create()->GetVar(var).value_or(std::string());
}

NO_SANITIZE("cfi-icall")
std::string CursorPathFromLibXcursor() {
  struct DlCloser {
    void operator()(void* ptr) const { dlclose(ptr); }
  };

  std::unique_ptr<void, DlCloser> lib(dlopen("libXcursor.so.1", RTLD_LAZY));
  if (!lib)
    return "";

  if (auto* sym = reinterpret_cast<decltype(&XcursorLibraryPath)>(
          dlsym(lib.get(), "XcursorLibraryPath"))) {
    if (const char* path = sym())
      return path;
  }
  return "";
}

std::string CursorPathImpl() {
  constexpr const char kDefaultPath[] =
      "~/.local/share/icons:~/.icons:/usr/share/icons:/usr/share/pixmaps:"
      "/usr/X11R6/lib/X11/icons";

  auto libxcursor_path = CursorPathFromLibXcursor();
  if (!libxcursor_path.empty())
    return libxcursor_path;

  std::string path = GetEnv("XCURSOR_PATH");
  return path.empty() ? kDefaultPath : path;
}

const std::string& CursorPath() {
  static base::NoDestructor<std::string> path(CursorPathImpl());
  return *path;
}

x11::Render::PictFormat GetRenderARGBFormat(
    const x11::Render::QueryPictFormatsReply& formats) {
  for (const auto& format : formats.formats) {
    if (format.type == x11::Render::PictType::Direct && format.depth == 32 &&
        format.direct.alpha_shift == 24 && format.direct.alpha_mask == 0xff &&
        format.direct.red_shift == 16 && format.direct.red_mask == 0xff &&
        format.direct.green_shift == 8 && format.direct.green_mask == 0xff &&
        format.direct.blue_shift == 0 && format.direct.blue_mask == 0xff) {
      return format.id;
    }
  }
  return {};
}

std::vector<std::string> GetBaseThemes(const base::FilePath& abspath) {
  DCHECK(abspath.IsAbsolute());
  constexpr const char kKeyInherits[] = "Inherits";
  std::string contents;
  base::ReadFileToString(abspath, &contents);
  base::StringPairs pairs;
  base::SplitStringIntoKeyValuePairs(contents, '=', '\n', &pairs);
  for (const auto& pair : pairs) {
    if (base::TrimWhitespaceASCII(pair.first, base::TRIM_ALL) == kKeyInherits) {
      return base::SplitString(pair.second, ",;", base::TRIM_WHITESPACE,
                               base::SPLIT_WANT_NONEMPTY);
    }
  }
  return {};
}

base::FilePath CanonicalizePath(base::FilePath path) {
  std::vector<std::string> components = path.GetComponents();
  if (components[0] == "~") {
    path = base::GetHomeDir();
    for (size_t i = 1; i < components.size(); i++)
      path = path.Append(components[i]);
  } else {
    path = base::MakeAbsoluteFilePath(path);
  }
  return path;
}

scoped_refptr<base::RefCountedMemory> ReadCursorFromThemeImpl(
    const std::string& theme,
    const std::string& cursor_name,
    base::flat_set<ThemeAndCursorName>* parent_theme_and_cursor_names,
    base::flat_map<ThemeAndCursorName, scoped_refptr<base::RefCountedMemory>>*
        cache) {
  constexpr const char kCursorDir[] = "cursors";
  constexpr const char kThemeInfo[] = "index.theme";

  auto theme_and_cursor_name = std::make_pair(theme, cursor_name);
  auto it = cache->find(theme_and_cursor_name);
  if (it != cache->end()) {
    return it->second;
  }

  if (parent_theme_and_cursor_names->contains(theme_and_cursor_name)) {
    // Circular dependency.
    return nullptr;
  }
  ScopedSetInsertion scoped_set_insertion(parent_theme_and_cursor_names,
                                          theme_and_cursor_name);

  std::vector<std::string> base_themes;
  auto paths = base::SplitString(CursorPath(), ":", base::TRIM_WHITESPACE,
                                 base::SPLIT_WANT_NONEMPTY);
  for (const auto& path : paths) {
    auto dir = CanonicalizePath(base::FilePath(path));
    if (dir.empty())
      continue;
    base::FilePath theme_dir = dir.Append(theme);
    base::FilePath cursor_dir = theme_dir.Append(kCursorDir);

    std::string contents;
    if (base::ReadFileToString(cursor_dir.Append(cursor_name), &contents)) {
      auto result =
          base::MakeRefCounted<base::RefCountedString>(std::move(contents));
      (*cache)[theme_and_cursor_name] = result;
      return result;
    }

    if (base_themes.empty())
      base_themes = GetBaseThemes(theme_dir.Append(kThemeInfo));
  }

  for (const auto& path : base_themes) {
    if (auto contents = ReadCursorFromThemeImpl(
            path, cursor_name, parent_theme_and_cursor_names, cache)) {
      (*cache)[theme_and_cursor_name] = contents;
      return contents;
    }
  }

  (*cache)[theme_and_cursor_name] = nullptr;
  return nullptr;
}

// Reads the cursor called `name` for the theme named `theme`. Searches all
// paths in the XCursor path and parent themes.
scoped_refptr<base::RefCountedMemory> ReadCursorFromTheme(
    const std::string& theme,
    const std::string& cursor_name) {
  base::flat_set<ThemeAndCursorName> parent_theme_names;
  base::flat_map<ThemeAndCursorName, scoped_refptr<base::RefCountedMemory>>
      cache;
  return ReadCursorFromThemeImpl(theme, cursor_name, &parent_theme_names,
                                 &cache);
}

scoped_refptr<base::RefCountedMemory> ReadCursorFile(
    const std::string& cursor_name,
    const std::string& rm_xcursor_theme) {
  constexpr const char kDefaultTheme[] = "default";
  std::string themes[] = {
#if BUILDFLAG(IS_LINUX)
    // The toolkit theme has the highest priority.
    LinuxUi::instance() ? LinuxUi::instance()->GetCursorThemeName()
                        : std::string(),
#endif

    // Next try Xcursor.theme.
    rm_xcursor_theme,

    // As a last resort, use the default theme.
    kDefaultTheme,
  };

  for (const std::string& theme : themes) {
    if (theme.empty())
      continue;
    if (auto file = ReadCursorFromTheme(theme, cursor_name)) {
      return file;
    }
  }
  return nullptr;
}

std::vector<XCursorLoader::Image> ReadCursorImages(
    const std::vector<std::string>& cursor_names,
    const std::string& rm_xcursor_theme,
    uint32_t preferred_size) {
  // Fallback on a left pointer if possible.
  auto cursor_names_copy = cursor_names;
  cursor_names_copy.push_back("left_ptr");
  for (const auto& cursor_name : cursor_names_copy) {
    if (auto contents = ReadCursorFile(cursor_name, rm_xcursor_theme)) {
      auto images = ParseCursorFile(contents, preferred_size);
      if (!images.empty())
        return images;
    }
  }
  return {};
}

}  // namespace

XCursorLoader::XCursorLoader(x11::Connection* connection,
                             base::RepeatingClosure on_cursor_config_changed)
    : connection_(connection),
      on_cursor_config_changed_(std::move(on_cursor_config_changed)),
      rm_cache_(connection,
                connection->default_root(),
                {x11::Atom::RESOURCE_MANAGER},
                base::BindRepeating(&XCursorLoader::OnPropertyChanged,
                                    base::Unretained(this))) {
  auto pf_cookie = connection_->render().QueryPictFormats();
  cursor_font_ = connection_->GenerateId<x11::Font>();
  connection_->OpenFont({cursor_font_, "cursor"});

  // Fetch the initial property value which will call `OnPropertyChanged` and
  // initialize `rm_xcursor_theme_`, `rm_xcursor_size_`, and `rm_xft_dpi_`.
  rm_cache_.Get(x11::Atom::RESOURCE_MANAGER);

  if (auto pf_reply = pf_cookie.Sync())
    pict_format_ = GetRenderARGBFormat(*pf_reply.reply);
}

XCursorLoader::~XCursorLoader() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}

scoped_refptr<X11Cursor> XCursorLoader::LoadCursor(
    const std::vector<std::string>& cursor_names) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  auto cursor = base::MakeRefCounted<X11Cursor>();
  if (SupportsCreateCursor()) {
    base::ThreadPool::PostTaskAndReplyWithResult(
        FROM_HERE,
        {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
        base::BindOnce(ReadCursorImages, cursor_names, rm_xcursor_theme_,
                       GetPreferredCursorSize()),
        base::BindOnce(&XCursorLoader::LoadCursorImpl,
                       weak_factory_.GetWeakPtr(), cursor, cursor_names));
  } else {
    LoadCursorImpl(cursor, cursor_names, {});
  }
  return cursor;
}

scoped_refptr<X11Cursor> XCursorLoader::CreateCursor(
    const std::vector<Image>& images) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  std::vector<scoped_refptr<X11Cursor>> cursors;
  std::vector<x11::Render::AnimationCursorElement> elements;
  cursors.reserve(images.size());
  elements.reserve(images.size());

  for (const Image& image : images) {
    auto cursor = CreateCursor(image.bitmap, image.hotspot);
    cursors.push_back(cursor);
    elements.push_back(x11::Render::AnimationCursorElement{
        cursor->xcursor_,
        static_cast<uint32_t>(image.frame_delay.InMilliseconds())});
  }

  if (elements.empty())
    return nullptr;
  if (elements.size() == 1 || !SupportsCreateAnimCursor())
    return cursors[0];

  auto cursor = connection_->GenerateId<x11::Cursor>();
  connection_->render().CreateAnimCursor({cursor, elements});
  return base::MakeRefCounted<X11Cursor>(cursor);
}

scoped_refptr<X11Cursor> XCursorLoader::CreateCursor(
    const SkBitmap& bitmap,
    const gfx::Point& hotspot) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  auto pixmap = connection_->GenerateId<x11::Pixmap>();
  auto gc = connection_->GenerateId<x11::GraphicsContext>();
  uint16_t width = bitmap.width();
  uint16_t height = bitmap.height();
  connection_->CreatePixmap(
      {32, pixmap, connection_->default_root(), width, height});
  connection_->CreateGC({gc, pixmap});

  size_t size = bitmap.computeByteSize();
  std::vector<uint8_t> vec(size);
  UNSAFE_TODO(memcpy(vec.data(), bitmap.getPixels(), size));
  auto* connection = x11::Connection::Get();
  x11::PutImageRequest put_image_request{
      .format = x11::ImageFormat::ZPixmap,
      .drawable = pixmap,
      .gc = gc,
      .width = width,
      .height = height,
      .depth = 32,
      .data = base::MakeRefCounted<base::RefCountedBytes>(std::move(vec)),
  };
  connection->PutImage(put_image_request);

  x11::Render::Picture pic = connection_->GenerateId<x11::Render::Picture>();
  connection_->render().CreatePicture({pic, pixmap, pict_format_});

  auto cursor = connection_->GenerateId<x11::Cursor>();
  connection_->render().CreateCursor({cursor, pic,
                                      static_cast<uint16_t>(hotspot.x()),
                                      static_cast<uint16_t>(hotspot.y())});

  connection_->render().FreePicture({pic});
  connection_->FreePixmap({pixmap});
  connection_->FreeGC({gc});

  return base::MakeRefCounted<X11Cursor>(cursor);
}

void XCursorLoader::LoadCursorImpl(
    scoped_refptr<X11Cursor> cursor,
    const std::vector<std::string>& cursor_names,
    const std::vector<XCursorLoader::Image>& images) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  auto xcursor = connection_->GenerateId<x11::Cursor>();
  if (!images.empty()) {
    xcursor = CreateCursor(images)->ReleaseCursor();
  } else {
    // Fallback to using a font cursor.
    auto core_char = CursorNamesToChar(cursor_names);
    constexpr uint16_t kFontCursorFgColor = 0;
    constexpr uint16_t kFontCursorBgColor = 65535;
    connection_->CreateGlyphCursor({xcursor, cursor_font_, cursor_font_,
                                    static_cast<uint16_t>(2 * core_char),
                                    static_cast<uint16_t>(2 * core_char + 1),
                                    kFontCursorFgColor, kFontCursorFgColor,
                                    kFontCursorFgColor, kFontCursorBgColor,
                                    kFontCursorBgColor, kFontCursorBgColor});
  }
  cursor->SetCursor(xcursor);
}

uint32_t XCursorLoader::GetPreferredCursorSize() const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  constexpr const char kXcursorSizeEnv[] = "XCURSOR_SIZE";
  constexpr unsigned int kCursorSizeInchNum = 16;
  constexpr unsigned int kCursorSizeInchDen = 72;
  constexpr unsigned int kScreenCursorRatio = 48;

  // Allow the XCURSOR_SIZE environment variable to override GTK settings.
  int size;
  if (base::StringToInt(GetEnv(kXcursorSizeEnv), &size) && size > 0) {
    return size;
  }

#if BUILDFLAG(IS_LINUX)
  // Let the toolkit have the next say.
  auto* linux_ui = LinuxUi::instance();
  size = linux_ui ? linux_ui->GetCursorThemeSize() : 0;
  if (size > 0) {
    return size;
  }
#endif

  // Use Xcursor.size from RESOURCE_MANAGER if available.
  if (rm_xcursor_size_) {
    return rm_xcursor_size_;
  }

  // Guess the cursor size based on the DPI.
  if (rm_xft_dpi_)
    return rm_xft_dpi_ * kCursorSizeInchNum / kCursorSizeInchDen;

  // As a last resort, guess the cursor size based on the screen size.
  const auto& screen = connection_->default_screen();
  return std::min(screen.width_in_pixels, screen.height_in_pixels) /
         kScreenCursorRatio;
}

void XCursorLoader::ParseXResources(std::string_view resources) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  base::StringPairs pairs;
  base::SplitStringIntoKeyValuePairs(resources, ':', '\n', &pairs);
  for (const auto& pair : pairs) {
    auto key = base::TrimWhitespaceASCII(pair.first, base::TRIM_ALL);
    auto value = base::TrimWhitespaceASCII(pair.second, base::TRIM_ALL);

    if (key == "Xcursor.theme")
      rm_xcursor_theme_ = std::string(value);
    else if (key == "Xcursor.size")
      base::StringToUint(value, &rm_xcursor_size_);
    else if (key == "Xft.dpi")
      base::StringToUint(value, &rm_xft_dpi_);
  }
}

uint16_t XCursorLoader::CursorNamesToChar(
    const std::vector<std::string>& cursor_names) const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  // These cursor names are indexed by their ID in a cursor font.
  constexpr auto kMap = base::MakeFixedFlatMap<std::string_view, uint16_t>({
      {"X_cursor", 0u},
      {"arrow", 1u},
      {"based_arrow_down", 2u},
      {"based_arrow_up", 3u},
      {"boat", 4u},
      {"bogosity", 5u},
      {"bottom_left_corner", 6u},
      {"bottom_right_corner", 7u},
      {"bottom_side", 8u},
      {"bottom_tee", 9u},
      {"box_spiral", 10u},
      {"center_ptr", 11u},
      {"circle", 12u},
      {"clock", 13u},
      {"coffee_mug", 14u},
      {"cross", 15u},
      {"cross_reverse", 16u},
      {"crosshair", 17u},
      {"diamond_cross", 18u},
      {"dot", 19u},
      {"dotbox", 20u},
      {"double_arrow", 21u},
      {"draft_large", 22u},
      {"draft_small", 23u},
      {"draped_box", 24u},
      {"exchange", 25u},
      {"fleur", 26u},
      {"gobbler", 27u},
      {"gumby", 28u},
      {"hand1", 29u},
      {"hand2", 30u},
      {"heart", 31u},
      {"icon", 32u},
      {"iron_cross", 33u},
      {"left_ptr", 34u},
      {"left_side", 35u},
      {"left_tee", 36u},
      {"leftbutton", 37u},
      {"ll_angle", 38u},
      {"lr_angle", 39u},
      {"man", 40u},
      {"middlebutton", 41u},
      {"mouse", 42u},
      {"pencil", 43u},
      {"pirate", 44u},
      {"plus", 45u},
      {"question_arrow", 46u},
      {"right_ptr", 47u},
      {"right_side", 48u},
      {"right_tee", 49u},
      {"rightbutton", 50u},
      {"rtl_logo", 51u},
      {"sailboat", 52u},
      {"sb_down_arrow", 53u},
      {"sb_h_double_arrow", 54u},
      {"sb_left_arrow", 55u},
      {"sb_right_arrow", 56u},
      {"sb_up_arrow", 57u},
      {"sb_v_double_arrow", 58u},
      {"shuttle", 59u},
      {"sizing", 60u},
      {"spider", 61u},
      {"spraycan", 62u},
      {"star", 63u},
      {"target", 64u},
      {"tcross", 65u},
      {"top_left_arrow", 66u},
      {"top_left_corner", 67u},
      {"top_right_corner", 68u},
      {"top_side", 69u},
      {"top_tee", 70u},
      {"trek", 71u},
      {"ul_angle", 72u},
      {"umbrella", 73u},
      {"ur_angle", 74u},
      {"watch", 75u},
      {"xterm", 76u},
  });

  for (const auto& cursor_name : cursor_names) {
    auto it = kMap.find(cursor_name);
    if (it != kMap.end()) {
      return it->second;
    }
  }

  // Use a left pointer as a fallback.
  return 0;
}

bool XCursorLoader::SupportsCreateCursor() const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  return connection_->render_version() >= std::pair<uint32_t, uint32_t>{0, 5};
}

bool XCursorLoader::SupportsCreateAnimCursor() const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  return connection_->render_version() >= std::pair<uint32_t, uint32_t>{0, 8};
}

void XCursorLoader::OnPropertyChanged(x11::Atom property,
                                      const x11::GetPropertyResponse& value) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK_EQ(property, x11::Atom::RESOURCE_MANAGER);

  rm_xcursor_theme_ = "";
  rm_xcursor_size_ = 0;
  rm_xft_dpi_ = 0;

  size_t size = 0;
  if (const char* resource_manager =
          x11::PropertyCache::GetAs<char>(value, &size)) {
    ParseXResources(std::string_view(resource_manager, size));
  }

  if (on_cursor_config_changed_) {
    on_cursor_config_changed_.Run();
  }
}

// This is ported from libxcb-cursor's parse_cursor_file.c:
// https://gitlab.freedesktop.org/xorg/lib/libxcb-cursor/-/blob/master/cursor/parse_cursor_file.c
std::vector<XCursorLoader::Image> ParseCursorFile(
    scoped_refptr<base::RefCountedMemory> file,
    uint32_t preferred_size) {
  constexpr uint32_t kMagic = 0x72756358u;
  constexpr uint32_t kImageType = 0xfffd0002u;

  size_t offset = 0u;

  // Reads bytes from `file` and writes them into the `dest` buffer.
  auto ReadBytes = [&](base::span<uint8_t> dest) {
    CHECK_EQ(dest.size() % 4u, 0u);
    auto src = base::span<const uint8_t>(*file);
    if (auto end = base::CheckAdd(offset, dest.size());
        !end.IsValid() || end.ValueOrDie() > src.size()) {
      return false;
    }
    dest.copy_from(src.subspan(offset, dest.size()));
    offset += dest.size();
    return true;
  };
  // Reads a single 32-bit value from `file` and writes it to `dest`.
  auto ReadU32 = [&](uint32_t& dest) {
    auto src = base::span(*file);
    if (auto end = base::CheckAdd(offset, sizeof(dest));
        !end.IsValid() || end.ValueOrDie() > src.size()) {
      return false;
    }
    dest = base::U32FromLittleEndian(src.subspan(offset).first<sizeof(dest)>());
    offset += sizeof(dest);
    return true;
  };

  struct FileHeader {
    uint32_t magic;
    uint32_t header;
    uint32_t version;
    uint32_t ntoc;
  } header;
  if (!ReadU32(header.magic) ||    //
      !ReadU32(header.header) ||   //
      !ReadU32(header.version) ||  //
      !ReadU32(header.ntoc) ||     //
      header.magic != kMagic) {
    return {};
  }

  struct TableOfContentsEntry {
    uint32_t type;
    uint32_t subtype;
    uint32_t position;
  };
  std::vector<TableOfContentsEntry> toc;
  for (uint32_t i = 0u; i < header.ntoc; i++) {
    TableOfContentsEntry entry;
    if (!ReadU32(entry.type) ||     //
        !ReadU32(entry.subtype) ||  //
        !ReadU32(entry.position)) {
      return {};
    }
    toc.push_back(entry);
  }

  uint32_t best_size = std::numeric_limits<uint32_t>::max();
  for (const auto& entry : toc) {
    auto delta = [](uint32_t x, uint32_t y) {
      return std::max(x, y) - std::min(x, y);
    };
    if (entry.type != kImageType)
      continue;
    if (delta(entry.subtype, preferred_size) < delta(best_size, preferred_size))
      best_size = entry.subtype;
  }

  std::vector<XCursorLoader::Image> images;
  for (const auto& entry : toc) {
    if (entry.type != kImageType || entry.subtype != best_size)
      continue;
    offset = entry.position;
    struct ChunkHeader {
      uint32_t header;
      uint32_t type;
      uint32_t subtype;
      uint32_t version;
    } chunk_header;
    if (!ReadU32(chunk_header.header) ||   //
        !ReadU32(chunk_header.type) ||     //
        !ReadU32(chunk_header.subtype) ||  //
        !ReadU32(chunk_header.version) ||  //
        chunk_header.type != entry.type ||
        chunk_header.subtype != entry.subtype) {
      return {};
    }

    struct ImageHeader {
      uint32_t width;
      uint32_t height;
      uint32_t xhot;
      uint32_t yhot;
      uint32_t delay;
    } image;
    if (!ReadU32(image.width) ||   //
        !ReadU32(image.height) ||  //
        !ReadU32(image.xhot) ||    //
        !ReadU32(image.yhot) ||    //
        !ReadU32(image.delay)) {
      return {};
    }
    // Ignore unreasonably-sized cursors to prevent allocating too much
    // memory in the bitmap below.
    if (image.width > 8192u || image.height > 8192u) {
      return {};
    }
    SkBitmap bitmap;
    bitmap.allocN32Pixels(image.width, image.height);
    base::span<uint8_t> pixels =
        // SAFETY: SkBitmap promises that getPixels() returns a pointer to
        // at least as many bytes as computeByteSize().
        //
        // TODO(crbug.com/40284755): SkBitmap should provide a span-based
        // API.
        UNSAFE_TODO(base::span(static_cast<uint8_t*>(bitmap.getPixels()),
                               bitmap.computeByteSize()));
    if (!ReadBytes(pixels)) {
      return {};
    }
    images.push_back(XCursorLoader::Image{bitmap,
                                          gfx::Point(image.xhot, image.yhot),
                                          base::Milliseconds(image.delay)});
  }
  return images;
}

}  // namespace ui
