proguard

A Rust library for parsing ProGuard and R8 mapping files and deobfuscating Android stack traces and crash reports.

Library
Cargo
v5.10.4
29stars
BSD 3-Clause License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
45/100Fair
Development Activity48
Maintenance36
Community24
Maturity60
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
76/100Good
Architecture82
Code Quality88
Innovation80
Learning Curve55

proguard is a Rust crate, maintained by Sentry, for working with ProGuard and R8 mapping files — the class/method/line renaming tables Android build tooling produces when it obfuscates and inlines code. It parses these mapping files into a structured, queryable form and uses them to remap obfuscated class names, stack frames, and full Java stack traces back to their original, human-readable identifiers, including R8-specific behavior such as inlined frames, outline methods, and synthetic bridge methods.

For services that process large volumes of crash reports, the crate also defines ProguardCache, a versioned, zero-copy binary cache format that lets a mapping file be parsed once and then loaded and queried repeatedly without re-parsing the original text — the approach Sentry uses in its own crash-symbolication pipeline.

What You Get

  • A line-by-line ProguardMapping parser exposing typed ProguardRecord (Header/Class/Method) entries.
  • A ProguardMapper for remapping obfuscated class names and full StackFrame sequences, including R8 inlining and outline resolution.
  • A StackTrace/Throwable parser that ingests raw Java exception dumps end to end, including “Caused by” chains.
  • A versioned, zero-copy ProguardCache binary format for repeated lookups without re-parsing the source text.
  • An optional uuid feature for computing a stable identity hash of a mapping file.

Common Use Cases

  • Deobfuscating incoming Android crash reports in a crash-ingestion backend using the build’s stored mapping file.
  • Verifying build/obfuscation metadata at CI time via MappingSummary’s compiler/version/class counts.
  • Serving high volumes of crash symbolication requests by converting each mapping to a ProguardCache once and reusing it.

Under The Hood

Architecture The crate is a modular parse -> build -> map pipeline: mapping.rs implements a low-level, allocation-light line-by-line parser (ProguardMapping / ProguardRecordIter) over raw mapping-file bytes; builder.rs turns those records into a structured ParsedProguardMapping (class info, method receivers, rewrite rules); mapper.rs consumes the built mapping through ProguardMapper to remap class names and expand/rewrite full StackFrame sequences via a lazy RemappedFrameIter (with span expansion capped by MAX_SPAN_EXPANSION to guard against malformed R8 catch-all ranges); and cache/ (raw.rs + debug.rs) defines a separate versioned, zero-copy on-disk ProguardCache binary format as an alternate persisted representation of the same built mapping. stacktrace.rs and java.rs supply the shared StackTrace/Throwable/StackFrame value types and Java signature parsing consumed by both the mapper and the cache. The layering is clean — changing the cache’s binary layout only touches raw.rs/debug.rs, not the parsing or mapping logic.

Tech Stack A pure Rust crate (edition 2021, rust-version 1.83) with a deliberately small dependency set: serde/serde_json for structured/debug export, thiserror for typed CacheErrors, an optional uuid dependency (feature-gated) for computing a mapping’s stable identity, and watto for the binary cache’s writer/string-table helpers; criterion is a dev-dependency backing two harness-less benchmarks (proguard_parsing, proguard_mapping). It has no web/ORM/CLI framework — it’s a focused parsing/remapping library built for embedding into Sentry’s Rust-based crash-symbolication services and distributed via crates.io/docs.rs.

Code Quality Testing is extensive: ten integration test files under tests/ (basic.rs, callback.rs, retrace.rs, plus seven r8-*.rs files covering ambiguous methods, exception handling, inlining, line-number handling, method overloading, source-file edge cases, and synthetic methods) validated against real fixture mapping files and companion Kotlin source snippets under tests/res/. CI (.github/workflows/ci.yml) runs cargo fmt --check, cargo clippy --all-features --workspace --tests --examples -- -D clippy::all under RUSTFLAGS=-Dwarnings, a cargo doc --document-private-items build, cargo test --all-features --all-targets plus doctests, and a dedicated code-coverage job via cargo-llvm-cov + Codecov — a notably rigorous gate for a crate this size. Error handling is idiomatic: parse errors are typed (ParseError/ParseErrorKind, carrying the offending line) and cache errors use thiserror-derived CacheError; a workspace-level [lints.clippy] unwrap-used = "warn" discourages panicking unwraps. Public items are documented under #![warn(missing_docs)], several with runnable doctests, and naming follows idiomatic Rust conventions throughout.

API Design The public surface is minimal and purpose-built for the crash-symbolication use case: ProguardMapper::from(&str) needs no builder ceremony for the common case, remap_frame returns a lazy iterator (RemappedFrameIter) so a single obfuscated frame can expand into multiple inlined frames without upfront allocation, and StackTrace::try_parse takes a raw Java exception dump and performs the whole split/parse/remap pipeline in one call — matching the shape of real production input. ProguardCache is offered as an opt-in escape hatch for repeated production lookups rather than forced on casual callers, and the uuid feature is similarly opt-in via Cargo [features]. The top-of-crate example in lib.rs demonstrates both core flows (class remap and frame remap) in under twenty lines.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search