chromium/chrome/common/safe_browsing/disk_image_type_sniffer_mac.cc

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

#include "chrome/common/safe_browsing/disk_image_type_sniffer_mac.h"
#include "base/threading/scoped_blocking_call.h"

namespace safe_browsing {

namespace {

const uint8_t kKolySignature[4] = {'k', 'o', 'l', 'y'};
constexpr size_t kSizeKolySignatureInBytes = sizeof(kKolySignature);

}  // namespace

DiskImageTypeSnifferMac::DiskImageTypeSnifferMac() {}

// static
bool DiskImageTypeSnifferMac::IsAppleDiskImage(const base::FilePath& dmg_file) {
  // TODO(drubery): Macs accept DMGs with koly blocks at the beginning of the
  // file. Investigate if this is a problem, and if so, update this function.
  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
                                                base::BlockingType::MAY_BLOCK);

  base::File file(dmg_file, base::File::FLAG_OPEN | base::File::FLAG_READ);
  if (!file.IsValid())
    return false;

  uint8_t data[kSizeKolySignatureInBytes];

  if (file.Seek(base::File::FROM_END, -1 * kAppleDiskImageTrailerSize) == -1)
    return false;

  if (file.ReadAtCurrentPos(data) != kSizeKolySignatureInBytes) {
    return false;
  }

  return IsAppleDiskImageTrailer(data);
}

// static
bool DiskImageTypeSnifferMac::IsAppleDiskImageTrailer(
    const base::span<const uint8_t>& trailer) {
  if (trailer.size() < kSizeKolySignatureInBytes)
    return false;

  const base::span<const uint8_t> subspan =
      trailer.last(kSizeKolySignatureInBytes);

  return (memcmp(subspan.data(), kKolySignature, kSizeKolySignatureInBytes) ==
          0);
}

DiskImageTypeSnifferMac::~DiskImageTypeSnifferMac() = default;

constexpr size_t DiskImageTypeSnifferMac::kAppleDiskImageTrailerSize;

}  // namespace safe_browsing