From b9bde27938aae48415d3663402e8494af08b6052 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Tue, 30 Dec 2025 17:19:35 +0000 Subject: [PATCH] Update CXX to v1.0.192 --- Cargo.lock | 46 +++++++++---------- cpp/src/api/convert.cpp | 31 ++++++------- cpp/src/api/convert.h | 9 +++- cpp/src/api/database.cpp | 3 +- cpp/src/database.rs | 7 ++- cpp/src/lib.rs | 25 ++++++----- cpp/src/metadata.rs | 70 +++++++++++++++++++++++------ supply-chain/audits.toml | 30 +++++++++++++ supply-chain/imports.lock | 95 +++++++-------------------------------- 9 files changed, 165 insertions(+), 151 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4a0ae041..dbfd1b52 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -99,9 +99,9 @@ checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "codespan-reporting" -version = "0.12.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" +checksum = "af491d569909a7e4dee0ad7db7f5341fef5c614d5b8ec8cf765732aba3cff681" dependencies = [ "serde", "termcolor", @@ -195,23 +195,24 @@ checksum = "4f211af61d8efdd104f96e57adf5e426ba1bc3ed7a4ead616e15e5881fd79c4d" [[package]] name = "cxx" -version = "1.0.161" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3523cc02ad831111491dd64b27ad999f1ae189986728e477604e61b81f828df" +checksum = "bbda285ba6e5866529faf76352bdf73801d9b44a6308d7cd58ca2379f378e994" dependencies = [ "cc", + "cxx-build", "cxxbridge-cmd", "cxxbridge-flags", "cxxbridge-macro", - "foldhash", + "foldhash 0.2.0", "link-cplusplus", ] [[package]] name = "cxx-build" -version = "1.0.161" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212b754247a6f07b10fa626628c157593f0abf640a3dd04cce2760eca970f909" +checksum = "af9efde466c5d532d57efd92f861da3bdb7f61e369128ce8b4c3fe0c9de4fa4d" dependencies = [ "cc", "codespan-reporting", @@ -224,9 +225,9 @@ dependencies = [ [[package]] name = "cxxbridge-cmd" -version = "1.0.161" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f426a20413ec2e742520ba6837c9324b55ffac24ead47491a6e29f933c5b135a" +checksum = "3efb93799095bccd4f763ca07997dc39a69e5e61ab52d2c407d4988d21ce144d" dependencies = [ "clap", "codespan-reporting", @@ -238,20 +239,19 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.161" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258b6069020b4e5da6415df94a50ee4f586a6c38b037a180e940a43d06a070d" +checksum = "3092010228026e143b32a4463ed9fa8f86dca266af4bf5f3b2a26e113dbe4e45" [[package]] name = "cxxbridge-macro" -version = "1.0.161" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8dec184b52be5008d6eaf7e62fc1802caf1ad1227d11b3b7df2c409c7ffc3f4" +checksum = "31d72ebfcd351ae404fb00ff378dfc9571827a00722c9e735c9181aec320ba0a" dependencies = [ "indexmap", "proc-macro2", "quote", - "rustversion", "syn", ] @@ -372,6 +372,12 @@ 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 = "getrandom" version = "0.2.15" @@ -409,7 +415,7 @@ checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ "allocator-api2", "equivalent", - "foldhash", + "foldhash 0.1.5", ] [[package]] @@ -553,9 +559,9 @@ dependencies = [ [[package]] name = "link-cplusplus" -version = "1.0.10" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a6f6da007f968f9def0d65a05b187e2960183de70c160204ecfccf0ee330212" +checksum = "7f78c730aaa7d0b9336a299029ea49f9ee53b0ed06e9202e8cb7db9bae7b8c82" dependencies = [ "cc", ] @@ -937,12 +943,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "rustversion" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" - [[package]] name = "saphyr" version = "0.0.6" diff --git a/cpp/src/api/convert.cpp b/cpp/src/api/convert.cpp index 2c23cbf4..11d7c91a 100644 --- a/cpp/src/api/convert.cpp +++ b/cpp/src/api/convert.cpp @@ -164,7 +164,7 @@ loot::Vertex convert(const loot::rust::Vertex& vertex) { std::string(file.GetName()), file.GetDisplayName(), file.GetCondition(), - ::rust::Slice(convert(file.GetDetail())), + convert(file.GetDetail()), file.GetConstraint()); } catch (const ::rust::Error& e) { std::rethrow_exception(mapError(e)); @@ -194,8 +194,7 @@ loot::rust::MessageType convert(loot::MessageType messageType) { try { return loot::rust::multilingual_message( convert(message.GetType()), - ::rust::Slice( - convert(message.GetContent())), + convert(message.GetContent()), message.GetCondition()); } catch (const ::rust::Error& e) { std::rethrow_exception(mapError(e)); @@ -219,7 +218,7 @@ loot::rust::MessageType convert(loot::MessageType messageType) { return loot::rust::new_plugin_cleaning_data( data.GetCRC(), data.GetCleaningUtility(), - ::rust::Slice(convert(data.GetDetail())), + convert(data.GetDetail()), data.GetITMCount(), data.GetDeletedReferenceCount(), data.GetDeletedNavmeshCount()); @@ -242,21 +241,19 @@ loot::rust::MessageType convert(loot::MessageType messageType) { } output->set_load_after_files( - ::rust::Slice(convert(metadata.GetLoadAfterFiles()))); + convert(metadata.GetLoadAfterFiles())); output->set_requirements( - ::rust::Slice(convert(metadata.GetRequirements()))); - output->set_incompatibilities(::rust::Slice( - convert(metadata.GetIncompatibilities()))); - output->set_messages( - ::rust::Slice(convert(metadata.GetMessages()))); - output->set_tags( - ::rust::Slice(convert(metadata.GetTags()))); - output->set_dirty_info(::rust::Slice( - convert(metadata.GetDirtyInfo()))); - output->set_clean_info(::rust::Slice( - convert(metadata.GetCleanInfo()))); + convert(metadata.GetRequirements())); + output->set_incompatibilities( + convert(metadata.GetIncompatibilities())); + output->set_messages(convert(metadata.GetMessages())); + output->set_tags(convert(metadata.GetTags())); + output->set_dirty_info( + convert(metadata.GetDirtyInfo())); + output->set_clean_info( + convert(metadata.GetCleanInfo())); output->set_locations( - ::rust::Slice(convert(metadata.GetLocations()))); + convert(metadata.GetLocations())); return output; } catch (const ::rust::Error& e) { diff --git a/cpp/src/api/convert.h b/cpp/src/api/convert.h index 99cfae5c..8fa9cd63 100644 --- a/cpp/src/api/convert.h +++ b/cpp/src/api/convert.h @@ -83,8 +83,13 @@ std::vector convert(const ::rust::Vec& vec) { } template -const std::vector<::rust::Box> convert(const std::vector& vec) { - return convert<::rust::Box, U>(::rust::Slice(vec)); +const ::rust::Vec<::rust::Box> convert(const std::vector& vec) { + ::rust::Vec<::rust::Box> output; + for (const auto& element : vec) { + output.push_back(convert(element)); + } + + return output; } } diff --git a/cpp/src/api/database.cpp b/cpp/src/api/database.cpp index d0a174b8..8a2003e6 100644 --- a/cpp/src/api/database.cpp +++ b/cpp/src/api/database.cpp @@ -87,8 +87,7 @@ std::vector Database::GetUserGroups() const { void Database::SetUserGroups(const std::vector& groups) { try { - database_->set_user_groups( - ::rust::Slice(convert(groups))); + database_->set_user_groups(convert(groups)); } catch (const ::rust::Error& e) { std::rethrow_exception(mapError(e)); } diff --git a/cpp/src/database.rs b/cpp/src/database.rs index 04c3a59b..e5c887be 100644 --- a/cpp/src/database.rs +++ b/cpp/src/database.rs @@ -138,8 +138,11 @@ impl Database { .collect()) } - // This is ugly, but Group can't be held as a value in C++ and CXX doesn't support Vec> as a parameter, so this can't take ownership of the input groups. - pub fn set_user_groups(&self, groups: &[Box]) -> Result<(), VerboseError> { + #[expect( + clippy::vec_box, + reason = "Group is an opaque type to C++ so needs to be held in a Box." + )] + pub fn set_user_groups(&self, groups: Vec>) -> Result<(), VerboseError> { let groups = to_vec_of_unwrapped(groups); self.0 .write() diff --git a/cpp/src/lib.rs b/cpp/src/lib.rs index 52ee9538..c83adc41 100644 --- a/cpp/src/lib.rs +++ b/cpp/src/lib.rs @@ -118,6 +118,7 @@ impl TryFrom for libloot::LogLevel { clippy::allow_attributes, clippy::multiple_unsafe_ops_per_block, clippy::needless_lifetimes, + clippy::vec_box, reason = "Required by CXX. clippy::allow_attributes is because CXX doesn't support #[expect(...)]" )] #[cxx::bridge(namespace = "loot::rust")] @@ -273,7 +274,7 @@ mod ffi { pub fn user_groups(&self) -> Result>; - pub fn set_user_groups(&self, groups: &[Box]) -> Result<()>; + pub fn set_user_groups(&self, groups: Vec>) -> Result<()>; pub fn groups_path( &self, @@ -315,7 +316,7 @@ mod ffi { pub fn multilingual_message( message_type: MessageType, - contents: &[Box], + contents: Vec>, condition: &str, ) -> Result>; @@ -466,21 +467,21 @@ mod ffi { pub fn unset_group(&mut self); - pub fn set_load_after_files(&mut self, files: &[Box]); + pub fn set_load_after_files(&mut self, files: Vec>); - pub fn set_requirements(&mut self, files: &[Box]); + pub fn set_requirements(&mut self, files: Vec>); - pub fn set_incompatibilities(&mut self, files: &[Box]); + pub fn set_incompatibilities(&mut self, files: Vec>); - pub fn set_messages(&mut self, messages: &[Box]); + pub fn set_messages(&mut self, messages: Vec>); - pub fn set_tags(&mut self, tags: &[Box]); + pub fn set_tags(&mut self, tags: Vec>); - pub fn set_dirty_info(&mut self, info: &[Box]); + pub fn set_dirty_info(&mut self, info: Vec>); - pub fn set_clean_info(&mut self, info: &[Box]); + pub fn set_clean_info(&mut self, info: Vec>); - pub fn set_locations(&mut self, locations: &[Box]); + pub fn set_locations(&mut self, locations: Vec>); pub fn merge_metadata(&mut self, plugin: &PluginMetadata); @@ -502,7 +503,7 @@ mod ffi { name: String, display_name: &str, condition: &str, - detail: &[Box], + detail: Vec>, constraint: &str, ) -> Result>; @@ -565,7 +566,7 @@ mod ffi { pub fn new_plugin_cleaning_data( crc: u32, cleaning_utility: String, - detail: &[Box], + detail: Vec>, itm_count: u32, deleted_reference_count: u32, deleted_navmesh_count: u32, diff --git a/cpp/src/metadata.rs b/cpp/src/metadata.rs index 72c11ad5..ffad29e7 100644 --- a/cpp/src/metadata.rs +++ b/cpp/src/metadata.rs @@ -141,9 +141,13 @@ pub fn new_message( Ok(Box::new(Message(message))) } +#[expect( + clippy::vec_box, + reason = "MessageContent is an opaque type to C++ so needs to be held in a Box." +)] pub fn multilingual_message( message_type: MessageType, - contents: &[Box], + contents: Vec>, condition: &str, ) -> Result, VerboseError> { let contents = to_vec_of_unwrapped(contents); @@ -306,35 +310,67 @@ impl PluginMetadata { Location::wrap_slice(self.0.locations()) } - pub fn set_load_after_files(&mut self, files: &[Box]) { + #[expect( + clippy::vec_box, + reason = "File is an opaque type to C++ so needs to be held in a Box." + )] + pub fn set_load_after_files(&mut self, files: Vec>) { self.0.set_load_after_files(to_vec_of_unwrapped(files)); } - pub fn set_requirements(&mut self, files: &[Box]) { + #[expect( + clippy::vec_box, + reason = "File is an opaque type to C++ so needs to be held in a Box." + )] + pub fn set_requirements(&mut self, files: Vec>) { self.0.set_requirements(to_vec_of_unwrapped(files)); } - pub fn set_incompatibilities(&mut self, files: &[Box]) { + #[expect( + clippy::vec_box, + reason = "File is an opaque type to C++ so needs to be held in a Box." + )] + pub fn set_incompatibilities(&mut self, files: Vec>) { self.0.set_incompatibilities(to_vec_of_unwrapped(files)); } - pub fn set_messages(&mut self, messages: &[Box]) { + #[expect( + clippy::vec_box, + reason = "Message is an opaque type to C++ so needs to be held in a Box." + )] + pub fn set_messages(&mut self, messages: Vec>) { self.0.set_messages(to_vec_of_unwrapped(messages)); } - pub fn set_tags(&mut self, tags: &[Box]) { + #[expect( + clippy::vec_box, + reason = "Tag is an opaque type to C++ so needs to be held in a Box." + )] + pub fn set_tags(&mut self, tags: Vec>) { self.0.set_tags(to_vec_of_unwrapped(tags)); } - pub fn set_dirty_info(&mut self, info: &[Box]) { + #[expect( + clippy::vec_box, + reason = "PluginCleaningData is an opaque type to C++ so needs to be held in a Box." + )] + pub fn set_dirty_info(&mut self, info: Vec>) { self.0.set_dirty_info(to_vec_of_unwrapped(info)); } - pub fn set_clean_info(&mut self, info: &[Box]) { + #[expect( + clippy::vec_box, + reason = "PluginCleaningData is an opaque type to C++ so needs to be held in a Box." + )] + pub fn set_clean_info(&mut self, info: Vec>) { self.0.set_clean_info(to_vec_of_unwrapped(info)); } - pub fn set_locations(&mut self, locations: &[Box]) { + #[expect( + clippy::vec_box, + reason = "Location is an opaque type to C++ so needs to be held in a Box." + )] + pub fn set_locations(&mut self, locations: Vec>) { self.0.set_locations(to_vec_of_unwrapped(locations)); } @@ -381,11 +417,15 @@ impl From> for libloot::metadata::PluginMetadata { #[repr(transparent)] pub struct File(libloot::metadata::File); +#[expect( + clippy::vec_box, + reason = "File is an opaque type to C++ so needs to be held in a Box." +)] pub fn new_file( name: String, display_name: &str, condition: &str, - detail: &[Box], + detail: Vec>, constraint: &str, ) -> Result, VerboseError> { let mut file = libloot::metadata::File::new(name); @@ -534,10 +574,14 @@ impl TryFrom for libloot::metadata::TagSuggestion { #[repr(transparent)] pub struct PluginCleaningData(libloot::metadata::PluginCleaningData); +#[expect( + clippy::vec_box, + reason = "PluginCleaningData is an opaque type to C++ so needs to be held in a Box." +)] pub fn new_plugin_cleaning_data( crc: u32, cleaning_utility: String, - detail: &[Box], + detail: Vec>, itm_count: u32, deleted_reference_count: u32, deleted_navmesh_count: u32, @@ -630,6 +674,6 @@ impl From> for libloot::metadata::Location { } } -pub fn to_vec_of_unwrapped>>(slice: &[Box]) -> Vec { - slice.iter().cloned().map(Into::into).collect() +pub fn to_vec_of_unwrapped>>(vec: Vec>) -> Vec { + vec.into_iter().map(Into::into).collect() } diff --git a/supply-chain/audits.toml b/supply-chain/audits.toml index e465f534..58d874c4 100644 --- a/supply-chain/audits.toml +++ b/supply-chain/audits.toml @@ -1,6 +1,31 @@ # cargo-vet audits file +[[audits.codespan-reporting]] +who = "Oliver Hamlet " +criteria = "safe-to-deploy" +delta = "0.12.0 -> 0.13.1" + +[[audits.cxx]] +who = "Oliver Hamlet " +criteria = "safe-to-deploy" +delta = "1.0.161 -> 1.0.192" + +[[audits.cxx-build]] +who = "Oliver Hamlet " +criteria = "safe-to-deploy" +delta = "1.0.161 -> 1.0.192" + +[[audits.cxxbridge-flags]] +who = "Oliver Hamlet " +criteria = "safe-to-deploy" +delta = "1.0.161 -> 1.0.192" + +[[audits.cxxbridge-macro]] +who = "Oliver Hamlet " +criteria = "safe-to-deploy" +delta = "1.0.161 -> 1.0.192" + [[audits.libloading]] who = "Oliver Hamlet " criteria = "safe-to-deploy" @@ -13,6 +38,11 @@ criteria = "safe-to-deploy" version = "18.5.1" notes = "This is my own crate published using Trusted Publishing, but I can't mark it as trusted by cargo-vet because it doesn't support Trusted Publishing and just sees that the publisher is unknown." +[[audits.link-cplusplus]] +who = "Oliver Hamlet " +criteria = "safe-to-deploy" +delta = "1.0.10 -> 1.0.12" + [[audits.loot-condition-interpreter]] who = "Oliver Hamlet " criteria = "safe-to-deploy" diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock index bc79b705..6565d8c3 100644 --- a/supply-chain/imports.lock +++ b/supply-chain/imports.lock @@ -97,6 +97,15 @@ criteria = "safe-to-deploy" delta = "2.1.1 -> 2.3.0" notes = "Minor refactoring, nothing new." +[[audits.bytecode-alliance.audits.foldhash]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +version = "0.1.3" +notes = """ +Only a minor amount of `unsafe` code in this crate related to global per-process +initialization which looks correct to me. +""" + [[audits.bytecode-alliance.audits.hashbrown]] who = "Chris Fallin " criteria = "safe-to-deploy" @@ -267,18 +276,6 @@ that the RNG here is not cryptographically secure. """ aggregated-from = "https://chromium.googlesource.com/chromiumos/third_party/rust_crates/+/refs/heads/main/cargo-vet/audits.toml?format=TEXT" -[[audits.google.audits.foldhash]] -who = "Lukasz Anforowicz " -criteria = "safe-to-deploy" -version = "0.1.3" -notes = """ -`ub-risk-2` review notes can be found in https://crrev.com/c/6071306/5/third_party/rust/chromium_crates_io/vendor/foldhash-0.1.3/src/seed.rs - -`does-not-implement-crypto` based on `README.md` which explicitly says that -\"Foldhash is **not appropriate for any cryptographic purpose**.\" -""" -aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" - [[audits.google.audits.foldhash]] who = "Adrian Taylor " criteria = "safe-to-deploy" @@ -432,74 +429,6 @@ version = "0.8.5" notes = "Contains no unsafe" aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" -[[audits.google.audits.rustversion]] -who = "Lukasz Anforowicz " -criteria = "safe-to-deploy" -version = "1.0.14" -notes = """ -Grepped for `-i cipher`, `-i crypto`, `'\bfs\b'``, `'\bnet\b'``, `'\bunsafe\b'`` -and there were no hits except for: - -* Using trivially-safe `unsafe` in test code: - - ``` - tests/test_const.rs:unsafe fn _unsafe() {} - tests/test_const.rs:const _UNSAFE: () = unsafe { _unsafe() }; - ``` - -* Using `unsafe` in a string: - - ``` - src/constfn.rs: \"unsafe\" => Qualifiers::Unsafe, - ``` - -* Using `std::fs` in `build/build.rs` to write `${OUT_DIR}/version.expr` - which is later read back via `include!` used in `src/lib.rs`. - -Version `1.0.6` of this crate has been added to Chromium in -https://source.chromium.org/chromium/chromium/src/+/28841c33c77833cc30b286f9ae24c97e7a8f4057 -""" -aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" - -[[audits.google.audits.rustversion]] -who = "Adrian Taylor " -criteria = "safe-to-deploy" -delta = "1.0.14 -> 1.0.15" -aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" - -[[audits.google.audits.rustversion]] -who = "danakj " -criteria = "safe-to-deploy" -delta = "1.0.15 -> 1.0.16" -aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" - -[[audits.google.audits.rustversion]] -who = "Dustin J. Mitchell " -criteria = "safe-to-deploy" -delta = "1.0.16 -> 1.0.17" -notes = "Just updates windows compat" -aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" - -[[audits.google.audits.rustversion]] -who = "Liza Burakova " -criteria = "safe-to-deploy" -delta = "1.0.17 -> 1.0.18" -aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" - -[[audits.google.audits.rustversion]] -who = "Dustin J. Mitchell " -criteria = "safe-to-deploy" -delta = "1.0.18 -> 1.0.19" -notes = "No unsafe, just doc changes" -aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" - -[[audits.google.audits.rustversion]] -who = "Daniel Cheng " -criteria = "safe-to-deploy" -delta = "1.0.19 -> 1.0.20" -notes = "Only minor updates to documentation and the mock today used for testing." -aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" - [[audits.google.audits.serde]] who = "Lukasz Anforowicz " criteria = "safe-to-deploy" @@ -927,6 +856,12 @@ delta = "2.1.0 -> 2.1.1" notes = "Fairly trivial changes, no chance of security regression." aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" +[[audits.mozilla.audits.foldhash]] +who = "Erich Gubler " +criteria = "safe-to-deploy" +delta = "0.1.5 -> 0.2.0" +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + [[audits.mozilla.audits.getrandom]] who = "Chris Martin " criteria = "safe-to-deploy"