Files
craft-libs/Cargo.toml
skylar taylor-barrick 1fea3964a2 archive: add craft-archive parsing budgets for ZIP and XML
One small crate for the checks that must run before an archive or XML parser
touches a file the app did not write, following craft-libs#126.

- Budget/Exceeded: a named limit and a running total of real bytes, charged
  before allocating, reporting the name, limit and request on a breach.
- zip::preflight: allocation-free validation of the end records and the
  central directory before ZipArchive::new indexes every entry. Exactly one
  end record must span the end of the file (ambiguous records are refused);
  the ZIP64 record and locator are checked against each other; entry count,
  directory size and name lengths are limited; the directory must fill its
  declared size and reach the end records. Single-disk only; malformed input
  is an error, never a panic.
- zip::read_entry: bounds one entry against the per-entry limit, a fixed
  preallocation and the total budget, charges only bytes actually read, and
  reports a lying declared size or a decompression bomb as an overrun.
- xml::check: one iterative linear pass that measures nesting (comments,
  CDATA, processing instructions and quoted values cannot fake a tag) and
  applies a DTD policy, so a recursive parser never sees input that would
  exhaust the stack. xml::Depth does the same for readers that count as they
  parse.

Zero dependencies, no unsafe, no numbers of the crate's own. Tests cover bombs,
lying declared sizes, entry-count and directory-size caps, lying EOCD counts,
truncation, ZIP64 variants, DTD policies, quote/comment/CDATA confusion, the
depth boundary and a 250k-deep hostile document.
2026-10-14 15:02:49 -06:00

30 lines
770 B
TOML

[workspace]
resolver = "3"
members = ["crates/*"]
[workspace.package]
version = "0.1.0"
edition = "2024"
license = "MIT OR Apache-2.0"
rust-version = "1.95"
repository = "https://github.com/storytold/craft-libs"
[workspace.dependencies]
# internal: add each crate here as `craft-<name> = { path = "crates/<name>" }`
craft-atomic = { path = "crates/atomic" }
craft-archive = { path = "crates/archive" }
craft-cms = { path = "crates/cms" }
craft-print = { path = "crates/print" }
craft-quit = { path = "crates/quit" }
craft-settings = { path = "crates/settings" }
craft-ui = { path = "crates/ui" }
egui = { version = "0.36", default-features = false }
rayon = "1"
[workspace.lints.rust]
unsafe_code = "forbid"
[workspace.lints.clippy]
dbg_macro = "warn"
todo = "warn"