cargo-audit-0.22.2/.cargo_vcs_info.json0000644000000001511046102023000133350ustar { "git": { "sha1": "281452c35cf0870969042374110f099a411bc185" }, "path_in_vcs": "cargo-audit" }cargo-audit-0.22.2/CHANGELOG.md000064400000000000000000000420701046102023000137220ustar 00000000000000# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## 0.21.2 (2025-02-28) ### Fixed - Upgraded to `rustsec` v0.30.2 to fix an incompatibility with Rust v1.85 and later ([#1333]) [#1333]: https://github.com/RustSec/rustsec/pull/1333 ## 0.21.1 (2025-01-18) ### Fixed - Upgraded `cargo-lock` to fix an issue with Cargo.lock v4 format parsing in presence of git tags ([#1298]) - Fix handling of the `database.fetch` configuration option ([#1302]) [#1298]: https://github.com/RustSec/rustsec/pull/1298 [#1302]: https://github.com/RustSec/rustsec/pull/1302 ## 0.21.0 (2024-10-29) ### Added - V4 lockfile support ([#1275]) - `cargo audit bin` can now audit WebAssembly ([#1182]) - `cargo audit` now honors the `CARGO_TERM_COLOR` environment variable ([#1207]) - Allow specifying multiple `--target-os` and `--target-arch` flags ([#1185]) ### Changed - Bump `auditable-info` => 0.8; `auditable-serde` => v0.7 ([#1229]) - Bump `abscissa` to v0.8 ([#1262]) - Bump `rustsec` to v0.30; adds V4 lockfile support ([#1275]) [#1182]: https://github.com/rustsec/rustsec/pull/1182 [#1185]: https://github.com/rustsec/rustsec/pull/1185 [#1207]: https://github.com/rustsec/rustsec/pull/1207 [#1229]: https://github.com/rustsec/rustsec/pull/1229 [#1262]: https://github.com/rustsec/rustsec/pull/1262 [#1275]: https://github.com/rustsec/rustsec/pull/1275 ## 0.20.1 (2024-08-16) ### Fixed - Fix build for `cargo install --locked` by bumping `time` crate in `Cargo.lock` to work around a [breaking change in rustc](https://github.com/rust-lang/rust/issues/127343). ## 0.20.0 (2024-02-16) ### Changed - Completely rewritten `cargo audit fix` subcommand ([#1113]) - Now it edits `Cargo.lock` as opposed to `Cargo.toml`, and performs only semver-compatible upgrades. - Fixes are performed by calling `cargo update`, migrating away from the unmaintained `cargo-edit-9` crate. - The subcommand is still experimental, and its behavior may change in the future. It still requires enabling the non-default `fix` feature. - Require `tame-index` 0.9.3 or later, fixing [issues with some enterprise firewalls](https://github.com/rustsec/rustsec/issues/1058). ([#1103]) [#1103]: https://github.com/rustsec/rustsec/pull/1103 [#1113]: https://github.com/rustsec/rustsec/pull/1113 ## 0.19.0 (2024-02-03) ### Fixed - Fix `--color=auto` always printing terminal escape sequences ([#1057]) ### Changed - Display the chain of errors instead of just the top-level error for more complete error reporting ([#1063]) - Upgrade to clap 4.x and abscissa-core 0.7.x. This may have introduced minor changes to the command-line interface. This is the reason for the minor version bump. ([#1092]) [#1057]: https://github.com/rustsec/rustsec/pull/1057 [#1063]: https://github.com/rustsec/rustsec/pull/1063 [#1092]: https://github.com/rustsec/rustsec/pull/1092 ## 0.18.3 (2023-10-24) ### Fixed - Fix a deadlock when the `Cargo.lock` file is missing. It only occurs with `rustsec` v0.28.3 or later. ([#1051]) [#1051]: https://github.com/rustsec/rustsec/pull/1051 ## 0.18.2 (2023-09-25) ### Fixed - Fix [RUSTSEC-2023-0064](https://rustsec.org/advisories/RUSTSEC-2023-0064.html) security issue by requiring `rustsec` 0.28.2 or higher. [#980]: https://github.com/rustsec/rustsec/pull/980 ## 0.18.1 (2023-08-31) ### Fixed - Release workflow: don't enable `fix` and `vendored-openssl` features ([#980]) [#980]: https://github.com/rustsec/rustsec/pull/980 ## 0.18.0 (2023-08-31) ### Added - Implement proper attribution for advisories licensed under CC-BY ([#955]) - `cargo audit bin` no longer shows warnings not applicable to the binary type (e.g. no more reports of Windows-only unsoundness in ELF binaries). Previously this was implemented for vulnerabilities, but not warnings. ([#964]) ### Changed - Upgraded to `rustsec` v0.28, bringing performance, security and compatibility improvements, but also temporarily dropping support for CPU platforms other than x86 and ARM. See the [rustsec changelog](https://github.com/rustsec/rustsec/blob/main/rustsec/CHANGELOG.md) for details. [#955]: https://github.com/rustsec/rustsec/pull/955 [#964]: https://github.com/rustsec/rustsec/pull/964 ## 0.17.6 (2023-05-10) ### Added - Upgraded to `cargo-lock` v9.0.0, which enables support for sparse registries. - When scanning binary files, the binary's platform is taken into account. This prevents scenarios such as Windows-only vulnerabilities being reported on Linux binaries ([#814]) ### Fixed - Advisories about `cargo audit` itself are no longer printed multiple times when scanning multiple files ([#848]) [#848]: https://github.com/rustsec/rustsec/pull/848 ## 0.17.5 (2023-03-23) ### Added - Vulnerability severity is now included in the `cargo audit` output, if known ([#825]) ### Changed - Advisories marked `informational = unsound` are now reported by default, but only as warnings ([#819]). They do not cause the audit to fail, i.e. the exit code of the process is still 0. This behavior can be suppressed through the configuration file. ### Fixed - The help text now correctly refers to the command as `cargo audit` instead of `cargo audit audit` ([#824]) - The `--version` argument now works correctly, reporting the current version ([#838]) [#819]: https://github.com/rustsec/rustsec/pull/819 [#824]: https://github.com/rustsec/rustsec/pull/824 [#825]: https://github.com/rustsec/rustsec/pull/825 [#838]: https://github.com/rustsec/rustsec/pull/838 ## 0.17.4 (2022-11-08) ### Fixed - Checks for yanked crates were broken since 0.17.0. This release restores them and adds tests to prevent future regressions. ### Changed - Binary scanning is enabled by default and documented as such. It can still be disabled by disabling the `binary-scanning` feature. ## 0.17.3 (2022-11-01) ### Added - `cargo audit bin` now attempts to detect dependencies in binaries not built with [`cargo auditable`](https://github.com/rust-secure-code/cargo-auditable) by parsing the panic messages ([#729]). This only detects about a half of the dependency list and never detects C code such as OpenSSL, but works on any Rust binaries built with `cargo`. - Added integration tests for the `--deny=warnings` flag. ### Fixed - `cargo audit bin --deny=warnings` no longer exits after finding the first binary with warnings. ### Changed - Up to 5x faster `cargo audit bin` when scanning multiple files thanks to caching crates.io index lookups (implemented in `rustsec` crate). - Notices about `cargo audit` or `rustsec` will now result in a scanning error being reported (exit code 2) as opposed to reporting them as vulnerabilities in the scanned binary (exit code 1). They are treated as warnings by default, so `--deny=warnings` is required to observe the new behavior. - The `binary-scanning` feature that adds the `cargo audit bin` subcommand is now enabled by default, but is not documented as such. [#729]: https://github.com/rustsec/rustsec/pull/729 ## 0.17.2 (2022-10-07) ### Changed - Fixed the screenshot URL in README.md ## 0.17.1 (2022-10-07) ### Added - Initial support for scanning binaries built with [`cargo auditable`](https://github.com/rust-secure-code/cargo-auditable) ## 0.17.0 (2022-05-23) ### Changed - Update Abscissa to 0.6; replace `gumdrop` with `clap` v3 ([#525]) - 2021 edition upgrade ([#539]) - MSRV 1.57 ([#539], [#574]) - Bump `rustsec` to v0.26 ([#574]) ### Fixed - Terminal output fixups ([#570]) ### Removed - Unused `lazy_static` from dependencies ([#500]) - Deprecated `--deny-warnings` CLI option ([#545]) [#500]: https://github.com/rustsec/rustsec/pull/500 [#525]: https://github.com/rustsec/rustsec/pull/525 [#539]: https://github.com/rustsec/rustsec/pull/539 [#545]: https://github.com/rustsec/rustsec/pull/54qgq5 [#570]: https://github.com/rustsec/rustsec/pull/570 [#574]: https://github.com/rustsec/rustsec/pull/574 ## 0.16.0 (2021-11-15) ### Changed - Bump `rustsec` dependency to v0.25; MSRV 1.52 ([#480]) ### Fixed - Parse `--color=auto` correctly ([#436]) [#436]: https://github.com/rustsec/rustsec/pull/436 [#480]: https://github.com/rustsec/rustsec/pull/480 ## 0.15.2 (2021-09-11) ### Added - `vendored-libgit2` feature ([#432]) [#432]: https://github.com/rustsec/rustsec/pull/432 ## 0.15.1 (2021-09-10) ### Changed - Pin `thiserror` and `zeroize` to avoid MSRV breakages ([#415]) [#415]: https://github.com/rustsec/rustsec/pull/415 ## 0.15.0 (2021-07-01) ### Added - New exit status (`2`) for Cargo.lock parsing errors ([#368]) ### Changed - Bump `rustsec` crate dependency to v0.24 ([#388]) [#368]: https://github.com/RustSec/cargo-audit/pull/368 [#388]: https://github.com/RustSec/cargo-audit/pull/388 ## 0.14.1 (2021-04-29) ### Added - Generate release builds with github actions ([#337]) ### Changed - Bump rustsec from 0.23.2 to 0.23.3 ([#333]) [#333]: https://github.com/RustSec/cargo-audit/pull/333 [#337]: https://github.com/RustSec/cargo-audit/pull/337 ## 0.14.0 (2021-03-07) ### Changed - When running in no-fetch mode, allow accessing a non-git repo ([#315]) - Enable informational warnings with deny ([#320]) - Bump `rustsec` dependency to v0.23 ([#327]) - MSRV 1.46+ ([#327]) [#315]: https://github.com/RustSec/cargo-audit/pull/315 [#320]: https://github.com/RustSec/cargo-audit/pull/320 [#327]: https://github.com/RustSec/cargo-audit/pull/327 ## 0.13.1 (2020-10-27) ### Changed - Split `-D`/`--deny` and `--deny-warnings` ([#278]) - Bump `rustsec` crate to v0.22.2 ([#277]) ### Fixed - JSON serialization ([#277]) [#278]: https://github.com/RustSec/cargo-audit/pull/278 [#a277]: https://github.com/RustSec/cargo-audit/pull/277 ## 0.13.0 (2020-10-26) [YANKED] ### Added - Support for project specific config directories ([#252]) ### Changed - Bump `rustsec` crate to v0.22; MSRV 1.41+ ([#271]) - JSON report format changes ([#271]) - Presenter improvements ([#268]) - Make warning types an argument ([#206]) ### Fixed - `fix --dry-run` no longer requires argument ([#231]) [#271]: https://github.com/RustSec/cargo-audit/pull/258 [#268]: https://github.com/RustSec/cargo-audit/pull/268 [#255]: https://github.com/RustSec/cargo-audit/pull/255 [#252]: https://github.com/RustSec/cargo-audit/pull/252 [#231]: https://github.com/RustSec/cargo-audit/pull/231 [#206]: https://github.com/RustSec/cargo-audit/pull/206 ## 0.12.1 (2020-09-22) - Pin `smol_str` to v0.1.16 to ensure MSRV 1.41 compatibility ([#255], [#258]) [#258]: https://github.com/RustSec/cargo-audit/pull/258 [#255]: https://github.com/RustSec/cargo-audit/pull/255 ## 0.12.0 (2020-05-06) - Update `rustsec` crate to v0.20 ([#221]) - Regenerate lockfile after `cargo audit fix` ([#219]) - Update dependencies; MSRV 1.40+ ([#216]) [#221]: https://github.com/RustSec/cargo-audit/pull/221 [#219]: https://github.com/RustSec/cargo-audit/pull/219 [#216]: https://github.com/RustSec/cargo-audit/pull/216 ## 0.11.2 (2020-02-07) - Improve yanked crate auditing messages and config ([#200]) - Fix `-c`/`--color` command line argument ([#199]) [#200]: https://github.com/RustSec/cargo-audit/pull/200 [#199]: https://github.com/RustSec/cargo-audit/pull/199 ## 0.11.1 (2020-01-24) - Add `vendored-openssl` feature ([#193]) [#193]: https://github.com/RustSec/cargo-audit/pull/193 ## 0.11.0 (2020-01-22) - Update `rustsec` crate to v0.17 release; MSRV 1.39+ ([#186], [#188]) - Warn for yanked crates ([#180]) - Respect sources of dependencies when auditing ([#175]) - Upgrade to `abscissa` v0.5 ([#174]) - `cargo audit fix` subcommand ([#157], [#166], [#181]) [#188]: https://github.com/RustSec/cargo-audit/pull/188 [#186]: https://github.com/RustSec/cargo-audit/pull/186 [#181]: https://github.com/RustSec/cargo-audit/pull/181 [#180]: https://github.com/RustSec/cargo-audit/pull/180 [#175]: https://github.com/RustSec/cargo-audit/pull/175 [#174]: https://github.com/RustSec/cargo-audit/pull/174 [#166]: https://github.com/RustSec/cargo-audit/pull/166 [#157]: https://github.com/RustSec/cargo-audit/pull/157 ## 0.10.0 (2019-10-13) - Upgrade `rustsec` to v0.16; new self-audit system ([#155]) - Upgrade to Abscissa v0.4; MSRV 1.36 ([#154]) [#155]: https://github.com/RustSec/cargo-audit/pull/155 [#154]: https://github.com/RustSec/cargo-audit/pull/154 ## 0.9.3 (2019-10-08) - Update to `rustsec` crate v0.15.2 ([#149]) - presenter: Cleanups for informational advisories ([#148]) - presenter: Print better message when no solution is available ([#144]) [#149]: https://github.com/RustSec/cargo-audit/pull/149 [#148]: https://github.com/RustSec/cargo-audit/pull/148 [#144]: https://github.com/RustSec/cargo-audit/pull/144 ## 0.9.2 (2019-10-01) - Update to `rustsec` crate v0.15 ([#138]) [#138]: https://github.com/RustSec/cargo-audit/pull/138 ## 0.9.1 (2019-09-25) - Update to `rustsec` crate v0.14.1 ([#134]) [#134]: https://github.com/RustSec/cargo-audit/pull/134 ## 0.9.0 (2019-09-25) - Add `--deny-warnings` option ([#128]) - Upgrade to `rustsec` crate v0.14 ([#126]) - Configuration file: `~/.cargo/audit.toml` ([#123], [#125]) - Fix `--help` ([#113]) - Warn for outdated `rustsec` crate versions ([#112]) - Display warnings for select informational advisories ([#110]) - Display dependency trees with each advisory ([#109]) [#128]: https://github.com/RustSec/cargo-audit/pull/128 [#126]: https://github.com/RustSec/cargo-audit/pull/126 [#125]: https://github.com/RustSec/cargo-audit/pull/125 [#123]: https://github.com/RustSec/cargo-audit/pull/123 [#113]: https://github.com/RustSec/cargo-audit/pull/113 [#112]: https://github.com/RustSec/cargo-audit/pull/112 [#110]: https://github.com/RustSec/cargo-audit/pull/110 [#109]: https://github.com/RustSec/cargo-audit/pull/109 ## 0.8.1 (2019-08-25) - Fix `--version` ([#101]) [#101]: https://github.com/RustSec/cargo-audit/pull/101 ## 0.8.0 (2019-08-16) - Use the Abscissa application framework ([#85], [#87], [#92], [#94]) - Implement `--no-fetch` ([#97]) - Add support for reading lockfiles from STDIN ([#98]) [#98]: https://github.com/RustSec/cargo-audit/pull/98 [#97]: https://github.com/RustSec/cargo-audit/pull/97 [#94]: https://github.com/RustSec/cargo-audit/pull/94 [#92]: https://github.com/RustSec/cargo-audit/pull/92 [#87]: https://github.com/RustSec/cargo-audit/pull/87 [#85]: https://github.com/RustSec/cargo-audit/pull/85 ## 0.7.0 (2019-07-15) - Switch from `term` to `termcolor` crate ([#83]) - Update `gumdrop` to v0.6, `rustsec` crate to v0.12; min Rust 1.32+ ([#82]) - Produce valid JSON when no vulnerabilities are detected ([#77]) - Implement `--ignore` option ([#75]) [#83]: https://github.com/RustSec/cargo-audit/pull/83 [#82]: https://github.com/RustSec/cargo-audit/pull/82 [#77]: https://github.com/RustSec/cargo-audit/pull/77 [#75]: https://github.com/RustSec/cargo-audit/pull/75 ## 0.6.1 (2018-12-16) - Fix option parsing ([#64]) [#64]: https://github.com/RustSec/cargo-audit/pull/64 ## 0.6.0 (2018-12-15) - Update to Rust 2018 edition ([#61]) - Update to `rustsec` crate v0.10 ([#59]) - Prevent `--help` from exiting with error ([#57]) - Add `--json` flag for JSON output ([#41]) [#61]: https://github.com/RustSec/cargo-audit/pull/61 [#59]: https://github.com/RustSec/cargo-audit/pull/59 [#57]: https://github.com/RustSec/cargo-audit/pull/57 [#41]: https://github.com/RustSec/cargo-audit/pull/41 ## 0.5.2 (2018-07-29) - Have `cargo audit version` exit with status `0` ([#38]) [#38]: https://github.com/RustSec/cargo-audit/pull/38 ## 0.5.1 (2018-07-29) - Refactoring and UI improvements ([#37]) [#37]: https://github.com/RustSec/cargo-audit/pull/37 ## 0.5.0 (2018-07-29) - Upgrade `rustsec` crate to 0.9 ([#36]) [#36]: https://github.com/RustSec/cargo-audit/pull/36 ## 0.4.0 (2018-07-24) - Honor the `affected_platforms` attribute ([#35]) - Update `rustsec` crate dependency to `0.8` series ([#34]) - Update `term` crate dependency to `0.5` series ([#31]) [#35]: https://github.com/RustSec/cargo-audit/pull/35 [#34]: https://github.com/RustSec/cargo-audit/pull/34 [#31]: https://github.com/RustSec/cargo-audit/pull/31 ## 0.3.2 (2018-07-23) - README.md: Use `` tag for screenshot so it renders on crates.io ([#28]) [#28]: https://github.com/RustSec/cargo-audit/pull/28 ## 0.3.1 (2018-07-23) - Use ` OR ` delimiter to display patched versions ([#25]) - Fix `cargo audit --version` ([#24]) [#25]: https://github.com/RustSec/cargo-audit/pull/25 [#24]: https://github.com/RustSec/cargo-audit/pull/24 ## 0.3.0 (2018-07-23) - Near rewrite of cargo-audit using `rustsec` 0.7.0 ([#22]) [#22]: https://github.com/RustSec/cargo-audit/pull/22 ## 0.2.1 (2017-09-24) - Use crate isatty to resolve Windows build errors ([#14]) [#14]: https://github.com/RustSec/cargo-audit/pull/14 ## 0.2.0 (2017-03-05) - Upgrade to rustsec 0.6.0 crate ([#12]) - Configurable colors ([#10]) - Avoid panicking if there are no dependencies ([#8]) - Handle error and instruct the user to generate a lockfile before audit ([#6]) [#12]: https://github.com/RustSec/cargo-audit/pull/12 [#10]: https://github.com/RustSec/cargo-audit/pull/10 [#8]: https://github.com/RustSec/cargo-audit/pull/8 [#6]: https://github.com/RustSec/cargo-audit/pull/6 ## 0.1.1 (2017-02-27) - Make cargo-audit a proper cargo subcommand ([#2]) [#2]: https://github.com/RustSec/cargo-audit/pull/2 ## 0.1.0 (2017-02-27) - Initial release cargo-audit-0.22.2/Cargo.lock0000644000003036201046102023000113170ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 4 [[package]] name = "abscissa_core" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cd87587023faadfc7f6e93b1ad45074b72f1f6d22c1e0f19333a952446ab1c1" dependencies = [ "abscissa_derive", "arc-swap", "backtrace", "canonical-path", "clap", "color-eyre", "fs-err", "once_cell", "regex", "secrecy", "semver", "serde", "termcolor", "toml 0.9.12+spec-1.1.0", "tracing", "tracing-log", "tracing-subscriber", "wait-timeout", ] [[package]] name = "abscissa_derive" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3da54f552dccbdec19736d713720dd88af932a82eb02ca0f22410de5d31ad726" dependencies = [ "ident_case", "proc-macro2", "quote", "syn", "synstructure", ] [[package]] name = "addr2line" version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" dependencies = [ "gimli", ] [[package]] name = "adler2" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aho-corasick" version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] [[package]] name = "allocator-api2" version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "anstream" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anstyle-parse" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ "windows-sys 0.61.2", ] [[package]] name = "anstyle-wincon" version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", "windows-sys 0.61.2", ] [[package]] name = "anyhow" version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "arc-swap" version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207" dependencies = [ "rustversion", ] [[package]] name = "arrayvec" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "async-compression" version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e79b3f8a79cccc2898f31920fc69f304859b3bd567490f75ebf51ae1c792a9ac" dependencies = [ "compression-codecs", "compression-core", "pin-project-lite", "tokio", ] [[package]] name = "atomic-waker" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "auditable-extract" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44371e9f9759dea49c42b6c6fe4c64ea216ee2af325a4524a7180823e00d3e7a" dependencies = [ "binfarce", "wasmparser 0.207.0", ] [[package]] name = "auditable-info" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c692b37b578433ebc75db30941a7ff137c381a204beb2429a30b7587d4d4dff3" dependencies = [ "auditable-extract", "auditable-serde", "miniz_oxide", "serde_json", ] [[package]] name = "auditable-serde" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d026218ae25ba5c72834245412dd1338f6d270d2c5109ee03a4badec288d4056" dependencies = [ "semver", "serde", "serde_json", "topological-sort", ] [[package]] name = "autocfg" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-lc-rs" version = "1.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ec6fb3fe69024a75fa7e1bfb48aa6cf59706a101658ea01bfd33b2b248a038f" dependencies = [ "aws-lc-sys", "zeroize", ] [[package]] name = "aws-lc-sys" version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f50037ee5e1e41e7b8f9d161680a725bd1626cb6f8c7e901f91f942850852fe7" dependencies = [ "cc", "cmake", "dunce", "fs_extra", ] [[package]] name = "backtrace" version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" dependencies = [ "addr2line", "cfg-if", "libc", "miniz_oxide", "object 0.37.3", "rustc-demangle", "windows-link", ] [[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "binfarce" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18464ccbb85e5dede30d70cc7676dc9950a0fb7dbf595a43d765be9123c616a2" [[package]] name = "bitflags" version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" [[package]] name = "block-buffer" version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] [[package]] name = "borsh" version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfd1e3f8955a5d7de9fab72fc8373fade9fb8a703968cb200ae3dc6cf08e185a" dependencies = [ "bytes", "cfg_aliases", ] [[package]] name = "bstr" version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" dependencies = [ "memchr", "regex-automata", "serde", ] [[package]] name = "bumpalo" version = "3.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" [[package]] name = "byteorder" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "camino" version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" [[package]] name = "canonical-path" version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e9e01327e6c86e92ec72b1c798d4a94810f147209bbe3ffab6a86954937a6f" [[package]] name = "cargo-audit" version = "0.22.2" dependencies = [ "abscissa_core", "cargo-lock", "clap", "display-error-chain", "home", "object 0.39.1", "once_cell", "rustc-demangle", "rustsec", "serde", "serde_json", "syn", "tempfile", "thiserror", "toml 1.1.2+spec-1.1.0", ] [[package]] name = "cargo-lock" version = "11.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63585cdf8572aa7adf0e30a253f988f2b77233bfac1973d52efb6dd53a75920e" dependencies = [ "petgraph", "semver", "serde", "toml 0.9.12+spec-1.1.0", "url", ] [[package]] name = "cc" version = "1.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" dependencies = [ "find-msvc-tools", "jobserver", "libc", "shlex", ] [[package]] name = "cfg-if" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "clap" version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" dependencies = [ "clap_builder", "clap_derive", ] [[package]] name = "clap_builder" version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" dependencies = [ "anstream", "anstyle", "clap_lex", "strsim", ] [[package]] name = "clap_derive" version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" dependencies = [ "heck", "proc-macro2", "quote", "syn", ] [[package]] name = "clap_lex" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "clru" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "197fd99cb113a8d5d9b6376f3aa817f32c1078f2343b714fff7d2ca44fdf67d5" dependencies = [ "hashbrown 0.16.1", ] [[package]] name = "cmake" version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" dependencies = [ "cc", ] [[package]] name = "color-eyre" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5920befb47832a6d61ee3a3a846565cfa39b331331e68a3b1d1116630f2f26d" dependencies = [ "backtrace", "eyre", "indenter", "once_cell", "owo-colors", ] [[package]] name = "colorchoice" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "combine" version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" dependencies = [ "bytes", "memchr", ] [[package]] name = "compression-codecs" version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce2548391e9c1929c21bf6aa2680af86fe4c1b33e6cea9ac1cfeec0bd11218cf" dependencies = [ "compression-core", "flate2", "memchr", ] [[package]] name = "compression-core" version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc14f565cf027a105f7a44ccf9e5b424348421a1d8952a8fc9d499d313107789" [[package]] name = "core-foundation" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" dependencies = [ "core-foundation-sys", "libc", ] [[package]] name = "core-foundation-sys" version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] [[package]] name = "crc32fast" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-channel" version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-deque" version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crypto-common" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", "typenum", ] [[package]] name = "cvss" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fb220d3ce1b565af39cee5b89e47fd8dd1dab162900ee4363c8ee4169ee8a2" dependencies = [ "serde", ] [[package]] name = "deranged" version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" dependencies = [ "powerfmt", "serde_core", ] [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", "crypto-common", ] [[package]] name = "display-error-chain" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bc2146e86bc19f52f4c064a64782f05f139ca464ed72937301631e73f8d6cf5" [[package]] name = "displaydoc" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "dunce" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "either" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "encoding_rs" version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if", ] [[package]] name = "equivalent" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", "windows-sys 0.61.2", ] [[package]] name = "eyre" version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" dependencies = [ "indenter", "once_cell", ] [[package]] name = "faster-hex" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7223ae2d2f179b803433d9c830478527e92b8117eab39460edae7f1614d9fb73" dependencies = [ "heapless", "serde", ] [[package]] name = "fastrand" version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "filetime" version = "0.2.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d5b2eef6fafbf69f877e55509ce5b11a760690ac9700a2921be067aa6afaef6" dependencies = [ "cfg-if", "libc", ] [[package]] name = "find-msvc-tools" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "fixedbitset" version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" [[package]] name = "flate2" version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" dependencies = [ "crc32fast", "miniz_oxide", ] [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "foldhash" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "form_urlencoded" version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] [[package]] name = "fs-err" version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73fde052dbfc920003cfd2c8e2c6e6d4cc7c1091538c3a24226cec0665ab08c0" dependencies = [ "autocfg", ] [[package]] name = "fs_extra" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" [[package]] name = "futures-channel" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" dependencies = [ "futures-core", "futures-sink", ] [[package]] name = "futures-core" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" [[package]] name = "futures-io" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" [[package]] name = "futures-sink" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" [[package]] name = "futures-task" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-util" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-core", "futures-io", "futures-sink", "futures-task", "memchr", "pin-project-lite", "slab", ] [[package]] name = "generic-array" version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", ] [[package]] name = "getrandom" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", "js-sys", "libc", "wasi", "wasm-bindgen", ] [[package]] name = "getrandom" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "js-sys", "libc", "r-efi 5.3.0", "wasip2", "wasm-bindgen", ] [[package]] name = "getrandom" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" dependencies = [ "cfg-if", "libc", "r-efi 6.0.0", "wasip2", "wasip3", ] [[package]] name = "gimli" version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" [[package]] name = "gix" version = "0.84.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae54ae0ebd1a5a3c3f8d95dd3b5ca6e63f4fed9bfd585e13801a97d7bde8f9ce" dependencies = [ "gix-actor", "gix-attributes", "gix-command", "gix-commitgraph", "gix-config", "gix-credentials", "gix-date", "gix-diff", "gix-discover", "gix-error", "gix-features", "gix-filter", "gix-fs", "gix-glob", "gix-hash", "gix-hashtable", "gix-ignore", "gix-index", "gix-lock", "gix-negotiate", "gix-object", "gix-odb", "gix-pack", "gix-path", "gix-pathspec", "gix-prompt", "gix-protocol", "gix-ref", "gix-refspec", "gix-revision", "gix-revwalk", "gix-sec", "gix-shallow", "gix-submodule", "gix-tempfile", "gix-trace", "gix-transport", "gix-traverse", "gix-url", "gix-utils", "gix-validate", "gix-worktree", "gix-worktree-state", "gix-worktree-stream", "nonempty", "smallvec", "thiserror", ] [[package]] name = "gix-actor" version = "0.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8bc998b8f746dda8565450d08a63b792ced9165d8c27a1ed3f02799ec6a7820f" dependencies = [ "bstr", "gix-date", "gix-error", ] [[package]] name = "gix-attributes" version = "0.33.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d43f12e246d3bf7ec624c8fc15ac4a4b62b7c4c6f586cb82be6c90bf84c9d02" dependencies = [ "bstr", "gix-glob", "gix-path", "gix-quote", "gix-trace", "kstring", "smallvec", "thiserror", "unicode-bom", ] [[package]] name = "gix-bitmap" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52ebef0c26ad305747649e727bbcd56a7b7910754eb7cea88f6dff6f93c51283" dependencies = [ "gix-error", ] [[package]] name = "gix-chunk" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9faee47943b638e58ddd5e275a4906ad3e4b6c8584f1d41bd18ab9032ec52afb" dependencies = [ "gix-error", ] [[package]] name = "gix-command" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00706d4fef135ef4b01680d5218c6ee40cda8baf697b864296cbc887d19118f6" dependencies = [ "bstr", "gix-path", "gix-quote", "gix-trace", "shell-words", ] [[package]] name = "gix-commitgraph" version = "0.37.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f675d0df484a7f6a47e64bd6f311af489d947c0323b0564f36d14f3d7762abb" dependencies = [ "bstr", "gix-chunk", "gix-error", "gix-hash", "memmap2", "nonempty", ] [[package]] name = "gix-config" version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f2372d4b49ca28431e7d150cab9d25edc1890f0184bd57eb0e917c7799e63de" dependencies = [ "bstr", "gix-config-value", "gix-features", "gix-glob", "gix-path", "gix-ref", "gix-sec", "smallvec", "thiserror", "unicode-bom", ] [[package]] name = "gix-config-value" version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed42168329552f6c2e5df09665c104199d45d84bedb53683738a49b57fe1baab" dependencies = [ "bitflags", "bstr", "gix-path", "libc", "thiserror", ] [[package]] name = "gix-credentials" version = "0.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f40cd22f0dd71988be12d6e78b1709de2370e1957c5f107ff31e56caeba3745d" dependencies = [ "bstr", "gix-command", "gix-config-value", "gix-date", "gix-path", "gix-prompt", "gix-sec", "gix-trace", "gix-url", "thiserror", ] [[package]] name = "gix-date" version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3ecab64a98bbac9f8e02990a9ea5e3c974a7d49b95f2bd70ad94ad22fa6b48c" dependencies = [ "bstr", "gix-error", "itoa", "jiff", ] [[package]] name = "gix-diff" version = "0.64.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b6d9528f32d94cef2edf39a1ac01fe5a0fc44ddbb18d9e44099936047c3302b" dependencies = [ "bstr", "gix-hash", "gix-object", "thiserror", ] [[package]] name = "gix-discover" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77bacdd12b7879d2178a80c58c2f319995e4654e1a7a23e3181e5c8a12b824f7" dependencies = [ "bstr", "dunce", "gix-fs", "gix-path", "gix-ref", "gix-sec", "thiserror", ] [[package]] name = "gix-error" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e57831e199be480af90dcd7e459abed8a174c09ec9a6e2cc8f7ca6c54598b06b" dependencies = [ "bstr", ] [[package]] name = "gix-features" version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1849ae154d38bc403185be14fa871e38e3c93ee606875d94e207fdb9fba52dbc" dependencies = [ "bytes", "crc32fast", "crossbeam-channel", "gix-path", "gix-trace", "gix-utils", "libc", "once_cell", "parking_lot", "prodash", "thiserror", "walkdir", "zlib-rs", ] [[package]] name = "gix-filter" version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ecf74b7d16f6694ce4a3049074c41be0c7987105743674f1671807bd6dce09fa" dependencies = [ "bstr", "encoding_rs", "gix-attributes", "gix-command", "gix-hash", "gix-object", "gix-packetline", "gix-path", "gix-quote", "gix-trace", "gix-utils", "smallvec", "thiserror", ] [[package]] name = "gix-fs" version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6cdff46db8798e47e2f727d84b9379aac5add3dd3d9d0b07bb4d7d5d640771fe" dependencies = [ "bstr", "fastrand", "gix-features", "gix-path", "gix-utils", "thiserror", ] [[package]] name = "gix-glob" version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1fcb8ef5b16bcf874abe9b68d8abb3c0493c876d367ab824151f30a0f3f3756" dependencies = [ "bitflags", "bstr", "gix-features", "gix-path", ] [[package]] name = "gix-hash" version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0926d3819c837750b4e03c7754901e73f68b8c9b690753a6372a1bed4eedce" dependencies = [ "faster-hex", "gix-features", "sha1-checked", "thiserror", ] [[package]] name = "gix-hashtable" version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0e30b93eea8718baf7d8153fcb938e2926175bbf18097c09f1c01b6f0be0563" dependencies = [ "gix-hash", "hashbrown 0.17.1", "parking_lot", ] [[package]] name = "gix-ignore" version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d491bab9bf2c9f341dc754f425c31d5d3f63aca615312167b82e1deeaca97d8d" dependencies = [ "bstr", "gix-glob", "gix-path", "gix-trace", "unicode-bom", ] [[package]] name = "gix-index" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e6b28cc592dc753adb58302bb14a64e412ee591a3bec77aa4df87bff74fa80d" dependencies = [ "bitflags", "bstr", "filetime", "fnv", "gix-bitmap", "gix-features", "gix-fs", "gix-hash", "gix-lock", "gix-object", "gix-traverse", "gix-utils", "gix-validate", "hashbrown 0.17.1", "itoa", "libc", "memmap2", "rustix", "smallvec", "thiserror", ] [[package]] name = "gix-lock" version = "23.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09b3bc074e5723027b482dcd9ab99d95804a53742f6de812d0172fbba4a186c1" dependencies = [ "gix-tempfile", "gix-utils", "thiserror", ] [[package]] name = "gix-negotiate" version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "890c936a215bae25818c076cb881cb2e54d2c66ba947ba58b8dd47cff921bf55" dependencies = [ "bitflags", "gix-commitgraph", "gix-date", "gix-hash", "gix-object", "gix-revwalk", ] [[package]] name = "gix-object" version = "0.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5cd857e29429c7213bdef3f5aef83f8cc124774fe8ae0d27b1607d218d6d525" dependencies = [ "bstr", "gix-actor", "gix-date", "gix-features", "gix-hash", "gix-hashtable", "gix-utils", "gix-validate", "itoa", "smallvec", "thiserror", ] [[package]] name = "gix-odb" version = "0.81.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d004c32858b1556f2d7874405edb3c97dc78fc09beaa87d57bb077ee2858a7d" dependencies = [ "arc-swap", "gix-features", "gix-fs", "gix-hash", "gix-hashtable", "gix-object", "gix-pack", "gix-path", "gix-quote", "memmap2", "parking_lot", "tempfile", "thiserror", ] [[package]] name = "gix-pack" version = "0.71.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e43626f2a27d1033674ec1a196b845614231e6bbd949d5e21c133045ff56b174" dependencies = [ "clru", "gix-chunk", "gix-error", "gix-features", "gix-hash", "gix-hashtable", "gix-object", "gix-path", "gix-tempfile", "memmap2", "parking_lot", "smallvec", "thiserror", "uluru", ] [[package]] name = "gix-packetline" version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb18337ba2830bb43367d1af43819c8c78f31337f079fc76d0f1f1750a173126" dependencies = [ "bstr", "faster-hex", "gix-trace", "thiserror", ] [[package]] name = "gix-path" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afa6ac14cd14939ea94a496ce7460daa6511c09f5b84757e9cfc6f9c8d0f93a6" dependencies = [ "bstr", "gix-trace", "gix-validate", "thiserror", ] [[package]] name = "gix-pathspec" version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3050783b41ee11511e1e8fb35623df81806194f4030395f14f48ea37c2798c9f" dependencies = [ "bitflags", "bstr", "gix-attributes", "gix-config-value", "gix-glob", "gix-path", "thiserror", ] [[package]] name = "gix-prompt" version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ee604d7746080ae7e1023bf47204bcc2c5f307bfbe2306a3c90b1bfd1a2c6d8" dependencies = [ "gix-command", "gix-config-value", "parking_lot", "rustix", "thiserror", ] [[package]] name = "gix-protocol" version = "0.62.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51dea3acb390707ab868f1f9584f18449eb95d869deffae96768e47d303595ee" dependencies = [ "bstr", "gix-credentials", "gix-date", "gix-features", "gix-hash", "gix-lock", "gix-negotiate", "gix-object", "gix-ref", "gix-refspec", "gix-revwalk", "gix-shallow", "gix-trace", "gix-transport", "gix-utils", "maybe-async", "nonempty", "thiserror", ] [[package]] name = "gix-quote" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6e541fc33cc2b783b7979040d445a0c86a2eca747c8faea4ca84230d06ae6ef" dependencies = [ "bstr", "gix-error", "gix-utils", ] [[package]] name = "gix-ref" version = "0.64.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c04f64c37eb7e6feb73c7060f8dc6f381cc5de5d53249bfd450bc48a86b2e8b" dependencies = [ "gix-actor", "gix-features", "gix-fs", "gix-hash", "gix-lock", "gix-object", "gix-path", "gix-tempfile", "gix-utils", "gix-validate", "memmap2", "thiserror", ] [[package]] name = "gix-refspec" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b216ae06ec74b5f24ad0142026a997fb0a935b7410eaf9c1616fc3f0e6c5a6d3" dependencies = [ "bstr", "gix-error", "gix-glob", "gix-hash", "gix-revision", "gix-validate", "smallvec", "thiserror", ] [[package]] name = "gix-revision" version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b47c88884dd3c1a19a39da19d10211fcdea2809aadc86869b6e824a1774340f" dependencies = [ "bitflags", "bstr", "gix-commitgraph", "gix-date", "gix-error", "gix-hash", "gix-hashtable", "gix-object", "gix-revwalk", "gix-trace", "nonempty", ] [[package]] name = "gix-revwalk" version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85f5756abffe0917827aac683b13684ed99875bc398fa1f9b8f479b0681ef9e6" dependencies = [ "gix-commitgraph", "gix-date", "gix-error", "gix-hash", "gix-hashtable", "gix-object", "smallvec", "thiserror", ] [[package]] name = "gix-sec" version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab8519976e4c7e486270740a5400369f37940779b80bd1377d94cfa1125d01b3" dependencies = [ "bitflags", "gix-path", "libc", "windows-sys 0.61.2", ] [[package]] name = "gix-shallow" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a292fc2fe548c5dfa575479d16b445b0ddf1dd2f56f1fec6aed386f82553cd97" dependencies = [ "bstr", "gix-hash", "gix-lock", "nonempty", "thiserror", ] [[package]] name = "gix-submodule" version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3059890ef054066c22a94bfc6a3eaba0d806aedcd630a0bc9e5783fd88884781" dependencies = [ "bstr", "gix-config", "gix-path", "gix-pathspec", "gix-refspec", "gix-url", "thiserror", ] [[package]] name = "gix-tempfile" version = "23.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "691ea1e31435c7e7d4d04705ec9d1c0d9482c46b2acf512bc723939d8f0af7fb" dependencies = [ "gix-fs", "libc", "parking_lot", "tempfile", ] [[package]] name = "gix-trace" version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44dc45eae785c0eb14173e0f152e6e224dcf4d45b6a6999a3aed22af541ad678" [[package]] name = "gix-transport" version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cd0e34995b1aab0fa8dff2af8db726a0bfad3e119c89302604463264046e7ff" dependencies = [ "base64", "bstr", "gix-command", "gix-credentials", "gix-features", "gix-packetline", "gix-quote", "gix-sec", "gix-url", "reqwest", "thiserror", ] [[package]] name = "gix-traverse" version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8de590ecc86a3b2870665f2288324fa9f7f8672c7fc2d4e020fdd81cd1f7aed" dependencies = [ "bitflags", "gix-commitgraph", "gix-date", "gix-hash", "gix-hashtable", "gix-object", "gix-revwalk", "smallvec", "thiserror", ] [[package]] name = "gix-url" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65bb01ec69d55e82ccb7a19e264501ead4e6aac38463a8cebfdd81e22bb67ab2" dependencies = [ "bstr", "gix-path", "percent-encoding", "thiserror", ] [[package]] name = "gix-utils" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66c50966184123caf580ffa64e28031a878597f1c7fceb8fe19566c38eb1b771" dependencies = [ "fastrand", "unicode-normalization", ] [[package]] name = "gix-validate" version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7bc6fc771c4063ba7cd2f47b91fb6076251c6a823b64b7fe7b8874b0fe4afae3" dependencies = [ "bstr", ] [[package]] name = "gix-worktree" version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cef414ed275e8407cd5d53d301e83be19700b0dd3f859d2434417b58f454a2d1" dependencies = [ "bstr", "gix-attributes", "gix-fs", "gix-glob", "gix-hash", "gix-ignore", "gix-index", "gix-object", "gix-path", "gix-validate", ] [[package]] name = "gix-worktree-state" version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4bffae8b3ca258fdd50370cd51f06deb4c76a3b43db3868bc28dde45ffa77d69" dependencies = [ "bstr", "gix-features", "gix-filter", "gix-fs", "gix-index", "gix-object", "gix-path", "gix-worktree", "io-close", "thiserror", ] [[package]] name = "gix-worktree-stream" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d25e9ed30100c63f7590bc581c225e53f731a53e06aa79a245739c07f7dcc557" dependencies = [ "gix-attributes", "gix-error", "gix-features", "gix-filter", "gix-fs", "gix-hash", "gix-object", "gix-path", "gix-traverse", "parking_lot", ] [[package]] name = "h2" version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" dependencies = [ "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", "http", "indexmap", "slab", "tokio", "tokio-util", "tracing", ] [[package]] name = "hash32" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" dependencies = [ "byteorder", ] [[package]] name = "hashbrown" version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ "foldhash 0.1.5", ] [[package]] name = "hashbrown" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" dependencies = [ "allocator-api2", "equivalent", "foldhash 0.2.0", ] [[package]] name = "hashbrown" version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" dependencies = [ "allocator-api2", "equivalent", "foldhash 0.2.0", ] [[package]] name = "heapless" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" dependencies = [ "hash32", "stable_deref_trait", ] [[package]] name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "home" version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" dependencies = [ "windows-sys 0.61.2", ] [[package]] name = "http" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" dependencies = [ "bytes", "itoa", ] [[package]] name = "http-body" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", "http", ] [[package]] name = "http-body-util" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", "futures-core", "http", "http-body", "pin-project-lite", ] [[package]] name = "httparse" version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "hyper" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" dependencies = [ "atomic-waker", "bytes", "futures-channel", "futures-core", "h2", "http", "http-body", "httparse", "itoa", "pin-project-lite", "smallvec", "tokio", "want", ] [[package]] name = "hyper-rustls" version = "0.27.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" dependencies = [ "http", "hyper", "hyper-util", "rustls", "tokio", "tokio-rustls", "tower-service", ] [[package]] name = "hyper-util" version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ "base64", "bytes", "futures-channel", "futures-util", "http", "http-body", "hyper", "ipnet", "libc", "percent-encoding", "pin-project-lite", "socket2", "tokio", "tower-service", "tracing", ] [[package]] name = "icu_collections" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" dependencies = [ "displaydoc", "potential_utf", "yoke", "zerofrom", "zerovec", ] [[package]] name = "icu_locale_core" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" dependencies = [ "displaydoc", "litemap", "tinystr", "writeable", "zerovec", ] [[package]] name = "icu_normalizer" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" dependencies = [ "icu_collections", "icu_normalizer_data", "icu_properties", "icu_provider", "smallvec", "zerovec", ] [[package]] name = "icu_normalizer_data" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" dependencies = [ "icu_collections", "icu_locale_core", "icu_properties_data", "icu_provider", "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" [[package]] name = "icu_provider" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" dependencies = [ "displaydoc", "icu_locale_core", "writeable", "yoke", "zerofrom", "zerotrie", "zerovec", ] [[package]] name = "id-arena" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" [[package]] name = "ident_case" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", "utf8_iter", ] [[package]] name = "idna_adapter" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ "icu_normalizer", "icu_properties", ] [[package]] name = "indenter" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" [[package]] name = "indexmap" version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", "hashbrown 0.17.1", "serde", "serde_core", ] [[package]] name = "io-close" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cadcf447f06744f8ce713d2d6239bb5bde2c357a452397a9ed90c625da390bc" dependencies = [ "libc", "winapi", ] [[package]] name = "ipnet" version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "is_terminal_polyfill" version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itoa" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jiff" version = "0.2.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4603d3033e49e2b0e31229fcab20a5d40089c607d975cd9c80551dc69eed9102" dependencies = [ "jiff-static", "jiff-tzdb-platform", "log", "portable-atomic", "portable-atomic-util", "serde_core", "windows-link", ] [[package]] name = "jiff-static" version = "0.2.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "782d32378dddf207193ac91cefb848ad41abb58195c95168e1291227a0832b47" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "jiff-tzdb" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c900ef84826f1338a557697dc8fc601df9ca9af4ac137c7fb61d4c6f2dfd3076" [[package]] name = "jiff-tzdb-platform" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" dependencies = [ "jiff-tzdb", ] [[package]] name = "jni" version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" dependencies = [ "cfg-if", "combine", "jni-macros", "jni-sys", "log", "simd_cesu8", "thiserror", "walkdir", "windows-link", ] [[package]] name = "jni-macros" version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" dependencies = [ "proc-macro2", "quote", "rustc_version", "simd_cesu8", "syn", ] [[package]] name = "jni-sys" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" dependencies = [ "jni-sys-macros", ] [[package]] name = "jni-sys-macros" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" dependencies = [ "quote", "syn", ] [[package]] name = "jobserver" version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ "getrandom 0.3.4", "libc", ] [[package]] name = "js-sys" version = "0.3.98" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" dependencies = [ "cfg-if", "futures-util", "once_cell", "wasm-bindgen", ] [[package]] name = "kstring" version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "558bf9508a558512042d3095138b1f7b8fe90c5467d94f9f1da28b3731c5dbd1" dependencies = [ "static_assertions", ] [[package]] name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "leb128fmt" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "linux-raw-sys" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "lock_api" version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ "scopeguard", ] [[package]] name = "log" version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "lru-slab" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" [[package]] name = "matchers" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" dependencies = [ "regex-automata", ] [[package]] name = "maybe-async" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "memchr" version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "memmap2" version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" dependencies = [ "libc", ] [[package]] name = "mime" version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", "simd-adler32", ] [[package]] name = "mio" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" dependencies = [ "libc", "wasi", "windows-sys 0.61.2", ] [[package]] name = "nonempty" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9737e026353e5cd0736f98eddae28665118eb6f6600902a7f50db585621fecb6" [[package]] name = "nu-ansi-term" version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ "windows-sys 0.61.2", ] [[package]] name = "num-conv" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" [[package]] name = "object" version = "0.37.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" dependencies = [ "memchr", ] [[package]] name = "object" version = "0.39.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e5a6c098c7a3b6547378093f5cc30bc54fd361ce711e05293a5cc589562739b" dependencies = [ "memchr", "wasmparser 0.247.0", ] [[package]] name = "once_cell" version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "once_cell_polyfill" version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "openssl-probe" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "owo-colors" version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d" [[package]] name = "parking_lot" version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", ] [[package]] name = "parking_lot_core" version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", "windows-link", ] [[package]] name = "percent-encoding" version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "petgraph" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" dependencies = [ "fixedbitset", "hashbrown 0.15.5", "indexmap", "serde", ] [[package]] name = "pin-project-lite" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "platforms" version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6001d2ac55b4eb1ca634c65fc06555068b8dd89c9f20fd92064e5341a436e63" dependencies = [ "serde", ] [[package]] name = "portable-atomic" version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "portable-atomic-util" version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" dependencies = [ "portable-atomic", ] [[package]] name = "potential_utf" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" dependencies = [ "zerovec", ] [[package]] name = "powerfmt" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ "zerocopy", ] [[package]] name = "prettyplease" version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", "syn", ] [[package]] name = "proc-macro2" version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] [[package]] name = "prodash" version = "31.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "962200e2d7d551451297d9fdce85138374019ada198e30ea9ede38034e27604c" dependencies = [ "parking_lot", ] [[package]] name = "quinn" version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" dependencies = [ "bytes", "cfg_aliases", "pin-project-lite", "quinn-proto", "quinn-udp", "rustc-hash", "rustls", "socket2", "thiserror", "tokio", "tracing", "web-time", ] [[package]] name = "quinn-proto" version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" dependencies = [ "aws-lc-rs", "bytes", "getrandom 0.3.4", "lru-slab", "rand", "ring", "rustc-hash", "rustls", "rustls-pki-types", "slab", "thiserror", "tinyvec", "tracing", "web-time", ] [[package]] name = "quinn-udp" version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" dependencies = [ "cfg_aliases", "libc", "once_cell", "socket2", "tracing", "windows-sys 0.60.2", ] [[package]] name = "quitters" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e88ccde7d84d2115b250b5cba923973fc42fe23ad42d9d63bb129d956a6db014" dependencies = [ "once_cell", "regex", "semver", ] [[package]] name = "quote" version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2", ] [[package]] name = "r-efi" version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "r-efi" version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "rand" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" dependencies = [ "rand_chacha", "rand_core", ] [[package]] name = "rand_chacha" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", "rand_core", ] [[package]] name = "rand_core" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" dependencies = [ "getrandom 0.3.4", ] [[package]] name = "rayon" version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" dependencies = [ "either", "rayon-core", ] [[package]] name = "rayon-core" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" dependencies = [ "crossbeam-deque", "crossbeam-utils", ] [[package]] name = "redox_syscall" version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ "bitflags", ] [[package]] name = "regex" version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", "regex-automata", "regex-syntax", ] [[package]] name = "regex-automata" version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", "regex-syntax", ] [[package]] name = "regex-syntax" version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "reqwest" version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62e0021ea2c22aed41653bc7e1419abb2c97e038ff2c33d0e1309e49a97deec0" dependencies = [ "base64", "bytes", "encoding_rs", "futures-channel", "futures-core", "futures-util", "h2", "http", "http-body", "http-body-util", "hyper", "hyper-rustls", "hyper-util", "js-sys", "log", "mime", "percent-encoding", "pin-project-lite", "quinn", "rustls", "rustls-pki-types", "rustls-platform-verifier", "sync_wrapper", "tokio", "tokio-rustls", "tower", "tower-http", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", ] [[package]] name = "ring" version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", "getrandom 0.2.17", "libc", "untrusted", "windows-sys 0.52.0", ] [[package]] name = "rustc-demangle" version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" [[package]] name = "rustc-hash" version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" [[package]] name = "rustc-stable-hash" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "781442f29170c5c93b7185ad559492601acdc71d5bb0706f5868094f45cfcd08" [[package]] name = "rustc_version" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] [[package]] name = "rustix" version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", "windows-sys 0.61.2", ] [[package]] name = "rustls" version = "0.23.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" dependencies = [ "aws-lc-rs", "once_cell", "rustls-pki-types", "rustls-webpki", "subtle", "zeroize", ] [[package]] name = "rustls-native-certs" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" dependencies = [ "openssl-probe", "rustls-pki-types", "schannel", "security-framework", ] [[package]] name = "rustls-pki-types" version = "1.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" dependencies = [ "web-time", "zeroize", ] [[package]] name = "rustls-platform-verifier" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" dependencies = [ "core-foundation", "core-foundation-sys", "jni", "log", "once_cell", "rustls", "rustls-native-certs", "rustls-platform-verifier-android", "rustls-webpki", "security-framework", "security-framework-sys", "webpki-root-certs", "windows-sys 0.61.2", ] [[package]] name = "rustls-platform-verifier-android" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", ] [[package]] name = "rustsec" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c60fd662f245fd3d6ae7ee2371f59042c4e9dc00a02183c0b1735f4da2aa5ed" dependencies = [ "auditable-info", "auditable-serde", "binfarce", "cargo-lock", "cvss", "fs-err", "gix", "home", "jiff", "once_cell", "platforms", "quitters", "semver", "serde", "tame-index", "thiserror", "time", "toml 1.1.2+spec-1.1.0", "url", ] [[package]] name = "rustversion" version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "same-file" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" dependencies = [ "winapi-util", ] [[package]] name = "schannel" version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" dependencies = [ "windows-sys 0.61.2", ] [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "secrecy" version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e891af845473308773346dc847b2c23ee78fe442e0472ac50e22a18a93d3ae5a" dependencies = [ "serde", "zeroize", ] [[package]] name = "security-framework" version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ "bitflags", "core-foundation", "core-foundation-sys", "libc", "security-framework-sys", ] [[package]] name = "security-framework-sys" version = "2.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" dependencies = [ "core-foundation-sys", "libc", ] [[package]] name = "semver" version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" dependencies = [ "serde", "serde_core", ] [[package]] name = "serde" version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ "serde_core", "serde_derive", ] [[package]] name = "serde_core" version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "serde_json" version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "itoa", "memchr", "serde", "serde_core", "zmij", ] [[package]] name = "serde_spanned" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" dependencies = [ "serde_core", ] [[package]] name = "sha1" version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures", "digest", ] [[package]] name = "sha1-checked" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89f599ac0c323ebb1c6082821a54962b839832b03984598375bff3975b804423" dependencies = [ "digest", "sha1", ] [[package]] name = "sharded-slab" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ "lazy_static", ] [[package]] name = "shell-words" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77" [[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "simd-adler32" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" [[package]] name = "simd_cesu8" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" dependencies = [ "rustc_version", "simdutf8", ] [[package]] name = "simdutf8" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "slab" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "smol_str" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9676b89cd56310a87b93dec47b11af744f34d5fc9f367b829474eec0a891350d" dependencies = [ "borsh", "serde", ] [[package]] name = "socket2" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", "windows-sys 0.61.2", ] [[package]] name = "stable_deref_trait" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "strsim" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subtle" version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "sync_wrapper" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" dependencies = [ "futures-core", ] [[package]] name = "synstructure" version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "tame-index" version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c51563c6639245219c077420e0a207e99b5e82e2e6bb78fd4898d42028ea7dde" dependencies = [ "camino", "crossbeam-channel", "http", "libc", "memchr", "rayon", "reqwest", "rustc-stable-hash", "semver", "serde", "serde_json", "smol_str", "thiserror", "tokio", "toml-span", "twox-hash", ] [[package]] name = "tempfile" version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", "getrandom 0.4.2", "once_cell", "rustix", "windows-sys 0.61.2", ] [[package]] name = "termcolor" version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] [[package]] name = "thiserror" version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "thread_local" version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" dependencies = [ "cfg-if", ] [[package]] name = "time" version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "itoa", "num-conv", "powerfmt", "serde_core", "time-core", "time-macros", ] [[package]] name = "time-core" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "time-macros" version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" dependencies = [ "num-conv", "time-core", ] [[package]] name = "tinystr" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" dependencies = [ "displaydoc", "zerovec", ] [[package]] name = "tinyvec" version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" dependencies = [ "tinyvec_macros", ] [[package]] name = "tinyvec_macros" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes", "libc", "mio", "pin-project-lite", "socket2", "windows-sys 0.61.2", ] [[package]] name = "tokio-rustls" version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ "rustls", "tokio", ] [[package]] name = "tokio-util" version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", ] [[package]] name = "toml" version = "0.9.12+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" dependencies = [ "indexmap", "serde_core", "serde_spanned", "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", "toml_writer", "winnow 0.7.15", ] [[package]] name = "toml" version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" dependencies = [ "indexmap", "serde_core", "serde_spanned", "toml_datetime 1.1.1+spec-1.1.0", "toml_parser", "toml_writer", "winnow 1.0.2", ] [[package]] name = "toml-span" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f22ba417d437b5fa5dcba6c27dbd6c14f38845315b724d89fed73b7a426451b7" dependencies = [ "smallvec", ] [[package]] name = "toml_datetime" version = "0.7.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" dependencies = [ "serde_core", ] [[package]] name = "toml_datetime" version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" dependencies = [ "serde_core", ] [[package]] name = "toml_parser" version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ "winnow 1.0.2", ] [[package]] name = "toml_writer" version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" [[package]] name = "topological-sort" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea68304e134ecd095ac6c3574494fc62b909f416c4fca77e440530221e549d3d" [[package]] name = "tower" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" dependencies = [ "futures-core", "futures-util", "pin-project-lite", "sync_wrapper", "tokio", "tower-layer", "tower-service", ] [[package]] name = "tower-http" version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68d6fdd9f81c2819c9a8b0e0cd91660e7746a8e6ea2ba7c6b2b057985f6bcb51" dependencies = [ "async-compression", "bitflags", "bytes", "futures-core", "futures-util", "http", "http-body", "http-body-util", "pin-project-lite", "tokio", "tokio-util", "tower", "tower-layer", "tower-service", "url", ] [[package]] name = "tower-layer" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "pin-project-lite", "tracing-attributes", "tracing-core", ] [[package]] name = "tracing-attributes" version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "tracing-core" version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", "valuable", ] [[package]] name = "tracing-log" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" dependencies = [ "log", "once_cell", "tracing-core", ] [[package]] name = "tracing-subscriber" version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" dependencies = [ "matchers", "nu-ansi-term", "once_cell", "regex-automata", "sharded-slab", "smallvec", "thread_local", "tracing", "tracing-core", "tracing-log", ] [[package]] name = "try-lock" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "twox-hash" version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" [[package]] name = "typenum" version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" [[package]] name = "uluru" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c8a2469e56e6e5095c82ccd3afb98dad95f7af7929aab6d8ba8d6e0f73657da" dependencies = [ "arrayvec", ] [[package]] name = "unicode-bom" version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7eec5d1121208364f6793f7d2e222bf75a915c19557537745b195b253dd64217" [[package]] name = "unicode-ident" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-normalization" version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" dependencies = [ "tinyvec", ] [[package]] name = "unicode-xid" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "untrusted" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", "idna", "percent-encoding", "serde", "serde_derive", ] [[package]] name = "utf8_iter" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "utf8parse" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "valuable" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wait-timeout" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" dependencies = [ "libc", ] [[package]] name = "walkdir" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", ] [[package]] name = "want" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" dependencies = [ "try-lock", ] [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" version = "1.0.3+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" dependencies = [ "wit-bindgen 0.57.1", ] [[package]] name = "wasip3" version = "0.4.0+wasi-0.3.0-rc-2026-01-06" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" dependencies = [ "wit-bindgen 0.51.0", ] [[package]] name = "wasm-bindgen" version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" version = "0.4.71" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8" dependencies = [ "js-sys", "wasm-bindgen", ] [[package]] name = "wasm-bindgen-macro" version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" dependencies = [ "quote", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" dependencies = [ "bumpalo", "proc-macro2", "quote", "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" dependencies = [ "unicode-ident", ] [[package]] name = "wasm-encoder" version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" dependencies = [ "leb128fmt", "wasmparser 0.244.0", ] [[package]] name = "wasm-metadata" version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" dependencies = [ "anyhow", "indexmap", "wasm-encoder", "wasmparser 0.244.0", ] [[package]] name = "wasmparser" version = "0.207.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e19bb9f8ab07616da582ef8adb24c54f1424c7ec876720b7da9db8ec0626c92c" dependencies = [ "bitflags", ] [[package]] name = "wasmparser" version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ "bitflags", "hashbrown 0.15.5", "indexmap", "semver", ] [[package]] name = "wasmparser" version = "0.247.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e6fb4c2bee46c5ea4d40f8cdb5c131725cd976718ec56f1c8e82fbde5fa2a80" dependencies = [ "bitflags", ] [[package]] name = "web-sys" version = "0.3.98" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa" dependencies = [ "js-sys", "wasm-bindgen", ] [[package]] name = "web-time" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", "wasm-bindgen", ] [[package]] name = "webpki-root-certs" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c" dependencies = [ "rustls-pki-types", ] [[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ "windows-sys 0.61.2", ] [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-link" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ "windows-targets 0.52.6", ] [[package]] name = "windows-sys" version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ "windows-targets 0.53.5", ] [[package]] name = "windows-sys" version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ "windows-link", ] [[package]] name = "windows-targets" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] [[package]] name = "windows-targets" version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ "windows-link", "windows_aarch64_gnullvm 0.53.1", "windows_aarch64_msvc 0.53.1", "windows_i686_gnu 0.53.1", "windows_i686_gnullvm 0.53.1", "windows_i686_msvc 0.53.1", "windows_x86_64_gnu 0.53.1", "windows_x86_64_gnullvm 0.53.1", "windows_x86_64_msvc 0.53.1", ] [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_gnullvm" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_aarch64_msvc" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnu" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_gnullvm" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_i686_msvc" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnu" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_gnullvm" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "windows_x86_64_msvc" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" [[package]] name = "winnow" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0" [[package]] name = "wit-bindgen" version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" dependencies = [ "wit-bindgen-rust-macro", ] [[package]] name = "wit-bindgen" version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" [[package]] name = "wit-bindgen-core" version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" dependencies = [ "anyhow", "heck", "wit-parser", ] [[package]] name = "wit-bindgen-rust" version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" dependencies = [ "anyhow", "heck", "indexmap", "prettyplease", "syn", "wasm-metadata", "wit-bindgen-core", "wit-component", ] [[package]] name = "wit-bindgen-rust-macro" version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" dependencies = [ "anyhow", "prettyplease", "proc-macro2", "quote", "syn", "wit-bindgen-core", "wit-bindgen-rust", ] [[package]] name = "wit-component" version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", "bitflags", "indexmap", "log", "serde", "serde_derive", "serde_json", "wasm-encoder", "wasm-metadata", "wasmparser 0.244.0", "wit-parser", ] [[package]] name = "wit-parser" version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" dependencies = [ "anyhow", "id-arena", "indexmap", "log", "semver", "serde", "serde_derive", "serde_json", "unicode-xid", "wasmparser 0.244.0", ] [[package]] name = "writeable" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "yoke" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" dependencies = [ "stable_deref_trait", "yoke-derive", "zerofrom", ] [[package]] name = "yoke-derive" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", "syn", "synstructure", ] [[package]] name = "zerocopy" version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "zerofrom" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", "syn", "synstructure", ] [[package]] name = "zeroize" version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zerotrie" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" dependencies = [ "displaydoc", "yoke", "zerofrom", ] [[package]] name = "zerovec" version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" dependencies = [ "yoke", "zerofrom", "zerovec-derive", ] [[package]] name = "zerovec-derive" version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "zlib-rs" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3be3d40e40a133f9c916ee3f9f4fa2d9d63435b5fbe1bfc6d9dae0aa0ada1513" [[package]] name = "zmij" version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" cargo-audit-0.22.2/Cargo.toml0000644000000044201046102023000113360ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2024" rust-version = "1.88" name = "cargo-audit" version = "0.22.2" authors = ["Tony Arcieri "] build = false exclude = ["tests/"] autolib = false autobins = false autoexamples = false autotests = false autobenches = false description = "Audit Cargo.lock for crates with security vulnerabilities" homepage = "https://rustsec.org" readme = "README.md" keywords = [ "cargo-subcommand", "security", "audit", "vulnerability", ] categories = ["development-tools::cargo-plugins"] license = "Apache-2.0 OR MIT" repository = "https://github.com/rustsec/rustsec" resolver = "2" [badges.maintenance] status = "actively-developed" [features] binary-scanning = [ "rustsec/binary-scanning", "dep:object", "dep:rustc-demangle", "dep:syn", ] default = ["binary-scanning"] fix = [] [lib] name = "cargo_audit" path = "src/lib.rs" [[bin]] name = "cargo-audit" path = "src/bin/cargo-audit/main.rs" [dependencies.abscissa_core] version = "0.9" [dependencies.cargo-lock] version = "11" [dependencies.clap] version = "4" [dependencies.display-error-chain] version = "0.2.0" [dependencies.home] version = "0.5" [dependencies.object] version = "0.39" features = [ "read", "wasm", ] optional = true default-features = false [dependencies.rustc-demangle] version = "0.1" optional = true [dependencies.rustsec] version = "0.33" features = ["dependency-tree"] [dependencies.serde] version = "1" features = ["serde_derive"] [dependencies.serde_json] version = "1" [dependencies.syn] version = "2" features = ["extra-traits"] optional = true [dependencies.thiserror] version = "2" [dev-dependencies.abscissa_core] version = "0.9" features = ["testing"] [dev-dependencies.once_cell] version = "1.15.0" [dev-dependencies.tempfile] version = "3" [dev-dependencies.toml] version = "1.0" cargo-audit-0.22.2/Cargo.toml.orig000064400000000000000000000026541046102023000150040ustar 00000000000000[package] name = "cargo-audit" description = "Audit Cargo.lock for crates with security vulnerabilities" version = "0.22.2" authors = ["Tony Arcieri "] license = "Apache-2.0 OR MIT" homepage = "https://rustsec.org" repository = "https://github.com/rustsec/rustsec" readme = "README.md" categories = ["development-tools::cargo-plugins"] keywords = ["cargo-subcommand", "security", "audit", "vulnerability"] edition = "2024" rust-version = "1.88" exclude = ["tests/"] [badges] maintenance = { status = "actively-developed" } [dependencies] abscissa_core = { workspace = true } cargo-lock = { workspace = true } clap = { workspace = true } home = { workspace = true } object = { workspace = true, optional = true } rustc-demangle = { workspace = true, optional = true } rustsec = { workspace = true, features = ["dependency-tree"] } serde = { workspace = true, features = ["serde_derive"] } serde_json = { workspace = true } syn = { workspace = true, optional = true } thiserror = { workspace = true } display-error-chain = { workspace = true } [dev-dependencies] abscissa_core = { workspace = true, features = ["testing"] } once_cell = { workspace = true } tempfile = { workspace = true } toml = { workspace = true } [features] default = ["binary-scanning"] fix = [] binary-scanning = [ "rustsec/binary-scanning", "dep:object", "dep:rustc-demangle", "dep:syn", ] cargo-audit-0.22.2/LICENSE-APACHE000064400000000000000000000251371046102023000140420ustar 00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. cargo-audit-0.22.2/LICENSE-MIT000064400000000000000000000020571046102023000135460ustar 00000000000000Copyright (c) 2017 The Rust Project Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. cargo-audit-0.22.2/README.md000064400000000000000000000133451046102023000133730ustar 00000000000000# RustSec: `cargo audit` [![Latest Version][crate-image]][crate-link] [![Build Status][build-image]][build-link] [![Safety Dance][safety-image]][safety-link] ![MSRV][rustc-image] ![Apache 2.0 OR MIT licensed][license-image] [![Project Chat][chat-image]][chat-link] Audit your dependencies for crates with security vulnerabilities reported to the [RustSec Advisory Database]. ## Related Experimental Tool If you want additional function-level reachability context, see [`reachsec`](https://github.com/xizheyin/reachsec), an experimental standalone companion to `cargo audit`. ## Requirements `cargo audit` requires Rust **1.74** or later. ## Installation Packaging status `cargo audit` is a Cargo subcommand and can be installed with `cargo install`: ``` $ cargo install cargo-audit ``` Once installed, run `cargo audit` at the toplevel of any Cargo project. ### Alpine Linux ``` # apk add cargo-audit ``` ### Arch Linux ``` # pacman -S cargo-audit ``` ### MacOS ``` $ brew install cargo-audit ``` ### OpenBSD ``` # pkg_add cargo-audit ``` ## Screenshot Screenshot ## `cargo audit fix` subcommand This tool supports an experimental feature to automatically update `Cargo.toml` to fix vulnerable dependency requirements. To enable it, install `cargo audit` with the `fix` feature enabled: ``` $ cargo install cargo-audit --features=fix ``` Once installed, run `cargo audit fix` to automatically fix vulnerable dependency requirements in your `Cargo.toml`: Screenshot This will modify `Cargo.toml` in place. To perform a dry run instead, which shows a preview of what dependencies would be upgraded, run `cargo audit fix --dry-run`. ## `cargo audit bin` subcommand Run `cargo audit bin` followed by the paths to your binaries to audit them: Screenshot You can scan a directory recursively using [`fd`](https://crates.io/crates/fd-find): ``` fd --type=executable --exec-batch cargo audit bin ``` If your programs have been compiled with [`cargo auditable`](https://github.com/rust-secure-code/cargo-auditable), the audit is fully accurate because all the necessary information is embedded in the compiled binary. For binaries that were not compiled with [`cargo auditable`](https://github.com/rust-secure-code/cargo-auditable) it will recover a part of the dependency list by parsing panic messages. This will miss any embedded C code (e.g. OpenSSL) as well as roughly half of the Rust dependencies because the Rust compiler is very good at removing unnecessary panics, but that's better than having no vulnerability information whatsoever. ## Ignoring advisories The first and best way to fix a vulnerability is to upgrade the vulnerable crate. But there may be situations where an upgrade isn't available and the advisory doesn't affect your application. For example the advisory might involve a cargo feature or API that is unused. In these cases, you can ignore advisories using the `--ignore` option. ``` $ cargo audit --ignore RUSTSEC-2017-0001 ``` This option can also be configured via the [`audit.toml`](./audit.toml.example) file. ## Using `cargo audit` on Travis CI To automatically run `cargo audit` on every build in Travis CI, you can add the following to your `.travis.yml`: ```yaml language: rust cache: cargo # cache cargo-audit once installed before_script: - cargo install --force cargo-audit - cargo generate-lockfile script: - cargo audit ``` ## Using `cargo audit` on GitHub Action Please use [`audit-check` action](https://github.com/rustsec/audit-check) directly. ## Reporting Vulnerabilities Report vulnerabilities by opening pull requests against the [RustSec Advisory Database] GitHub repo: Report Vulnerability ## License Licensed under either of: * Apache License, Version 2.0 ([LICENSE-APACHE] or https://www.apache.org/licenses/LICENSE-2.0) * MIT license ([LICENSE-MIT] or https://opensource.org/licenses/MIT) at your option. ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you shall be dual licensed as above, without any additional terms or conditions. [//]: # (badges) [crate-image]: https://img.shields.io/crates/v/cargo-audit.svg?logo=rust [crate-link]: https://crates.io/crates/cargo-audit [build-image]: https://github.com/RustSec/rustsec/actions/workflows/cargo-audit.yml/badge.svg [build-link]: https://github.com/RustSec/rustsec/actions/workflows/cargo-audit.yml [license-image]: https://img.shields.io/badge/license-Apache2.0%2FMIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.74+-blue.svg [safety-image]: https://img.shields.io/badge/unsafe-forbidden-success.svg [safety-link]: https://github.com/rust-secure-code/safety-dance/ [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rust-lang.zulipchat.com/#narrow/stream/146229-wg-secure-code/ [//]: # (general links) [RustSec Advisory Database]: https://github.com/RustSec/advisory-db/ [LICENSE-APACHE]: https://github.com/RustSec/cargo-audit/blob/main/LICENSE-APACHE [LICENSE-MIT]: https://github.com/RustSec/cargo-audit/blob/main/LICENSE-MIT cargo-audit-0.22.2/audit.toml.example000064400000000000000000000027571046102023000155560ustar 00000000000000# Example audit config file # # It may be located in the user home (`~/.cargo/audit.toml`) or in the project # root (`.cargo/audit.toml`). # # All of the options which can be passed via CLI arguments can also be # permanently specified in this file. [advisories] ignore = [] # advisory IDs to ignore e.g. ["RUSTSEC-2019-0001", ...] informational_warnings = ["unmaintained"] # warn for categories of informational advisories severity_threshold = "low" # CVSS severity ("none", "low", "medium", "high", "critical") # Advisory Database Configuration [database] path = "~/.cargo/advisory-db" # Path where advisory git repo will be cloned url = "https://github.com/RustSec/advisory-db.git" # URL to git repo fetch = true # Perform a `git fetch` before auditing (default: true) stale = false # Allow stale advisory DB (i.e. no commits for 90 days, default: false) # Output Configuration [output] deny = ["unmaintained"] # exit on error if unmaintained dependencies are found format = "terminal" # "terminal" (human readable report) or "json" quiet = false # Only print information on error show_tree = true # Show inverse dependency trees along with advisories (default: true) # Target Configuration [target] arch = ["x86_64"] # Ignore advisories for CPU architectures other than these os = ["linux", "windows"] # Ignore advisories for operating systems other than these [yanked] enabled = true # Warn for yanked crates in Cargo.lock (default: true) update_index = true # Auto-update the crates.io index (default: true) cargo-audit-0.22.2/src/application.rs000064400000000000000000000047631046102023000155600ustar 00000000000000//! Abscissa application for `cargo audit` //! //! use std::sync::Arc; use crate::{commands::CargoAuditCommand, config::AuditConfig}; use abscissa_core::{ Application, FrameworkError, StandardPaths, application::{self, AppCell}, config::CfgCell, terminal::ColorChoice, trace, }; /// Application state pub static APP: AppCell = AppCell::new(); /// `cargo audit` application #[derive(Debug)] pub struct CargoAuditApplication { /// Application configuration. config: CfgCell, /// Application state. state: application::State, } /// Initialize a new application instance. /// /// By default no configuration is loaded, and the framework state is /// initialized to a default, empty state (no components, threads, etc). impl Default for CargoAuditApplication { fn default() -> Self { Self { config: CfgCell::default(), state: application::State::default(), } } } impl Application for CargoAuditApplication { /// Entrypoint command for this application. type Cmd = CargoAuditCommand; /// Application configuration. type Cfg = AuditConfig; /// Paths to resources within the application. type Paths = StandardPaths; /// Accessor for application configuration. fn config(&self) -> Arc { self.config.read() } /// Borrow the application state immutably. fn state(&self) -> &application::State { &self.state } /// Register all components used by this application. fn register_components(&mut self, command: &Self::Cmd) -> Result<(), FrameworkError> { let components = self.framework_components(command)?; self.state.components_mut().register(components) } /// Post-configuration lifecycle callback. fn after_config(&mut self, config: Self::Cfg) -> Result<(), FrameworkError> { // Configure components self.state.components_mut().after_config(&config)?; self.config.set_once(config); Ok(()) } /// Color configuration for this application. fn term_colors(&self, entrypoint: &CargoAuditCommand) -> ColorChoice { entrypoint.term_colors() } /// Get tracing configuration from command-line options fn tracing_config(&self, command: &CargoAuditCommand) -> trace::Config { if command.verbose { trace::Config::verbose() } else { trace::Config::default() } } } cargo-audit-0.22.2/src/auditor.rs000064400000000000000000000360611046102023000147200ustar 00000000000000//! Core auditing functionality use crate::{ config::AuditConfig, error::display_err_with_source, prelude::*, presenter::Presenter, }; use rustsec::{Error, ErrorKind, Lockfile, Warning, WarningKind, registry, report}; use rustsec::binary_scanning::BinaryFormat; use std::{ io::{self, Read}, path::Path, process::exit, time::Duration, }; // TODO: make configurable const DEFAULT_LOCK_TIMEOUT: Duration = Duration::from_secs(5 * 60); #[cfg(feature = "binary-scanning")] const DEFAULT_MAX_BINARY_SIZE: u64 = 100 * 1024 * 1024; // 100MB /// Security vulnerability auditor pub struct Auditor { /// RustSec Advisory Database database: rustsec::Database, /// Crates.io registry index registry_index: Option, /// Presenter for displaying the report presenter: Presenter, /// Audit report settings report_settings: report::Settings, /// Binary scanning configuration (max input size) #[cfg(feature = "binary-scanning")] binary_size_limit: Option, /// Binary scanning configuration (max auditable payload size) #[cfg(feature = "binary-scanning")] audit_data_size_limit: Option, } impl Auditor { /// Initialize the auditor pub fn new(config: &AuditConfig) -> Self { let advisory_db_url = config .database .url .as_ref() .map(AsRef::as_ref) .unwrap_or(rustsec::repository::git::DEFAULT_URL); let advisory_db_path = config .database .path .as_ref() .cloned() .unwrap_or_else(rustsec::repository::git::Repository::default_path); let database = if config.database.fetch { if !config.output.is_quiet() { status_ok!("Fetching", "advisory database from `{}`", advisory_db_url); } let mut result = rustsec::repository::git::Repository::fetch( advisory_db_url, &advisory_db_path, !config.database.stale, Duration::from_secs(0), ); // If the directory is locked, print a message and wait for it to become unlocked. // If we don't print the message, `cargo audit` would just hang with no explanation. if let Err(e) = &result && e.kind() == ErrorKind::LockTimeout { status_warn!( "directory {} is locked, waiting for up to {} seconds for it to become available", advisory_db_path.display(), DEFAULT_LOCK_TIMEOUT.as_secs() ); result = rustsec::repository::git::Repository::fetch( advisory_db_url, &advisory_db_path, !config.database.stale, DEFAULT_LOCK_TIMEOUT, ); } let advisory_db_repo = result.unwrap_or_else(|e| { status_err!( "couldn't fetch advisory database: {}", display_err_with_source(&e) ); exit(1); }); rustsec::Database::load_from_repo(&advisory_db_repo).unwrap_or_else(|e| { status_err!( "error loading advisory database: {}", display_err_with_source(&e) ); exit(1); }) } else { rustsec::Database::open(&advisory_db_path).unwrap_or_else(|e| { status_err!( "error loading advisory database: {}", display_err_with_source(&e) ); exit(1); }) }; if !config.output.is_quiet() { status_ok!( "Loaded", "{} security advisories (from {})", database.iter().count(), advisory_db_path.display() ); } let registry_index = if config.yanked.enabled { if config.yanked.update_index && config.database.fetch { if !config.output.is_quiet() { status_ok!("Updating", "crates.io index"); } let mut result = registry::CachedIndex::fetch(Duration::from_secs(0)); // If the directory is locked, print a message and wait for it to become unlocked. // If we don't print the message, `cargo audit` would just hang with no explanation. if let Err(e) = &result && e.kind() == ErrorKind::LockTimeout { status_warn!( "directory {} is locked, waiting for up to {} seconds for it to become available", advisory_db_path.display(), DEFAULT_LOCK_TIMEOUT.as_secs() ); result = registry::CachedIndex::fetch(DEFAULT_LOCK_TIMEOUT); } match result { Ok(index) => Some(index), Err(err) => { if !config.output.is_quiet() { status_warn!("couldn't update crates.io index: {}", err); } None } } } else { let mut result = registry::CachedIndex::open(Duration::from_secs(0)); // If the directory is locked, print a message and wait for it to become unlocked. // If we don't print the message, `cargo audit` would just hang with no explanation. if let Err(e) = &result && e.kind() == ErrorKind::LockTimeout { status_warn!( "directory {} is locked, waiting for up to {} seconds for it to become available", advisory_db_path.display(), DEFAULT_LOCK_TIMEOUT.as_secs() ); result = registry::CachedIndex::open(DEFAULT_LOCK_TIMEOUT) } match result { Ok(index) => Some(index), Err(err) => { if !config.output.is_quiet() { status_warn!("couldn't open crates.io index: {}", err); } None } } } } else { None }; Self { database, registry_index, presenter: Presenter::new(&config.output), report_settings: config.report_settings(), #[cfg(feature = "binary-scanning")] binary_size_limit: Some(DEFAULT_MAX_BINARY_SIZE), #[cfg(feature = "binary-scanning")] audit_data_size_limit: None, } } /// Perform an audit of a textual `Cargo.lock` file pub fn audit_lockfile(&mut self, lockfile_path: &Path) -> rustsec::Result { let lockfile = match self.load_lockfile(lockfile_path) { Ok(l) => l, Err(e) => { return Err(Error::with_source( ErrorKind::NotFound, format!("Couldn't load {}", lockfile_path.display()), e, )); } }; self.presenter.before_report(lockfile_path, &lockfile); let report = self.audit(&lockfile, None, None); let self_advisories = self.self_advisories(); self.presenter.print_self_report(self_advisories.as_slice()); report } #[cfg(feature = "binary-scanning")] /// Perform an audit of multiple binary files pub fn audit_binaries

