Subject
toml_edit is a format-preserving TOML parser and editor. Unlike a "plain" deserialiser, the crate retains whitespace, comments, and the original ordering of items in a parsed document so that modifications can be written back without churning unrelated formatting. The public API centres on Document / DocumentMut (the root TOML table together with surrounding whitespace), Table / InlineTable (key/value maps backed by indexmap::IndexMap), Array / ArrayOfTables, the Item enum, the scalar Value variants (string, integer, float, boolean, datetime), Key / KeyMut, and the visit/visit_mut traversal traits. Two optional sub-modules expose serde integration: toml_edit::de (deserialise into Rust types) and toml_edit::ser (serialise Rust types into TOML). The crate is a thin edit-preserving layer over the lexer/event-stream in toml_parser; this audit covers only toml_edit itself.
Methodology
Tooling used:
openvet audit new (0.6.0) to fetch and unpack the crate from crates.io and clone the upstream multi-crate workspace at the commit recorded in .cargo_vcs_info.json. The workspace is checked out into vcs-root/ with vcs/ symlinked into crates/toml_edit.
diff -r (Apple Darwin) to compare published crate contents against the upstream VCS tree.
grep to scan contents/src/ for unsafe, extern "C", process::*, std::net::*, std::fs::*, env::*, allocator usage, transmute, panic-prone calls (panic!, expect, unwrap, unimplemented!, unreachable!) and the unbounded/RecursionGuard/LIMIT tokens.
- Manual reading of the crate-level entry point (
src/lib.rs), the parser-dispatch layer (src/parser/mod.rs, src/parser/document.rs, src/parser/value.rs, src/parser/array.rs, src/parser/key.rs), the AST root (src/document.rs), src/encode.rs (display layer), src/raw_string.rs (the span-or-explicit string storage), src/error.rs, src/repr.rs, and the serde integration (src/de/mod.rs, src/de/value.rs, src/ser/mod.rs). The larger AST node modules (src/table.rs, src/inline_table.rs, src/array.rs) were surveyed for panic sites, unsafe blocks and I/O calls; the per-node serde and visitor code was not read end to end.
- Survey of the upstream test suite (
vcs/tests/ — ~2 KLOC of compliance/, serde/, testsuite/edit.rs plus the decoder/encoder compliance harnesses driven by toml-test-data/toml-test-harness) and the upstream toml_edit_fuzz workspace member with its parse_document libfuzzer target.
The published toml_edit-0.25.12+spec-1.1.0.crate was diffed against the upstream repository at the commit pinned in .cargo_vcs_info.json. All files under src/ and examples/ match the upstream tree byte-for-byte; the published crate excludes the multi-crate workspace's other members and the tests/ directory at the workspace level via the include list in Cargo.toml.orig. Cargo's Cargo.toml normalisation is the only manifest-level difference.
Results
The diff between published contents and the upstream repository shows no unexpected changes. The crate contains no binary artefacts (justifying has-binaries) and no build.rs; Cargo.toml declares build = false and [lib] has no proc-macro = true. There is no install-time hook either, justifying has-build-exec and has-install-exec.
A grep across contents/src/ returned zero unsafe blocks, no FFI declarations, no std::net/std::fs/std::process/env:: calls, and no thread- or async-runtime usage. This justifies uses-unsafe, uses-exec, uses-network, uses-filesystem, uses-environment, uses-concurrency, uses-crypto, uses-jit, and uses-interpreter, and the corresponding implementation claims impl-crypto, impl-jit, impl-interpreter, impl-protocol, and impl-concurrency. The Table/InlineTable types are wrappers around indexmap::IndexMap rather than novel data structures, justifying impl-datastructure; the crate implements no compute-heavy algorithms beyond the parser, justifying impl-algorithm.
The crate's central function is parsing TOML into an edit-preserving AST, justifying impl-parser. Three conditional parser claims were evaluated:
- parser-impl-safe: the lexing and event generation are delegated to
toml_parser; the toml_edit layer's parser walks the event stream without unsafe code. On numeric overflow the parser emits a ParseError into the error sink and substitutes a sentinel (f64::NAN, i64::MAX); Document::parse rejects the result if the sink saw any error, so overflow sentinels do not leak into a successful parse. The recursion guard at LIMIT = 80 (in src/parser/mod.rs) and the dotted-key-path depth check (in src/parser/key.rs) bound the stack-depth that an adversarial document can demand of the parser — but only when the unbounded feature is off (see FINDING-1). The panic! / expect sites that exist (~10 across the crate) are all on internal invariants — for example, "non-value item in an array", "span should be in input" — not reachable from a successful parse of any byte string.
- parser-impl-correct: the upstream
tests/decoder.rs / tests/encoder.rs harnesses are driven against the language-agnostic toml-test-data conformance suite via toml-test-harness; an additional tests/compliance/ directory checks invalid-input handling. src/encode.rs contains an embedded proptest that round-trips arbitrary printable strings through value and key parsers.
- parser-impl-tested: the integration tests under
vcs/tests/testsuite/edit.rs (~1900 lines) exercise the editing API in addition to parsing; the upstream workspace member toml_edit_fuzz/parse_document.rs provides a libfuzzer harness for the document parser. Together these justify has-unit-tests, has-integration-tests, has-fuzz-tests, and has-property-tests.
One low-severity quality finding was recorded: FINDING-1 notes that the unbounded feature flag is declared in Cargo.toml without any documentation. Enabling it disables the recursion guard and the dotted-key depth check — a real DoS mitigation for code that parses untrusted TOML — yet no doc comment, no # Crate features section in lib.rs, and no README note flags the trade-off. The default behaviour is safe.
No malicious behaviour was identified, justifying is-benign.
Conclusion
toml_edit is a mature TOML parser/editor with no unsafe code, no I/O, no concurrency, and a focused dependency set anchored in the same upstream workspace (toml_parser, toml_writer, toml_datetime, serde_spanned). The parsing path properly delegates byte-level lexing and escape handling to toml_parser, surfaces overflow errors to the caller, and bounds recursion depth by default. The test suite combines unit tests, integration tests, the language-neutral toml-test conformance suite, proptests, and an upstream libfuzzer target. The one finding is a documentation gap on a security-relevant feature flag.