git-checks 4.2.1

Checks to run against a topic in git to enforce coding standards.
Documentation
// Copyright Kitware, Inc.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::mem;

const AR_MAGIC: &[u8] = b"!<arch>\n";
const ELF_MAGIC: &[u8] = &[0x7f, 0x45, 0x4c, 0x46]; // 0x7f ELF
const MACHO_MAGIC: &[u8] = &[0xcf, 0xfa, 0xed, 0xfe];
const MACHO_CIGAM: &[u8] = &[0xfe, 0xed, 0xfa, 0xcf];
const MACHO_FAT_MAGIC: &[u8] = &[0xca, 0xfe, 0xba, 0xbe];
const MACHO_FAT_CIGAM: &[u8] = &[0xbe, 0xba, 0xfe, 0xca];

const PE_OFFSET: usize = 0x3c;
type PeOffset = u32;
const PE_OFFSET_SIZE: usize = mem::size_of::<PeOffset>();
const PE_MAGIC: &[u8] = &[0x50, 0x45, 0x00, 0x00]; // PE 0x00 0x00

pub(crate) enum BinaryFormat {
    Ar,
    Elf,
    MachO,
    Pe,
}

impl BinaryFormat {
    pub(crate) fn name(&self) -> &'static str {
        match *self {
            BinaryFormat::Ar => "AR",
            BinaryFormat::Elf => "ELF",
            BinaryFormat::MachO => "Mach-O",
            BinaryFormat::Pe => "PE",
        }
    }

    #[allow(clippy::match_like_matches_macro)]
    pub(crate) fn is_executable(&self) -> bool {
        match *self {
            BinaryFormat::Ar => false,
            _ => true,
        }
    }
}

fn detect_pe(file: &[u8]) -> bool {
    if file.len() < PE_OFFSET + PE_OFFSET_SIZE {
        return false;
    }

    // Find the offset in the file.
    let mut offset = [0; PE_OFFSET_SIZE];
    offset.copy_from_slice(&file[PE_OFFSET..PE_OFFSET + PE_OFFSET_SIZE]);

    // Read the offset. It is in native-endian order and we don't know the endianness of the
    // binary, so try it as big- and little-endian.
    let offset_le = PeOffset::from_le_bytes(offset);
    let offset_be = offset_le.swap_bytes();

    let offset_le_sz = offset_le as usize;
    let offset_be_sz = offset_be as usize;

    let magic_at_offset = |offset| offset < file.len() && file[offset..].starts_with(PE_MAGIC);

    magic_at_offset(offset_le_sz) || magic_at_offset(offset_be_sz)
}

pub(crate) fn detect_binary_format<C>(content: C) -> Option<BinaryFormat>
where
    C: AsRef<[u8]>,
{
    detect_binary_format_impl(content.as_ref())
}

fn detect_binary_format_impl(content: &[u8]) -> Option<BinaryFormat> {
    if content.starts_with(ELF_MAGIC) {
        Some(BinaryFormat::Elf)
    } else if content.starts_with(AR_MAGIC) {
        Some(BinaryFormat::Ar)
    } else if content.starts_with(MACHO_MAGIC)
        || content.starts_with(MACHO_CIGAM)
        || content.starts_with(MACHO_FAT_MAGIC)
        || content.starts_with(MACHO_FAT_CIGAM)
    {
        Some(BinaryFormat::MachO)
    } else if detect_pe(content) {
        Some(BinaryFormat::Pe)
    } else {
        None
    }
}