hf2q 0.1.7

Pure Rust CLI for converting HuggingFace models to hardware-optimized formats and serving them over an OpenAI-compatible API on Apple Silicon
use super::{u32_at, MachOError, LC_DATA_IN_CODE, LC_FUNCTION_STARTS};

pub(super) fn verify_symtab(
    record: &[u8],
    file_length: u64,
    payloads: &mut Vec<(u64, u64)>,
) -> Result<u32, MachOError> {
    if record.len() != 24 {
        return Err(MachOError::Invalid);
    }
    let symbol_count = u32_at(record, 12)?;
    push_optional_range(
        payloads,
        u32_at(record, 8)?,
        symbol_count.checked_mul(16).ok_or(MachOError::Invalid)?,
        file_length,
    )?;
    push_optional_range(
        payloads,
        u32_at(record, 16)?,
        u32_at(record, 20)?,
        file_length,
    )?;
    Ok(symbol_count)
}

pub(super) fn verify_dysymtab(
    record: &[u8],
    symbol_count: u32,
    file_length: u64,
    payloads: &mut Vec<(u64, u64)>,
) -> Result<(), MachOError> {
    if record.len() != 80 {
        return Err(MachOError::Invalid);
    }
    let local_start = u32_at(record, 8)?;
    let local_count = u32_at(record, 12)?;
    let external_start = u32_at(record, 16)?;
    let external_count = u32_at(record, 20)?;
    let undefined_start = u32_at(record, 24)?;
    let undefined_count = u32_at(record, 28)?;
    let local_end = local_start
        .checked_add(local_count)
        .ok_or(MachOError::Invalid)?;
    let external_end = external_start
        .checked_add(external_count)
        .ok_or(MachOError::Invalid)?;
    let undefined_end = undefined_start
        .checked_add(undefined_count)
        .ok_or(MachOError::Invalid)?;
    if local_start != 0
        || external_start != local_end
        || undefined_start != external_end
        || undefined_end != symbol_count
    {
        return Err(MachOError::Invalid);
    }
    for (offset, count, width) in [
        (32, 36, 8_u32),
        (40, 44, 56),
        (48, 52, 4),
        (56, 60, 4),
        (64, 68, 8),
        (72, 76, 8),
    ] {
        push_optional_range(
            payloads,
            u32_at(record, offset)?,
            u32_at(record, count)?
                .checked_mul(width)
                .ok_or(MachOError::Invalid)?,
            file_length,
        )?;
    }
    Ok(())
}

pub(super) fn verify_dyld_info(
    record: &[u8],
    file_length: u64,
    payloads: &mut Vec<(u64, u64)>,
) -> Result<(), MachOError> {
    if record.len() != 48 {
        return Err(MachOError::Invalid);
    }
    for offset in [8, 16, 24, 32, 40] {
        push_optional_range(
            payloads,
            u32_at(record, offset)?,
            u32_at(record, offset + 4)?,
            file_length,
        )?;
    }
    Ok(())
}

pub(super) fn verify_linkedit_data(
    record: &[u8],
    kind: u32,
    file_length: u64,
) -> Result<(u64, u64), MachOError> {
    if record.len() != 16 {
        return Err(MachOError::Invalid);
    }
    let size = u32_at(record, 12)?;
    if (kind == LC_FUNCTION_STARTS && size == 0) || (kind == LC_DATA_IN_CODE && size % 8 != 0) {
        return Err(MachOError::Invalid);
    }
    checked_file_range(u32_at(record, 8)?, size, file_length)
}

fn push_optional_range(
    payloads: &mut Vec<(u64, u64)>,
    offset: u32,
    size: u32,
    file_length: u64,
) -> Result<(), MachOError> {
    if size == 0 {
        if offset != 0 {
            return Err(MachOError::Invalid);
        }
        return Ok(());
    }
    payloads.push(checked_file_range(offset, size, file_length)?);
    Ok(())
}

fn checked_file_range(offset: u32, size: u32, file_length: u64) -> Result<(u64, u64), MachOError> {
    let start = u64::from(offset);
    let end = start
        .checked_add(u64::from(size))
        .ok_or(MachOError::Invalid)?;
    if end > file_length {
        return Err(MachOError::Invalid);
    }
    Ok((start, end))
}