Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/holger

intel/src/subject.rs

//! What a file on disk is, for a scan with no server around it: a wheel's own
//! METADATA first, then the `name-version.ext` file name.

/// Bound on a wheel's METADATA member.
const MAX_METADATA: usize = 1024 * 1024;

const EXTS: &[&str] = &[
    ".tar.gz", ".tar.zst", ".tar.bz2", ".crate", ".whl", ".tgz", ".jar", ".pom", ".war", ".gem",
    ".deb", ".rpm", ".nupkg", ".conda", ".zip", ".tar", ".gz", ".tbz",
];

/// `(name, version)` from a `name-version[-tags].ext` file name: the version
/// starts at the first `-` followed by a digit and runs to the next `-`.
pub fn coords_from_file_name(file_name: &str) -> Option<(String, String)> {
    let base = file_name.rsplit('/').next().unwrap_or(file_name);
    let stem = EXTS
        .iter()
        .find_map(|e| base.strip_suffix(e))
        .unwrap_or(base);
    let b = stem.as_bytes();
    let idx =
        (0..b.len().saturating_sub(1)).find(|&i| b[i] == b'-' && b[i + 1].is_ascii_digit())?;
    let (name, rest) = (&stem[..idx], &stem[idx + 1..]);
    let version = rest.split('-').next().unwrap_or(rest);
    (!name.is_empty() && !version.is_empty()).then(|| (name.to_string(), version.to_string()))
}

/// `(name, version)` from a wheel's `*.dist-info/METADATA`.
pub fn wheel_coords(bytes: &[u8]) -> Option<(String, String)> {
    let members = zip_entry::members(bytes).ok()?;
    let m = members
        .iter()
        .find(|m| m.name.ends_with(".dist-info/METADATA") && m.name.matches('/').count() == 1)?;
    let body = zip_entry::read_member_capped(bytes, m, MAX_METADATA).ok()?;
    let text = String::from_utf8_lossy(&body);
    let mut name = None;
    let mut version = None;
    for line in text.lines() {
        if line.is_empty() {
            break; // the headers end at the first blank line
        }
        if let Some(v) = line.strip_prefix("Name:") {
            name.get_or_insert_with(|| v.trim().to_string());
        } else if let Some(v) = line.strip_prefix("Version:") {
            version.get_or_insert_with(|| v.trim().to_string());
        }
    }
    Some((name?, version?))
}

/// The coords a scan keys on: the wheel's own METADATA, else the file name.
pub fn coords(file_name: &str, bytes: &[u8]) -> Option<(String, String)> {
    if file_name.ends_with(".whl") {
        if let Some(c) = wheel_coords(bytes) {
            return Some(c);
        }
    }
    coords_from_file_name(file_name)
}