pyrograph 0.1.0

GPU-accelerated taint analysis for supply chain malware detection
Documentation
use std::collections::HashMap;
use std::path::PathBuf;

use syn::visit::Visit;

use crate::error::{Error, Result};
pub(crate) use crate::ir::{EdgeKind, NodeId, NodeKind, TaintGraph};
pub(crate) use crate::labels::LabelSet;

mod expr;
mod labels_default;
mod visitor;

pub use labels_default::default_label_set;
use labels_default::apply_labels;
use visitor::RustParser;

/// Parse a single Rust file into a taint graph with optional custom labels.
pub fn parse_rust_with_labels(
    source: &str,
    filename: &str,
    labels: Option<&LabelSet>,
) -> Result<TaintGraph> {
    let syntax = syn::parse_file(source)
        .map_err(|err| Error::Analysis(format!("Fix: parse Rust file `{filename}`: {err}")))?;
    let mut parser = RustParser::new(PathBuf::from(filename));
    parser.visit_file(&syntax);
    let mut graph = parser.into_graph();
    let label_set = labels.map_or_else(default_label_set, Clone::clone);
    apply_labels(&mut graph, &label_set);
    graph.set_label_set(label_set);
    Ok(graph)
}

/// Parse a single Rust file into a taint graph.
pub fn parse_rust(source: &str, filename: &str) -> Result<TaintGraph> {
    parse_rust_with_labels(source, filename, None)
}

#[derive(Clone, Debug)]
pub(crate) struct EvalResult {
    pub(crate) node: NodeId,
    pub(crate) descriptor: Option<String>,
    pub(crate) literal: Option<String>,
}

#[derive(Clone, Debug)]
pub(crate) struct FunctionInfo {
    pub(crate) node: NodeId,
    pub(crate) params: Vec<NodeId>,
}

#[derive(Default)]
pub(crate) struct Scope {
    values: HashMap<String, NodeId>,
}

impl Scope {
    pub(crate) fn define(&mut self, name: String, node: NodeId) {
        self.values.insert(name, node);
    }

    pub(crate) fn resolve(&self, name: &str) -> Option<NodeId> {
        self.values.get(name).copied()
    }
}