(&mut self, binaries: &[P]) -> MultiFileReportSummmary where P: AsRef, { let mut summary = MultiFileReportSummmary::default(); for path in binaries { let result = self.audit_binary(path.as_ref()); match result { Ok(report) => { if self.presenter.should_exit_with_failure(&report) { summary.vulnerabilities_found = true; } } Err(e) => { status_err!("{}", display_err_with_source(&e)); summary.errors_encountered = true; } } } let self_advisories = self.self_advisories(); self.presenter.print_self_report(self_advisories.as_slice()); if self .presenter .should_exit_with_failure_due_to_self(&self.self_advisories()) { summary.errors_encountered = true; } summary } #[cfg(feature = "binary-scanning")] /// Configure binary-scanning limits for this `Auditor`. /// /// `max_binary_size` is in bytes. If unset, defaults to 100MB. /// /// `audit_data_size_limit` is the maximum size (in bytes) of embedded auditable payload data /// to parse. If unset, the default from `rustsec` applies (currently 8MB). pub fn set_binary_scan_limits( &mut self, max_binary_size: Option, audit_data_size_limit: Option, ) { self.binary_size_limit = Some(max_binary_size.unwrap_or(DEFAULT_MAX_BINARY_SIZE)); self.audit_data_size_limit = audit_data_size_limit.or(Some(8 * 1024 * 1024)); } #[cfg(feature = "binary-scanning")] /// Perform an audit of a binary file with dependency data embedded by `cargo auditable` fn audit_binary(&mut self, binary_path: &Path) -> rustsec::Result { use rustsec::binary_scanning::BinaryReport::*; let file_contents = self.read_binary_with_limit(binary_path)?; let (binary_type, report) = rustsec::binary_scanning::load_deps_from_binary( &file_contents, self.audit_data_size_limit, )?; self.presenter.binary_scan_report(&report, binary_path); self.presenter.set_binary_contents(file_contents); match report { Complete(lockfile) | Incomplete(lockfile) => { self.audit(&lockfile, Some(binary_path), Some(binary_type)) } None => Err(Error::new( ErrorKind::Parse, "No dependency information found! Is this a Rust executable built with cargo?", )), } } #[cfg(feature = "binary-scanning")] fn read_binary_with_limit(&self, binary_path: &Path) -> rustsec::Result> { let file = std::fs::File::open(binary_path)?; let limit = self.binary_size_limit.unwrap_or(DEFAULT_MAX_BINARY_SIZE); let mut limited = file.take(limit.saturating_add(1)); let mut buffer = Vec::new(); limited.read_to_end(&mut buffer)?; if buffer.len() as u64 > limit { return Err(Error::new( ErrorKind::BadParam, format!( "binary {} exceeds max size limit of {} bytes", binary_path.display(), limit ), )); } Ok(buffer) } /// The part of the auditing process that is shared between auditing lockfiles and binary files fn audit( &mut self, lockfile: &Lockfile, path: Option<&Path>, #[allow(unused_variables)] // May be unused when the "binary-scanning" feature is disabled binary_format: Option, ) -> rustsec::Result { let mut report = rustsec::Report::generate(&self.database, lockfile, &self.report_settings); #[cfg(feature = "binary-scanning")] if let Some(format) = binary_format { use rustsec::binary_scanning::filter_report_by_binary_type; filter_report_by_binary_type(&format, &mut report); } // Warn for yanked crates let mut yanked = self.check_for_yanked_crates(lockfile); if !yanked.is_empty() { report .warnings .entry(WarningKind::Yanked) .or_default() .append(&mut yanked); } self.presenter.print_report(&report, lockfile, path); Ok(report) } fn check_for_yanked_crates(&mut self, lockfile: &Lockfile) -> Vec { let mut result = Vec::new(); if let Some(index) = &mut self.registry_index { let pkgs_to_check: Vec<_> = lockfile .packages .iter() .filter(|pkg| match &pkg.source { Some(source) => source.is_default_registry(), None => false, }) .collect(); let yanked = index.find_yanked(pkgs_to_check); for pkg in yanked { match pkg { Ok(pkg) => { let warning = Warning::new(WarningKind::Yanked, pkg, None, None, None); result.push(warning); } Err(e) => status_err!( "couldn't check if the package is yanked: {}", display_err_with_source(&e) ), } } } result } /// Load the lockfile to be audited fn load_lockfile(&self, lockfile_path: &Path) -> rustsec::Result { if lockfile_path == Path::new("-") { // Read Cargo.lock from STDIN let mut lockfile_toml = String::new(); io::stdin().read_to_string(&mut lockfile_toml)?; Ok(lockfile_toml.parse()?) } else { Ok(Lockfile::load(lockfile_path)?) } } /// Query the database for advisories about `cargo-audit` or `rustsec` itself fn self_advisories(&self) -> Vec { let mut results = vec![]; for (package_name, package_version) in [ ("cargo-audit", crate::VERSION), ("rustsec", rustsec::VERSION), ] { let query = rustsec::database::Query::crate_scope() .package_name(package_name.parse().unwrap()) .package_version(package_version.parse().unwrap()); for advisory in self.database.query(&query) { results.push(advisory.clone()); } } results } /// Determines whether the process should exit with failure based on configuration /// such as `--deny=warnings`. /// **Performance:** calls `Auditor.self_advisories()`, which is costly. /// Do not call this in a hot loop. pub fn should_exit_with_failure(&self, report: &rustsec::Report) -> bool { self.presenter.should_exit_with_failure(report) || self .presenter .should_exit_with_failure_due_to_self(&self.self_advisories()) } } /// Summary of the report over multiple scanned files #[derive(Clone, Copy, Debug, Default)] pub struct MultiFileReportSummmary { /// Whether any vulnerabilities were found pub vulnerabilities_found: bool, /// Whether any errors were encountered during scanning pub errors_encountered: bool, } cargo-audit-0.22.2/src/bin/cargo-audit/main.rs000064400000000000000000000003311046102023000171330ustar 00000000000000//! Main entry point for `cargo audit` #![deny(warnings, missing_docs, trivial_casts, unused_qualifications)] #![forbid(unsafe_code)] use cargo_audit::application::APP; fn main() { abscissa_core::boot(&APP); } cargo-audit-0.22.2/src/binary_scanning.rs000064400000000000000000000115121046102023000164070ustar 00000000000000use std::collections::HashSet; use cargo_lock::Package; use object::{File, Object, ObjectSymbol}; use rustc_demangle::demangle; use rustsec::advisory::affected::FunctionPath; use syn::{Ident, Type, TypePath, parse_str}; pub(crate) struct SymbolSet(Vec>); impl SymbolSet { /// Extract and demangle all symbols from a binary. pub(crate) fn from_file<'a>( contents: &[u8], vulnerable_crates: impl Iterator, ) -> Result { let crate_names = vulnerable_crates .map(|c| c.name.as_str().replace('-', "_")) .collect::>(); let file = File::parse(contents)?; let mut symbols = Vec::new(); for symbol in file.symbols() { let Ok(name) = symbol.name() else { continue; }; // `parse_str::` is expensive. The filter on `crate_names` // eliminates symbols that we know would be irrelevant. if !crate_names .iter() .any(|crate_name| name.contains(crate_name.as_str())) { continue; } let name = format!("{:#}", demangle(name)); if let Ok(type_path) = parse_str::(&name) { symbols.push(flatten_type_path(&type_path)); } } symbols.sort(); symbols.dedup(); Ok(Self(symbols)) } pub(crate) fn filter( &self, affected: impl IntoIterator, ) -> impl Iterator { affected.into_iter().filter(|affected| { let affected = affected .iter() .map(|ident| match ident.as_str().split_once('<') { Some((path, _)) => path, None => ident.as_str(), }) .collect::>(); self.0.iter().any(|symbol| { match (symbol.as_slice(), affected.as_slice()) { ([ident], [affected]) => ident == affected, ( [ident_first, ident_middle @ .., ident_last], [affected_first, affected_middle @ .., affected_last], ) => { // First segments must match (crate name). ident_first == affected_first // In between the first and last segments, the function path segments must // be a subsequence of the symbol segments. && is_subsequence(affected_middle, ident_middle) // Last segments must match (function name). && ident_last == affected_last } (_, _) => false, } }) }) } } fn flatten_type_path(mut type_path: &TypePath) -> Vec { let mut idents = Vec::new(); let mut stack = Vec::new(); loop { stack.push(type_path); if let Some(qself) = &type_path.qself && let Type::Path(inner) = &*qself.ty { type_path = inner; continue; } else { break; } } while let Some(type_path) = stack.pop() { for segment in &type_path.path.segments { // Discard any generic parameters. idents.push(segment.ident.clone()); } } idents } fn is_subsequence(function_path: &[&str], symbol: &[Ident]) -> bool { let mut symbol_iter = symbol.iter(); for function_path_seg in function_path { loop { match symbol_iter.next() { Some(symbol_seg) if symbol_seg == function_path_seg => break, Some(_) => {} None => return false, } } } true } #[cfg(test)] mod tests { use std::{str::FromStr, vec}; use cargo_lock::Name; use rustsec::Version; use super::*; // Test case based on https://rustsec.org/advisories/RUSTSEC-2024-0360 #[test] fn filter() { let package = Package { name: Name::from_str("xmp_toolkit").unwrap(), version: Version::from_str("0.1.0").unwrap(), source: None, replace: None, checksum: None, dependencies: Vec::new(), }; let set = SymbolSet::from_file( include_bytes!("../tests/support/binaries/binary-with-affected-functions"), [&package].into_iter(), ) .unwrap(); let affected = vec![FunctionPath::from_str("xmp_toolkit::XmpFile::close").unwrap()]; let filtered = set.filter(affected).collect::>(); assert_eq!( filtered, vec![FunctionPath::from_str("xmp_toolkit::XmpFile::close").unwrap()] ); } } cargo-audit-0.22.2/src/commands/audit/binary_scanning.rs000064400000000000000000000030351046102023000213170ustar 00000000000000//! The `cargo audit bin` subcommand use crate::{auditor::Auditor, prelude::*}; use clap::Parser; use std::{path::PathBuf, process::exit}; #[cfg(feature = "binary-scanning")] /// The `cargo audit` subcommand #[derive(Command, Clone, Default, Debug, Parser)] #[command()] pub struct BinCommand { /// Maximum binary size in bytes to read #[arg( long = "max-binary-size", value_name = "BYTES", help = "Maximum binary size in bytes to read (default: 100MB; use 0 for unlimited)" )] max_binary_size: Option, /// Maximum audit data size in bytes to parse #[arg( long = "audit-data-size-limit", value_name = "BYTES", help = "Maximum audit data size in bytes to parse (default: 8MB)" )] audit_data_size_limit: Option, /// Paths to the binaries to be scanned #[arg( value_parser, required = true, help = "Paths to the binaries to be scanned" )] binary_paths: Vec, } impl Runnable for BinCommand { fn run(&self) { let mut auditor = self.auditor(); auditor.set_binary_scan_limits(self.max_binary_size, self.audit_data_size_limit); let report = auditor.audit_binaries(&self.binary_paths); if report.vulnerabilities_found { exit(1) } else if report.errors_encountered { exit(2) } else { exit(0) } } } impl BinCommand { /// Initialize `Auditor` pub fn auditor(&self) -> Auditor { Auditor::new(&APP.config()) } } cargo-audit-0.22.2/src/commands/audit/fix.rs000064400000000000000000000144051046102023000167440ustar 00000000000000//! The `cargo audit fix` subcommand use crate::{auditor::Auditor, lockfile, prelude::*}; use abscissa_core::{Command, Runnable}; use cargo_lock::Lockfile; use clap::Parser; use rustsec::{Fixer, advisory::Id}; use std::{ collections::BTreeSet, path::{Path, PathBuf}, process::exit, }; #[derive(Command, Clone, Default, Debug, Parser)] #[command(author, version, about)] pub struct FixCommand { /// Path to `Cargo.lock` #[arg(short = 'f', long = "file", help = "Cargo lockfile to inspect")] file: Option, /// Perform a dry run #[arg(long = "dry-run", help = "perform a dry run for the fix")] dry_run: bool, } impl FixCommand { /// Initialize `Auditor` pub fn auditor(&self) -> Auditor { Auditor::new(&APP.config()) } /// Locate `Cargo.lock` pub fn cargo_lock_path(&self) -> Option<&Path> { self.file.as_deref() } } impl Runnable for FixCommand { fn run(&self) { let path = lockfile::locate_or_generate(self.cargo_lock_path()).unwrap_or_else(|e| { status_err!("{}", e); exit(2); }); let report = self.auditor().audit_lockfile(&path); let report = match report { Ok(report) => { // TODO: also handle warnings if report.vulnerabilities.list.is_empty() { exit(0); } report } Err(e) => { status_err!("{}", e); exit(2); } }; // This should always succeed because the auditor loaded it successfully already let lockfile = Lockfile::load(&path).expect("Failed to load Cargo.lock"); // TODO: allow specifying manifest path let path_to_cargo: Option = std::env::var_os("CARGO").map(|path| path.into()); let fixer = Fixer::new(lockfile, None, path_to_cargo); let dry_run = self.dry_run; if dry_run { status_warn!("Performing a dry run, the fixes will not be applied"); } let mut unpatchable_vulns: BTreeSet = BTreeSet::new(); let mut failed_patches = 0; for vulnerability in &report.vulnerabilities.list { if vulnerability.versions.patched().is_empty() { unpatchable_vulns.insert(vulnerability.advisory.id.clone()); status_warn!( "No patched versions available for {} in crate {}", vulnerability.advisory.id, vulnerability.package.name ); } else { let mut command = fixer.get_fix_command(vulnerability, dry_run); // If the path to Cargo.lock has been specified explicitly, // run the `cargo update` command in that directory if let Some(path) = self.cargo_lock_path() { // documentation on .current_dir() recommends canonicalizing the path let canonical_path = path.canonicalize().unwrap(); let dir = canonical_path.parent().unwrap(); command.current_dir(dir); } // When calling `.status()` the stdout and stderr are inherited from the parent, // so any status or error messages from `cargo update` will automatically be forwarded // to the user of `cargo audit fix`. let status = command.status(); if let Err(e) = status { failed_patches += 1; status_warn!( "Failed to run `cargo update` for package {}: {}", vulnerability.package.name, e ); } } } if failed_patches != 0 { exit(2); } if dry_run { // When performing a dry run, the exit status is determined by whether we had any issues along the way if !unpatchable_vulns.is_empty() { exit(1); } else { exit(0) } } else { // It is possible that some vulns we tried to fix actually weren't fixed, // either because there is no semver-compatible fix or because Cargo.toml version specification // is too restrictive (uses e.g. `=` or `=<` operators). status_ok!( "Verifying", "that the vulnerabilities are fixed after updating dependencies" ); let mut config = (*APP.config()).to_owned(); config.output.quiet = true; let mut auditor = Auditor::new(&config); let report_after_fix = auditor.audit_lockfile(&path).unwrap(); let vulns_after_fix = &report_after_fix.vulnerabilities.list; let fixable_but_unfixed: Vec = vulns_after_fix .iter() .filter(|vuln| !unpatchable_vulns.contains(&vuln.advisory.id)) .map(|vuln| vuln.advisory.id.to_string()) .collect(); if !fixable_but_unfixed.is_empty() { status_warn!( "The following advisories have patched versions but could not be fixed:\n {}\n\ This usually occurs when the fixed version is not semver-compatible,\n\ or the version range specified in your `Cargo.toml` is too restrictive\n\ (e.g. uses `=` or `=<` operators) so the fixed version would not match it.", fixable_but_unfixed.join(", ") ); } let remaining_vulns_count = report_after_fix.vulnerabilities.list.len(); let fixed_vulns_count = report .vulnerabilities .list .len() .saturating_sub(remaining_vulns_count); if fixed_vulns_count != 0 { if remaining_vulns_count == 0 { status_ok!("Fixed", "{} vulnerabilities", fixed_vulns_count); } else { status_warn!( "Fixed {} vulnerabilities but {} remain", fixed_vulns_count, remaining_vulns_count ); } } } } } cargo-audit-0.22.2/src/commands/audit.rs000064400000000000000000000237771046102023000161720ustar 00000000000000//! The `cargo audit` subcommand #[cfg(feature = "fix")] mod fix; #[cfg(feature = "binary-scanning")] mod binary_scanning; use crate::{ auditor::Auditor, config::{AuditConfig, DenyOption, FilterList, OutputFormat}, error::display_err_with_source, lockfile, prelude::*, }; use abscissa_core::{ FrameworkError, FrameworkErrorKind, config::Override, error::Context, terminal::ColorChoice, }; use clap::{Parser, ValueEnum}; use rustsec::platforms::target::{Arch, OS}; use std::{ fmt, io::{self, IsTerminal}, path::PathBuf, process::exit, }; #[cfg(feature = "binary-scanning")] use self::binary_scanning::BinCommand; #[cfg(feature = "fix")] use self::fix::FixCommand; #[cfg(any(feature = "fix", feature = "binary-scanning"))] use clap::Subcommand; #[derive(Debug, Clone, Copy, Default, ValueEnum)] #[value(rename_all = "kebab-case")] // If you change this, remember to update `fmt::Display` impl. enum Color { Always, // TODO: Should this be also supported? // AlwaysAnsi, #[default] Auto, Never, } impl From for ColorChoice { fn from(value: Color) -> Self { match value { Color::Always => ColorChoice::Always, Color::Auto => ColorChoice::Auto, Color::Never => ColorChoice::Never, } } } impl fmt::Display for Color { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // NOTE: This must be in sync with values genereted in ValueEnum implementation. match self { Color::Always => f.write_str("always"), Color::Auto => f.write_str("auto"), Color::Never => f.write_str("never"), } } } /// The `cargo audit` subcommand #[derive(Command, Clone, Default, Debug, Parser)] #[command(version)] pub struct AuditCommand { /// Optional subcommand (used for `cargo audit fix` and `cargo audit bin`) #[cfg(any(feature = "fix", feature = "binary-scanning"))] #[command(subcommand)] subcommand: Option, /// Colored output configuration #[arg( short = 'c', long = "color", help = "color configuration (default: auto)" )] color: Option, /// Filesystem path to the advisory database git repository #[arg( short, long = "db", help = "advisory database git repo path (default: ~/.cargo/advisory-db)" )] db: Option, /// Deny flag #[arg( short = 'D', long = "deny", help = "exit with an error on: warnings (any), unmaintained, unsound, yanked" )] deny: Vec, /// Path to `Cargo.lock` #[arg( short = 'f', long = "file", help = "Cargo lockfile to inspect (or `-` for STDIN, default: Cargo.lock)" )] file: Option, /// Advisory IDs to ignore #[arg( long = "ignore", value_name = "ADVISORY_ID", help = "Advisory id to ignore (can be specified multiple times)" )] ignore: Vec, /// Skip checking for yanked crates #[arg(long = "no-yanked", help = "do not check for yanked crates")] no_yanked: bool, /// Skip fetching the advisory database git repository #[arg( short = 'n', long = "no-fetch", help = "do not perform a git fetch on the advisory DB" )] no_fetch: bool, /// Allow stale advisory databases that haven't been recently updated #[arg(long = "stale", help = "allow stale database")] stale: bool, /// Target CPU architecture to find vulnerabilities for #[arg( long = "target-arch", help = "filter vulnerabilities by CPU (default: no filter). Can be specified multiple times" )] target_arch: Vec, /// Target OS to find vulnerabilities for #[arg( long = "target-os", help = "filter vulnerabilities by OS (default: no filter). Can be specified multiple times" )] target_os: Vec, /// URL to the advisory database git repository #[arg(short = 'u', long = "url", help = "URL for advisory database git repo")] url: Option, /// Quiet mode - avoids printing extraneous information #[arg( short = 'q', long = "quiet", help = "Avoid printing unnecessary information" )] quiet: bool, /// Output format #[arg( long = "format", value_name = "FORMAT", help = "Output format: terminal, json, or sarif" )] output_format: Option, /// Output reports as JSON #[arg(long = "json", help = "Output report in JSON format")] output_json: bool, } /// Subcommands of `cargo audit` #[cfg(any(feature = "fix", feature = "binary-scanning"))] #[derive(Subcommand, Clone, Debug, Runnable)] pub enum AuditSubcommand { /// `cargo audit fix` subcommand #[cfg(feature = "fix")] #[command(about = "automatically upgrade vulnerable dependencies")] Fix(FixCommand), /// `cargo audit bin` subcommand #[cfg(feature = "binary-scanning")] #[command( about = "scan compiled binaries", long_about = "Scan compiled binaries for known vulnerabilities. Performs a complete scan if the binary is built with 'cargo auditable'. If not, recovers a part of the dependency list from panic messages." )] Bin(BinCommand), } impl AuditCommand { /// Get the color configuration pub fn term_colors(&self) -> ColorChoice { if let Some(color) = self.color { return color.into(); } match std::env::var("CARGO_TERM_COLOR") { Ok(e) if e == "always" => ColorChoice::Always, Ok(e) if e == "never" => ColorChoice::Never, Ok(e) if e == "auto" => ColorChoice::Auto, _ => match io::stdout().is_terminal() { true => ColorChoice::Auto, false => ColorChoice::Never, }, } } } impl Override for AuditCommand { fn override_config(&self, config: AuditConfig) -> Result { let mut config = config; if let Some(db) = &self.db { config.database.path = Some(db.into()); } for advisory_id in &self.ignore { config.advisories.ignore.push( advisory_id .parse() .map_err(|e| Context::new(FrameworkErrorKind::ParseError, Some(Box::new(e))))?, ); } config.database.fetch &= !self.no_fetch; config.database.stale |= self.stale; if !self.target_arch.is_empty() { config.target.arch = Some(FilterList::Many(self.target_arch.clone())); } if !self.target_os.is_empty() { config.target.os = Some(FilterList::Many(self.target_os.clone())); } if let Some(url) = &self.url { config.database.url = Some(url.clone()) } for kind in &self.deny { if *kind == DenyOption::Warnings { config.output.deny = DenyOption::all(); } else { config.output.deny.push(*kind); } } config.output.quiet |= self.quiet; if self.quiet { config.output.show_tree = false; } // Handle output format (--json flag takes precedence for backward compatibility) if self.output_json { config.output.format = OutputFormat::Json; } else if let Some(format) = self.output_format { config.output.format = format; } if self.no_yanked { config.yanked.enabled = false; } Ok(config) } } impl Runnable for AuditCommand { fn run(&self) { #[cfg(feature = "fix")] if let Some(AuditSubcommand::Fix(fix)) = &self.subcommand { fix.run(); exit(0) } #[cfg(feature = "binary-scanning")] if let Some(AuditSubcommand::Bin(bin)) = &self.subcommand { bin.run(); exit(0) } let maybe_path = self.file.as_deref(); // It is important to generate the lockfile before initializing the auditor, // otherwise we might deadlock because both need the Cargo package lock let path = lockfile::locate_or_generate(maybe_path).unwrap_or_else(|e| { status_err!("{}", display_err_with_source(&e)); exit(2); }); let mut auditor = self.auditor(); let report = auditor.audit_lockfile(&path); match report { Ok(report) => { if auditor.should_exit_with_failure(&report) { exit(1); } exit(0); } Err(e) => { status_err!("{}", display_err_with_source(&e)); exit(2); } }; } } impl AuditCommand { /// Initialize `Auditor` pub fn auditor(&self) -> Auditor { Auditor::new(&APP.config()) } } #[cfg(test)] mod tests { use super::*; /// Ensure that when the database fetch option is false in the config file /// that it takes precedence when the CLI --no-fetch flag is _not_ set. #[test] fn override_default_fetch_option() { // Assert the default value for the fetch option is true let mut config: AuditConfig = AuditConfig::default(); assert!(config.database.fetch); let mut audit_command = AuditCommand::default(); let overridden_config = audit_command.override_config(config.clone()).unwrap(); assert!(overridden_config.database.fetch); // as the CLI flag --no-fetch is false when not provided // override_config should not change the fetch option // when it is set to false in the config file config.database.fetch = false; let overridden_config = audit_command.override_config(config.clone()).unwrap(); assert!(!overridden_config.database.fetch); config.database.fetch = true; audit_command.no_fetch = true; let overridden_config = audit_command.override_config(config.clone()).unwrap(); assert!(!overridden_config.database.fetch); } } cargo-audit-0.22.2/src/commands.rs000064400000000000000000000056761046102023000150620ustar 00000000000000//! `cargo audit` subcommands // This is fired for code expanded from a derive macro, // but there is nothing explaining what the problem with this is // and what this pattern is bad for other than being less readable when written by humans. // https://github.com/rust-lang/rust/issues/120363 // https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#non-local-definitions // TODO: move this into abscissa-derive #![allow(unknown_lints)] // don't warn/error on older rustc since non_local_definitions is a recent lint #![allow(non_local_definitions)] mod audit; use self::audit::AuditCommand; use crate::config::AuditConfig; use abscissa_core::{Command, Configurable, FrameworkError, Runnable, config::Override}; use clap::Parser; use std::{ops::Deref, path::PathBuf}; /// Name of the configuration file /// /// This file allows setting some default auditing options. pub const CONFIG_FILE: &str = "audit.toml"; /// `cargo audit` subcommands (presently only `audit`) #[derive(Command, Debug, Parser, Runnable)] #[command(bin_name = "cargo")] pub enum CargoAuditSubCommand { /// The `cargo audit` subcommand #[command(about = "Audit Cargo.lock files for vulnerable crates")] Audit(AuditCommand), } /// `cargo audit` entrypoint #[derive(Command, Debug, Parser)] #[command(author, version, about)] pub struct CargoAuditCommand { #[command(subcommand)] cmd: CargoAuditSubCommand, /// Increase verbosity setting #[arg(short = 'v', long, help = "Increase verbosity")] pub verbose: bool, } impl Runnable for CargoAuditCommand { fn run(&self) { self.cmd.run() } } impl Configurable for CargoAuditCommand { /// Location of `audit.toml` (if it exists) fn config_path(&self) -> Option { // Check if the config file exists, and if it does not, ignore it. // // The order of precedence for which config file to use is: // 1. The current project's `.cargo` configuration directory. // 2. The current user's home directory configuration. let project_config_filename = PathBuf::from("./.cargo").join(CONFIG_FILE); if project_config_filename.exists() { return Some(project_config_filename); } let home_config_filename = home::cargo_home() .ok() .map(|cargo_home| cargo_home.join(CONFIG_FILE))?; if home_config_filename.exists() { Some(home_config_filename) } else { None } } /// Override loaded config with explicit command-line arguments fn process_config(&self, config: AuditConfig) -> Result { match &self.cmd { CargoAuditSubCommand::Audit(cmd) => cmd.override_config(config), } } } impl Deref for CargoAuditCommand { type Target = AuditCommand; fn deref(&self) -> &AuditCommand { match &self.cmd { CargoAuditSubCommand::Audit(cmd) => cmd, } } } cargo-audit-0.22.2/src/config.rs000064400000000000000000000243261046102023000145170ustar 00000000000000//! The configuration file use rustsec::{ Error, ErrorKind, WarningKind, advisory, platforms::target::{Arch, OS}, report, }; use serde::{Deserialize, Serialize}; use std::{path::PathBuf, str::FromStr}; /// `cargo audit` configuration: /// /// An optional TOML config file located in `~/.cargo/audit.toml` or /// `.cargo/audit.toml`. #[derive(Clone, Debug, Default, Deserialize, Serialize)] #[serde(deny_unknown_fields)] pub struct AuditConfig { /// Advisory-related configuration #[serde(default)] pub advisories: AdvisoryConfig, /// Advisory Database configuration #[serde(default)] pub database: DatabaseConfig, /// Output configuration #[serde(default)] pub output: OutputConfig, /// Target-related configuration #[serde(default)] pub target: TargetConfig, /// Configuration for auditing for yanked crates #[serde(default)] pub yanked: YankedConfig, } impl AuditConfig { /// Get audit report settings from the configuration pub fn report_settings(&self) -> report::Settings { let mut settings = report::Settings { ignore: self.advisories.ignore.clone(), severity: self.advisories.severity_threshold, target_arch: self.target.arch(), target_os: self.target.os(), ..Default::default() }; if let Some(informational_warnings) = &self.advisories.informational_warnings { settings .informational_warnings .clone_from(informational_warnings); } else { // Alert for all informational packages by default settings.informational_warnings = vec![ advisory::Informational::Unmaintained, advisory::Informational::Unsound, advisory::Informational::Notice, ]; } // Enable warnings for all informational advisories if they are marked deny. // Deny only works on the output if a corresponding advisory is found but only the // informational categories listed in informational_warnings are reported. // This means that if "Unsound" is missing from informational_warnings then deny unsound // will not do anything. // To fix this always add the corresponding warning category let mut insert_if_not_present = |warning| { if !settings.informational_warnings.contains(&warning) { settings.informational_warnings.push(warning); } }; for deny in &self.output.deny { match deny { DenyOption::Warnings => { insert_if_not_present(advisory::Informational::Notice); insert_if_not_present(advisory::Informational::Unmaintained); insert_if_not_present(advisory::Informational::Unsound); break; } DenyOption::Unmaintained => { insert_if_not_present(advisory::Informational::Unmaintained) } DenyOption::Unsound => insert_if_not_present(advisory::Informational::Unsound), DenyOption::Yanked => continue, }; } settings } } /// Advisory-related configuration. #[derive(Clone, Debug, Default, Deserialize, Serialize)] #[serde(deny_unknown_fields)] pub struct AdvisoryConfig { /// Ignore advisories for the given IDs #[serde(default)] pub ignore: Vec, /// Warn for the given types of informational advisories pub informational_warnings: Option>, /// CVSS Qualitative Severity Rating Scale threshold to alert at. /// /// Vulnerabilities with explicit CVSS info which have a severity below /// this threshold will be ignored. pub severity_threshold: Option, } /// Advisory Database configuration. /// /// The advisory database is stored in a Git repository. This section of the /// configuration stores settings related to it. #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(deny_unknown_fields)] pub struct DatabaseConfig { /// Path to the local copy of advisory database's git repo (default: ~/.cargo/advisory-db) pub path: Option, /// URL to the advisory database's git repo (default: ) pub url: Option, /// Perform a `git fetch` before auditing (default: true) #[serde(default = "default_true")] pub fetch: bool, /// Allow a stale advisory database? (i.e. one which hasn't been updated in 90 days) pub stale: bool, } impl Default for DatabaseConfig { fn default() -> Self { Self { path: None, url: None, fetch: true, stale: false, } } } /// Output configuration #[derive(Clone, Debug, Default, Deserialize, Serialize)] #[serde(deny_unknown_fields)] pub struct OutputConfig { /// Disallow advisories which trigger warnings #[serde(default)] pub deny: Vec, /// Output format to use #[serde(default)] pub format: OutputFormat, /// Enable quiet mode pub quiet: bool, /// Show inverse dependency trees along with advisories (default: true) #[serde(default = "default_show_tree")] pub show_tree: bool, } impl OutputConfig { /// Is quiet mode enabled? pub fn is_quiet(&self) -> bool { self.quiet || self.format == OutputFormat::Json || self.format == OutputFormat::Sarif } } fn default_show_tree() -> bool { true } /// Warning kinds #[derive(Copy, Clone, Debug, Deserialize, Eq, Hash, PartialEq, PartialOrd, Serialize, Ord)] pub enum DenyOption { /// Deny all warnings #[serde(rename = "warnings")] Warnings, /// Deny unmaintained dependency warnings #[serde(rename = "unmaintained")] Unmaintained, /// Deny unsound dependency warnings #[serde(rename = "unsound")] Unsound, /// Deny yanked dependency warnings #[serde(rename = "yanked")] Yanked, } impl DenyOption { /// Get all of the possible warnings to be denied pub fn all() -> Vec { vec![ DenyOption::Warnings, DenyOption::Unmaintained, DenyOption::Unsound, DenyOption::Yanked, ] } /// Get the warning::Kind that corresponds to self, if applicable pub fn get_warning_kind(self) -> &'static [WarningKind] { match self { DenyOption::Warnings => &[ WarningKind::Unmaintained, WarningKind::Unsound, WarningKind::Yanked, ], DenyOption::Unmaintained => &[WarningKind::Unmaintained], DenyOption::Unsound => &[WarningKind::Unsound], DenyOption::Yanked => &[WarningKind::Yanked], } } } impl FromStr for DenyOption { type Err = Error; fn from_str(s: &str) -> Result { match s { "warnings" => Ok(DenyOption::Warnings), "unmaintained" => Ok(DenyOption::Unmaintained), "unsound" => Ok(DenyOption::Unsound), "yanked" => Ok(DenyOption::Yanked), other => Err(Error::new( ErrorKind::Parse, format!("invalid deny option: {other}"), )), } } } /// Output format #[derive(Default, Copy, Clone, Debug, Deserialize, Eq, PartialEq, Serialize, clap::ValueEnum)] pub enum OutputFormat { /// Display JSON #[serde(rename = "json")] Json, /// Display SARIF (Static Analysis Results Interchange Format) #[serde(rename = "sarif")] Sarif, /// Display human-readable output to the terminal #[serde(rename = "terminal")] #[default] Terminal, } impl FromStr for OutputFormat { type Err = Error; fn from_str(s: &str) -> Result { match s { "json" => Ok(OutputFormat::Json), "sarif" => Ok(OutputFormat::Sarif), "terminal" => Ok(OutputFormat::Terminal), other => Err(Error::new( ErrorKind::Parse, format!("invalid output format: {other}"), )), } } } /// Helper enum for configuring filter values /// /// This enum exists for backwards compatibility reasons. /// In `cargo-audit` versions `<= 0.20.0` target's config /// options `arch` and `os` were deserialized from a single /// string. But following next minor release those values can be /// configured as a list. Serde's untagged enum provides /// dispatch that is backwards compatible. #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(untagged)] pub enum FilterList { /// Legacy, single filter value Single(T), /// List of filters Many(Vec), } /// Target configuration #[derive(Clone, Debug, Default, Deserialize, Serialize)] #[serde(deny_unknown_fields)] pub struct TargetConfig { /// Target architecture to find vulnerabilities for pub arch: Option>, /// Target OS to find vulnerabilities for pub os: Option>, } impl TargetConfig { /// Returns list of configured target architectures, cloning if needed pub fn arch(&self) -> Vec { match &self.arch { Some(FilterList::Single(single)) => vec![*single], Some(FilterList::Many(many)) => many.clone(), None => vec![], } } /// Returns list of configured target operating systems, cloning if needed pub fn os(&self) -> Vec { match &self.os { Some(FilterList::Single(single)) => vec![*single], Some(FilterList::Many(many)) => many.clone(), None => vec![], } } } /// Configuration for auditing for yanked crates #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(deny_unknown_fields)] pub struct YankedConfig { /// Is auditing for yanked crates enabled? #[serde(default = "default_true")] pub enabled: bool, /// Should the crates.io index be updated before checking for yanked crates? #[serde(default = "default_true")] pub update_index: bool, } impl Default for YankedConfig { fn default() -> Self { Self { enabled: true, update_index: true, } } } /// Helper function for returning a default of `true` fn default_true() -> bool { true } cargo-audit-0.22.2/src/error.rs000064400000000000000000000056331046102023000144030ustar 00000000000000//! Error types use abscissa_core::error::{BoxError, Context}; use std::{ error::Error as ErrorTrait, fmt::{self, Display}, io, ops::Deref, }; use thiserror::Error; /// Kinds of errors #[derive(Copy, Clone, Debug, Eq, Error, PartialEq)] pub enum ErrorKind { /// Error in configuration file #[error("config error")] Config, /// Input/output error #[error("I/O error")] Io, /// Parse errors #[error("parse error")] Parse, /// Repository errors #[error("git repo error")] Repo, /// Version errors #[error("version error")] Version, /// Other kinds of errors #[error("other error")] Other, } impl ErrorKind { /// Create an error context from this error pub fn context(self, source: impl Into) -> Context { Context::new(self, Some(source.into())) } } /// Error type #[derive(Debug)] pub struct Error(Box>); impl Error { /// Get the kind of error that occurred pub fn kind(&self) -> ErrorKind { *self.0.kind() } } impl Deref for Error { type Target = Context; fn deref(&self) -> &Context { &self.0 } } impl Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) } } impl From> for Error { fn from(context: Context) -> Self { Error(Box::new(context)) } } impl From for Error { fn from(other: io::Error) -> Self { ErrorKind::Io.context(other).into() } } impl From for Error { fn from(err: rustsec::Error) -> Self { match err.kind() { rustsec::ErrorKind::Io => ErrorKind::Io, rustsec::ErrorKind::Parse => ErrorKind::Parse, rustsec::ErrorKind::Repo => ErrorKind::Repo, rustsec::ErrorKind::Version => ErrorKind::Version, _ => ErrorKind::Other, } .context(err) .into() } } impl From for Error { fn from(err: cargo_lock::Error) -> Self { match err { cargo_lock::Error::Io(_) => ErrorKind::Io, cargo_lock::Error::Parse(_) => ErrorKind::Parse, cargo_lock::Error::Version(_) => ErrorKind::Version, _ => ErrorKind::Other, } .context(err) .into() } } impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { self.0.source() } } /// Displays the error and also follows the chain of the `.source` fields, /// printing any errors that caused the top-level error. /// /// This is required to properly present some `gix` errors to the user: /// pub fn display_err_with_source(error: &E) -> String { display_error_chain::DisplayErrorChain::new(error).to_string() } cargo-audit-0.22.2/src/lib.rs000064400000000000000000000020271046102023000140120ustar 00000000000000//! Audit Cargo.lock files for crates containing security vulnerabilities. //! //! `cargo audit` is a Cargo subcommand. Install it using the following: //! //! ```text //! $ cargo install cargo-audit //! ``` //! //! Then run `cargo audit` in the toplevel directory of any crate or workspace. //! //! If you wish to consume its core functionality as a library, see the //! documentation for the `rustsec` crate: //! //! #![doc( html_logo_url = "https://raw.githubusercontent.com/RustSec/logos/main/rustsec-logo-lg.png", html_root_url = "https://docs.rs/cargo-audit/0.16.0" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms, trivial_casts, unused_qualifications)] pub mod application; pub mod auditor; pub mod commands; pub mod config; pub mod error; pub mod lockfile; mod prelude; pub mod presenter; mod sarif; pub use sarif::SarifLog; #[cfg(feature = "binary-scanning")] mod binary_scanning; /// Current version of the `cargo-audit` crate pub const VERSION: &str = env!("CARGO_PKG_VERSION"); cargo-audit-0.22.2/src/lockfile.rs000064400000000000000000000030711046102023000150340ustar 00000000000000//! Cargo.lock-related utilities use rustsec::{Error, ErrorKind}; use std::{ path::{Path, PathBuf}, process::Command, }; /// Name of `Cargo.lock` const CARGO_LOCK_FILE: &str = "Cargo.lock"; /// Tries to locate the lockfile at the specified file path. If it's missing, tries to generate it from `Cargo.toml`. /// Defaults to `Cargo.lock` in the current directory if passed `None` as the path. pub fn locate_or_generate(maybe_lockfile_path: Option<&Path>) -> rustsec::Result { match maybe_lockfile_path { Some(p) => Ok(p.into()), None => { let path = Path::new(CARGO_LOCK_FILE); if !path.exists() && Path::new("Cargo.toml").exists() { generate()?; } Ok(path.into()) } } } /// Run `cargo generate-lockfile` pub fn generate() -> rustsec::Result<()> { let status = Command::new("cargo") .arg("update") .arg("--workspace") .status(); if let Err(e) = status { return Err(Error::with_source( ErrorKind::Io, "couldn't run `cargo update --workspace` to generate a lockfile".to_string(), e, )); } let status = status.unwrap(); if !status.success() { let msg = match status.code() { Some(code) => { format!("non-zero exit status running `cargo update --workspace`: {code}") } _ => "no exit status running `cargo update --workspace`!".to_string(), }; return Err(Error::new(ErrorKind::Io, msg)); } Ok(()) } cargo-audit-0.22.2/src/prelude.rs000064400000000000000000000004031046102023000147000ustar 00000000000000//! Application-local prelude: conveniently import types/functions/macros //! which are generally useful and should be available everywhere. /// Abscissa core prelude pub use abscissa_core::prelude::*; /// Application state pub use crate::application::APP; cargo-audit-0.22.2/src/presenter.rs000064400000000000000000000525361046102023000152650ustar 00000000000000//! Presenter for `rustsec::Report` information. use std::{collections::BTreeSet as Set, io, path::Path}; use std::{io::Write as _, string::ToString as _}; use abscissa_core::terminal::{ self, Color::{self, Red, Yellow}, }; use rustsec::{ Vulnerability, Warning, WarningKind, advisory::License, cargo_lock::{ Lockfile, Package, dependency::{Dependency, Tree, graph::EdgeDirection}, }, }; #[cfg(feature = "binary-scanning")] use rustsec::{advisory::affected::FunctionPath, binary_scanning::BinaryReport}; #[cfg(feature = "binary-scanning")] use crate::binary_scanning::SymbolSet; use crate::{ config::{DenyOption, OutputConfig, OutputFormat}, prelude::*, }; /// Vulnerability information presenter #[derive(Clone, Debug)] pub struct Presenter { /// Keep track packages we've displayed once so we don't show the same dep tree // TODO(tarcieri): group advisories about the same package? displayed_packages: Set, /// Keep track of the warning kinds that correspond to deny-warnings options deny_warning_kinds: Set, /// Output configuration config: OutputConfig, /// Binary contents for affected-function analysis #[cfg(feature = "binary-scanning")] binary_contents: Option>, } impl Presenter { /// Create a new vulnerability information presenter pub fn new(config: &OutputConfig) -> Self { Self { displayed_packages: Set::new(), deny_warning_kinds: config .deny .iter() .flat_map(|k| k.get_warning_kind()) .copied() .collect(), config: config.clone(), #[cfg(feature = "binary-scanning")] binary_contents: None, } } /// Set the binary contents for affected-function analysis #[cfg(feature = "binary-scanning")] pub fn set_binary_contents(&mut self, contents: Vec) { self.binary_contents = Some(contents); } /// Information to display before a report is generated pub fn before_report(&mut self, path: &Path, lockfile: &Lockfile) { if !self.config.is_quiet() { status_ok!( "Scanning", "{} for vulnerabilities ({} crate dependencies)", path.display(), lockfile.packages.len(), ); } } #[cfg(feature = "binary-scanning")] /// Information to display before a binary file is scanned pub fn binary_scan_report(&mut self, report: &BinaryReport, path: &Path) { use rustsec::binary_scanning::BinaryReport::*; if !self.config.is_quiet() { match report { Complete(lockfile) => status_ok!( "Found", "'cargo auditable' data in {} ({} dependencies)", path.display(), lockfile.packages.len() ), Incomplete(lockfile) => { status_warn!( "{} was not built with 'cargo auditable', the report will be incomplete ({} dependencies recovered)", path.display(), lockfile.packages.len() ); } None => status_err!( "No dependency information found in {}! Is it a Rust program built with cargo?", path.display(), ), } } } fn warning_word(&self, count: u64) -> &str { if count != 1 { "warnings" } else { "warning" } } /// Print the vulnerability report generated by an audit pub fn print_report( &mut self, report: &rustsec::Report, lockfile: &Lockfile, path: Option<&Path>, ) { match self.config.format { OutputFormat::Json => { let mut stdout = io::stdout().lock(); serde_json::to_writer(&mut stdout, &report).unwrap(); // End with a newline as a terminator/separator. Another json report may follow. writeln!(&mut stdout).unwrap(); return; } OutputFormat::Sarif => { let cargo_lock_path = path .map(|p| p.to_string_lossy().into_owned()) .unwrap_or_else(|| "Cargo.lock".to_string()); let sarif_log = crate::sarif::SarifLog::from_report(report, &cargo_lock_path); let mut stdout = io::stdout().lock(); serde_json::to_writer(&mut stdout, &sarif_log).unwrap(); // End with a newline as a terminator/separator. Another sarif report may follow. writeln!(&mut stdout).unwrap(); return; } OutputFormat::Terminal => { // Continue with terminal output below } } let tree = lockfile .dependency_tree() .expect("invalid Cargo.lock dependency tree"); #[cfg(feature = "binary-scanning")] let symbols = match &self.binary_contents { Some(binary_contents) => { let packages = report .vulnerabilities .list .iter() .map(|v| &v.package) .chain(report.warnings.values().flatten().map(|w| &w.package)); match SymbolSet::from_file(binary_contents, packages) { Ok(symbols) => Some(symbols), Err(e) => { status_warn!( "Failed to extract symbols from binary for affected-function analysis: {}", e ); None } } } None => None, }; // NOTE: when modifying the following logic, be sure to also update should_exit_with_failure() // Print out vulnerabilities and warnings for vulnerability in &report.vulnerabilities.list { self.print_vulnerability(vulnerability); #[cfg(feature = "binary-scanning")] if let Some(symbols) = &symbols { self.print_affected( Red, symbols.filter(vulnerability.affected_functions().unwrap_or_default()), ); } self.print_tree(Red, &vulnerability.package, &tree); println!(); } for warnings in report.warnings.values() { for warning in warnings.iter() { let color = self.warning_color(self.deny_warning_kinds.contains(&warning.kind)); self.print_warning(warning, color); #[cfg(feature = "binary-scanning")] if let Some(symbols) = &symbols { self.print_affected( color, symbols.filter( warning .affected .as_ref() .map(|affected| affected.functions.iter()) .unwrap_or_default() .filter_map(|(path, version_reqs)| { if version_reqs .iter() .any(|req| req.matches(&warning.package.version)) { Some(path.clone()) } else { None } }), ), ); } self.print_tree(color, &warning.package, &tree); println!(); } } if report.vulnerabilities.found { if report.vulnerabilities.count == 1 { match path { Some(path) => status_err!("1 vulnerability found in {}", path.display()), None => status_err!("1 vulnerability found!"), } } else { match path { Some(path) => status_err!( "{} vulnerabilities found in {}", report.vulnerabilities.count, path.display() ), None => status_err!("{} vulnerabilities found!", report.vulnerabilities.count), } } } let (num_denied, num_not_denied) = self.count_warnings(report); if num_denied > 0 || num_not_denied > 0 { if num_denied > 0 { match path { Some(path) => status_err!( "{} denied {} found in {}", num_denied, self.warning_word(num_denied), path.display(), ), None => status_err!( "{} denied {} found!", num_denied, self.warning_word(num_denied) ), } } if num_not_denied > 0 { match path { Some(path) => status_warn!( "{} allowed {} found in {}", num_not_denied, self.warning_word(num_not_denied), path.display(), ), None => status_warn!( "{} allowed {} found", num_not_denied, self.warning_word(num_not_denied) ), } } } } /// Print the vulnerability report for cargo-audit pub fn print_self_report(&mut self, self_advisories: &[rustsec::Advisory]) { if self_advisories.is_empty() { return; } // Print out any self-advisories let msg = "This copy of cargo-audit has known advisories! Upgrade cargo-audit to the \ latest version: cargo install --force cargo-audit"; if self.config.deny.contains(&DenyOption::Warnings) { status_err!(msg); } else { status_warn!(msg); } for advisory in self_advisories { self.print_metadata( &advisory.metadata, self.warning_color(self.config.deny.contains(&DenyOption::Warnings)), ); } println!(); } /// Determines whether the process should exit with failure based on configuration /// such as --deny=warnings #[must_use] pub fn should_exit_with_failure(&self, report: &rustsec::Report) -> bool { if report.vulnerabilities.found { return true; } let (denied, _allowed) = self.count_warnings(report); if denied != 0 { return true; } false } /// Determines whether the process should exit with failure based on configuration /// such as --deny=warnings #[must_use] pub fn should_exit_with_failure_due_to_self( &self, self_advisories: &[rustsec::Advisory], ) -> bool { !self_advisories.is_empty() && self.config.deny.contains(&DenyOption::Warnings) } /// Count up the warnings, sorting into denied and allowed. /// Returns `(denied, allowed)` fn count_warnings(&self, report: &rustsec::Report) -> (u64, u64) { let mut num_denied: u64 = 0; let mut num_not_denied: u64 = 0; for (kind, warnings) in report.warnings.iter() { if self.deny_warning_kinds.contains(kind) { num_denied += warnings.len() as u64; } else { num_not_denied += warnings.len() as u64; } } (num_denied, num_not_denied) } /// Print information about the given vulnerability fn print_vulnerability(&self, vulnerability: &Vulnerability) { self.print_attr(Red, "Crate: ", &vulnerability.package.name); self.print_attr(Red, "Version: ", vulnerability.package.version.to_string()); self.print_metadata(&vulnerability.advisory, Red); if vulnerability.versions.patched().is_empty() { self.print_attr(Red, "Solution: ", "No fixed upgrade is available!"); } else { self.print_attr( Red, "Solution: ", format!( "Upgrade to {}", vulnerability .versions .patched() .iter() .map(ToString::to_string) .collect::>() .as_slice() .join(" OR ") ), ); } } /// Print information about a given warning fn print_warning(&self, warning: &Warning, color: Color) { self.print_attr(color, "Crate: ", &warning.package.name); self.print_attr(color, "Version: ", warning.package.version.to_string()); self.print_attr(color, "Warning: ", warning.kind.as_str()); if let Some(metadata) = &warning.advisory { self.print_metadata(metadata, color) } } /// Get the color to use when displaying warnings fn warning_color(&self, deny_warning: bool) -> Color { if deny_warning { Red } else { Yellow } } /// Print a warning about a particular advisory fn print_metadata(&self, metadata: &rustsec::advisory::Metadata, color: Color) { self.print_attr(color, "Title: ", &metadata.title); self.print_attr(color, "Date: ", &metadata.date); self.print_attr(color, "ID: ", &metadata.id); if metadata.license == License::CcBy40 { // We must preserve the original URL from the `url` field if let Some(url) = &metadata.url { self.print_attr(color, "URL: ", url); } else if let Some(url) = &metadata.id.url() { self.print_attr(color, "URL: ", url); } } else { // Prefer ID URL because the `url` field usually points to a bug tracker // or any other non-canonical source rather than an actual security advisory if let Some(url) = &metadata.id.url() { self.print_attr(color, "URL: ", url); } else if let Some(url) = &metadata.url { self.print_attr(color, "URL: ", url); } } if let Some(cvss) = &metadata.cvss { self.print_attr( color, "Severity: ", format!("{} ({})", cvss.score(), cvss.severity()), ); } } /// Display an attribute of a particular vulnerability fn print_attr(&self, color: Color, attr: &str, content: impl AsRef) { terminal::status::Status::new() .bold() .color(color) .status(attr) .print_stdout(content.as_ref()) .unwrap(); } #[cfg(feature = "binary-scanning")] fn print_affected(&self, color: Color, funcs: impl IntoIterator) { let mut funcs = funcs.into_iter().peekable(); if funcs.peek().is_none() { return; } self.print_attr( color, "Affected: ", funcs .map(|func| func.to_string()) .collect::>() .join(", "), ); } /// Print the inverse dependency tree to standard output fn print_tree(&mut self, color: Color, package: &Package, tree: &Tree) { // Only show the tree once per package if !self.displayed_packages.insert(Dependency::from(package)) { return; } if !self.config.show_tree { return; } terminal::status::Status::new() .bold() .color(color) .status("Dependency tree:\n") .print_stdout("") .unwrap(); let package_node = tree.nodes()[&Dependency::from(package)]; tree.render( &mut io::stdout(), package_node, EdgeDirection::Incoming, false, ) .unwrap(); } } #[cfg(test)] mod tests { use abscissa_core::testing::{CmdRunner, process::Process}; use once_cell::sync::Lazy; use std::{ collections::{BTreeMap, BTreeSet}, io::Read, path::Path, str::from_utf8, }; use tempfile::TempDir; #[test] fn affected_functions() { let binary_path = Path::new("tests/support/binaries/binary-with-affected-functions"); // Run `cargo audit bin...` on the binary and read its stdout. let mut cmd = RUNNER.clone(); let mut process = cmd.arg(binary_path).capture_stdout().capture_stderr().run(); let reports = read_process_stdout(&mut process); // Ensure `cargo audit bin...` exits with 1. let status = process.wait().unwrap(); assert_eq!(1, status.code()); // Verify that all of the expected affected functions were reported. for (id, function_paths) in EXPECTED_FUNCTION_PATHS { let report = reports .iter() .find(|map| map.get("ID").unwrap() == id) .unwrap_or_else(|| panic!("failed to find {id}")); let affected = report .get("Affected") .unwrap_or_else(|| panic!("{id} has no 'Affected' line")); assert_eq!(function_paths.join(", "), *affected); } // Verify that each report with an "Affected" line was expected. for report in reports { if !report.contains_key("Affected") { continue; } let id = report.get("ID").unwrap(); assert!( EXPECTED_FUNCTION_PATHS.iter().any(|(key, _)| key == id), "{id} has unexpected 'Affected' line" ); } } fn read_process_stdout(process: &mut Process<'_>) -> BTreeSet> { let stdout = process.stdout(); let mut buf = Vec::new(); stdout.read_to_end(&mut buf).unwrap(); let s = from_utf8(&buf).unwrap(); let mut reports = BTreeSet::new(); let mut report = BTreeMap::new(); for line in s.lines() { let Some(index) = line.as_bytes().iter().position(|&x| x == b':') else { continue; }; let key = &line[..index]; let value = line[index + 1..].trim_start(); // Assume "Crate:" starts a new report. if key == "Crate" && !report.is_empty() { reports.insert(report); report = BTreeMap::new(); } report.insert(key.to_owned(), value.to_owned()); } if !report.is_empty() { reports.insert(report); } reports } #[rustfmt::skip] const EXPECTED_FUNCTION_PATHS: &[(&str, &[&str])] = &[ ("RUSTSEC-2019-0036", &["failure::Fail::__private_get_type_id__"]), ("RUSTSEC-2020-0071", &["time::OffsetDateTime::now_local", "time::OffsetDateTime::try_now_local", "time::UtcOffset::current_local_offset", "time::UtcOffset::local_offset_at", "time::UtcOffset::try_current_local_offset", "time::UtcOffset::try_local_offset_at"]), ("RUSTSEC-2020-0075", &["branca::Branca::decode", "branca::decode"]), ("RUSTSEC-2021-0041", &["parse_duration::parse"]), ("RUSTSEC-2022-0004", &["rustc_serialize::json::Json::from_str"]), ("RUSTSEC-2022-0067", &["lzf::compress", "lzf::decompress"]), ("RUSTSEC-2023-0032", &["ntru::types::PrivateKey::export", "ntru::types::PublicKey::export"]), ("RUSTSEC-2023-0054", &["mail_internals::utils::vec_insert_bytes"]), ("RUSTSEC-2024-0018", &["crayon::utils::object_pool::ObjectPool::free"]), ("RUSTSEC-2024-0020", &["whoami::realname", "whoami::realname_os", "whoami::username", "whoami::username_os"]), ("RUSTSEC-2024-0360", &["xmp_toolkit::XmpFile::close"]), ("RUSTSEC-2024-0401", &["zlib_rs::inflate::inflate"]), ("RUSTSEC-2024-0404", &["anstream::adapter::strip_str"]), ("RUSTSEC-2024-0442", &["wasmtime_jit_debug::perf_jitdump::JitDumpFile::dump_code_load_record"]), ("RUSTSEC-2025-0027", &["mp3_metadata::read_from_slice"]), ("RUSTSEC-2025-0113", &["shaman::cryptoutil::read_u32v_be", "shaman::cryptoutil::read_u32v_le", "shaman::cryptoutil::read_u64v_be", "shaman::cryptoutil::read_u64v_le", "shaman::cryptoutil::write_u32v_le", "shaman::cryptoutil::write_u64v_le"]), ("RUSTSEC-2025-0131", &["rtvm_interpreter::Interpreter::program_counter"]), ("RUSTSEC-2025-0136", &["sequoia_openpgp::crypto::ecdh::aes_key_unwrap"]), ("RUSTSEC-2025-0137", &["ruint::algorithms::div::reciprocal_mg10"]), ("RUSTSEC-2025-0140", &["gix_date::parse::TimeBuf::as_str"]), ("RUSTSEC-2026-0097", &["rand::rng"]), ]; static RUNNER: Lazy = Lazy::new(|| { let mut runner = CmdRunner::default(); runner .arg("audit") .arg("--color=never") .arg("--db") .arg(ADVISORY_DB_DIR.path()) .arg("bin"); runner }); static ADVISORY_DB_DIR: Lazy = Lazy::new(|| TempDir::new().unwrap()); } cargo-audit-0.22.2/src/sarif.rs000064400000000000000000000340551046102023000143560ustar 00000000000000//! SARIF (Static Analysis Results Interchange Format) output support //! //! This module provides functionality to convert cargo-audit reports to SARIF format, //! which can be uploaded to GitHub Security tab and other security analysis platforms. //! //! SARIF is an OASIS Standard that defines a common format for static analysis tools //! to report their findings. This implementation follows SARIF 2.1.0 specification //! and is compatible with GitHub's code scanning requirements. use std::collections::{HashMap, HashSet}; use rustsec::{Report, Vulnerability, Warning, WarningKind, advisory}; use serde::{Serialize, Serializer, ser::SerializeStruct}; /// SARIF log root object #[derive(Debug)] pub struct SarifLog { /// Array of analysis runs runs: Vec, } impl SarifLog { /// Convert a cargo-audit report to SARIF format pub fn from_report(report: &Report, cargo_lock_path: &str) -> Self { Self { runs: vec![Run::from_report(report, cargo_lock_path)], } } } impl Serialize for SarifLog { fn serialize(&self, serializer: S) -> Result { let mut state = Serializer::serialize_struct(serializer, "SarifLog", 3)?; state.serialize_field("$schema", "https://json.schemastore.org/sarif-2.1.0.json")?; state.serialize_field("version", "2.1.0")?; state.serialize_field("runs", &self.runs)?; state.end() } } /// A run represents a single invocation of an analysis tool #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct Run { /// Tool information for this run tool: Tool, /// Array of results (findings) from the analysis results: Vec, } impl Run { fn from_report(report: &Report, cargo_lock_path: &str) -> Self { let mut rules = Vec::new(); let mut seen_rules = HashSet::new(); let mut results = Vec::new(); for vuln in &report.vulnerabilities.list { let rule_id = vuln.advisory.id.to_string(); if seen_rules.insert(rule_id.clone()) { rules.push(ReportingDescriptor::from_advisory(&vuln.advisory, true)); } results.push(SarifResult::from_vulnerability(vuln, cargo_lock_path)); } for (warning_kind, warnings) in &report.warnings { for warning in warnings { let rule_id = if let Some(advisory) = &warning.advisory { advisory.id.to_string() } else { format!("{warning_kind:?}").to_lowercase() }; if seen_rules.insert(rule_id) { rules.push(match &warning.advisory { Some(advisory) => ReportingDescriptor::from_advisory(advisory, false), None => ReportingDescriptor::from_warning_kind(*warning_kind), }); } results.push(SarifResult::from_warning(warning, cargo_lock_path)); } } Self { tool: Tool { driver: ToolComponent { rules }, }, results, } } } /// Tool information #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] struct Tool { /// The analysis tool that was run driver: ToolComponent, } /// Tool component (driver) information #[derive(Debug)] struct ToolComponent { /// Rules defined by this tool rules: Vec, } impl Serialize for ToolComponent { fn serialize(&self, serializer: S) -> Result { let mut state = serializer.serialize_struct("ToolComponent", 4)?; state.serialize_field("name", "cargo-audit")?; state.serialize_field("version", env!("CARGO_PKG_VERSION"))?; state.serialize_field("semanticVersion", env!("CARGO_PKG_VERSION"))?; state.serialize_field("rules", &self.rules)?; state.end() } } /// Rule/reporting descriptor #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] struct ReportingDescriptor { /// Unique identifier for the rule id: String, /// Human-readable name of the rule name: String, /// Brief description of the rule short_description: MultiformatMessageString, /// Detailed description of the rule #[serde(skip_serializing_if = "Option::is_none")] full_description: Option, /// Default severity and enablement for the rule default_configuration: ReportingConfiguration, /// Help text or URI for the rule #[serde(skip_serializing_if = "Option::is_none")] help: Option, /// Additional properties including tags and severity scores properties: RuleProperties, } impl ReportingDescriptor { /// Create a ReportingDescriptor from an advisory fn from_advisory(metadata: &advisory::Metadata, is_vulnerability: bool) -> Self { let tags = if is_vulnerability { &[Tag::Security, Tag::Vulnerability] } else { &[Tag::Security, Tag::Warning] }; let security_severity = metadata .cvss .as_ref() .map(|cvss| format!("{:.1}", cvss.score())); ReportingDescriptor { id: metadata.id.to_string(), name: metadata.id.to_string(), short_description: MultiformatMessageString { text: metadata.title.clone(), markdown: None, }, full_description: if metadata.description.is_empty() { None } else { Some(MultiformatMessageString { text: metadata.description.clone(), markdown: None, }) }, default_configuration: ReportingConfiguration { level: match is_vulnerability { true => ReportingLevel::Error, false => ReportingLevel::Warning, }, }, help: metadata.url.as_ref().map(|url| MultiformatMessageString { text: format!("For more information, see: {url}"), markdown: Some(format!( "For more information, see: [{}]({url})", metadata.id )), }), properties: RuleProperties { tags, precision: Precision::VeryHigh, problem_severity: if !is_vulnerability { Some(ProblemSeverity::Warning) } else { None }, security_severity, }, } } /// Create a ReportingDescriptor from a warning kind fn from_warning_kind(kind: WarningKind) -> Self { let (name, description) = match kind { WarningKind::Unmaintained => ( "unmaintained", "Package is unmaintained and may have unaddressed security vulnerabilities", ), WarningKind::Unsound => ( "unsound", "Package has known soundness issues that may lead to memory safety problems", ), WarningKind::Yanked => ( "yanked", "Package version has been yanked from the registry", ), _ => ("unknown", "Unknown warning type"), }; ReportingDescriptor { id: name.to_string(), name: name.to_string(), short_description: MultiformatMessageString { text: description.to_string(), markdown: None, }, full_description: None, default_configuration: ReportingConfiguration { level: ReportingLevel::Warning, }, help: None, properties: RuleProperties { tags: &[Tag::Security, Tag::Warning], precision: Precision::High, problem_severity: Some(ProblemSeverity::Warning), security_severity: None, }, } } } /// Rule properties #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] struct RuleProperties { /// Tags associated with the rule #[serde(skip_serializing_if = "<[Tag]>::is_empty")] tags: &'static [Tag], /// Precision of the rule (e.g., "very-high", "high") precision: Precision, /// Problem severity for non-security issues #[serde(skip_serializing_if = "Option::is_none")] #[serde(rename = "problem.severity")] problem_severity: Option, /// CVSS score as a string (0.0-10.0) #[serde(skip_serializing_if = "Option::is_none")] #[serde(rename = "security-severity")] security_severity: Option, } #[derive(Debug, Serialize)] #[serde(rename_all = "lowercase")] enum ProblemSeverity { Warning, } /// Reporting configuration for a rule #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] struct ReportingConfiguration { /// Default level for the rule ("error", "warning", "note") level: ReportingLevel, } #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] enum ReportingLevel { Error, Warning, } /// Message with optional markdown #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct MultiformatMessageString { /// Plain text message text: String, /// Optional markdown-formatted message #[serde(skip_serializing_if = "Option::is_none")] markdown: Option, } /// A result (finding/alert) #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct SarifResult { /// ID of the rule that was violated rule_id: String, /// Message describing the result message: Message, /// Severity level of the result level: ResultLevel, /// Locations where the issue was detected locations: Vec, /// Fingerprints for result matching partial_fingerprints: HashMap, } impl SarifResult { /// Create a Result from a vulnerability fn from_vulnerability(vuln: &Vulnerability, cargo_lock_path: &str) -> Self { let fingerprint = format!( "{}:{}:{}", vuln.advisory.id, vuln.package.name, vuln.package.version ); SarifResult { rule_id: vuln.advisory.id.to_string(), message: Message { text: format!( "{} {} is vulnerable to {} ({})", vuln.package.name, vuln.package.version, vuln.advisory.id, vuln.advisory.title ), }, level: ResultLevel::Error, locations: vec![Location::new(cargo_lock_path)], partial_fingerprints: { let mut fingerprints = HashMap::new(); // Use a custom fingerprint key instead of primaryLocationLineHash // to avoid conflicts with GitHub's calculated fingerprints fingerprints.insert("cargo-audit/advisory-fingerprint".to_string(), fingerprint); fingerprints }, } } /// Create a Result from a warning fn from_warning(warning: &Warning, cargo_lock_path: &str) -> Self { let rule_id = if let Some(advisory) = &warning.advisory { advisory.id.to_string() } else { format!("{:?}", warning.kind).to_lowercase() }; let message_text = if let Some(advisory) = &warning.advisory { format!( "{} {} has a {} warning: {}", warning.package.name, warning.package.version, warning.kind.as_str(), advisory.title ) } else { format!( "{} {} has a {} warning", warning.package.name, warning.package.version, warning.kind.as_str() ) }; let fingerprint = format!( "{rule_id}:{}:{}", warning.package.name, warning.package.version ); SarifResult { rule_id, message: Message { text: message_text }, level: ResultLevel::Warning, locations: vec![Location::new(cargo_lock_path)], partial_fingerprints: { let mut fingerprints = HashMap::new(); // Use a custom fingerprint key instead of primaryLocationLineHash // to avoid conflicts with GitHub's calculated fingerprints fingerprints.insert("cargo-audit/advisory-fingerprint".to_string(), fingerprint); fingerprints }, } } } #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] enum ResultLevel { Error, Warning, } /// Simple message #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] struct Message { /// The message text text: String, } /// Location of a finding #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] struct Location { /// Physical location of the finding physical_location: PhysicalLocation, } impl Location { fn new(cargo_lock_path: &str) -> Self { Self { physical_location: PhysicalLocation { artifact_location: ArtifactLocation { uri: cargo_lock_path.to_string(), }, region: Region { start_line: 1 }, }, } } } /// Physical location in a file #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] struct PhysicalLocation { /// The artifact (file) containing the issue artifact_location: ArtifactLocation, /// Region within the artifact region: Region, } /// Artifact (file) location #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] struct ArtifactLocation { /// URI of the artifact uri: String, } /// Region within a file #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] struct Region { /// Starting line number (1-based) start_line: u32, } #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] enum Tag { Security, Vulnerability, Warning, } #[derive(Debug, Serialize)] #[serde(rename_all = "kebab-case")] enum Precision { High, VeryHigh, }