From a51a7e8cddcea37693fe885e1820033810c8e5c0 Mon Sep 17 00:00:00 2001 From: Facundo Lerena Date: Fri, 8 Mar 2024 11:05:09 -0300 Subject: [PATCH 01/13] update versions again! --- clippy_config/Cargo.toml | 21 + clippy_config/src/conf.rs | 795 ++++++++++++++++++ clippy_config/src/lib.rs | 23 + clippy_config/src/metadata.rs | 116 +++ .../src/msrvs.rs | 107 ++- clippy_config/src/types.rs | 128 +++ detectors/assert-violation/src/lib.rs | 2 +- detectors/avoid-format-string/src/lib.rs | 2 +- detectors/delegate-call/src/lib.rs | 3 - detectors/divide-before-multiply/src/lib.rs | 6 +- detectors/dos-unbounded-operation/src/lib.rs | 4 +- .../src/lib.rs | 6 +- .../integer-overflow-or-underflow/src/lib.rs | 2 +- detectors/iterators-over-indexing/src/lib.rs | 6 +- detectors/lazy-delegate/src/lib.rs | 2 +- detectors/panic-error/src/lib.rs | 2 +- detectors/reentrancy-2/src/lib.rs | 3 +- detectors/rust-toolchain | 2 +- detectors/set-code-hash/src/lib.rs | 6 +- .../unprotected-mapping-operation/src/lib.rs | 6 +- .../unprotected-self-destruct/src/lib.rs | 6 +- .../unrestricted-transfer-from/src/lib.rs | 3 - scout-audit-clippy-utils/Cargo.toml | 1 + scout-audit-clippy-utils/rust-toolchain | 2 +- scout-audit-clippy-utils/src/ast_utils.rs | 25 +- .../src/check_proc_macro.rs | 80 +- scout-audit-clippy-utils/src/consts.rs | 269 +++--- scout-audit-clippy-utils/src/diagnostics.rs | 10 +- scout-audit-clippy-utils/src/eager_or_lazy.rs | 52 +- scout-audit-clippy-utils/src/higher.rs | 81 +- scout-audit-clippy-utils/src/hir_utils.rs | 126 ++- scout-audit-clippy-utils/src/lib.rs | 697 +++++++++++---- scout-audit-clippy-utils/src/macros.rs | 18 +- scout-audit-clippy-utils/src/mir/mod.rs | 32 +- scout-audit-clippy-utils/src/paths.rs | 79 +- .../src/qualify_min_const_fn.rs | 30 +- scout-audit-clippy-utils/src/source.rs | 8 +- scout-audit-clippy-utils/src/str_utils.rs | 67 +- scout-audit-clippy-utils/src/sugg.rs | 16 +- scout-audit-clippy-utils/src/ty.rs | 116 ++- .../src/ty/type_certainty/mod.rs | 31 +- scout-audit-clippy-utils/src/visitors.rs | 44 + scout-audit-internal/rust-toolchain | 2 +- scout-audit-internal/src/detector.rs | 5 +- .../src/socket-protobuf/definition.proto | 31 + scout-audit-internal/src/socket.rs | 36 + templates/detector/early-lint/rust-toolchain | 2 +- templates/detector/late-lint/rust-toolchain | 2 +- 48 files changed, 2436 insertions(+), 677 deletions(-) create mode 100644 clippy_config/Cargo.toml create mode 100644 clippy_config/src/conf.rs create mode 100644 clippy_config/src/lib.rs create mode 100644 clippy_config/src/metadata.rs rename {scout-audit-clippy-utils => clippy_config}/src/msrvs.rs (56%) create mode 100644 clippy_config/src/types.rs create mode 100644 scout-audit-internal/src/socket-protobuf/definition.proto create mode 100644 scout-audit-internal/src/socket.rs diff --git a/clippy_config/Cargo.toml b/clippy_config/Cargo.toml new file mode 100644 index 00000000..20f31320 --- /dev/null +++ b/clippy_config/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "clippy_config" +version = "0.1.76" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rustc-semver = "1.1" +serde = { version = "1.0", features = ["derive"] } +toml = "0.7.3" + +[dev-dependencies] +walkdir = "2.3" + +[features] +deny-warnings = [] + +[package.metadata.rust-analyzer] +# This crate uses #[feature(rustc_private)] +rustc_private = true diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs new file mode 100644 index 00000000..88611eb7 --- /dev/null +++ b/clippy_config/src/conf.rs @@ -0,0 +1,795 @@ +use crate::msrvs::Msrv; +use crate::types::{DisallowedPath, MacroMatcher, MatchLintBehaviour, Rename}; +use crate::ClippyConfiguration; +use rustc_data_structures::fx::FxHashSet; +use rustc_session::Session; +use rustc_span::{BytePos, Pos, SourceFile, Span, SyntaxContext}; +use serde::de::{IgnoredAny, IntoDeserializer, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use std::fmt::{Debug, Display, Formatter}; +use std::ops::Range; +use std::path::PathBuf; +use std::str::FromStr; +use std::sync::OnceLock; +use std::{cmp, env, fmt, fs, io}; + +#[rustfmt::skip] +const DEFAULT_DOC_VALID_IDENTS: &[&str] = &[ + "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", + "DirectX", + "ECMAScript", + "GPLv2", "GPLv3", + "GitHub", "GitLab", + "IPv4", "IPv6", + "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", + "WebAssembly", + "NaN", "NaNs", + "OAuth", "GraphQL", + "OCaml", + "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenDNS", + "WebGL", + "TensorFlow", + "TrueType", + "iOS", "macOS", "FreeBSD", + "TeX", "LaTeX", "BibTeX", "BibLaTeX", + "MinGW", + "CamelCase", +]; +const DEFAULT_DISALLOWED_NAMES: &[&str] = &["foo", "baz", "quux"]; +const DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS: &[&str] = &["i", "j", "x", "y", "z", "w", "n"]; + +/// Conf with parse errors +#[derive(Default)] +struct TryConf { + conf: Conf, + errors: Vec, + warnings: Vec, +} + +impl TryConf { + fn from_toml_error(file: &SourceFile, error: &toml::de::Error) -> Self { + Self { + conf: Conf::default(), + errors: vec![ConfError::from_toml(file, error)], + warnings: vec![], + } + } +} + +#[derive(Debug)] +struct ConfError { + message: String, + span: Span, +} + +impl ConfError { + fn from_toml(file: &SourceFile, error: &toml::de::Error) -> Self { + let span = error.span().unwrap_or(0..file.source_len.0 as usize); + Self::spanned(file, error.message(), span) + } + + fn spanned(file: &SourceFile, message: impl Into, span: Range) -> Self { + Self { + message: message.into(), + span: Span::new( + file.start_pos + BytePos::from_usize(span.start), + file.start_pos + BytePos::from_usize(span.end), + SyntaxContext::root(), + None, + ), + } + } +} + +macro_rules! wrap_option { + () => { + None + }; + ($x:literal) => { + Some($x) + }; +} + +macro_rules! default_text { + ($value:expr) => {{ + let mut text = String::new(); + $value.serialize(toml::ser::ValueSerializer::new(&mut text)).unwrap(); + text + }}; + ($value:expr, $override:expr) => { + $override.to_string() + }; +} + +macro_rules! define_Conf { + ($( + $(#[doc = $doc:literal])+ + $(#[conf_deprecated($dep:literal, $new_conf:ident)])? + $(#[default_text = $default_text:expr])? + ($name:ident: $ty:ty = $default:expr), + )*) => { + /// Clippy lint configuration + pub struct Conf { + $($(#[doc = $doc])+ pub $name: $ty,)* + } + + mod defaults { + use super::*; + $(pub fn $name() -> $ty { $default })* + } + + impl Default for Conf { + fn default() -> Self { + Self { $($name: defaults::$name(),)* } + } + } + + #[derive(Deserialize)] + #[serde(field_identifier, rename_all = "kebab-case")] + #[allow(non_camel_case_types)] + enum Field { $($name,)* third_party, } + + struct ConfVisitor<'a>(&'a SourceFile); + + impl<'de> Visitor<'de> for ConfVisitor<'_> { + type Value = TryConf; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("Conf") + } + + fn visit_map(self, mut map: V) -> Result where V: MapAccess<'de> { + let mut errors = Vec::new(); + let mut warnings = Vec::new(); + $(let mut $name = None;)* + // could get `Field` here directly, but get `String` first for diagnostics + while let Some(name) = map.next_key::>()? { + match Field::deserialize(name.get_ref().as_str().into_deserializer()) { + Err(e) => { + let e: FieldError = e; + errors.push(ConfError::spanned(self.0, e.0, name.span())); + } + $(Ok(Field::$name) => { + $(warnings.push(ConfError::spanned(self.0, format!("deprecated field `{}`. {}", name.get_ref(), $dep), name.span()));)? + let raw_value = map.next_value::>()?; + let value_span = raw_value.span(); + match <$ty>::deserialize(raw_value.into_inner()) { + Err(e) => errors.push(ConfError::spanned(self.0, e.to_string().replace('\n', " ").trim(), value_span)), + Ok(value) => match $name { + Some(_) => errors.push(ConfError::spanned(self.0, format!("duplicate field `{}`", name.get_ref()), name.span())), + None => { + $name = Some(value); + // $new_conf is the same as one of the defined `$name`s, so + // this variable is defined in line 2 of this function. + $(match $new_conf { + Some(_) => errors.push(ConfError::spanned(self.0, concat!( + "duplicate field `", stringify!($new_conf), + "` (provided as `", stringify!($name), "`)" + ), name.span())), + None => $new_conf = $name.clone(), + })? + }, + } + } + })* + // ignore contents of the third_party key + Ok(Field::third_party) => drop(map.next_value::()) + } + } + let conf = Conf { $($name: $name.unwrap_or_else(defaults::$name),)* }; + Ok(TryConf { conf, errors, warnings }) + } + } + + pub fn get_configuration_metadata() -> Vec { + vec![ + $( + { + let deprecation_reason = wrap_option!($($dep)?); + + ClippyConfiguration::new( + stringify!($name), + default_text!(defaults::$name() $(, $default_text)?), + concat!($($doc, '\n',)*), + deprecation_reason, + ) + }, + )+ + ] + } + }; +} + +define_Conf! { + /// Lint: ARITHMETIC_SIDE_EFFECTS. + /// + /// Suppress checking of the passed type names in all types of operations. + /// + /// If a specific operation is desired, consider using `arithmetic_side_effects_allowed_binary` or `arithmetic_side_effects_allowed_unary` instead. + /// + /// #### Example + /// + /// ```toml + /// arithmetic-side-effects-allowed = ["SomeType", "AnotherType"] + /// ``` + /// + /// #### Noteworthy + /// + /// A type, say `SomeType`, listed in this configuration has the same behavior of + /// `["SomeType" , "*"], ["*", "SomeType"]` in `arithmetic_side_effects_allowed_binary`. + (arithmetic_side_effects_allowed: FxHashSet = <_>::default()), + /// Lint: ARITHMETIC_SIDE_EFFECTS. + /// + /// Suppress checking of the passed type pair names in binary operations like addition or + /// multiplication. + /// + /// Supports the "*" wildcard to indicate that a certain type won't trigger the lint regardless + /// of the involved counterpart. For example, `["SomeType", "*"]` or `["*", "AnotherType"]`. + /// + /// Pairs are asymmetric, which means that `["SomeType", "AnotherType"]` is not the same as + /// `["AnotherType", "SomeType"]`. + /// + /// #### Example + /// + /// ```toml + /// arithmetic-side-effects-allowed-binary = [["SomeType" , "f32"], ["AnotherType", "*"]] + /// ``` + (arithmetic_side_effects_allowed_binary: Vec<[String; 2]> = <_>::default()), + /// Lint: ARITHMETIC_SIDE_EFFECTS. + /// + /// Suppress checking of the passed type names in unary operations like "negation" (`-`). + /// + /// #### Example + /// + /// ```toml + /// arithmetic-side-effects-allowed-unary = ["SomeType", "AnotherType"] + /// ``` + (arithmetic_side_effects_allowed_unary: FxHashSet = <_>::default()), + /// Lint: ENUM_VARIANT_NAMES, LARGE_TYPES_PASSED_BY_VALUE, TRIVIALLY_COPY_PASS_BY_REF, UNNECESSARY_WRAPS, UNUSED_SELF, UPPER_CASE_ACRONYMS, WRONG_SELF_CONVENTION, BOX_COLLECTION, REDUNDANT_ALLOCATION, RC_BUFFER, VEC_BOX, OPTION_OPTION, LINKEDLIST, RC_MUTEX, UNNECESSARY_BOX_RETURNS, SINGLE_CALL_FN. + /// + /// Suppress lints whenever the suggested change would cause breakage for other crates. + (avoid_breaking_exported_api: bool = true), + /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, OPTION_MAP_UNWRAP_OR, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS, TUPLE_ARRAY_CONVERSIONS, MANUAL_TRY_FOLD, MANUAL_HASH_ONE, ITER_KV_MAP. + /// + /// The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml` + #[default_text = ""] + (msrv: Msrv = Msrv::empty()), + /// DEPRECATED LINT: BLACKLISTED_NAME. + /// + /// Use the Disallowed Names lint instead + #[conf_deprecated("Please use `disallowed-names` instead", disallowed_names)] + (blacklisted_names: Vec = Vec::new()), + /// Lint: COGNITIVE_COMPLEXITY. + /// + /// The maximum cognitive complexity a function can have + (cognitive_complexity_threshold: u64 = 25), + /// Lint: EXCESSIVE_NESTING. + /// + /// The maximum amount of nesting a block can reside in + (excessive_nesting_threshold: u64 = 0), + /// DEPRECATED LINT: CYCLOMATIC_COMPLEXITY. + /// + /// Use the Cognitive Complexity lint instead. + #[conf_deprecated("Please use `cognitive-complexity-threshold` instead", cognitive_complexity_threshold)] + (cyclomatic_complexity_threshold: u64 = 25), + /// Lint: DISALLOWED_NAMES. + /// + /// The list of disallowed names to lint about. NB: `bar` is not here since it has legitimate uses. The value + /// `".."` can be used as part of the list to indicate that the configured values should be appended to the + /// default configuration of Clippy. By default, any configuration will replace the default value. + (disallowed_names: Vec = DEFAULT_DISALLOWED_NAMES.iter().map(ToString::to_string).collect()), + /// Lint: SEMICOLON_INSIDE_BLOCK. + /// + /// Whether to lint only if it's multiline. + (semicolon_inside_block_ignore_singleline: bool = false), + /// Lint: SEMICOLON_OUTSIDE_BLOCK. + /// + /// Whether to lint only if it's singleline. + (semicolon_outside_block_ignore_multiline: bool = false), + /// Lint: DOC_MARKDOWN. + /// + /// The list of words this lint should not consider as identifiers needing ticks. The value + /// `".."` can be used as part of the list to indicate, that the configured values should be appended to the + /// default configuration of Clippy. By default, any configuration will replace the default value. For example: + /// * `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`. + /// * `doc-valid-idents = ["ClipPy", ".."]` would append `ClipPy` to the default list. + (doc_valid_idents: Vec = DEFAULT_DOC_VALID_IDENTS.iter().map(ToString::to_string).collect()), + /// Lint: TOO_MANY_ARGUMENTS. + /// + /// The maximum number of argument a function or method can have + (too_many_arguments_threshold: u64 = 7), + /// Lint: TYPE_COMPLEXITY. + /// + /// The maximum complexity a type can have + (type_complexity_threshold: u64 = 250), + /// Lint: MANY_SINGLE_CHAR_NAMES. + /// + /// The maximum number of single char bindings a scope may have + (single_char_binding_names_threshold: u64 = 4), + /// Lint: BOXED_LOCAL, USELESS_VEC. + /// + /// The maximum size of objects (in bytes) that will be linted. Larger objects are ok on the heap + (too_large_for_stack: u64 = 200), + /// Lint: ENUM_VARIANT_NAMES. + /// + /// The minimum number of enum variants for the lints about variant names to trigger + (enum_variant_name_threshold: u64 = 3), + /// Lint: STRUCT_VARIANT_NAMES. + /// + /// The minimum number of struct fields for the lints about field names to trigger + (struct_field_name_threshold: u64 = 3), + /// Lint: LARGE_ENUM_VARIANT. + /// + /// The maximum size of an enum's variant to avoid box suggestion + (enum_variant_size_threshold: u64 = 200), + /// Lint: VERBOSE_BIT_MASK. + /// + /// The maximum allowed size of a bit mask before suggesting to use 'trailing_zeros' + (verbose_bit_mask_threshold: u64 = 1), + /// Lint: DECIMAL_LITERAL_REPRESENTATION. + /// + /// The lower bound for linting decimal literals + (literal_representation_threshold: u64 = 16384), + /// Lint: TRIVIALLY_COPY_PASS_BY_REF. + /// + /// The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by + /// reference. By default there is no limit + #[default_text = ""] + (trivial_copy_size_limit: Option = None), + /// Lint: LARGE_TYPES_PASSED_BY_VALUE. + /// + /// The minimum size (in bytes) to consider a type for passing by reference instead of by value. + (pass_by_value_size_limit: u64 = 256), + /// Lint: TOO_MANY_LINES. + /// + /// The maximum number of lines a function or method can have + (too_many_lines_threshold: u64 = 100), + /// Lint: LARGE_STACK_ARRAYS, LARGE_CONST_ARRAYS. + /// + /// The maximum allowed size for arrays on the stack + (array_size_threshold: u64 = 512_000), + /// Lint: LARGE_STACK_FRAMES. + /// + /// The maximum allowed stack size for functions in bytes + (stack_size_threshold: u64 = 512_000), + /// Lint: VEC_BOX. + /// + /// The size of the boxed type in bytes, where boxing in a `Vec` is allowed + (vec_box_size_threshold: u64 = 4096), + /// Lint: TYPE_REPETITION_IN_BOUNDS. + /// + /// The maximum number of bounds a trait can have to be linted + (max_trait_bounds: u64 = 3), + /// Lint: STRUCT_EXCESSIVE_BOOLS. + /// + /// The maximum number of bool fields a struct can have + (max_struct_bools: u64 = 3), + /// Lint: FN_PARAMS_EXCESSIVE_BOOLS. + /// + /// The maximum number of bool parameters a function can have + (max_fn_params_bools: u64 = 3), + /// Lint: WILDCARD_IMPORTS. + /// + /// Whether to allow certain wildcard imports (prelude, super in tests). + (warn_on_all_wildcard_imports: bool = false), + /// Lint: DISALLOWED_MACROS. + /// + /// The list of disallowed macros, written as fully qualified paths. + (disallowed_macros: Vec = Vec::new()), + /// Lint: DISALLOWED_METHODS. + /// + /// The list of disallowed methods, written as fully qualified paths. + (disallowed_methods: Vec = Vec::new()), + /// Lint: DISALLOWED_TYPES. + /// + /// The list of disallowed types, written as fully qualified paths. + (disallowed_types: Vec = Vec::new()), + /// Lint: UNREADABLE_LITERAL. + /// + /// Should the fraction of a decimal be linted to include separators. + (unreadable_literal_lint_fractions: bool = true), + /// Lint: UPPER_CASE_ACRONYMS. + /// + /// Enables verbose mode. Triggers if there is more than one uppercase char next to each other + (upper_case_acronyms_aggressive: bool = false), + /// Lint: MANUAL_LET_ELSE. + /// + /// Whether the matches should be considered by the lint, and whether there should + /// be filtering for common types. + (matches_for_let_else: MatchLintBehaviour = MatchLintBehaviour::WellKnownTypes), + /// Lint: CARGO_COMMON_METADATA. + /// + /// For internal testing only, ignores the current `publish` settings in the Cargo manifest. + (cargo_ignore_publish: bool = false), + /// Lint: NONSTANDARD_MACRO_BRACES. + /// + /// Enforce the named macros always use the braces specified. + /// + /// A `MacroMatcher` can be added like so `{ name = "macro_name", brace = "(" }`. If the macro + /// could be used with a full path two `MacroMatcher`s have to be added one with the full path + /// `crate_name::macro_name` and one with just the macro name. + (standard_macro_braces: Vec = Vec::new()), + /// Lint: MISSING_ENFORCED_IMPORT_RENAMES. + /// + /// The list of imports to always rename, a fully qualified path followed by the rename. + (enforced_import_renames: Vec = Vec::new()), + /// Lint: DISALLOWED_SCRIPT_IDENTS. + /// + /// The list of unicode scripts allowed to be used in the scope. + (allowed_scripts: Vec = vec!["Latin".to_string()]), + /// Lint: NON_SEND_FIELDS_IN_SEND_TY. + /// + /// Whether to apply the raw pointer heuristic to determine if a type is `Send`. + (enable_raw_pointer_heuristic_for_send: bool = true), + /// Lint: INDEX_REFUTABLE_SLICE. + /// + /// When Clippy suggests using a slice pattern, this is the maximum number of elements allowed in + /// the slice pattern that is suggested. If more elements are necessary, the lint is suppressed. + /// For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements. + (max_suggested_slice_pattern_length: u64 = 3), + /// Lint: AWAIT_HOLDING_INVALID_TYPE. + (await_holding_invalid_types: Vec = Vec::new()), + /// Lint: LARGE_INCLUDE_FILE. + /// + /// The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes + (max_include_file_size: u64 = 1_000_000), + /// Lint: EXPECT_USED. + /// + /// Whether `expect` should be allowed in test functions or `#[cfg(test)]` + (allow_expect_in_tests: bool = false), + /// Lint: UNWRAP_USED. + /// + /// Whether `unwrap` should be allowed in test functions or `#[cfg(test)]` + (allow_unwrap_in_tests: bool = false), + /// Lint: DBG_MACRO. + /// + /// Whether `dbg!` should be allowed in test functions or `#[cfg(test)]` + (allow_dbg_in_tests: bool = false), + /// Lint: PRINT_STDOUT, PRINT_STDERR. + /// + /// Whether print macros (ex. `println!`) should be allowed in test functions or `#[cfg(test)]` + (allow_print_in_tests: bool = false), + /// Lint: RESULT_LARGE_ERR. + /// + /// The maximum size of the `Err`-variant in a `Result` returned from a function + (large_error_threshold: u64 = 128), + /// Lint: MUTABLE_KEY_TYPE, IFS_SAME_COND. + /// + /// A list of paths to types that should be treated like `Arc`, i.e. ignored but + /// for the generic parameters for determining interior mutability + (ignore_interior_mutability: Vec = Vec::from(["bytes::Bytes".into()])), + /// Lint: UNINLINED_FORMAT_ARGS. + /// + /// Whether to allow mixed uninlined format args, e.g. `format!("{} {}", a, foo.bar)` + (allow_mixed_uninlined_format_args: bool = true), + /// Lint: INDEXING_SLICING. + /// + /// Whether to suppress a restriction lint in constant code. In same + /// cases the restructured operation might not be unavoidable, as the + /// suggested counterparts are unavailable in constant code. This + /// configuration will cause restriction lints to trigger even + /// if no suggestion can be made. + (suppress_restriction_lint_in_const: bool = false), + /// Lint: MISSING_DOCS_IN_PRIVATE_ITEMS. + /// + /// Whether to **only** check for missing documentation in items visible within the current + /// crate. For example, `pub(crate)` items. + (missing_docs_in_crate_items: bool = false), + /// Lint: LARGE_FUTURES. + /// + /// The maximum byte size a `Future` can have, before it triggers the `clippy::large_futures` lint + (future_size_threshold: u64 = 16 * 1024), + /// Lint: UNNECESSARY_BOX_RETURNS. + /// + /// The byte size a `T` in `Box` can have, below which it triggers the `clippy::unnecessary_box` lint + (unnecessary_box_size: u64 = 128), + /// Lint: MODULE_INCEPTION. + /// + /// Whether to allow module inception if it's not public. + (allow_private_module_inception: bool = false), + /// Lint: MIN_IDENT_CHARS. + /// + /// Allowed names below the minimum allowed characters. The value `".."` can be used as part of + /// the list to indicate, that the configured values should be appended to the default + /// configuration of Clippy. By default, any configuration will replace the default value. + (allowed_idents_below_min_chars: FxHashSet = + DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS.iter().map(ToString::to_string).collect()), + /// Lint: MIN_IDENT_CHARS. + /// + /// Minimum chars an ident can have, anything below or equal to this will be linted. + (min_ident_chars_threshold: u64 = 1), + /// Lint: UNDOCUMENTED_UNSAFE_BLOCKS. + /// + /// Whether to accept a safety comment to be placed above the statement containing the `unsafe` block + (accept_comment_above_statement: bool = true), + /// Lint: UNDOCUMENTED_UNSAFE_BLOCKS. + /// + /// Whether to accept a safety comment to be placed above the attributes for the `unsafe` block + (accept_comment_above_attributes: bool = true), + /// Lint: UNNECESSARY_RAW_STRING_HASHES. + /// + /// Whether to allow `r#""#` when `r""` can be used + (allow_one_hash_in_raw_strings: bool = false), + /// Lint: ABSOLUTE_PATHS. + /// + /// The maximum number of segments a path can have before being linted, anything above this will + /// be linted. + (absolute_paths_max_segments: u64 = 2), + /// Lint: ABSOLUTE_PATHS. + /// + /// Which crates to allow absolute paths from + (absolute_paths_allowed_crates: FxHashSet = FxHashSet::default()), + /// Lint: PATH_ENDS_WITH_EXT. + /// + /// Additional dotfiles (files or directories starting with a dot) to allow + (allowed_dotfiles: FxHashSet = FxHashSet::default()), + /// Lint: EXPLICIT_ITER_LOOP + /// + /// Whether to recommend using implicit into iter for reborrowed values. + /// + /// #### Example + /// ```no_run + /// let mut vec = vec![1, 2, 3]; + /// let rmvec = &mut vec; + /// for _ in rmvec.iter() {} + /// for _ in rmvec.iter_mut() {} + /// ``` + /// + /// Use instead: + /// ```no_run + /// let mut vec = vec![1, 2, 3]; + /// let rmvec = &mut vec; + /// for _ in &*rmvec {} + /// for _ in &mut *rmvec {} + /// ``` + (enforce_iter_loop_reborrow: bool = false), + /// Lint: MISSING_SAFETY_DOC, UNNECESSARY_SAFETY_DOC, MISSING_PANICS_DOC, MISSING_ERRORS_DOC + /// + /// Whether to also run the listed lints on private items. + (check_private_items: bool = false), +} + +/// Search for the configuration file. +/// +/// # Errors +/// +/// Returns any unexpected filesystem error encountered when searching for the config file +pub fn lookup_conf_file() -> io::Result<(Option, Vec)> { + /// Possible filename to search for. + const CONFIG_FILE_NAMES: [&str; 2] = [".clippy.toml", "clippy.toml"]; + + // Start looking for a config file in CLIPPY_CONF_DIR, or failing that, CARGO_MANIFEST_DIR. + // If neither of those exist, use ".". (Update documentation if this priority changes) + let mut current = env::var_os("CLIPPY_CONF_DIR") + .or_else(|| env::var_os("CARGO_MANIFEST_DIR")) + .map_or_else(|| PathBuf::from("."), PathBuf::from) + .canonicalize()?; + + let mut found_config: Option = None; + let mut warnings = vec![]; + + loop { + for config_file_name in &CONFIG_FILE_NAMES { + if let Ok(config_file) = current.join(config_file_name).canonicalize() { + match fs::metadata(&config_file) { + Err(e) if e.kind() == io::ErrorKind::NotFound => {}, + Err(e) => return Err(e), + Ok(md) if md.is_dir() => {}, + Ok(_) => { + // warn if we happen to find two config files #8323 + if let Some(ref found_config) = found_config { + warnings.push(format!( + "using config file `{}`, `{}` will be ignored", + found_config.display(), + config_file.display() + )); + } else { + found_config = Some(config_file); + } + }, + } + } + } + + if found_config.is_some() { + return Ok((found_config, warnings)); + } + + // If the current directory has no parent, we're done searching. + if !current.pop() { + return Ok((None, warnings)); + } + } +} + +fn deserialize(file: &SourceFile) -> TryConf { + match toml::de::Deserializer::new(file.src.as_ref().unwrap()).deserialize_map(ConfVisitor(file)) { + Ok(mut conf) => { + extend_vec_if_indicator_present(&mut conf.conf.doc_valid_idents, DEFAULT_DOC_VALID_IDENTS); + extend_vec_if_indicator_present(&mut conf.conf.disallowed_names, DEFAULT_DISALLOWED_NAMES); + // TODO: THIS SHOULD BE TESTED, this comment will be gone soon + if conf.conf.allowed_idents_below_min_chars.contains(&"..".to_owned()) { + conf.conf + .allowed_idents_below_min_chars + .extend(DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS.iter().map(ToString::to_string)); + } + + conf + }, + Err(e) => TryConf::from_toml_error(file, &e), + } +} + +fn extend_vec_if_indicator_present(vec: &mut Vec, default: &[&str]) { + if vec.contains(&"..".to_string()) { + vec.extend(default.iter().map(ToString::to_string)); + } +} + +impl Conf { + pub fn read(sess: &Session, path: &io::Result<(Option, Vec)>) -> &'static Conf { + static CONF: OnceLock = OnceLock::new(); + CONF.get_or_init(|| Conf::read_inner(sess, path)) + } + + fn read_inner(sess: &Session, path: &io::Result<(Option, Vec)>) -> Conf { + match path { + Ok((_, warnings)) => { + for warning in warnings { + sess.warn(warning.clone()); + } + }, + Err(error) => { + sess.err(format!("error finding Clippy's configuration file: {error}")); + }, + } + + let TryConf { + mut conf, + errors, + warnings, + } = match path { + Ok((Some(path), _)) => match sess.source_map().load_file(path) { + Ok(file) => deserialize(&file), + Err(error) => { + sess.err(format!("failed to read `{}`: {error}", path.display())); + TryConf::default() + }, + }, + _ => TryConf::default(), + }; + + conf.msrv.read_cargo(sess); + + // all conf errors are non-fatal, we just use the default conf in case of error + for error in errors { + sess.span_err( + error.span, + format!("error reading Clippy's configuration file: {}", error.message), + ); + } + + for warning in warnings { + sess.span_warn( + warning.span, + format!("error reading Clippy's configuration file: {}", warning.message), + ); + } + + conf + } +} + +const SEPARATOR_WIDTH: usize = 4; + +#[derive(Debug)] +struct FieldError(String); + +impl std::error::Error for FieldError {} + +impl Display for FieldError { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.pad(&self.0) + } +} + +impl serde::de::Error for FieldError { + fn custom(msg: T) -> Self { + Self(msg.to_string()) + } + + fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self { + // List the available fields sorted and at least one per line, more if `CLIPPY_TERMINAL_WIDTH` is + // set and allows it. + use fmt::Write; + + let mut expected = expected.to_vec(); + expected.sort_unstable(); + + let (rows, column_widths) = calculate_dimensions(&expected); + + let mut msg = format!("unknown field `{field}`, expected one of"); + for row in 0..rows { + writeln!(msg).unwrap(); + for (column, column_width) in column_widths.iter().copied().enumerate() { + let index = column * rows + row; + let field = expected.get(index).copied().unwrap_or_default(); + write!(msg, "{:SEPARATOR_WIDTH$}{field:column_width$}", " ").unwrap(); + } + } + Self(msg) + } +} + +fn calculate_dimensions(fields: &[&str]) -> (usize, Vec) { + let columns = env::var("CLIPPY_TERMINAL_WIDTH") + .ok() + .and_then(|s| ::from_str(&s).ok()) + .map_or(1, |terminal_width| { + let max_field_width = fields.iter().map(|field| field.len()).max().unwrap(); + cmp::max(1, terminal_width / (SEPARATOR_WIDTH + max_field_width)) + }); + + let rows = (fields.len() + (columns - 1)) / columns; + + let column_widths = (0..columns) + .map(|column| { + if column < columns - 1 { + (0..rows) + .map(|row| { + let index = column * rows + row; + let field = fields.get(index).copied().unwrap_or_default(); + field.len() + }) + .max() + .unwrap() + } else { + // Avoid adding extra space to the last column. + 0 + } + }) + .collect::>(); + + (rows, column_widths) +} + +#[cfg(test)] +mod tests { + use rustc_data_structures::fx::{FxHashMap, FxHashSet}; + use serde::de::IgnoredAny; + use std::fs; + use walkdir::WalkDir; + + #[test] + fn configs_are_tested() { + let mut names: FxHashSet = crate::get_configuration_metadata() + .into_iter() + .map(|meta| meta.name.replace('_', "-")) + .collect(); + + let toml_files = WalkDir::new("../tests") + .into_iter() + .map(Result::unwrap) + .filter(|entry| entry.file_name() == "clippy.toml"); + + for entry in toml_files { + let file = fs::read_to_string(entry.path()).unwrap(); + #[allow(clippy::zero_sized_map_values)] + if let Ok(map) = toml::from_str::>(&file) { + for name in map.keys() { + names.remove(name.as_str()); + } + } + } + + assert!( + names.remove("allow-one-hash-in-raw-strings"), + "remove this when #11481 is fixed" + ); + + assert!( + names.is_empty(), + "Configuration variable lacks test: {names:?}\nAdd a test to `tests/ui-toml`" + ); + } +} diff --git a/clippy_config/src/lib.rs b/clippy_config/src/lib.rs new file mode 100644 index 00000000..f5dcb16d --- /dev/null +++ b/clippy_config/src/lib.rs @@ -0,0 +1,23 @@ +#![feature(rustc_private, let_chains)] +#![cfg_attr(feature = "deny-warnings", deny(warnings))] +#![warn(rust_2018_idioms, unused_lifetimes)] +#![allow( + clippy::must_use_candidate, + clippy::missing_panics_doc, + rustc::untranslatable_diagnostic_trivial +)] + +extern crate rustc_ast; +extern crate rustc_data_structures; +#[allow(unused_extern_crates)] +extern crate rustc_driver; +extern crate rustc_session; +extern crate rustc_span; + +mod conf; +mod metadata; +pub mod msrvs; +pub mod types; + +pub use conf::{get_configuration_metadata, lookup_conf_file, Conf}; +pub use metadata::ClippyConfiguration; diff --git a/clippy_config/src/metadata.rs b/clippy_config/src/metadata.rs new file mode 100644 index 00000000..2451fbc9 --- /dev/null +++ b/clippy_config/src/metadata.rs @@ -0,0 +1,116 @@ +use std::fmt::{self, Write}; + +#[derive(Debug, Clone, Default)] +pub struct ClippyConfiguration { + pub name: String, + pub default: String, + pub lints: Vec, + pub doc: String, + pub deprecation_reason: Option<&'static str>, +} + +impl fmt::Display for ClippyConfiguration { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "- `{}`: {}", self.name, self.doc)?; + if !self.default.is_empty() { + write!(f, " (default: `{}`)", self.default)?; + } + Ok(()) + } +} + +impl ClippyConfiguration { + pub fn new( + name: &'static str, + default: String, + doc_comment: &'static str, + deprecation_reason: Option<&'static str>, + ) -> Self { + let (lints, doc) = parse_config_field_doc(doc_comment) + .unwrap_or_else(|| (vec![], "[ERROR] MALFORMED DOC COMMENT".to_string())); + + Self { + name: to_kebab(name), + lints, + doc, + default, + deprecation_reason, + } + } + + pub fn to_markdown_paragraph(&self) -> String { + let mut out = format!( + "## `{}`\n{}\n\n", + self.name, + self.doc + .lines() + .map(|line| line.strip_prefix(" ").unwrap_or(line)) + .collect::>() + .join("\n"), + ); + + if !self.default.is_empty() { + write!(out, "**Default Value:** `{}`\n\n", self.default).unwrap(); + } + + write!( + out, + "---\n**Affected lints:**\n{}\n\n", + self.lints + .iter() + .map(|name| name.to_string().split_whitespace().next().unwrap().to_string()) + .map(|name| format!("* [`{name}`](https://rust-lang.github.io/rust-clippy/master/index.html#{name})")) + .collect::>() + .join("\n"), + ) + .unwrap(); + + out + } + + pub fn to_markdown_link(&self) -> String { + const BOOK_CONFIGS_PATH: &str = "https://doc.rust-lang.org/clippy/lint_configuration.html"; + format!("[`{}`]: {BOOK_CONFIGS_PATH}#{}", self.name, self.name) + } +} + +/// This parses the field documentation of the config struct. +/// +/// ```rust, ignore +/// parse_config_field_doc(cx, "Lint: LINT_NAME_1, LINT_NAME_2. Papa penguin, papa penguin") +/// ``` +/// +/// Would yield: +/// ```rust, ignore +/// Some(["lint_name_1", "lint_name_2"], "Papa penguin, papa penguin") +/// ``` +fn parse_config_field_doc(doc_comment: &str) -> Option<(Vec, String)> { + const DOC_START: &str = " Lint: "; + if doc_comment.starts_with(DOC_START) + && let Some(split_pos) = doc_comment.find('.') + { + let mut doc_comment = doc_comment.to_string(); + let mut documentation = doc_comment.split_off(split_pos); + + // Extract lints + doc_comment.make_ascii_lowercase(); + let lints: Vec = doc_comment + .split_off(DOC_START.len()) + .split(", ") + .map(str::to_string) + .collect(); + + // Format documentation correctly + // split off leading `.` from lint name list and indent for correct formatting + documentation = documentation.trim_start_matches('.').trim().replace("\n ", "\n "); + + Some((lints, documentation)) + } else { + None + } +} + +/// Transforms a given `snake_case_string` to a tasty `kebab-case-string` +fn to_kebab(config_name: &str) -> String { + config_name.replace('_', "-") +} diff --git a/scout-audit-clippy-utils/src/msrvs.rs b/clippy_config/src/msrvs.rs similarity index 56% rename from scout-audit-clippy-utils/src/msrvs.rs rename to clippy_config/src/msrvs.rs index 0faff05e..b3ef666e 100644 --- a/scout-audit-clippy-utils/src/msrvs.rs +++ b/clippy_config/src/msrvs.rs @@ -1,11 +1,8 @@ -use std::sync::OnceLock; - use rustc_ast::Attribute; use rustc_semver::RustcVersion; use rustc_session::Session; -use rustc_span::Span; - -use crate::attrs::get_unique_attr; +use rustc_span::{sym, Symbol}; +use serde::Deserialize; macro_rules! msrv_aliases { ($($major:literal,$minor:literal,$patch:literal { @@ -19,13 +16,14 @@ macro_rules! msrv_aliases { // names may refer to stabilized feature flags or library items msrv_aliases! { - 1,71,0 { TUPLE_ARRAY_CONVERSIONS } + 1,71,0 { TUPLE_ARRAY_CONVERSIONS, BUILD_HASHER_HASH_ONE } 1,70,0 { OPTION_IS_SOME_AND, BINARY_HEAP_RETAIN } 1,68,0 { PATH_MAIN_SEPARATOR_STR } 1,65,0 { LET_ELSE, POINTER_CAST_CONSTNESS } 1,62,0 { BOOL_THEN_SOME, DEFAULT_ENUM_ATTRIBUTE } 1,58,0 { FORMAT_ARGS_CAPTURE, PATTERN_TRAIT_CHAR_ARRAY } 1,55,0 { SEEK_REWIND } + 1,54,0 { INTO_KEYS } 1,53,0 { OR_PATTERNS, MANUAL_BITS, BTREE_MAP_RETAIN, BTREE_SET_RETAIN, ARRAY_INTO_ITERATOR } 1,52,0 { STR_SPLIT_ONCE, REM_EUCLID_CONST } 1,51,0 { BORROW_AS_PTR, SEEK_FROM_CURRENT, UNSIGNED_ABS } @@ -53,65 +51,45 @@ msrv_aliases! { 1,15,0 { MAYBE_BOUND_IN_WHERE } } -fn parse_msrv(msrv: &str, sess: Option<&Session>, span: Option) -> Option { - if let Ok(version) = RustcVersion::parse(msrv) { - return Some(version); - } else if let Some(sess) = sess { - if let Some(span) = span { - sess.span_err(span, format!("`{msrv}` is not a valid Rust version")); - } - } - None -} - /// Tracks the current MSRV from `clippy.toml`, `Cargo.toml` or set via `#[clippy::msrv]` -#[derive(Debug, Clone, Default)] +#[derive(Debug, Clone)] pub struct Msrv { stack: Vec, } +impl<'de> Deserialize<'de> for Msrv { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let v = String::deserialize(deserializer)?; + RustcVersion::parse(&v) + .map(|v| Msrv { stack: vec![v] }) + .map_err(|_| serde::de::Error::custom("not a valid Rust version")) + } +} + impl Msrv { - fn new(initial: Option) -> Self { - Self { - stack: Vec::from_iter(initial), - } + pub fn empty() -> Msrv { + Msrv { stack: Vec::new() } } - fn read_inner(conf_msrv: &Option, sess: &Session) -> Self { + pub fn read_cargo(&mut self, sess: &Session) { let cargo_msrv = std::env::var("CARGO_PKG_RUST_VERSION") .ok() - .and_then(|v| parse_msrv(&v, None, None)); - let clippy_msrv = conf_msrv.as_ref().and_then(|s| { - parse_msrv(s, None, None).or_else(|| { - sess.err(format!( - "error reading Clippy's configuration file. `{s}` is not a valid Rust version" - )); - None - }) - }); - - // if both files have an msrv, let's compare them and emit a warning if they differ - if let Some(cargo_msrv) = cargo_msrv - && let Some(clippy_msrv) = clippy_msrv - && clippy_msrv != cargo_msrv - { - sess.warn(format!( - "the MSRV in `clippy.toml` and `Cargo.toml` differ; using `{clippy_msrv}` from `clippy.toml`" - )); + .and_then(|v| RustcVersion::parse(&v).ok()); + + match (self.current(), cargo_msrv) { + (None, Some(cargo_msrv)) => self.stack = vec![cargo_msrv], + (Some(clippy_msrv), Some(cargo_msrv)) => { + if clippy_msrv != cargo_msrv { + sess.warn(format!( + "the MSRV in `clippy.toml` and `Cargo.toml` differ; using `{clippy_msrv}` from `clippy.toml`" + )); + } + }, + _ => {}, } - - Self::new(clippy_msrv.or(cargo_msrv)) - } - - /// Set the initial MSRV from the Clippy config file or from Cargo due to the `rust-version` - /// field in `Cargo.toml` - /// - /// Returns a `&'static Msrv` as `Copy` types are more easily passed to the - /// `register_{late,early}_pass` callbacks - pub fn read(conf_msrv: &Option, sess: &Session) -> &'static Self { - static PARSED: OnceLock = OnceLock::new(); - - PARSED.get_or_init(|| Self::read_inner(conf_msrv, sess)) } pub fn current(&self) -> Option { @@ -123,12 +101,25 @@ impl Msrv { } fn parse_attr(sess: &Session, attrs: &[Attribute]) -> Option { - if let Some(msrv_attr) = get_unique_attr(sess, attrs, "msrv") { - if let Some(msrv) = msrv_attr.value_str() { - return parse_msrv(&msrv.to_string(), Some(sess), Some(msrv_attr.span)); + let sym_msrv = Symbol::intern("msrv"); + let mut msrv_attrs = attrs.iter().filter(|attr| attr.path_matches(&[sym::clippy, sym_msrv])); + + if let Some(msrv_attr) = msrv_attrs.next() { + if let Some(duplicate) = msrv_attrs.last() { + sess.struct_span_err(duplicate.span, "`clippy::msrv` is defined multiple times") + .span_note(msrv_attr.span, "first definition found here") + .emit(); } - sess.span_err(msrv_attr.span, "bad clippy attribute"); + if let Some(msrv) = msrv_attr.value_str() { + if let Ok(version) = RustcVersion::parse(msrv.as_str()) { + return Some(version); + } + + sess.span_err(msrv_attr.span, format!("`{msrv}` is not a valid Rust version")); + } else { + sess.span_err(msrv_attr.span, "bad clippy attribute"); + } } None diff --git a/clippy_config/src/types.rs b/clippy_config/src/types.rs new file mode 100644 index 00000000..df48cc3f --- /dev/null +++ b/clippy_config/src/types.rs @@ -0,0 +1,128 @@ +use serde::de::{self, Deserializer, Visitor}; +use serde::{ser, Deserialize, Serialize}; +use std::fmt; + +#[derive(Clone, Debug, Deserialize)] +pub struct Rename { + pub path: String, + pub rename: String, +} + +#[derive(Clone, Debug, Deserialize)] +#[serde(untagged)] +pub enum DisallowedPath { + Simple(String), + WithReason { path: String, reason: Option }, +} + +impl DisallowedPath { + pub fn path(&self) -> &str { + let (Self::Simple(path) | Self::WithReason { path, .. }) = self; + + path + } + + pub fn reason(&self) -> Option { + match self { + Self::WithReason { + reason: Some(reason), .. + } => Some(format!("{reason} (from clippy.toml)")), + _ => None, + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)] +pub enum MatchLintBehaviour { + AllTypes, + WellKnownTypes, + Never, +} + +#[derive(Debug)] +pub struct MacroMatcher { + pub name: String, + pub braces: (char, char), +} + +impl<'de> Deserialize<'de> for MacroMatcher { + fn deserialize(deser: D) -> Result + where + D: Deserializer<'de>, + { + #[derive(Deserialize)] + #[serde(field_identifier, rename_all = "lowercase")] + enum Field { + Name, + Brace, + } + struct MacVisitor; + impl<'de> Visitor<'de> for MacVisitor { + type Value = MacroMatcher; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("struct MacroMatcher") + } + + fn visit_map(self, mut map: V) -> Result + where + V: de::MapAccess<'de>, + { + let mut name = None; + let mut brace: Option = None; + while let Some(key) = map.next_key()? { + match key { + Field::Name => { + if name.is_some() { + return Err(de::Error::duplicate_field("name")); + } + name = Some(map.next_value()?); + }, + Field::Brace => { + if brace.is_some() { + return Err(de::Error::duplicate_field("brace")); + } + brace = Some(map.next_value()?); + }, + } + } + let name = name.ok_or_else(|| de::Error::missing_field("name"))?; + let brace = brace.ok_or_else(|| de::Error::missing_field("brace"))?; + Ok(MacroMatcher { + name, + braces: [('(', ')'), ('{', '}'), ('[', ']')] + .into_iter() + .find(|b| b.0 == brace) + .map(|(o, c)| (o.to_owned(), c.to_owned())) + .ok_or_else(|| de::Error::custom(format!("expected one of `(`, `{{`, `[` found `{brace}`")))?, + }) + } + } + + const FIELDS: &[&str] = &["name", "brace"]; + deser.deserialize_struct("MacroMatcher", FIELDS, MacVisitor) + } +} + +// these impls are never actually called but are used by the various config options that default to +// empty lists +macro_rules! unimplemented_serialize { + ($($t:ty,)*) => { + $( + impl Serialize for $t { + fn serialize(&self, _serializer: S) -> Result + where + S: ser::Serializer, + { + Err(ser::Error::custom("unimplemented")) + } + } + )* + } +} + +unimplemented_serialize! { + DisallowedPath, + Rename, + MacroMatcher, +} diff --git a/detectors/assert-violation/src/lib.rs b/detectors/assert-violation/src/lib.rs index fef74cd1..8c19eef4 100644 --- a/detectors/assert-violation/src/lib.rs +++ b/detectors/assert-violation/src/lib.rs @@ -156,6 +156,6 @@ fn is_test_item(item: &Item) -> bool { fn is_test_token_present(token_stream: &TokenStream) -> bool { token_stream.trees().any(|tree| match tree { TokenTree::Token(token, _) => token.is_ident_named(sym::test), - TokenTree::Delimited(_, _, token_stream) => is_test_token_present(token_stream), + TokenTree::Delimited(_, _, _, token_stream) => is_test_token_present(token_stream), }) } diff --git a/detectors/avoid-format-string/src/lib.rs b/detectors/avoid-format-string/src/lib.rs index 71ff1b1c..618273a6 100644 --- a/detectors/avoid-format-string/src/lib.rs +++ b/detectors/avoid-format-string/src/lib.rs @@ -131,6 +131,6 @@ fn is_test_item(item: &Item) -> bool { fn is_test_token_present(token_stream: &TokenStream) -> bool { token_stream.trees().any(|tree| match tree { TokenTree::Token(token, _) => token.is_ident_named(sym::test), - TokenTree::Delimited(_, _, token_stream) => is_test_token_present(token_stream), + TokenTree::Delimited(_, _, _, token_stream) => is_test_token_present(token_stream), }) } diff --git a/detectors/delegate-call/src/lib.rs b/detectors/delegate-call/src/lib.rs index 67641ae4..5088bc44 100644 --- a/detectors/delegate-call/src/lib.rs +++ b/detectors/delegate-call/src/lib.rs @@ -107,9 +107,6 @@ impl<'tcx> LateLintPass<'tcx> for DelegateCall { arg_hir_ids.push(path.segments[j].hir_id); } } - QPath::LangItem(_, _, Some(lang_item_hir_id)) => { - arg_hir_ids.push(*lang_item_hir_id); - } _ => (), } } diff --git a/detectors/divide-before-multiply/src/lib.rs b/detectors/divide-before-multiply/src/lib.rs index 327b765e..40e30d88 100644 --- a/detectors/divide-before-multiply/src/lib.rs +++ b/detectors/divide-before-multiply/src/lib.rs @@ -311,11 +311,7 @@ fn navigate_trough_basicblocks<'tcx>( ); } } - TerminatorKind::GeneratorDrop - | TerminatorKind::UnwindResume - | TerminatorKind::UnwindTerminate(_) - | TerminatorKind::Return - | TerminatorKind::Unreachable => {} + _ => {} } } } diff --git a/detectors/dos-unbounded-operation/src/lib.rs b/detectors/dos-unbounded-operation/src/lib.rs index c456a0ef..d3ef0a09 100644 --- a/detectors/dos-unbounded-operation/src/lib.rs +++ b/detectors/dos-unbounded-operation/src/lib.rs @@ -50,12 +50,12 @@ impl<'tcx> Visitor<'tcx> for ForLoopVisitor { && source == MatchSource::ForLoopDesugar && let ExprKind::Call(func, args) = match_expr.kind && let ExprKind::Path(qpath) = &func.kind - && let QPath::LangItem(item, _span, _id) = qpath + && let QPath::LangItem(item, _span) = qpath && item == &LangItem::IntoIterIntoIter { if args.first().is_some() && let ExprKind::Struct(qpath, fields, _) = args.first().unwrap().kind - && let QPath::LangItem(langitem, _span, _id) = qpath + && let QPath::LangItem(langitem, _span) = qpath && (LangItem::Range == *langitem || LangItem::RangeInclusiveStruct == *langitem || LangItem::RangeInclusiveNew == *langitem) diff --git a/detectors/dos-unexpected-revert-with-vector/src/lib.rs b/detectors/dos-unexpected-revert-with-vector/src/lib.rs index b7ac1c01..3c25cff3 100644 --- a/detectors/dos-unexpected-revert-with-vector/src/lib.rs +++ b/detectors/dos-unexpected-revert-with-vector/src/lib.rs @@ -379,11 +379,7 @@ impl<'tcx> LateLintPass<'tcx> for UnexpectedRevertWarn { )); } } - TerminatorKind::UnwindResume - | TerminatorKind::UnwindTerminate(_) - | TerminatorKind::Return - | TerminatorKind::Unreachable - | TerminatorKind::GeneratorDrop => {} + _ => {} } ret_vec } diff --git a/detectors/integer-overflow-or-underflow/src/lib.rs b/detectors/integer-overflow-or-underflow/src/lib.rs index 25e16103..0803e331 100644 --- a/detectors/integer-overflow-or-underflow/src/lib.rs +++ b/detectors/integer-overflow-or-underflow/src/lib.rs @@ -6,7 +6,7 @@ extern crate rustc_span; use rustc_hir::{self as hir, Body, Expr, ExprKind, UnOp}; use rustc_lint::LateContext; use rustc_lint::LateLintPass; -use rustc_span::source_map::Span; +use rustc_span::Span; use scout_audit_clippy_utils::consts::constant_simple; use scout_audit_clippy_utils::is_integer_literal; use scout_audit_internal::Detector; diff --git a/detectors/iterators-over-indexing/src/lib.rs b/detectors/iterators-over-indexing/src/lib.rs index 7eecd3a5..7579e7a9 100644 --- a/detectors/iterators-over-indexing/src/lib.rs +++ b/detectors/iterators-over-indexing/src/lib.rs @@ -49,11 +49,11 @@ impl<'tcx> Visitor<'tcx> for ForLoopVisitor { && source == MatchSource::ForLoopDesugar && let ExprKind::Call(func, args) = match_expr.kind && let ExprKind::Path(qpath) = &func.kind - && let QPath::LangItem(item, _span, _id) = qpath + && let QPath::LangItem(item, _) = qpath && item == &LangItem::IntoIterIntoIter && args.first().is_some() && let ExprKind::Struct(qpath, fields, _) = args.first().unwrap().kind - && let QPath::LangItem(langitem, _span, _id) = qpath + && let QPath::LangItem(langitem, _) = qpath && (LangItem::Range == *langitem || LangItem::RangeInclusiveStruct == *langitem || LangItem::RangeInclusiveNew == *langitem) @@ -74,7 +74,7 @@ impl<'tcx> Visitor<'tcx> for ForLoopVisitor { }; for arm in some_none_arms { if let PatKind::Struct(qpath, pats, _) = &arm.pat.kind - && let QPath::LangItem(item_type, _, _) = qpath + && let QPath::LangItem(item_type, _) = qpath && LangItem::OptionSome == *item_type && pats.last().is_some() { diff --git a/detectors/lazy-delegate/src/lib.rs b/detectors/lazy-delegate/src/lib.rs index aca258b2..568b3033 100644 --- a/detectors/lazy-delegate/src/lib.rs +++ b/detectors/lazy-delegate/src/lib.rs @@ -122,6 +122,6 @@ fn is_storage_present(token_stream: &TokenStream) -> bool { false } } - TokenTree::Delimited(_, _, token_stream) => is_storage_present(token_stream), + TokenTree::Delimited(_, _, _, token_stream) => is_storage_present(token_stream), }) } diff --git a/detectors/panic-error/src/lib.rs b/detectors/panic-error/src/lib.rs index 09e3e3cc..e6f6b35f 100644 --- a/detectors/panic-error/src/lib.rs +++ b/detectors/panic-error/src/lib.rs @@ -167,6 +167,6 @@ fn capitalize_err_msg(s: &str) -> String { fn is_test_token_present(token_stream: &TokenStream) -> bool { token_stream.trees().any(|tree| match tree { TokenTree::Token(token, _) => token.is_ident_named(sym::test), - TokenTree::Delimited(_, _, token_stream) => is_test_token_present(token_stream), + TokenTree::Delimited(_, _, _, token_stream) => is_test_token_present(token_stream), }) } diff --git a/detectors/reentrancy-2/src/lib.rs b/detectors/reentrancy-2/src/lib.rs index ada9e64c..f065722e 100644 --- a/detectors/reentrancy-2/src/lib.rs +++ b/detectors/reentrancy-2/src/lib.rs @@ -5,12 +5,12 @@ extern crate rustc_ast; extern crate rustc_hir; extern crate rustc_middle; extern crate rustc_span; +extern crate rustc_target; extern crate rustc_type_ir; use std::collections::{HashMap, HashSet}; use if_chain::if_chain; -use rustc_abi::VariantIdx; use rustc_ast::ast::LitKind; use rustc_hir::def::Res; use rustc_hir::intravisit::{walk_expr, FnKind}; @@ -21,6 +21,7 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::TyKind; use rustc_span::def_id::LocalDefId; use rustc_span::{Span, Symbol}; +use rustc_target::abi::VariantIdx; use scout_audit_internal::Detector; dylint_linting::declare_late_lint! { diff --git a/detectors/rust-toolchain b/detectors/rust-toolchain index 8811e92c..bcb80559 100644 --- a/detectors/rust-toolchain +++ b/detectors/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-09-29" +channel = "nightly-2023-12-16" components = ["llvm-tools-preview", "rustc-dev"] diff --git a/detectors/set-code-hash/src/lib.rs b/detectors/set-code-hash/src/lib.rs index 5d2dc5dc..67608745 100644 --- a/detectors/set-code-hash/src/lib.rs +++ b/detectors/set-code-hash/src/lib.rs @@ -336,11 +336,7 @@ impl<'tcx> LateLintPass<'tcx> for UnprotectedSetCodeHash { )); } } - TerminatorKind::Return - | TerminatorKind::Unreachable - | TerminatorKind::GeneratorDrop - | TerminatorKind::UnwindResume - | TerminatorKind::UnwindTerminate(_) => {} + _ => {} } ret_vec } diff --git a/detectors/unprotected-mapping-operation/src/lib.rs b/detectors/unprotected-mapping-operation/src/lib.rs index e1e5bf02..5fdf2ce5 100644 --- a/detectors/unprotected-mapping-operation/src/lib.rs +++ b/detectors/unprotected-mapping-operation/src/lib.rs @@ -335,11 +335,7 @@ impl<'tcx> LateLintPass<'tcx> for UnprotectedMappingOperation { )); } } - TerminatorKind::Return - | TerminatorKind::Unreachable - | TerminatorKind::GeneratorDrop - | TerminatorKind::UnwindResume - | TerminatorKind::UnwindTerminate(_) => {} + _ => {} } ret_vec } diff --git a/detectors/unprotected-self-destruct/src/lib.rs b/detectors/unprotected-self-destruct/src/lib.rs index 47aa651c..f9786af4 100644 --- a/detectors/unprotected-self-destruct/src/lib.rs +++ b/detectors/unprotected-self-destruct/src/lib.rs @@ -316,11 +316,7 @@ impl<'tcx> LateLintPass<'tcx> for UnprotectedSelfDestruct { )); } } - TerminatorKind::UnwindResume - | TerminatorKind::UnwindTerminate(_) - | TerminatorKind::Return - | TerminatorKind::Unreachable - | TerminatorKind::GeneratorDrop => {} + _ => {} } ret_vec } diff --git a/detectors/unrestricted-transfer-from/src/lib.rs b/detectors/unrestricted-transfer-from/src/lib.rs index 19140eef..7fdab3e9 100644 --- a/detectors/unrestricted-transfer-from/src/lib.rs +++ b/detectors/unrestricted-transfer-from/src/lib.rs @@ -121,9 +121,6 @@ impl<'tcx> LateLintPass<'tcx> for UnrestrictedTransferFrom { arg_hir_ids.push(path.segments[j].hir_id); } } - QPath::LangItem(_, _, Some(lang_item_hir_id)) => { - arg_hir_ids.push(*lang_item_hir_id); - } _ => (), } } diff --git a/scout-audit-clippy-utils/Cargo.toml b/scout-audit-clippy-utils/Cargo.toml index 7d163884..fd7bce96 100644 --- a/scout-audit-clippy-utils/Cargo.toml +++ b/scout-audit-clippy-utils/Cargo.toml @@ -11,6 +11,7 @@ arrayvec = { version = "0.7", default-features = false } if_chain = "1.0" itertools = "0.10.1" rustc-semver = "1.1" +clippy_config = { path = "/home/flerena/coinfabrik/scout/rust-clippy/clippy_config" } [features] deny-warnings = [] diff --git a/scout-audit-clippy-utils/rust-toolchain b/scout-audit-clippy-utils/rust-toolchain index a29f12c9..d575da6d 100644 --- a/scout-audit-clippy-utils/rust-toolchain +++ b/scout-audit-clippy-utils/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -use rustc_middle::mir::Const; +channel = "nightly-2023-12-16" components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] diff --git a/scout-audit-clippy-utils/src/ast_utils.rs b/scout-audit-clippy-utils/src/ast_utils.rs index a78ff020..e36f2fa8 100644 --- a/scout-audit-clippy-utils/src/ast_utils.rs +++ b/scout-audit-clippy-utils/src/ast_utils.rs @@ -188,7 +188,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool { Closure(box ast::Closure { binder: lb, capture_clause: lc, - asyncness: la, + coroutine_kind: la, movability: lm, fn_decl: lf, body: le, @@ -197,7 +197,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool { Closure(box ast::Closure { binder: rb, capture_clause: rc, - asyncness: ra, + coroutine_kind: ra, movability: rm, fn_decl: rf, body: re, @@ -206,12 +206,12 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool { ) => { eq_closure_binder(lb, rb) && lc == rc - && la.is_async() == ra.is_async() + && la.map_or(false, CoroutineKind::is_async) == ra.map_or(false, CoroutineKind::is_async) && lm == rm && eq_fn_decl(lf, rf) && eq_expr(le, re) }, - (Async(lc, lb), Async(rc, rb)) => lc == rc && eq_block(lb, rb), + (Gen(lc, lb, lk), Gen(rc, rb, rk)) => lc == rc && eq_block(lb, rb) && lk == rk, (Range(lf, lt, ll), Range(rf, rt, rl)) => ll == rl && eq_expr_opt(lf, rf) && eq_expr_opt(lt, rt), (AddrOf(lbk, lm, le), AddrOf(rbk, rm, re)) => lbk == rbk && lm == rm && eq_expr(le, re), (Path(lq, lp), Path(rq, rp)) => both(lq, rq, eq_qself) && eq_path(lp, rp), @@ -236,7 +236,7 @@ pub fn eq_field(l: &ExprField, r: &ExprField) -> bool { pub fn eq_arm(l: &Arm, r: &Arm) -> bool { l.is_placeholder == r.is_placeholder && eq_pat(&l.pat, &r.pat) - && eq_expr(&l.body, &r.body) + && eq_expr_opt(&l.body, &r.body) && eq_expr_opt(&l.guard, &r.guard) && over(&l.attrs, &r.attrs, eq_attr) } @@ -563,9 +563,22 @@ pub fn eq_fn_sig(l: &FnSig, r: &FnSig) -> bool { eq_fn_decl(&l.decl, &r.decl) && eq_fn_header(&l.header, &r.header) } +fn eq_opt_coroutine_kind(l: Option, r: Option) -> bool { + matches!( + (l, r), + (Some(CoroutineKind::Async { .. }), Some(CoroutineKind::Async { .. })) + | (Some(CoroutineKind::Gen { .. }), Some(CoroutineKind::Gen { .. })) + | ( + Some(CoroutineKind::AsyncGen { .. }), + Some(CoroutineKind::AsyncGen { .. }) + ) + | (None, None) + ) +} + pub fn eq_fn_header(l: &FnHeader, r: &FnHeader) -> bool { matches!(l.unsafety, Unsafe::No) == matches!(r.unsafety, Unsafe::No) - && l.asyncness.is_async() == r.asyncness.is_async() + && eq_opt_coroutine_kind(l.coroutine_kind, r.coroutine_kind) && matches!(l.constness, Const::No) == matches!(r.constness, Const::No) && eq_ext(&l.ext, &r.ext) } diff --git a/scout-audit-clippy-utils/src/check_proc_macro.rs b/scout-audit-clippy-utils/src/check_proc_macro.rs index 6be8b8bb..470d31fa 100644 --- a/scout-audit-clippy-utils/src/check_proc_macro.rs +++ b/scout-audit-clippy-utils/src/check_proc_macro.rs @@ -12,14 +12,14 @@ //! code was written, and check if the span contains that text. Note this will only work correctly //! if the span is not from a `macro_rules` based macro. -use rustc_ast::ast::{AttrKind, Attribute, IntTy, LitIntType, LitKind, StrStyle, UintTy}; +use rustc_ast::ast::{AttrKind, Attribute, IntTy, LitIntType, LitKind, StrStyle, TraitObjectSyntax, UintTy}; use rustc_ast::token::CommentKind; use rustc_ast::AttrStyle; use rustc_hir::intravisit::FnKind; use rustc_hir::{ - Block, BlockCheckMode, Body, Closure, Destination, Expr, ExprKind, FieldDef, FnHeader, HirId, Impl, ImplItem, - ImplItemKind, IsAuto, Item, ItemKind, LoopSource, MatchSource, MutTy, Node, QPath, TraitItem, TraitItemKind, Ty, - TyKind, UnOp, UnsafeSource, Unsafety, Variant, VariantData, YieldSource, + Block, BlockCheckMode, Body, Closure, Destination, Expr, ExprKind, FieldDef, FnHeader, FnRetTy, HirId, Impl, + ImplItem, ImplItemKind, IsAuto, Item, ItemKind, LoopSource, MatchSource, MutTy, Node, QPath, TraitItem, + TraitItemKind, Ty, TyKind, UnOp, UnsafeSource, Unsafety, Variant, VariantData, YieldSource, }; use rustc_lint::{LateContext, LintContext}; use rustc_middle::ty::TyCtxt; @@ -33,8 +33,6 @@ use rustc_target::spec::abi::Abi; pub enum Pat { /// A single string. Str(&'static str), - /// A single string. - OwnedStr(String), /// Any of the given strings. MultiStr(&'static [&'static str]), /// Any of the given strings. @@ -59,14 +57,12 @@ fn span_matches_pat(sess: &Session, span: Span, start_pat: Pat, end_pat: Pat) -> let end_str = s.trim_end_matches(|c: char| c.is_whitespace() || c == ')' || c == ','); (match start_pat { Pat::Str(text) => start_str.starts_with(text), - Pat::OwnedStr(text) => start_str.starts_with(&text), Pat::MultiStr(texts) => texts.iter().any(|s| start_str.starts_with(s)), Pat::OwnedMultiStr(texts) => texts.iter().any(|s| start_str.starts_with(s)), Pat::Sym(sym) => start_str.starts_with(sym.as_str()), Pat::Num => start_str.as_bytes().first().map_or(false, u8::is_ascii_digit), } && match end_pat { Pat::Str(text) => end_str.ends_with(text), - Pat::OwnedStr(text) => end_str.starts_with(&text), Pat::MultiStr(texts) => texts.iter().any(|s| start_str.ends_with(s)), Pat::OwnedMultiStr(texts) => texts.iter().any(|s| start_str.starts_with(s)), Pat::Sym(sym) => end_str.ends_with(sym.as_str()), @@ -125,6 +121,8 @@ fn qpath_search_pat(path: &QPath<'_>) -> (Pat, Pat) { fn expr_search_pat(tcx: TyCtxt<'_>, e: &Expr<'_>) -> (Pat, Pat) { match e.kind { ExprKind::ConstBlock(_) => (Pat::Str("const"), Pat::Str("}")), + // Parenthesis are trimmed from the text before the search patterns are matched. + // See: `span_matches_pat` ExprKind::Tup([]) => (Pat::Str(")"), Pat::Str("(")), ExprKind::Unary(UnOp::Deref, e) => (Pat::Str("*"), expr_search_pat(tcx, e).1), ExprKind::Unary(UnOp::Not, e) => (Pat::Str("!"), expr_search_pat(tcx, e).1), @@ -269,7 +267,7 @@ fn fn_kind_pat(tcx: TyCtxt<'_>, kind: &FnKind<'_>, body: &Body<'_>, hir_id: HirI FnKind::Method(.., sig) => (fn_header_search_pat(sig.header), Pat::Str("")), FnKind::Closure => return (Pat::Str(""), expr_search_pat(tcx, body.value).1), }; - let start_pat = match tcx.hir().get(hir_id) { + let start_pat = match tcx.hir_node(hir_id) { Node::Item(Item { vis_span, .. }) | Node::ImplItem(ImplItem { vis_span, .. }) => { if vis_span.is_empty() { start_pat @@ -286,21 +284,17 @@ fn fn_kind_pat(tcx: TyCtxt<'_>, kind: &FnKind<'_>, body: &Body<'_>, hir_id: HirI fn attr_search_pat(attr: &Attribute) -> (Pat, Pat) { match attr.kind { AttrKind::Normal(..) => { - let mut pat = if matches!(attr.style, AttrStyle::Outer) { - (Pat::Str("#["), Pat::Str("]")) - } else { - (Pat::Str("#!["), Pat::Str("]")) - }; - - if let Some(ident) = attr.ident() && let Pat::Str(old_pat) = pat.0 { + if let Some(ident) = attr.ident() { // TODO: I feel like it's likely we can use `Cow` instead but this will require quite a bit of // refactoring // NOTE: This will likely have false positives, like `allow = 1` - pat.0 = Pat::OwnedMultiStr(vec![ident.to_string(), old_pat.to_owned()]); - pat.1 = Pat::Str(""); + ( + Pat::OwnedMultiStr(vec![ident.to_string(), "#".to_owned()]), + Pat::Str(""), + ) + } else { + (Pat::Str("#"), Pat::Str("]")) } - - pat }, AttrKind::DocComment(_kind @ CommentKind::Line, ..) => { if matches!(attr.style, AttrStyle::Outer) { @@ -322,32 +316,42 @@ fn attr_search_pat(attr: &Attribute) -> (Pat, Pat) { fn ty_search_pat(ty: &Ty<'_>) -> (Pat, Pat) { match ty.kind { TyKind::Slice(..) | TyKind::Array(..) => (Pat::Str("["), Pat::Str("]")), - TyKind::Ptr(MutTy { mutbl, ty }) => ( - if mutbl.is_mut() { - Pat::Str("*const") - } else { - Pat::Str("*mut") - }, - ty_search_pat(ty).1, - ), + TyKind::Ptr(MutTy { ty, .. }) => (Pat::Str("*"), ty_search_pat(ty).1), TyKind::Ref(_, MutTy { ty, .. }) => (Pat::Str("&"), ty_search_pat(ty).1), TyKind::BareFn(bare_fn) => ( - Pat::OwnedStr(format!("{}{} fn", bare_fn.unsafety.prefix_str(), bare_fn.abi.name())), - ty_search_pat(ty).1, + if bare_fn.unsafety == Unsafety::Unsafe { + Pat::Str("unsafe") + } else if bare_fn.abi != Abi::Rust { + Pat::Str("extern") + } else { + Pat::MultiStr(&["fn", "extern"]) + }, + match bare_fn.decl.output { + FnRetTy::DefaultReturn(_) => { + if let [.., ty] = bare_fn.decl.inputs { + ty_search_pat(ty).1 + } else { + Pat::Str("(") + } + }, + FnRetTy::Return(ty) => ty_search_pat(ty).1, + }, ), - TyKind::Never => (Pat::Str("!"), Pat::Str("")), - TyKind::Tup(..) => (Pat::Str("("), Pat::Str(")")), + TyKind::Never => (Pat::Str("!"), Pat::Str("!")), + // Parenthesis are trimmed from the text before the search patterns are matched. + // See: `span_matches_pat` + TyKind::Tup([]) => (Pat::Str(")"), Pat::Str("(")), + TyKind::Tup([ty]) => ty_search_pat(ty), + TyKind::Tup([head, .., tail]) => (ty_search_pat(head).0, ty_search_pat(tail).1), TyKind::OpaqueDef(..) => (Pat::Str("impl"), Pat::Str("")), TyKind::Path(qpath) => qpath_search_pat(&qpath), - // NOTE: This is missing `TraitObject`. It will always return true then. + TyKind::Infer => (Pat::Str("_"), Pat::Str("_")), + TyKind::TraitObject(_, _, TraitObjectSyntax::Dyn) => (Pat::Str("dyn"), Pat::Str("")), + // NOTE: `TraitObject` is incomplete. It will always return true then. _ => (Pat::Str(""), Pat::Str("")), } } -fn ident_search_pat(ident: Ident) -> (Pat, Pat) { - (Pat::OwnedStr(ident.name.as_str().to_owned()), Pat::Str("")) -} - pub trait WithSearchPat<'cx> { type Context: LintContext; fn search_pat(&self, cx: &Self::Context) -> (Pat, Pat); @@ -406,7 +410,7 @@ impl<'cx> WithSearchPat<'cx> for Ident { type Context = LateContext<'cx>; fn search_pat(&self, _cx: &Self::Context) -> (Pat, Pat) { - ident_search_pat(*self) + (Pat::Sym(self.name), Pat::Sym(self.name)) } fn span(&self) -> Span { diff --git a/scout-audit-clippy-utils/src/consts.rs b/scout-audit-clippy-utils/src/consts.rs index d596eed4..727f93c8 100644 --- a/scout-audit-clippy-utils/src/consts.rs +++ b/scout-audit-clippy-utils/src/consts.rs @@ -2,18 +2,19 @@ use crate::source::{get_source_text, walk_span_to_context}; use crate::{clip, is_direct_expn_of, sext, unsext}; -use if_chain::if_chain; + use rustc_ast::ast::{self, LitFloatType, LitKind}; use rustc_data_structures::sync::Lrc; use rustc_hir::def::{DefKind, Res}; use rustc_hir::{BinOp, BinOpKind, Block, ConstBlock, Expr, ExprKind, HirId, Item, ItemKind, Node, QPath, UnOp}; use rustc_lexer::tokenize; use rustc_lint::LateContext; -use rustc_middle::mir::interpret::Scalar; -use rustc_middle::ty::{self, EarlyBinder, FloatTy, GenericArgsRef, List, ScalarInt, Ty, TyCtxt}; +use rustc_middle::mir::interpret::{alloc_range, Scalar}; +use rustc_middle::ty::{self, EarlyBinder, FloatTy, GenericArgsRef, IntTy, List, ScalarInt, Ty, TyCtxt, UintTy}; use rustc_middle::{bug, mir, span_bug}; use rustc_span::symbol::{Ident, Symbol}; use rustc_span::SyntaxContext; +use rustc_target::abi::Size; use std::cmp::Ordering::{self, Equal}; use std::hash::{Hash, Hasher}; use std::iter; @@ -50,6 +51,63 @@ pub enum Constant<'tcx> { Err, } +trait IntTypeBounds: Sized { + type Output: PartialOrd; + + fn min_max(self) -> Option<(Self::Output, Self::Output)>; + fn bits(self) -> Self::Output; + fn ensure_fits(self, val: Self::Output) -> Option { + let (min, max) = self.min_max()?; + (min <= val && val <= max).then_some(val) + } +} +impl IntTypeBounds for UintTy { + type Output = u128; + fn min_max(self) -> Option<(Self::Output, Self::Output)> { + Some(match self { + UintTy::U8 => (u8::MIN.into(), u8::MAX.into()), + UintTy::U16 => (u16::MIN.into(), u16::MAX.into()), + UintTy::U32 => (u32::MIN.into(), u32::MAX.into()), + UintTy::U64 => (u64::MIN.into(), u64::MAX.into()), + UintTy::U128 => (u128::MIN, u128::MAX), + UintTy::Usize => (usize::MIN.try_into().ok()?, usize::MAX.try_into().ok()?), + }) + } + fn bits(self) -> Self::Output { + match self { + UintTy::U8 => 8, + UintTy::U16 => 16, + UintTy::U32 => 32, + UintTy::U64 => 64, + UintTy::U128 => 128, + UintTy::Usize => usize::BITS.into(), + } + } +} +impl IntTypeBounds for IntTy { + type Output = i128; + fn min_max(self) -> Option<(Self::Output, Self::Output)> { + Some(match self { + IntTy::I8 => (i8::MIN.into(), i8::MAX.into()), + IntTy::I16 => (i16::MIN.into(), i16::MAX.into()), + IntTy::I32 => (i32::MIN.into(), i32::MAX.into()), + IntTy::I64 => (i64::MIN.into(), i64::MAX.into()), + IntTy::I128 => (i128::MIN, i128::MAX), + IntTy::Isize => (isize::MIN.try_into().ok()?, isize::MAX.try_into().ok()?), + }) + } + fn bits(self) -> Self::Output { + match self { + IntTy::I8 => 8, + IntTy::I16 => 16, + IntTy::I32 => 32, + IntTy::I64 => 64, + IntTy::I128 => 128, + IntTy::Isize => isize::BITS.into(), + } + } +} + impl<'tcx> PartialEq for Constant<'tcx> { fn eq(&self, other: &Self) -> bool { match (self, other) { @@ -371,27 +429,25 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { ExprKind::Binary(op, left, right) => self.binop(op, left, right), ExprKind::Call(callee, args) => { // We only handle a few const functions for now. - if_chain! { - if args.is_empty(); - if let ExprKind::Path(qpath) = &callee.kind; - let res = self.typeck_results.qpath_res(qpath, callee.hir_id); - if let Some(def_id) = res.opt_def_id(); - let def_path = self.lcx.get_def_path(def_id); - let def_path: Vec<&str> = def_path.iter().take(4).map(Symbol::as_str).collect(); - if let ["core", "num", int_impl, "max_value"] = *def_path; - then { - let value = match int_impl { - "" => i8::MAX as u128, - "" => i16::MAX as u128, - "" => i32::MAX as u128, - "" => i64::MAX as u128, - "" => i128::MAX as u128, - _ => return None, - }; - Some(Constant::Int(value)) - } else { - None - } + if args.is_empty() + && let ExprKind::Path(qpath) = &callee.kind + && let res = self.typeck_results.qpath_res(qpath, callee.hir_id) + && let Some(def_id) = res.opt_def_id() + && let def_path = self.lcx.get_def_path(def_id) + && let def_path = def_path.iter().take(4).map(Symbol::as_str).collect::>() + && let ["core", "num", int_impl, "max_value"] = *def_path + { + let value = match int_impl { + "" => i8::MAX as u128, + "" => i16::MAX as u128, + "" => i32::MAX as u128, + "" => i64::MAX as u128, + "" => i128::MAX as u128, + _ => return None, + }; + Some(Constant::Int(value)) + } else { + None } }, ExprKind::Index(arr, index, _) => self.index(arr, index), @@ -403,9 +459,8 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { && adt_def.is_struct() && let Some(desired_field) = field_of_struct(*adt_def, self.lcx, *constant, field) { - miri_to_const(self.lcx, desired_field) - } - else { + mir_to_const(self.lcx, desired_field) + } else { result } }, @@ -435,8 +490,15 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { match *o { Int(value) => { let ty::Int(ity) = *ty.kind() else { return None }; + let (min, _) = ity.min_max()?; // sign extend let value = sext(self.lcx.tcx, value, ity); + + // Applying unary - to the most negative value of any signed integer type panics. + if value == min { + return None; + } + let value = value.checked_neg()?; // clear unused bits Some(Int(unsext(self.lcx.tcx, value, ity))) @@ -461,11 +523,15 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { // Check if this constant is based on `cfg!(..)`, // which is NOT constant for our purposes. if let Some(node) = self.lcx.tcx.hir().get_if_local(def_id) - && let Node::Item(Item { kind: ItemKind::Const(.., body_id), .. }) = node - && let Node::Expr(Expr { kind: ExprKind::Lit(_), span, .. }) = self.lcx - .tcx - .hir() - .get(body_id.hir_id) + && let Node::Item(Item { + kind: ItemKind::Const(.., body_id), + .. + }) = node + && let Node::Expr(Expr { + kind: ExprKind::Lit(_), + span, + .. + }) = self.lcx.tcx.hir_node(body_id.hir_id) && is_direct_expn_of(*span, "cfg").is_some() { return None; @@ -483,7 +549,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { .const_eval_resolve(self.param_env, mir::UnevaluatedConst::new(def_id, args), None) .ok() .map(|val| rustc_middle::mir::Const::from_value(val, ty))?; - let result = miri_to_const(self.lcx, result)?; + let result = mir_to_const(self.lcx, result)?; self.source = ConstantSource::Constant; Some(result) }, @@ -503,7 +569,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { }, (Some(Constant::Vec(vec)), _) => { if !vec.is_empty() && vec.iter().all(|x| *x == vec[0]) { - match vec.get(0) { + match vec.first() { Some(Constant::F32(x)) => Some(Constant::F32(*x)), Some(Constant::F64(x)) => Some(Constant::F64(*x)), _ => None, @@ -530,7 +596,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { && let Some(src) = get_source_text(self.lcx, span.lo..expr_lo) && let Some(src) = src.as_str() { - use rustc_lexer::TokenKind::{Whitespace, LineComment, BlockComment, Semi, OpenBrace}; + use rustc_lexer::TokenKind::{BlockComment, LineComment, OpenBrace, Semi, Whitespace}; if !tokenize(src) .map(|t| t.kind) .filter(|t| !matches!(t, Whitespace | LineComment { .. } | BlockComment { .. } | Semi)) @@ -568,17 +634,33 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { match (l, r) { (Constant::Int(l), Some(Constant::Int(r))) => match *self.typeck_results.expr_ty_opt(left)?.kind() { ty::Int(ity) => { + let (ty_min_value, _) = ity.min_max()?; + let bits = ity.bits(); let l = sext(self.lcx.tcx, l, ity); let r = sext(self.lcx.tcx, r, ity); + + // Using / or %, where the left-hand argument is the smallest integer of a signed integer type and + // the right-hand argument is -1 always panics, even with overflow-checks disabled + if let BinOpKind::Div | BinOpKind::Rem = op.node + && l == ty_min_value + && r == -1 + { + return None; + } + let zext = |n: i128| Constant::Int(unsext(self.lcx.tcx, n, ity)); match op.node { - BinOpKind::Add => l.checked_add(r).map(zext), - BinOpKind::Sub => l.checked_sub(r).map(zext), - BinOpKind::Mul => l.checked_mul(r).map(zext), + // When +, * or binary - create a value greater than the maximum value, or less than + // the minimum value that can be stored, it panics. + BinOpKind::Add => l.checked_add(r).and_then(|n| ity.ensure_fits(n)).map(zext), + BinOpKind::Sub => l.checked_sub(r).and_then(|n| ity.ensure_fits(n)).map(zext), + BinOpKind::Mul => l.checked_mul(r).and_then(|n| ity.ensure_fits(n)).map(zext), BinOpKind::Div if r != 0 => l.checked_div(r).map(zext), BinOpKind::Rem if r != 0 => l.checked_rem(r).map(zext), - BinOpKind::Shr => l.checked_shr(r.try_into().ok()?).map(zext), - BinOpKind::Shl => l.checked_shl(r.try_into().ok()?).map(zext), + // Using << or >> where the right-hand argument is greater than or equal to the number of bits + // in the type of the left-hand argument, or is negative panics. + BinOpKind::Shr if r < bits && !r.is_negative() => l.checked_shr(r.try_into().ok()?).map(zext), + BinOpKind::Shl if r < bits && !r.is_negative() => l.checked_shl(r.try_into().ok()?).map(zext), BinOpKind::BitXor => Some(zext(l ^ r)), BinOpKind::BitOr => Some(zext(l | r)), BinOpKind::BitAnd => Some(zext(l & r)), @@ -591,24 +673,28 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { _ => None, } }, - ty::Uint(_) => match op.node { - BinOpKind::Add => l.checked_add(r).map(Constant::Int), - BinOpKind::Sub => l.checked_sub(r).map(Constant::Int), - BinOpKind::Mul => l.checked_mul(r).map(Constant::Int), - BinOpKind::Div => l.checked_div(r).map(Constant::Int), - BinOpKind::Rem => l.checked_rem(r).map(Constant::Int), - BinOpKind::Shr => l.checked_shr(r.try_into().ok()?).map(Constant::Int), - BinOpKind::Shl => l.checked_shl(r.try_into().ok()?).map(Constant::Int), - BinOpKind::BitXor => Some(Constant::Int(l ^ r)), - BinOpKind::BitOr => Some(Constant::Int(l | r)), - BinOpKind::BitAnd => Some(Constant::Int(l & r)), - BinOpKind::Eq => Some(Constant::Bool(l == r)), - BinOpKind::Ne => Some(Constant::Bool(l != r)), - BinOpKind::Lt => Some(Constant::Bool(l < r)), - BinOpKind::Le => Some(Constant::Bool(l <= r)), - BinOpKind::Ge => Some(Constant::Bool(l >= r)), - BinOpKind::Gt => Some(Constant::Bool(l > r)), - _ => None, + ty::Uint(ity) => { + let bits = ity.bits(); + + match op.node { + BinOpKind::Add => l.checked_add(r).and_then(|n| ity.ensure_fits(n)).map(Constant::Int), + BinOpKind::Sub => l.checked_sub(r).and_then(|n| ity.ensure_fits(n)).map(Constant::Int), + BinOpKind::Mul => l.checked_mul(r).and_then(|n| ity.ensure_fits(n)).map(Constant::Int), + BinOpKind::Div => l.checked_div(r).map(Constant::Int), + BinOpKind::Rem => l.checked_rem(r).map(Constant::Int), + BinOpKind::Shr if r < bits => l.checked_shr(r.try_into().ok()?).map(Constant::Int), + BinOpKind::Shl if r < bits => l.checked_shl(r.try_into().ok()?).map(Constant::Int), + BinOpKind::BitXor => Some(Constant::Int(l ^ r)), + BinOpKind::BitOr => Some(Constant::Int(l | r)), + BinOpKind::BitAnd => Some(Constant::Int(l & r)), + BinOpKind::Eq => Some(Constant::Bool(l == r)), + BinOpKind::Ne => Some(Constant::Bool(l != r)), + BinOpKind::Lt => Some(Constant::Bool(l < r)), + BinOpKind::Le => Some(Constant::Bool(l <= r)), + BinOpKind::Ge => Some(Constant::Bool(l >= r)), + BinOpKind::Gt => Some(Constant::Bool(l > r)), + _ => None, + } }, _ => None, }, @@ -655,10 +741,14 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { } } -pub fn miri_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::Const<'tcx>) -> Option> { +pub fn mir_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::Const<'tcx>) -> Option> { use rustc_middle::mir::ConstValue; - match result { - mir::Const::Val(ConstValue::Scalar(Scalar::Int(int)), _) => match result.ty().kind() { + let mir::Const::Val(val, _) = result else { + // We only work on evaluated consts. + return None; + }; + match (val, result.ty().kind()) { + (ConstValue::Scalar(Scalar::Int(int)), _) => match result.ty().kind() { ty::Adt(adt_def, _) if adt_def.is_struct() => Some(Constant::Adt(result)), ty::Bool => Some(Constant::Bool(int == ScalarInt::TRUE)), ty::Uint(_) | ty::Int(_) => Some(Constant::Int(int.assert_bits(int.size()))), @@ -671,42 +761,28 @@ pub fn miri_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::Const<'tcx>) -> ty::RawPtr(_) => Some(Constant::RawPtr(int.assert_bits(int.size()))), _ => None, }, - mir::Const::Val(cv, _) if matches!(result.ty().kind(), ty::Ref(_, inner_ty, _) if matches!(inner_ty.kind(), ty::Str)) => - { - let data = cv.try_get_slice_bytes_for_diagnostics(lcx.tcx)?; + (_, ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Str) => { + let data = val.try_get_slice_bytes_for_diagnostics(lcx.tcx)?; String::from_utf8(data.to_owned()).ok().map(Constant::Str) }, - mir::Const::Val(ConstValue::Indirect { alloc_id, offset: _ }, _) => { - let alloc = lcx.tcx.global_alloc(alloc_id).unwrap_memory(); - match result.ty().kind() { - ty::Adt(adt_def, _) if adt_def.is_struct() => Some(Constant::Adt(result)), - ty::Array(sub_type, len) => match sub_type.kind() { - ty::Float(FloatTy::F32) => match len.try_to_target_usize(lcx.tcx) { - Some(len) => alloc - .inner() - .inspect_with_uninit_and_ptr_outside_interpreter(0..(4 * usize::try_from(len).unwrap())) - .to_owned() - .array_chunks::<4>() - .map(|&chunk| Some(Constant::F32(f32::from_le_bytes(chunk)))) - .collect::>>>() - .map(Constant::Vec), - _ => None, - }, - ty::Float(FloatTy::F64) => match len.try_to_target_usize(lcx.tcx) { - Some(len) => alloc - .inner() - .inspect_with_uninit_and_ptr_outside_interpreter(0..(8 * usize::try_from(len).unwrap())) - .to_owned() - .array_chunks::<8>() - .map(|&chunk| Some(Constant::F64(f64::from_le_bytes(chunk)))) - .collect::>>>() - .map(Constant::Vec), - _ => None, - }, - _ => None, - }, - _ => None, + (_, ty::Adt(adt_def, _)) if adt_def.is_struct() => Some(Constant::Adt(result)), + (ConstValue::Indirect { alloc_id, offset }, ty::Array(sub_type, len)) => { + let alloc = lcx.tcx.global_alloc(alloc_id).unwrap_memory().inner(); + let len = len.try_to_target_usize(lcx.tcx)?; + let ty::Float(flt) = sub_type.kind() else { + return None; + }; + let size = Size::from_bits(flt.bit_width()); + let mut res = Vec::new(); + for idx in 0..len { + let range = alloc_range(offset + size * idx, size); + let val = alloc.read_scalar(&lcx.tcx, range, /* read_provenance */ false).ok()?; + res.push(match flt { + FloatTy::F32 => Constant::F32(f32::from_bits(val.to_u32().ok()?)), + FloatTy::F64 => Constant::F64(f64::from_bits(val.to_u64().ok()?)), + }); } + Some(Constant::Vec(res)) }, _ => None, } @@ -719,15 +795,14 @@ fn field_of_struct<'tcx>( field: &Ident, ) -> Option> { if let mir::Const::Val(result, ty) = result - && let Some(dc) = lcx.tcx.try_destructure_mir_constant_for_diagnostics(result, ty) + && let Some(dc) = lcx.tcx.try_destructure_mir_constant_for_user_output(result, ty) && let Some(dc_variant) = dc.variant && let Some(variant) = adt_def.variants().get(dc_variant) && let Some(field_idx) = variant.fields.iter().position(|el| el.name == field.name) && let Some(&(val, ty)) = dc.fields.get(field_idx) { Some(mir::Const::Val(val, ty)) - } - else { + } else { None } } diff --git a/scout-audit-clippy-utils/src/diagnostics.rs b/scout-audit-clippy-utils/src/diagnostics.rs index 210957a9..8b1773e4 100644 --- a/scout-audit-clippy-utils/src/diagnostics.rs +++ b/scout-audit-clippy-utils/src/diagnostics.rs @@ -11,7 +11,7 @@ use rustc_errors::{Applicability, Diagnostic, MultiSpan}; use rustc_hir::HirId; use rustc_lint::{LateContext, Lint, LintContext}; -use rustc_span::source_map::Span; +use rustc_span::Span; use std::env; fn docs_link(diag: &mut Diagnostic, lint: &'static Lint) { @@ -46,6 +46,7 @@ fn docs_link(diag: &mut Diagnostic, lint: &'static Lint) { /// | ^^^^^^^^^^^^^^^^^^^^^^^ /// ``` pub fn span_lint(cx: &T, lint: &'static Lint, sp: impl Into, msg: &str) { + #[expect(clippy::disallowed_methods)] cx.struct_span_lint(lint, sp, msg.to_string(), |diag| { docs_link(diag, lint); diag @@ -80,6 +81,7 @@ pub fn span_lint_and_help( help_span: Option, help: &str, ) { + #[expect(clippy::disallowed_methods)] cx.struct_span_lint(lint, span, msg.to_string(), |diag| { let help = help.to_string(); if let Some(help_span) = help_span { @@ -123,6 +125,7 @@ pub fn span_lint_and_note( note_span: Option, note: &str, ) { + #[expect(clippy::disallowed_methods)] cx.struct_span_lint(lint, span, msg.to_string(), |diag| { let note = note.to_string(); if let Some(note_span) = note_span { @@ -145,6 +148,7 @@ where S: Into, F: FnOnce(&mut Diagnostic), { + #[expect(clippy::disallowed_methods)] cx.struct_span_lint(lint, sp, msg.to_string(), |diag| { f(diag); docs_link(diag, lint); @@ -153,6 +157,7 @@ where } pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, sp: Span, msg: &str) { + #[expect(clippy::disallowed_methods)] cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg.to_string(), |diag| { docs_link(diag, lint); diag @@ -167,6 +172,7 @@ pub fn span_lint_hir_and_then( msg: &str, f: impl FnOnce(&mut Diagnostic), ) { + #[expect(clippy::disallowed_methods)] cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg.to_string(), |diag| { f(diag); docs_link(diag, lint); @@ -193,7 +199,7 @@ pub fn span_lint_hir_and_then( /// | /// = note: `-D fold-any` implied by `-D warnings` /// ``` -#[cfg_attr(feature = "internal", allow(clippy::collapsible_span_lint_calls))] +#[expect(clippy::collapsible_span_lint_calls)] pub fn span_lint_and_sugg( cx: &T, lint: &'static Lint, diff --git a/scout-audit-clippy-utils/src/eager_or_lazy.rs b/scout-audit-clippy-utils/src/eager_or_lazy.rs index 0bcefba7..4e71c648 100644 --- a/scout-audit-clippy-utils/src/eager_or_lazy.rs +++ b/scout-audit-clippy-utils/src/eager_or_lazy.rs @@ -9,12 +9,13 @@ //! - or-fun-call //! - option-if-let-else +use crate::consts::{constant, FullInt}; use crate::ty::{all_predicates_of, is_copy}; use crate::visitors::is_const_evaluatable; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{walk_expr, Visitor}; -use rustc_hir::{Block, Expr, ExprKind, QPath, UnOp}; +use rustc_hir::{BinOpKind, Block, Expr, ExprKind, QPath, UnOp}; use rustc_lint::LateContext; use rustc_middle::ty; use rustc_middle::ty::adjustment::Adjust; @@ -193,6 +194,12 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS self.eagerness = Lazy; } }, + + // `-i32::MIN` panics with overflow checks + ExprKind::Unary(UnOp::Neg, right) if constant(self.cx, self.cx.typeck_results(), right).is_none() => { + self.eagerness |= NoChange; + }, + // Custom `Deref` impl might have side effects ExprKind::Unary(UnOp::Deref, e) if self.cx.typeck_results().expr_ty(e).builtin_deref(true).is_none() => @@ -207,6 +214,49 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS self.cx.typeck_results().expr_ty(e).kind(), ty::Bool | ty::Int(_) | ty::Uint(_), ) => {}, + + // `>>` and `<<` panic when the right-hand side is greater than or equal to the number of bits in the + // type of the left-hand side, or is negative. + // We intentionally only check if the right-hand isn't a constant, because even if the suggestion would + // overflow with constants, the compiler emits an error for it and the programmer will have to fix it. + // Thus, we would realistically only delay the lint. + ExprKind::Binary(op, _, right) + if matches!(op.node, BinOpKind::Shl | BinOpKind::Shr) + && constant(self.cx, self.cx.typeck_results(), right).is_none() => + { + self.eagerness |= NoChange; + }, + + ExprKind::Binary(op, left, right) + if matches!(op.node, BinOpKind::Div | BinOpKind::Rem) + && let right_ty = self.cx.typeck_results().expr_ty(right) + && let left = constant(self.cx, self.cx.typeck_results(), left) + && let right = constant(self.cx, self.cx.typeck_results(), right) + .and_then(|c| c.int_value(self.cx, right_ty)) + && matches!( + (left, right), + // `1 / x`: x might be zero + (_, None) + // `x / -1`: x might be T::MIN + | (None, Some(FullInt::S(-1))) + ) => + { + self.eagerness |= NoChange; + }, + + // Similar to `>>` and `<<`, we only want to avoid linting entirely if either side is unknown and the + // compiler can't emit an error for an overflowing expression. + // Suggesting eagerness for `true.then(|| i32::MAX + 1)` is okay because the compiler will emit an + // error and it's good to have the eagerness warning up front when the user fixes the logic error. + ExprKind::Binary(op, left, right) + if matches!(op.node, BinOpKind::Add | BinOpKind::Sub | BinOpKind::Mul) + && !self.cx.typeck_results().expr_ty(e).is_floating_point() + && (constant(self.cx, self.cx.typeck_results(), left).is_none() + || constant(self.cx, self.cx.typeck_results(), right).is_none()) => + { + self.eagerness |= NoChange; + }, + ExprKind::Binary(_, lhs, rhs) if self.cx.typeck_results().expr_ty(lhs).is_primitive() && self.cx.typeck_results().expr_ty(rhs).is_primitive() => {}, diff --git a/scout-audit-clippy-utils/src/higher.rs b/scout-audit-clippy-utils/src/higher.rs index 802adbd4..3135a033 100644 --- a/scout-audit-clippy-utils/src/higher.rs +++ b/scout-audit-clippy-utils/src/higher.rs @@ -5,7 +5,7 @@ use crate::consts::{constant_simple, Constant}; use crate::ty::is_type_diagnostic_item; use crate::{is_expn_of, match_def_path, paths}; -use if_chain::if_chain; + use rustc_ast::ast; use rustc_hir as hir; use rustc_hir::{Arm, Block, Expr, ExprKind, HirId, LoopSource, MatchSource, Node, Pat, QPath}; @@ -30,24 +30,22 @@ pub struct ForLoop<'tcx> { impl<'tcx> ForLoop<'tcx> { /// Parses a desugared `for` loop pub fn hir(expr: &Expr<'tcx>) -> Option { - if_chain! { - if let hir::ExprKind::DropTemps(e) = expr.kind; - if let hir::ExprKind::Match(iterexpr, [arm], hir::MatchSource::ForLoopDesugar) = e.kind; - if let hir::ExprKind::Call(_, [arg]) = iterexpr.kind; - if let hir::ExprKind::Loop(block, ..) = arm.body.kind; - if let [stmt] = block.stmts; - if let hir::StmtKind::Expr(e) = stmt.kind; - if let hir::ExprKind::Match(_, [_, some_arm], _) = e.kind; - if let hir::PatKind::Struct(_, [field], _) = some_arm.pat.kind; - then { - return Some(Self { - pat: field.pat, - arg, - body: some_arm.body, - loop_id: arm.body.hir_id, - span: expr.span.ctxt().outer_expn_data().call_site, - }); - } + if let hir::ExprKind::DropTemps(e) = expr.kind + && let hir::ExprKind::Match(iterexpr, [arm], hir::MatchSource::ForLoopDesugar) = e.kind + && let hir::ExprKind::Call(_, [arg]) = iterexpr.kind + && let hir::ExprKind::Loop(block, ..) = arm.body.kind + && let [stmt] = block.stmts + && let hir::StmtKind::Expr(e) = stmt.kind + && let hir::ExprKind::Match(_, [_, some_arm], _) = e.kind + && let hir::PatKind::Struct(_, [field], _) = some_arm.pat.kind + { + return Some(Self { + pat: field.pat, + arg, + body: some_arm.body, + loop_id: arm.body.hir_id, + span: expr.span.ctxt().outer_expn_data().call_site, + }); } None } @@ -277,29 +275,28 @@ impl<'a> VecArgs<'a> { /// Returns the arguments of the `vec!` macro if this expression was expanded /// from `vec!`. pub fn hir(cx: &LateContext<'_>, expr: &'a hir::Expr<'_>) -> Option> { - if_chain! { - if let hir::ExprKind::Call(fun, args) = expr.kind; - if let hir::ExprKind::Path(ref qpath) = fun.kind; - if is_expn_of(fun.span, "vec").is_some(); - if let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id(); - then { - return if match_def_path(cx, fun_def_id, &paths::VEC_FROM_ELEM) && args.len() == 2 { - // `vec![elem; size]` case - Some(VecArgs::Repeat(&args[0], &args[1])) - } else if match_def_path(cx, fun_def_id, &paths::SLICE_INTO_VEC) && args.len() == 1 { - // `vec![a, b, c]` case - if let hir::ExprKind::Call(_, [arg]) = &args[0].kind - && let hir::ExprKind::Array(args) = arg.kind { - Some(VecArgs::Vec(args)) - } else { - None - } - } else if match_def_path(cx, fun_def_id, &paths::VEC_NEW) && args.is_empty() { - Some(VecArgs::Vec(&[])) + if let hir::ExprKind::Call(fun, args) = expr.kind + && let hir::ExprKind::Path(ref qpath) = fun.kind + && is_expn_of(fun.span, "vec").is_some() + && let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id() + { + return if match_def_path(cx, fun_def_id, &paths::VEC_FROM_ELEM) && args.len() == 2 { + // `vec![elem; size]` case + Some(VecArgs::Repeat(&args[0], &args[1])) + } else if match_def_path(cx, fun_def_id, &paths::SLICE_INTO_VEC) && args.len() == 1 { + // `vec![a, b, c]` case + if let hir::ExprKind::Call(_, [arg]) = &args[0].kind + && let hir::ExprKind::Array(args) = arg.kind + { + Some(VecArgs::Vec(args)) } else { None - }; - } + } + } else if match_def_path(cx, fun_def_id, &paths::VEC_NEW) && args.is_empty() { + Some(VecArgs::Vec(&[])) + } else { + None + }; } None @@ -449,7 +446,7 @@ pub fn get_vec_init_kind<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) - } else if name.ident.name == symbol::kw::Default { return Some(VecInitKind::Default); } else if name.ident.name.as_str() == "with_capacity" { - let arg = args.get(0)?; + let arg = args.first()?; return match constant_simple(cx, cx.typeck_results(), arg) { Some(Constant::Int(num)) => Some(VecInitKind::WithConstCapacity(num)), _ => Some(VecInitKind::WithExprCapacity(arg.hir_id)), @@ -457,7 +454,7 @@ pub fn get_vec_init_kind<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) - }; }, ExprKind::Path(QPath::Resolved(_, path)) - if match_def_path(cx, path.res.opt_def_id()?, &paths::DEFAULT_TRAIT_METHOD) + if cx.tcx.is_diagnostic_item(sym::default_fn, path.res.opt_def_id()?) && is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(expr), sym::Vec) => { return Some(VecInitKind::Default); diff --git a/scout-audit-clippy-utils/src/hir_utils.rs b/scout-audit-clippy-utils/src/hir_utils.rs index 52214e73..e610ed93 100644 --- a/scout-audit-clippy-utils/src/hir_utils.rs +++ b/scout-audit-clippy-utils/src/hir_utils.rs @@ -247,7 +247,7 @@ impl HirEqInterExpr<'_, '_, '_> { res } - #[expect(clippy::similar_names)] + #[expect(clippy::similar_names, clippy::too_many_lines)] pub fn eq_expr(&mut self, left: &Expr<'_>, right: &Expr<'_>) -> bool { if !self.check_ctxt(left.span.ctxt(), right.span.ctxt()) { return false; @@ -271,9 +271,7 @@ impl HirEqInterExpr<'_, '_, '_> { (&ExprKind::AddrOf(lb, l_mut, le), &ExprKind::AddrOf(rb, r_mut, re)) => { lb == rb && l_mut == r_mut && self.eq_expr(le, re) }, - (&ExprKind::Continue(li), &ExprKind::Continue(ri)) => { - both(&li.label, &ri.label, |l, r| l.ident.name == r.ident.name) - }, + (&ExprKind::Array(l), &ExprKind::Array(r)) => self.eq_exprs(l, r), (&ExprKind::Assign(ll, lr, _), &ExprKind::Assign(rl, rr, _)) => { self.inner.allow_side_effects && self.eq_expr(ll, rl) && self.eq_expr(lr, rr) }, @@ -294,9 +292,15 @@ impl HirEqInterExpr<'_, '_, '_> { (&ExprKind::Call(l_fun, l_args), &ExprKind::Call(r_fun, r_args)) => { self.inner.allow_side_effects && self.eq_expr(l_fun, r_fun) && self.eq_exprs(l_args, r_args) }, - (&ExprKind::Cast(lx, lt), &ExprKind::Cast(rx, rt)) | (&ExprKind::Type(lx, lt), &ExprKind::Type(rx, rt)) => { + (&ExprKind::Cast(lx, lt), &ExprKind::Cast(rx, rt)) => { self.eq_expr(lx, rx) && self.eq_ty(lt, rt) }, + (&ExprKind::Closure(_l), &ExprKind::Closure(_r)) => false, + (&ExprKind::ConstBlock(lb), &ExprKind::ConstBlock(rb)) => self.eq_body(lb.body, rb.body), + (&ExprKind::Continue(li), &ExprKind::Continue(ri)) => { + both(&li.label, &ri.label, |l, r| l.ident.name == r.ident.name) + }, + (&ExprKind::DropTemps(le), &ExprKind::DropTemps(re)) => self.eq_expr(le, re), (&ExprKind::Field(l_f_exp, ref l_f_ident), &ExprKind::Field(r_f_exp, ref r_f_ident)) => { l_f_ident.name == r_f_ident.name && self.eq_expr(l_f_exp, r_f_exp) }, @@ -329,24 +333,70 @@ impl HirEqInterExpr<'_, '_, '_> { && self.eq_expr(l_receiver, r_receiver) && self.eq_exprs(l_args, r_args) }, + (&ExprKind::OffsetOf(l_container, l_fields), &ExprKind::OffsetOf(r_container, r_fields)) => { + self.eq_ty(l_container, r_container) && over(l_fields, r_fields, |l, r| l.name == r.name) + }, + (ExprKind::Path(l), ExprKind::Path(r)) => self.eq_qpath(l, r), (&ExprKind::Repeat(le, ll), &ExprKind::Repeat(re, rl)) => { self.eq_expr(le, re) && self.eq_array_length(ll, rl) }, (ExprKind::Ret(l), ExprKind::Ret(r)) => both(l, r, |l, r| self.eq_expr(l, r)), - (ExprKind::Path(l), ExprKind::Path(r)) => self.eq_qpath(l, r), (&ExprKind::Struct(l_path, lf, ref lo), &ExprKind::Struct(r_path, rf, ref ro)) => { self.eq_qpath(l_path, r_path) && both(lo, ro, |l, r| self.eq_expr(l, r)) && over(lf, rf, |l, r| self.eq_expr_field(l, r)) }, (&ExprKind::Tup(l_tup), &ExprKind::Tup(r_tup)) => self.eq_exprs(l_tup, r_tup), + (&ExprKind::Type(le, lt), &ExprKind::Type(re, rt)) => self.eq_expr(le, re) && self.eq_ty(lt, rt), (&ExprKind::Unary(l_op, le), &ExprKind::Unary(r_op, re)) => l_op == r_op && self.eq_expr(le, re), - (&ExprKind::Array(l), &ExprKind::Array(r)) => self.eq_exprs(l, r), - (&ExprKind::DropTemps(le), &ExprKind::DropTemps(re)) => self.eq_expr(le, re), - (&ExprKind::OffsetOf(l_container, l_fields), &ExprKind::OffsetOf(r_container, r_fields)) => { - self.eq_ty(l_container, r_container) && over(l_fields, r_fields, |l, r| l.name == r.name) - }, - _ => false, + (&ExprKind::Yield(le, _), &ExprKind::Yield(re, _)) => return self.eq_expr(le, re), + ( + // Else branches for branches above, grouped as per `match_same_arms`. + | &ExprKind::AddrOf(..) + | &ExprKind::Array(..) + | &ExprKind::Assign(..) + | &ExprKind::AssignOp(..) + | &ExprKind::Binary(..) + | &ExprKind::Become(..) + | &ExprKind::Block(..) + | &ExprKind::Break(..) + | &ExprKind::Call(..) + | &ExprKind::Cast(..) + | &ExprKind::ConstBlock(..) + | &ExprKind::Continue(..) + | &ExprKind::DropTemps(..) + | &ExprKind::Field(..) + | &ExprKind::Index(..) + | &ExprKind::If(..) + | &ExprKind::Let(..) + | &ExprKind::Lit(..) + | &ExprKind::Loop(..) + | &ExprKind::Match(..) + | &ExprKind::MethodCall(..) + | &ExprKind::OffsetOf(..) + | &ExprKind::Path(..) + | &ExprKind::Repeat(..) + | &ExprKind::Ret(..) + | &ExprKind::Struct(..) + | &ExprKind::Tup(..) + | &ExprKind::Type(..) + | &ExprKind::Unary(..) + | &ExprKind::Yield(..) + + // --- Special cases that do not have a positive branch. + + // `Err` represents an invalid expression, so let's never assume that + // an invalid expressions is equal to anything. + | &ExprKind::Err(..) + + // For the time being, we always consider that two closures are unequal. + // This behavior may change in the future. + | &ExprKind::Closure(..) + // For the time being, we always consider that two instances of InlineAsm are different. + // This behavior may change in the future. + | &ExprKind::InlineAsm(_) + , _ + ) => false, }; (is_eq && (!self.should_ignore(left) || !self.should_ignore(right))) || self.inner.expr_fallback.as_mut().map_or(false, |f| f(left, right)) @@ -684,6 +734,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_name(i.ident.name); } }, + ExprKind::Array(v) => { + self.hash_exprs(v); + }, ExprKind::Assign(l, r, _) => { self.hash_expr(l); self.hash_expr(r); @@ -693,6 +746,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_expr(l); self.hash_expr(r); }, + ExprKind::Become(f) => { + self.hash_expr(f); + }, ExprKind::Block(b, _) => { self.hash_block(b); }, @@ -709,9 +765,6 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_expr(j); } }, - ExprKind::DropTemps(e) | ExprKind::Yield(e, _) => { - self.hash_expr(e); - }, ExprKind::Call(fun, args) => { self.hash_expr(fun); self.hash_exprs(args); @@ -727,6 +780,12 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { // closures inherit TypeckResults self.hash_expr(self.cx.tcx.hir().body(body).value); }, + ExprKind::ConstBlock(ref l_id) => { + self.hash_body(l_id.body); + }, + ExprKind::DropTemps(e) | ExprKind::Yield(e, _) => { + self.hash_expr(e); + }, ExprKind::Field(e, ref f) => { self.hash_expr(e); self.hash_name(f.name); @@ -788,12 +847,6 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { } } }, - ExprKind::OffsetOf(container, fields) => { - self.hash_ty(container); - for field in fields { - self.hash_name(field.name); - } - }, ExprKind::Let(Let { pat, init, ty, .. }) => { self.hash_expr(init); if let Some(ty) = ty { @@ -801,7 +854,6 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { } self.hash_pat(pat); }, - ExprKind::Err(_) => {}, ExprKind::Lit(l) => { l.node.hash(&mut self.s); }, @@ -836,8 +888,14 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_expr(receiver); self.hash_exprs(args); }, - ExprKind::ConstBlock(ref l_id) => { - self.hash_body(l_id.body); + ExprKind::OffsetOf(container, fields) => { + self.hash_ty(container); + for field in fields { + self.hash_name(field.name); + } + }, + ExprKind::Path(ref qpath) => { + self.hash_qpath(qpath); }, ExprKind::Repeat(e, len) => { self.hash_expr(e); @@ -848,12 +906,6 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_expr(e); } }, - ExprKind::Become(f) => { - self.hash_expr(f); - }, - ExprKind::Path(ref qpath) => { - self.hash_qpath(qpath); - }, ExprKind::Struct(path, fields, ref expr) => { self.hash_qpath(path); @@ -869,13 +921,11 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { ExprKind::Tup(tup) => { self.hash_exprs(tup); }, - ExprKind::Array(v) => { - self.hash_exprs(v); - }, ExprKind::Unary(lop, le) => { std::mem::discriminant(&lop).hash(&mut self.s); self.hash_expr(le); }, + ExprKind::Err(_) => {}, } } @@ -967,7 +1017,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { } e.hash(&mut self.s); }, - PatKind::Wild => {}, + PatKind::Never | PatKind::Wild => {}, } } @@ -1142,12 +1192,8 @@ fn eq_span_tokens( let pred = |t: &(_, _)| pred(t.0); let map = |(_, x)| x; - let ltok = tokenize_with_text(lsrc) - .filter(pred) - .map(map); - let rtok = tokenize_with_text(rsrc) - .filter(pred) - .map(map); + let ltok = tokenize_with_text(lsrc).filter(pred).map(map); + let rtok = tokenize_with_text(rsrc).filter(pred).map(map); ltok.eq(rtok) } else { // Unable to access the source. Conservatively assume the blocks aren't equal. diff --git a/scout-audit-clippy-utils/src/lib.rs b/scout-audit-clippy-utils/src/lib.rs index 0f7bc04c..70a3c6f8 100644 --- a/scout-audit-clippy-utils/src/lib.rs +++ b/scout-audit-clippy-utils/src/lib.rs @@ -54,7 +54,6 @@ pub mod higher; mod hir_utils; pub mod macros; pub mod mir; -pub mod msrvs; pub mod numeric_literal; pub mod paths; pub mod ptr; @@ -72,15 +71,14 @@ pub use self::hir_utils::{ both, count_eq, eq_expr_value, hash_expr, hash_stmt, is_bool, over, HirEqInterExpr, SpanlessEq, SpanlessHash, }; +use core::mem; use core::ops::ControlFlow; use std::collections::hash_map::Entry; use std::hash::BuildHasherDefault; use std::sync::{Mutex, MutexGuard, OnceLock}; -use if_chain::if_chain; use itertools::Itertools; use rustc_ast::ast::{self, LitKind, RangeLimits}; -use rustc_ast::Attribute; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::unhash::UnhashMap; use rustc_hir::def::{DefKind, Res}; @@ -113,7 +111,7 @@ use rustc_span::{sym, Span}; use rustc_target::abi::Integer; use visitors::Visitable; -use crate::consts::{constant, miri_to_const, Constant}; +use crate::consts::{constant, mir_to_const, Constant}; use crate::higher::Range; use crate::ty::{ adt_and_variant_of_res, can_partially_move_ty, expr_sig, is_copy, is_recursively_primitive_type, @@ -145,7 +143,7 @@ macro_rules! extract_msrv_attr { /// instead. /// /// Examples: -/// ``` +/// ```no_run /// let abc = 1; /// // ^ output /// let def = abc; @@ -178,14 +176,12 @@ pub fn expr_or_init<'a, 'b, 'tcx: 'b>(cx: &LateContext<'tcx>, mut expr: &'a Expr /// canonical binding `HirId`. pub fn find_binding_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Expr<'tcx>> { let hir = cx.tcx.hir(); - if_chain! { - if let Some(Node::Pat(pat)) = hir.find(hir_id); - if matches!(pat.kind, PatKind::Binding(BindingAnnotation::NONE, ..)); - let parent = hir.parent_id(hir_id); - if let Some(Node::Local(local)) = hir.find(parent); - then { - return local.init; - } + if let Some(Node::Pat(pat)) = cx.tcx.opt_hir_node(hir_id) + && matches!(pat.kind, PatKind::Binding(BindingAnnotation::NONE, ..)) + && let parent = hir.parent_id(hir_id) + && let Some(Node::Local(local)) = cx.tcx.opt_hir_node(parent) + { + return local.init; } None } @@ -288,8 +284,8 @@ pub fn is_wild(pat: &Pat<'_>) -> bool { /// Checks if the given `QPath` belongs to a type alias. pub fn is_ty_alias(qpath: &QPath<'_>) -> bool { match *qpath { - QPath::Resolved(_, path) => matches!(path.res, Res::Def(DefKind::TyAlias { .. } | DefKind::AssocTy, ..)), - QPath::TypeRelative(ty, _) if let TyKind::Path(qpath) = ty.kind => { is_ty_alias(&qpath) }, + QPath::Resolved(_, path) => matches!(path.res, Res::Def(DefKind::TyAlias | DefKind::AssocTy, ..)), + QPath::TypeRelative(ty, _) if let TyKind::Path(qpath) = ty.kind => is_ty_alias(&qpath), _ => false, } } @@ -567,7 +563,7 @@ fn local_item_children_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, name: Symb let hir = tcx.hir(); let root_mod; - let item_kind = match hir.find_by_def_id(local_id) { + let item_kind = match tcx.opt_hir_node_by_def_id(local_id) { Some(Node::Crate(r#mod)) => { root_mod = ItemKind::Mod(r#mod); &root_mod @@ -700,7 +696,7 @@ pub fn get_trait_def_id(cx: &LateContext<'_>, path: &[&str]) -> Option { /// /// Use this if you want to find the `TraitRef` of the `Add` trait in this example: /// -/// ```rust +/// ```no_run /// struct Point(isize, isize); /// /// impl std::ops::Add for Point { @@ -713,15 +709,13 @@ pub fn get_trait_def_id(cx: &LateContext<'_>, path: &[&str]) -> Option { /// ``` pub fn trait_ref_of_method<'tcx>(cx: &LateContext<'tcx>, def_id: LocalDefId) -> Option<&'tcx TraitRef<'tcx>> { // Get the implemented trait for the current function - let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def_id); + let hir_id = cx.tcx.local_def_id_to_hir_id(def_id); let parent_impl = cx.tcx.hir().get_parent_item(hir_id); - if_chain! { - if parent_impl != hir::CRATE_OWNER_ID; - if let hir::Node::Item(item) = cx.tcx.hir().get_by_def_id(parent_impl.def_id); - if let hir::ItemKind::Impl(impl_) = &item.kind; - then { - return impl_.of_trait.as_ref(); - } + if parent_impl != hir::CRATE_OWNER_ID + && let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(parent_impl.def_id) + && let hir::ItemKind::Impl(impl_) = &item.kind + { + return impl_.of_trait.as_ref(); } None } @@ -825,12 +819,14 @@ fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath< /// Returns true if the expr is equal to `Default::default` when evaluated. pub fn is_default_equivalent_call(cx: &LateContext<'_>, repl_func: &Expr<'_>) -> bool { - if_chain! { - if let hir::ExprKind::Path(ref repl_func_qpath) = repl_func.kind; - if let Some(repl_def_id) = cx.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id(); - if is_diag_trait_item(cx, repl_def_id, sym::Default) - || is_default_equivalent_ctor(cx, repl_def_id, repl_func_qpath); - then { true } else { false } + if let hir::ExprKind::Path(ref repl_func_qpath) = repl_func.kind + && let Some(repl_def_id) = cx.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id() + && (is_diag_trait_item(cx, repl_def_id, sym::Default) + || is_default_equivalent_ctor(cx, repl_def_id, repl_func_qpath)) + { + true + } else { + false } } @@ -845,14 +841,14 @@ pub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { _ => false, }, ExprKind::Tup(items) | ExprKind::Array(items) => items.iter().all(|x| is_default_equivalent(cx, x)), - ExprKind::Repeat(x, ArrayLen::Body(len)) => if_chain! { - if let ExprKind::Lit(const_lit) = cx.tcx.hir().body(len.body).value.kind; - if let LitKind::Int(v, _) = const_lit.node; - if v <= 32 && is_default_equivalent(cx, x); - then { + ExprKind::Repeat(x, ArrayLen::Body(len)) => { + if let ExprKind::Lit(const_lit) = cx.tcx.hir().body(len.body).value.kind + && let LitKind::Int(v, _) = const_lit.node + && v <= 32 + && is_default_equivalent(cx, x) + { true - } - else { + } else { false } }, @@ -865,8 +861,8 @@ pub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { } fn is_default_equivalent_from(cx: &LateContext<'_>, from_func: &Expr<'_>, arg: &Expr<'_>) -> bool { - if let ExprKind::Path(QPath::TypeRelative(ty, seg)) = from_func.kind && - seg.ident.name == sym::from + if let ExprKind::Path(QPath::TypeRelative(ty, seg)) = from_func.kind + && seg.ident.name == sym::from { match arg.kind { ExprKind::Lit(hir::Lit { @@ -875,12 +871,12 @@ fn is_default_equivalent_from(cx: &LateContext<'_>, from_func: &Expr<'_>, arg: & }) => return sym.is_empty() && is_path_lang_item(cx, ty, LangItem::String), ExprKind::Array([]) => return is_path_diagnostic_item(cx, ty, sym::Vec), ExprKind::Repeat(_, ArrayLen::Body(len)) => { - if let ExprKind::Lit(const_lit) = cx.tcx.hir().body(len.body).value.kind && - let LitKind::Int(v, _) = const_lit.node + if let ExprKind::Lit(const_lit) = cx.tcx.hir().body(len.body).value.kind + && let LitKind::Int(v, _) = const_lit.node { - return v == 0 && is_path_diagnostic_item(cx, ty, sym::Vec); + return v == 0 && is_path_diagnostic_item(cx, ty, sym::Vec); } - } + }, _ => (), } } @@ -896,7 +892,7 @@ fn is_default_equivalent_from(cx: &LateContext<'_>, from_func: &Expr<'_>, arg: & /// /// For example, given the following function: /// -/// ``` +/// ```no_run /// fn f<'a>(iter: &mut impl Iterator) { /// for item in iter { /// let s = item.1; @@ -1246,7 +1242,7 @@ pub fn is_in_panic_handler(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { /// Gets the name of the item the expression is in, if available. pub fn get_item_name(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option { let parent_id = cx.tcx.hir().get_parent_item(expr.hir_id).def_id; - match cx.tcx.hir().find_by_def_id(parent_id) { + match cx.tcx.opt_hir_node_by_def_id(parent_id) { Some( Node::Item(Item { ident, .. }) | Node::TraitItem(TraitItem { ident, .. }) @@ -1323,7 +1319,7 @@ pub fn get_enclosing_block<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Optio let map = &cx.tcx.hir(); let enclosing_node = map .get_enclosing_scope(hir_id) - .and_then(|enclosing_id| map.find(enclosing_id)); + .and_then(|enclosing_id| cx.tcx.opt_hir_node(enclosing_id)); enclosing_node.and_then(|node| match node { Node::Block(block) => Some(block), Node::Item(&Item { @@ -1491,6 +1487,43 @@ pub fn is_else_clause(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool { } } +/// Checks if the given expression is a part of `let else` +/// returns `true` for both the `init` and the `else` part +pub fn is_inside_let_else(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool { + let mut child_id = expr.hir_id; + for (parent_id, node) in tcx.hir().parent_iter(child_id) { + if let Node::Local(Local { + init: Some(init), + els: Some(els), + .. + }) = node + && (init.hir_id == child_id || els.hir_id == child_id) + { + return true; + } + + child_id = parent_id; + } + + false +} + +/// Checks if the given expression is the else clause of a `let else` expression +pub fn is_else_clause_in_let_else(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool { + let mut child_id = expr.hir_id; + for (parent_id, node) in tcx.hir().parent_iter(child_id) { + if let Node::Local(Local { els: Some(els), .. }) = node + && els.hir_id == child_id + { + return true; + } + + child_id = parent_id; + } + + false +} + /// Checks whether the given `Expr` is a range equivalent to a `RangeFull`. /// For the lower bound, this means that: /// - either there is none @@ -1509,9 +1542,7 @@ pub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Opti if let rustc_ty::Adt(_, subst) = ty.kind() && let bnd_ty = subst.type_at(0) && let Some(min_val) = bnd_ty.numeric_min_val(cx.tcx) - && let const_val = cx.tcx.valtree_to_const_val((bnd_ty, min_val.to_valtree())) - && let min_const_kind = Const::from_value(const_val, bnd_ty) - && let Some(min_const) = miri_to_const(cx, min_const_kind) + && let Some(min_const) = mir_to_const(cx, Const::from_ty_const(min_val, cx.tcx)) && let Some(start_const) = constant(cx, cx.typeck_results(), start) { start_const == min_const @@ -1519,34 +1550,30 @@ pub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Opti false } }); - let end_is_none_or_max = end.map_or(true, |end| { - match limits { - RangeLimits::Closed => { - if let rustc_ty::Adt(_, subst) = ty.kind() - && let bnd_ty = subst.type_at(0) - && let Some(max_val) = bnd_ty.numeric_max_val(cx.tcx) - && let const_val = cx.tcx.valtree_to_const_val((bnd_ty, max_val.to_valtree())) - && let max_const_kind = Const::from_value(const_val, bnd_ty) - && let Some(max_const) = miri_to_const(cx, max_const_kind) - && let Some(end_const) = constant(cx, cx.typeck_results(), end) - { - end_const == max_const - } else { - false - } - }, - RangeLimits::HalfOpen => { - if let Some(container_path) = container_path - && let ExprKind::MethodCall(name, self_arg, [], _) = end.kind - && name.ident.name == sym::len - && let ExprKind::Path(QPath::Resolved(None, path)) = self_arg.kind - { - container_path.res == path.res - } else { - false - } - }, - } + let end_is_none_or_max = end.map_or(true, |end| match limits { + RangeLimits::Closed => { + if let rustc_ty::Adt(_, subst) = ty.kind() + && let bnd_ty = subst.type_at(0) + && let Some(max_val) = bnd_ty.numeric_max_val(cx.tcx) + && let Some(max_const) = mir_to_const(cx, Const::from_ty_const(max_val, cx.tcx)) + && let Some(end_const) = constant(cx, cx.typeck_results(), end) + { + end_const == max_const + } else { + false + } + }, + RangeLimits::HalfOpen => { + if let Some(container_path) = container_path + && let ExprKind::MethodCall(name, self_arg, [], _) = end.kind + && name.ident.name == sym::len + && let ExprKind::Path(QPath::Resolved(None, path)) = self_arg.kind + { + container_path.res == path.res + } else { + false + } + }, }); return start_is_none_or_min && end_is_none_or_max; } @@ -1614,7 +1641,7 @@ pub fn is_expn_of(mut span: Span, name: &str) -> Option { /// Returns the pre-expansion span if the span directly comes from an expansion /// of the macro `name`. /// The difference with [`is_expn_of`] is that in -/// ```rust +/// ```no_run /// # macro_rules! foo { ($name:tt!$args:tt) => { $name!$args } } /// # macro_rules! bar { ($e:expr) => { $e } } /// foo!(bar!(42)); @@ -1640,13 +1667,13 @@ pub fn is_direct_expn_of(span: Span, name: &str) -> Option { /// Convenience function to get the return type of a function. pub fn return_ty<'tcx>(cx: &LateContext<'tcx>, fn_def_id: hir::OwnerId) -> Ty<'tcx> { let ret_ty = cx.tcx.fn_sig(fn_def_id).instantiate_identity().output(); - cx.tcx.erase_late_bound_regions(ret_ty) + cx.tcx.instantiate_bound_regions_with_erased(ret_ty) } /// Convenience function to get the nth argument type of a function. pub fn nth_arg<'tcx>(cx: &LateContext<'tcx>, fn_def_id: hir::OwnerId, nth: usize) -> Ty<'tcx> { let arg = cx.tcx.fn_sig(fn_def_id).instantiate_identity().input(nth); - cx.tcx.erase_late_bound_regions(arg) + cx.tcx.instantiate_bound_regions_with_erased(arg) } /// Checks if an expression is constructing a tuple-like enum variant or struct @@ -1679,7 +1706,7 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool { } match pat.kind { - PatKind::Wild => false, + PatKind::Wild | PatKind::Never => false, // If `!` typechecked then the type is empty, so not refutable. PatKind::Binding(_, _, _, pat) => pat.map_or(false, |pat| is_refutable(cx, pat)), PatKind::Box(pat) | PatKind::Ref(pat, _) => is_refutable(cx, pat), PatKind::Lit(..) | PatKind::Range(..) => true, @@ -1744,15 +1771,13 @@ pub fn iter_input_pats<'tcx>(decl: &FnDecl<'_>, body: &'tcx Body<'_>) -> impl It /// operator or the `try` macro. pub fn is_try<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> { fn is_ok(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool { - if_chain! { - if let PatKind::TupleStruct(ref path, pat, ddpos) = arm.pat.kind; - if ddpos.as_opt_usize().is_none(); - if is_res_lang_ctor(cx, cx.qpath_res(path, arm.pat.hir_id), ResultOk); - if let PatKind::Binding(_, hir_id, _, None) = pat[0].kind; - if path_to_local_id(arm.body, hir_id); - then { - return true; - } + if let PatKind::TupleStruct(ref path, pat, ddpos) = arm.pat.kind + && ddpos.as_opt_usize().is_none() + && is_res_lang_ctor(cx, cx.qpath_res(path, arm.pat.hir_id), ResultOk) + && let PatKind::Binding(_, hir_id, _, None) = pat[0].kind + && path_to_local_id(arm.body, hir_id) + { + return true; } false } @@ -1771,14 +1796,12 @@ pub fn is_try<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'tcx>) -> Option<&'tc return Some(expr); } - if_chain! { - if arms.len() == 2; - if arms[0].guard.is_none(); - if arms[1].guard.is_none(); - if (is_ok(cx, &arms[0]) && is_err(cx, &arms[1])) || (is_ok(cx, &arms[1]) && is_err(cx, &arms[0])); - then { - return Some(expr); - } + if arms.len() == 2 + && arms[0].guard.is_none() + && arms[1].guard.is_none() + && ((is_ok(cx, &arms[0]) && is_err(cx, &arms[1])) || (is_ok(cx, &arms[1]) && is_err(cx, &arms[0]))) + { + return Some(expr); } } @@ -1895,14 +1918,12 @@ pub fn match_function_call<'tcx>( expr: &'tcx Expr<'_>, path: &[&str], ) -> Option<&'tcx [Expr<'tcx>]> { - if_chain! { - if let ExprKind::Call(fun, args) = expr.kind; - if let ExprKind::Path(ref qpath) = fun.kind; - if let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id(); - if match_def_path(cx, fun_def_id, path); - then { - return Some(args); - } + if let ExprKind::Call(fun, args) = expr.kind + && let ExprKind::Path(ref qpath) = fun.kind + && let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id() + && match_def_path(cx, fun_def_id, path) + { + return Some(args); }; None } @@ -1912,13 +1933,11 @@ pub fn match_function_call_with_def_id<'tcx>( expr: &'tcx Expr<'_>, fun_def_id: DefId, ) -> Option<&'tcx [Expr<'tcx>]> { - if_chain! { - if let ExprKind::Call(fun, args) = expr.kind; - if let ExprKind::Path(ref qpath) = fun.kind; - if cx.qpath_res(qpath, fun.hir_id).opt_def_id() == Some(fun_def_id); - then { - return Some(args); - } + if let ExprKind::Call(fun, args) = expr.kind + && let ExprKind::Path(ref qpath) = fun.kind + && cx.qpath_res(qpath, fun.hir_id).opt_def_id() == Some(fun_def_id) + { + return Some(args); }; None } @@ -2016,10 +2035,10 @@ pub fn get_async_fn_body<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Option<&'t // check if expr is calling method or function with #[must_use] attribute pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { let did = match expr.kind { - ExprKind::Call(path, _) => if_chain! { - if let ExprKind::Path(ref qpath) = path.kind; - if let def::Res::Def(_, did) = cx.qpath_res(qpath, path.hir_id); - then { + ExprKind::Call(path, _) => { + if let ExprKind::Path(ref qpath) = path.kind + && let def::Res::Def(_, did) = cx.qpath_res(qpath, path.hir_id) + { Some(did) } else { None @@ -2032,51 +2051,111 @@ pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { did.map_or(false, |did| cx.tcx.has_attr(did, sym::must_use)) } -/// Checks if an expression represents the identity function -/// Only examines closures and `std::convert::identity` -pub fn is_expr_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - /// Checks if a function's body represents the identity function. Looks for bodies of the form: - /// * `|x| x` - /// * `|x| return x` - /// * `|x| { return x }` - /// * `|x| { return x; }` - fn is_body_identity_function(cx: &LateContext<'_>, func: &Body<'_>) -> bool { - let id = if_chain! { - if let [param] = func.params; - if let PatKind::Binding(_, id, _, _) = param.pat.kind; - then { - id - } else { - return false; - } - }; +/// Checks if a function's body represents the identity function. Looks for bodies of the form: +/// * `|x| x` +/// * `|x| return x` +/// * `|x| { return x }` +/// * `|x| { return x; }` +/// * `|(x, y)| (x, y)` +/// +/// Consider calling [`is_expr_untyped_identity_function`] or [`is_expr_identity_function`] instead. +fn is_body_identity_function(cx: &LateContext<'_>, func: &Body<'_>) -> bool { + fn check_pat(cx: &LateContext<'_>, pat: &Pat<'_>, expr: &Expr<'_>) -> bool { + if cx + .typeck_results() + .pat_binding_modes() + .get(pat.hir_id) + .is_some_and(|mode| matches!(mode, BindingMode::BindByReference(_))) + { + // If a tuple `(x, y)` is of type `&(i32, i32)`, then due to match ergonomics, + // the inner patterns become references. Don't consider this the identity function + // as that changes types. + return false; + } - let mut expr = func.value; - loop { - match expr.kind { - #[rustfmt::skip] - ExprKind::Block(&Block { stmts: [], expr: Some(e), .. }, _, ) - | ExprKind::Ret(Some(e)) => expr = e, - #[rustfmt::skip] - ExprKind::Block(&Block { stmts: [stmt], expr: None, .. }, _) => { - if_chain! { - if let StmtKind::Semi(e) | StmtKind::Expr(e) = stmt.kind; - if let ExprKind::Ret(Some(ret_val)) = e.kind; - then { - expr = ret_val; - } else { - return false; - } - } + match (pat.kind, expr.kind) { + (PatKind::Binding(_, id, _, _), _) => { + path_to_local_id(expr, id) && cx.typeck_results().expr_adjustments(expr).is_empty() + }, + (PatKind::Tuple(pats, dotdot), ExprKind::Tup(tup)) + if dotdot.as_opt_usize().is_none() && pats.len() == tup.len() => + { + pats.iter().zip(tup).all(|(pat, expr)| check_pat(cx, pat, expr)) + }, + _ => false, + } + } + + let [param] = func.params else { + return false; + }; + + let mut expr = func.value; + loop { + match expr.kind { + ExprKind::Block( + &Block { + stmts: [], + expr: Some(e), + .. }, - _ => return path_to_local_id(expr, id) && cx.typeck_results().expr_adjustments(expr).is_empty(), - } + _, + ) + | ExprKind::Ret(Some(e)) => expr = e, + ExprKind::Block( + &Block { + stmts: [stmt], + expr: None, + .. + }, + _, + ) => { + if let StmtKind::Semi(e) | StmtKind::Expr(e) = stmt.kind + && let ExprKind::Ret(Some(ret_val)) = e.kind + { + expr = ret_val; + } else { + return false; + } + }, + _ => return check_pat(cx, param.pat, expr), } } +} + +/// This is the same as [`is_expr_identity_function`], but does not consider closures +/// with type annotations for its bindings (or similar) as identity functions: +/// * `|x: u8| x` +/// * `std::convert::identity::` +pub fn is_expr_untyped_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { + match expr.kind { + ExprKind::Closure(&Closure { body, fn_decl, .. }) + if fn_decl.inputs.iter().all(|ty| matches!(ty.kind, TyKind::Infer)) => + { + is_body_identity_function(cx, cx.tcx.hir().body(body)) + }, + ExprKind::Path(QPath::Resolved(_, path)) + if path.segments.iter().all(|seg| seg.infer_args) + && let Some(did) = path.res.opt_def_id() => + { + cx.tcx.is_diagnostic_item(sym::convert_identity, did) + }, + _ => false, + } +} +/// Checks if an expression represents the identity function +/// Only examines closures and `std::convert::identity` +/// +/// NOTE: If you want to use this function to find out if a closure is unnecessary, you likely want +/// to call [`is_expr_untyped_identity_function`] instead, which makes sure that the closure doesn't +/// have type annotations. This is important because removing a closure with bindings can +/// remove type information that helped type inference before, which can then lead to compile +/// errors. +pub fn is_expr_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { match expr.kind { ExprKind::Closure(&Closure { body, .. }) => is_body_identity_function(cx, cx.tcx.hir().body(body)), - _ => path_def_id(cx, expr).map_or(false, |id| match_def_path(cx, id, &paths::CONVERT_IDENTITY)), + _ => path_def_id(cx, expr).map_or(false, |id| cx.tcx.is_diagnostic_item(sym::convert_identity, id)), } } @@ -2160,7 +2239,7 @@ pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool { /// Check if parent of a hir node is a trait implementation block. /// For example, `f` in -/// ```rust +/// ```no_run /// # struct S; /// # trait Trait { fn f(); } /// impl Trait for S { @@ -2412,7 +2491,8 @@ fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalModDefId, f: impl Fn(&[Sym for id in tcx.hir().module_items(module) { if matches!(tcx.def_kind(id.owner_id), DefKind::Const) && let item = tcx.hir().item(id) - && let ItemKind::Const(ty, _generics, _body) = item.kind { + && let ItemKind::Const(ty, _generics, _body) = item.kind + { if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind { // We could also check for the type name `test::TestDescAndFn` if let Res::Def(DefKind::Struct, _) = path.res { @@ -2456,11 +2536,12 @@ pub fn is_in_test_function(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { }) } -/// Checks if the item containing the given `HirId` has `#[cfg(test)]` attribute applied +/// Checks if `id` has a `#[cfg(test)]` attribute applied /// -/// Note: Add `//@compile-flags: --test` to UI tests with a `#[cfg(test)]` function -pub fn is_in_cfg_test(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { - fn is_cfg_test(attr: &Attribute) -> bool { +/// This only checks directly applied attributes, to see if a node is inside a `#[cfg(test)]` parent +/// use [`is_in_cfg_test`] +pub fn is_cfg_test(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { + tcx.hir().attrs(id).iter().any(|attr| { if attr.has_name(sym::cfg) && let Some(items) = attr.meta_item_list() && let [item] = &*items @@ -2470,11 +2551,14 @@ pub fn is_in_cfg_test(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { } else { false } - } + }) +} + +/// Checks if any parent node of `HirId` has `#[cfg(test)]` attribute applied +pub fn is_in_cfg_test(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { tcx.hir() - .parent_iter(id) - .flat_map(|(parent_id, _)| tcx.hir().attrs(parent_id)) - .any(is_cfg_test) + .parent_id_iter(id) + .any(|parent_id| is_cfg_test(tcx, parent_id)) } /// Checks if the item of any of its parents has `#[cfg(...)]` attribute applied. @@ -2483,7 +2567,7 @@ pub fn inherits_cfg(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { tcx.has_attr(def_id, sym::cfg) || hir - .parent_iter(hir.local_def_id_to_hir_id(def_id)) + .parent_iter(tcx.local_def_id_to_hir_id(def_id)) .flat_map(|(parent_id, _)| hir.attrs(parent_id)) .any(|attr| attr.has_name(sym::cfg)) } @@ -2603,11 +2687,11 @@ impl<'tcx> ExprUseNode<'tcx> { .and(Binder::dummy(cx.tcx.type_of(id).instantiate_identity())), )), Self::Return(id) => { - let hir_id = cx.tcx.hir().local_def_id_to_hir_id(id.def_id); + let hir_id = cx.tcx.local_def_id_to_hir_id(id.def_id); if let Some(Node::Expr(Expr { kind: ExprKind::Closure(c), .. - })) = cx.tcx.hir().find(hir_id) + })) = cx.tcx.opt_hir_node(hir_id) { match c.fn_decl.output { FnRetTy::DefaultReturn(_) => None, @@ -2672,7 +2756,9 @@ pub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> Optio let ctxt = e.span.ctxt(); walk_to_expr_usage(cx, e, &mut |parent, child_id| { // LocalTableInContext returns the wrong lifetime, so go use `expr_adjustments` instead. - if adjustments.is_empty() && let Node::Expr(e) = cx.tcx.hir().get(child_id) { + if adjustments.is_empty() + && let Node::Expr(e) = cx.tcx.hir_node(child_id) + { adjustments = cx.typeck_results().expr_adjustments(e); } match parent { @@ -2869,13 +2955,13 @@ pub fn pat_and_expr_can_be_question_mark<'a, 'hir>( pat: &'a Pat<'hir>, else_body: &Expr<'_>, ) -> Option<&'a Pat<'hir>> { - if let PatKind::TupleStruct(pat_path, [inner_pat], _) = pat.kind && - is_res_lang_ctor(cx, cx.qpath_res(&pat_path, pat.hir_id), OptionSome) && - !is_refutable(cx, inner_pat) && - let else_body = peel_blocks(else_body) && - let ExprKind::Ret(Some(ret_val)) = else_body.kind && - let ExprKind::Path(ret_path) = ret_val.kind && - is_res_lang_ctor(cx, cx.qpath_res(&ret_path, ret_val.hir_id), OptionNone) + if let PatKind::TupleStruct(pat_path, [inner_pat], _) = pat.kind + && is_res_lang_ctor(cx, cx.qpath_res(&pat_path, pat.hir_id), OptionSome) + && !is_refutable(cx, inner_pat) + && let else_body = peel_blocks(else_body) + && let ExprKind::Ret(Some(ret_val)) = else_body.kind + && let ExprKind::Path(ret_path) = ret_val.kind + && is_res_lang_ctor(cx, cx.qpath_res(&ret_path, ret_val.hir_id), OptionNone) { Some(inner_pat) } else { @@ -2913,3 +2999,260 @@ op_utils! { Shl ShlAssign Shr ShrAssign } + +/// Returns `true` if the pattern is a `PatWild`, or is an ident prefixed with `_` +/// that is not locally used. +pub fn pat_is_wild<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx PatKind<'_>, body: impl Visitable<'tcx>) -> bool { + match *pat { + PatKind::Wild => true, + PatKind::Binding(_, id, ident, None) if ident.as_str().starts_with('_') => { + !visitors::is_local_used(cx, body, id) + }, + _ => false, + } +} + +#[derive(Clone, Copy)] +pub enum RequiresSemi { + Yes, + No, +} +impl RequiresSemi { + pub fn requires_semi(self) -> bool { + matches!(self, Self::Yes) + } +} + +/// Check if the expression return `!`, a type coerced from `!`, or could return `!` if the final +/// expression were turned into a statement. +#[expect(clippy::too_many_lines)] +pub fn is_never_expr<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> Option { + struct BreakTarget { + id: HirId, + unused: bool, + } + + struct V<'cx, 'tcx> { + cx: &'cx LateContext<'tcx>, + break_targets: Vec, + break_targets_for_result_ty: u32, + in_final_expr: bool, + requires_semi: bool, + is_never: bool, + } + + impl<'tcx> V<'_, 'tcx> { + fn push_break_target(&mut self, id: HirId) { + self.break_targets.push(BreakTarget { id, unused: true }); + self.break_targets_for_result_ty += u32::from(self.in_final_expr); + } + } + + impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> { + fn visit_expr(&mut self, e: &'tcx Expr<'_>) { + // Note: Part of the complexity here comes from the fact that + // coercions are applied to the innermost expression. + // e.g. In `let x: u32 = { break () };` the never-to-any coercion + // is applied to the break expression. This means we can't just + // check the block's type as it will be `u32` despite the fact + // that the block always diverges. + + // The rest of the complexity comes from checking blocks which + // syntactically return a value, but will always diverge before + // reaching that point. + // e.g. In `let x = { foo(panic!()) };` the block's type will be the + // return type of `foo` even though it will never actually run. This + // can be trivially fixed by adding a semicolon after the call, but + // we must first detect that a semicolon is needed to make that + // suggestion. + + if self.is_never && self.break_targets.is_empty() { + if self.in_final_expr && !self.requires_semi { + // This expression won't ever run, but we still need to check + // if it can affect the type of the final expression. + match e.kind { + ExprKind::DropTemps(e) => self.visit_expr(e), + ExprKind::If(_, then, Some(else_)) => { + self.visit_expr(then); + self.visit_expr(else_); + }, + ExprKind::Match(_, arms, _) => { + for arm in arms { + self.visit_expr(arm.body); + } + }, + ExprKind::Loop(b, ..) => { + self.push_break_target(e.hir_id); + self.in_final_expr = false; + self.visit_block(b); + self.break_targets.pop(); + }, + ExprKind::Block(b, _) => { + if b.targeted_by_break { + self.push_break_target(b.hir_id); + self.visit_block(b); + self.break_targets.pop(); + } else { + self.visit_block(b); + } + }, + _ => { + self.requires_semi = !self.cx.typeck_results().expr_ty(e).is_never(); + }, + } + } + return; + } + match e.kind { + ExprKind::DropTemps(e) => self.visit_expr(e), + ExprKind::Ret(None) | ExprKind::Continue(_) => self.is_never = true, + ExprKind::Ret(Some(e)) | ExprKind::Become(e) => { + self.in_final_expr = false; + self.visit_expr(e); + self.is_never = true; + }, + ExprKind::Break(dest, e) => { + if let Some(e) = e { + self.in_final_expr = false; + self.visit_expr(e); + } + if let Ok(id) = dest.target_id + && let Some((i, target)) = self + .break_targets + .iter_mut() + .enumerate() + .find(|(_, target)| target.id == id) + { + target.unused &= self.is_never; + if i < self.break_targets_for_result_ty as usize { + self.requires_semi = true; + } + } + self.is_never = true; + }, + ExprKind::If(cond, then, else_) => { + let in_final_expr = mem::replace(&mut self.in_final_expr, false); + self.visit_expr(cond); + self.in_final_expr = in_final_expr; + + if self.is_never { + self.visit_expr(then); + if let Some(else_) = else_ { + self.visit_expr(else_); + } + } else { + self.visit_expr(then); + let is_never = mem::replace(&mut self.is_never, false); + if let Some(else_) = else_ { + self.visit_expr(else_); + self.is_never &= is_never; + } + } + }, + ExprKind::Match(scrutinee, arms, _) => { + let in_final_expr = mem::replace(&mut self.in_final_expr, false); + self.visit_expr(scrutinee); + self.in_final_expr = in_final_expr; + + if self.is_never { + for arm in arms { + self.visit_arm(arm); + } + } else { + let mut is_never = true; + for arm in arms { + self.is_never = false; + if let Some(guard) = arm.guard { + let in_final_expr = mem::replace(&mut self.in_final_expr, false); + self.visit_expr(guard.body()); + self.in_final_expr = in_final_expr; + // The compiler doesn't consider diverging guards as causing the arm to diverge. + self.is_never = false; + } + self.visit_expr(arm.body); + is_never &= self.is_never; + } + self.is_never = is_never; + } + }, + ExprKind::Loop(b, _, _, _) => { + self.push_break_target(e.hir_id); + self.in_final_expr = false; + self.visit_block(b); + self.is_never = self.break_targets.pop().unwrap().unused; + }, + ExprKind::Block(b, _) => { + if b.targeted_by_break { + self.push_break_target(b.hir_id); + self.visit_block(b); + self.is_never &= self.break_targets.pop().unwrap().unused; + } else { + self.visit_block(b); + } + }, + _ => { + self.in_final_expr = false; + walk_expr(self, e); + self.is_never |= self.cx.typeck_results().expr_ty(e).is_never(); + }, + } + } + + fn visit_block(&mut self, b: &'tcx Block<'_>) { + let in_final_expr = mem::replace(&mut self.in_final_expr, false); + for s in b.stmts { + self.visit_stmt(s); + } + self.in_final_expr = in_final_expr; + if let Some(e) = b.expr { + self.visit_expr(e); + } + } + + fn visit_local(&mut self, l: &'tcx Local<'_>) { + if let Some(e) = l.init { + self.visit_expr(e); + } + if let Some(else_) = l.els { + let is_never = self.is_never; + self.visit_block(else_); + self.is_never = is_never; + } + } + + fn visit_arm(&mut self, arm: &Arm<'tcx>) { + if let Some(guard) = arm.guard { + let in_final_expr = mem::replace(&mut self.in_final_expr, false); + self.visit_expr(guard.body()); + self.in_final_expr = in_final_expr; + } + self.visit_expr(arm.body); + } + } + + if cx.typeck_results().expr_ty(e).is_never() { + Some(RequiresSemi::No) + } else if let ExprKind::Block(b, _) = e.kind + && !b.targeted_by_break + && b.expr.is_none() + { + // If a block diverges without a final expression then it's type is `!`. + None + } else { + let mut v = V { + cx, + break_targets: Vec::new(), + break_targets_for_result_ty: 0, + in_final_expr: true, + requires_semi: false, + is_never: false, + }; + v.visit_expr(e); + v.is_never + .then_some(if v.requires_semi && matches!(e.kind, ExprKind::Block(..)) { + RequiresSemi::Yes + } else { + RequiresSemi::No + }) + } +} diff --git a/scout-audit-clippy-utils/src/macros.rs b/scout-audit-clippy-utils/src/macros.rs index 82508bcd..46ce4ffd 100644 --- a/scout-audit-clippy-utils/src/macros.rs +++ b/scout-audit-clippy-utils/src/macros.rs @@ -228,16 +228,26 @@ pub enum PanicExpn<'a> { impl<'a> PanicExpn<'a> { pub fn parse(expr: &'a Expr<'a>) -> Option { - let ExprKind::Call(callee, [arg, rest @ ..]) = &expr.kind else { + let ExprKind::Call(callee, args) = &expr.kind else { return None; }; let ExprKind::Path(QPath::Resolved(_, path)) = &callee.kind else { return None; }; - let result = match path.segments.last().unwrap().ident.as_str() { - "panic" if arg.span.ctxt() == expr.span.ctxt() => Self::Empty, + let name = path.segments.last().unwrap().ident.as_str(); + + // This has no argument + if name == "panic_cold_explicit" { + return Some(Self::Empty); + }; + + let [arg, rest @ ..] = args else { + return None; + }; + let result = match name { + "panic" if arg.span.eq_ctxt(expr.span) => Self::Empty, "panic" | "panic_str" => Self::Str(arg), - "panic_display" => { + "panic_display" | "panic_cold_display" => { let ExprKind::AddrOf(_, _, e) = &arg.kind else { return None; }; diff --git a/scout-audit-clippy-utils/src/mir/mod.rs b/scout-audit-clippy-utils/src/mir/mod.rs index f04467dc..9dbb4c68 100644 --- a/scout-audit-clippy-utils/src/mir/mod.rs +++ b/scout-audit-clippy-utils/src/mir/mod.rs @@ -30,20 +30,26 @@ pub fn visit_local_usage(locals: &[Local], mir: &Body<'_>, location: Location) - locals.len() ]; - traversal::ReversePostorder::new(mir, location.block).try_fold(init, |usage, (tbb, tdata)| { - // Give up on loops - if tdata.terminator().successors().any(|s| s == location.block) { - return None; - } + traversal::Postorder::new(&mir.basic_blocks, location.block) + .collect::>() + .into_iter() + .rev() + .try_fold(init, |usage, tbb| { + let tdata = &mir.basic_blocks[tbb]; + + // Give up on loops + if tdata.terminator().successors().any(|s| s == location.block) { + return None; + } - let mut v = V { - locals, - location, - results: usage, - }; - v.visit_basic_block_data(tbb, tdata); - Some(v.results) - }) + let mut v = V { + locals, + location, + results: usage, + }; + v.visit_basic_block_data(tbb, tdata); + Some(v.results) + }) } struct V<'a> { diff --git a/scout-audit-clippy-utils/src/paths.rs b/scout-audit-clippy-utils/src/paths.rs index 2fb24b5c..0a820a17 100644 --- a/scout-audit-clippy-utils/src/paths.rs +++ b/scout-audit-clippy-utils/src/paths.rs @@ -4,16 +4,13 @@ //! Whenever possible, please consider diagnostic items over hardcoded paths. //! See for more information. -#[cfg(feature = "internal")] pub const APPLICABILITY: [&str; 2] = ["rustc_lint_defs", "Applicability"]; -#[cfg(feature = "internal")] pub const APPLICABILITY_VALUES: [[&str; 3]; 4] = [ ["rustc_lint_defs", "Applicability", "Unspecified"], ["rustc_lint_defs", "Applicability", "HasPlaceholders"], ["rustc_lint_defs", "Applicability", "MaybeIncorrect"], ["rustc_lint_defs", "Applicability", "MachineApplicable"], ]; -#[cfg(feature = "internal")] pub const DIAGNOSTIC_BUILDER: [&str; 3] = ["rustc_errors", "diagnostic_builder", "DiagnosticBuilder"]; pub const BINARYHEAP_ITER: [&str; 5] = ["alloc", "collections", "binary_heap", "BinaryHeap", "iter"]; pub const BTREEMAP_CONTAINS_KEY: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "contains_key"]; @@ -25,44 +22,34 @@ pub const CORE_ITER_COPIED: [&str; 6] = ["core", "iter", "traits", "iterator", " pub const CORE_ITER_FILTER: [&str; 6] = ["core", "iter", "traits", "iterator", "Iterator", "filter"]; pub const CORE_RESULT_OK_METHOD: [&str; 4] = ["core", "result", "Result", "ok"]; pub const CSTRING_AS_C_STR: [&str; 5] = ["alloc", "ffi", "c_str", "CString", "as_c_str"]; -pub const DEFAULT_TRAIT_METHOD: [&str; 4] = ["core", "default", "Default", "default"]; -pub const DEREF_MUT_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "DerefMut", "deref_mut"]; -#[cfg(feature = "internal")] pub const EARLY_CONTEXT: [&str; 2] = ["rustc_lint", "EarlyContext"]; -#[cfg(feature = "internal")] pub const EARLY_LINT_PASS: [&str; 3] = ["rustc_lint", "passes", "EarlyLintPass"]; -pub const EXIT: [&str; 3] = ["std", "process", "exit"]; pub const F32_EPSILON: [&str; 4] = ["core", "f32", "", "EPSILON"]; pub const F64_EPSILON: [&str; 4] = ["core", "f64", "", "EPSILON"]; -pub const FROM_ITERATOR_METHOD: [&str; 6] = ["core", "iter", "traits", "collect", "FromIterator", "from_iter"]; -pub const FROM_STR_METHOD: [&str; 5] = ["core", "str", "traits", "FromStr", "from_str"]; #[expect(clippy::invalid_paths)] // internal lints do not know about all external crates pub const FUTURES_IO_ASYNCREADEXT: [&str; 3] = ["futures_util", "io", "AsyncReadExt"]; #[expect(clippy::invalid_paths)] // internal lints do not know about all external crates pub const FUTURES_IO_ASYNCWRITEEXT: [&str; 3] = ["futures_util", "io", "AsyncWriteExt"]; pub const HASHMAP_CONTAINS_KEY: [&str; 6] = ["std", "collections", "hash", "map", "HashMap", "contains_key"]; pub const HASHMAP_INSERT: [&str; 6] = ["std", "collections", "hash", "map", "HashMap", "insert"]; +pub const HASHMAP_ITER: [&str; 5] = ["std", "collections", "hash", "map", "Iter"]; +pub const HASHMAP_ITER_MUT: [&str; 5] = ["std", "collections", "hash", "map", "IterMut"]; +pub const HASHMAP_KEYS: [&str; 5] = ["std", "collections", "hash", "map", "Keys"]; +pub const HASHMAP_VALUES: [&str; 5] = ["std", "collections", "hash", "map", "Values"]; +pub const HASHMAP_DRAIN: [&str; 5] = ["std", "collections", "hash", "map", "Drain"]; +pub const HASHMAP_VALUES_MUT: [&str; 5] = ["std", "collections", "hash", "map", "ValuesMut"]; +pub const HASHSET_ITER_TY: [&str; 5] = ["std", "collections", "hash", "set", "Iter"]; pub const HASHSET_ITER: [&str; 6] = ["std", "collections", "hash", "set", "HashSet", "iter"]; -#[cfg(feature = "internal")] +pub const HASHSET_DRAIN: [&str; 5] = ["std", "collections", "hash", "set", "Drain"]; pub const IDENT: [&str; 3] = ["rustc_span", "symbol", "Ident"]; -#[cfg(feature = "internal")] pub const IDENT_AS_STR: [&str; 4] = ["rustc_span", "symbol", "Ident", "as_str"]; pub const INSERT_STR: [&str; 4] = ["alloc", "string", "String", "insert_str"]; -pub const ITER_EMPTY: [&str; 5] = ["core", "iter", "sources", "empty", "Empty"]; -pub const ITER_ONCE: [&str; 5] = ["core", "iter", "sources", "once", "Once"]; pub const ITERTOOLS_NEXT_TUPLE: [&str; 3] = ["itertools", "Itertools", "next_tuple"]; -#[cfg(feature = "internal")] pub const KW_MODULE: [&str; 3] = ["rustc_span", "symbol", "kw"]; -#[cfg(feature = "internal")] pub const LATE_CONTEXT: [&str; 2] = ["rustc_lint", "LateContext"]; -#[cfg(feature = "internal")] pub const LATE_LINT_PASS: [&str; 3] = ["rustc_lint", "passes", "LateLintPass"]; -#[cfg(feature = "internal")] pub const LINT: [&str; 2] = ["rustc_lint_defs", "Lint"]; -pub const MEM_SWAP: [&str; 3] = ["core", "mem", "swap"]; -#[cfg(feature = "internal")] -pub const MSRV: [&str; 3] = ["clippy_utils", "msrvs", "Msrv"]; -pub const OPEN_OPTIONS: [&str; 3] = ["std", "fs", "OpenOptions"]; +pub const MSRV: [&str; 3] = ["clippy_config", "msrvs", "Msrv"]; pub const OS_STRING_AS_OS_STR: [&str; 5] = ["std", "ffi", "os_str", "OsString", "as_os_str"]; pub const OS_STR_TO_OS_STRING: [&str; 5] = ["std", "ffi", "os_str", "OsStr", "to_os_string"]; pub const PARKING_LOT_MUTEX_GUARD: [&str; 3] = ["lock_api", "mutex", "MutexGuard"]; @@ -71,28 +58,9 @@ pub const PARKING_LOT_RWLOCK_WRITE_GUARD: [&str; 3] = ["lock_api", "rwlock", "Rw pub const PATH_BUF_AS_PATH: [&str; 4] = ["std", "path", "PathBuf", "as_path"]; pub const PATH_MAIN_SEPARATOR: [&str; 3] = ["std", "path", "MAIN_SEPARATOR"]; pub const PATH_TO_PATH_BUF: [&str; 4] = ["std", "path", "Path", "to_path_buf"]; -pub const PEEKABLE: [&str; 5] = ["core", "iter", "adapters", "peekable", "Peekable"]; -pub const PERMISSIONS: [&str; 3] = ["std", "fs", "Permissions"]; #[cfg_attr(not(unix), allow(clippy::invalid_paths))] pub const PERMISSIONS_FROM_MODE: [&str; 6] = ["std", "os", "unix", "fs", "PermissionsExt", "from_mode"]; -pub const PTR_COPY: [&str; 3] = ["core", "intrinsics", "copy"]; -pub const PTR_COPY_NONOVERLAPPING: [&str; 3] = ["core", "intrinsics", "copy_nonoverlapping"]; -pub const PTR_EQ: [&str; 3] = ["core", "ptr", "eq"]; -pub const PTR_SLICE_FROM_RAW_PARTS: [&str; 3] = ["core", "ptr", "slice_from_raw_parts"]; -pub const PTR_SLICE_FROM_RAW_PARTS_MUT: [&str; 3] = ["core", "ptr", "slice_from_raw_parts_mut"]; -pub const PTR_SWAP_NONOVERLAPPING: [&str; 3] = ["core", "ptr", "swap_nonoverlapping"]; -pub const PTR_READ: [&str; 3] = ["core", "ptr", "read"]; -pub const PTR_READ_UNALIGNED: [&str; 3] = ["core", "ptr", "read_unaligned"]; -pub const PTR_READ_VOLATILE: [&str; 3] = ["core", "ptr", "read_volatile"]; -pub const PTR_REPLACE: [&str; 3] = ["core", "ptr", "replace"]; -pub const PTR_SWAP: [&str; 3] = ["core", "ptr", "swap"]; -pub const PTR_UNALIGNED_VOLATILE_LOAD: [&str; 3] = ["core", "intrinsics", "unaligned_volatile_load"]; -pub const PTR_UNALIGNED_VOLATILE_STORE: [&str; 3] = ["core", "intrinsics", "unaligned_volatile_store"]; -pub const PTR_WRITE_BYTES: [&str; 3] = ["core", "intrinsics", "write_bytes"]; pub const PUSH_STR: [&str; 4] = ["alloc", "string", "String", "push_str"]; -pub const RANGE_ARGUMENT_TRAIT: [&str; 3] = ["core", "ops", "RangeBounds"]; -pub const REFCELL_REF: [&str; 3] = ["core", "cell", "Ref"]; -pub const REFCELL_REFMUT: [&str; 3] = ["core", "cell", "RefMut"]; pub const REGEX_BUILDER_NEW: [&str; 3] = ["regex", "RegexBuilder", "new"]; pub const REGEX_BYTES_BUILDER_NEW: [&str; 4] = ["regex", "bytes", "RegexBuilder", "new"]; pub const REGEX_BYTES_NEW: [&str; 4] = ["regex", "bytes", "Regex", "new"]; @@ -101,21 +69,11 @@ pub const REGEX_NEW: [&str; 3] = ["regex", "Regex", "new"]; pub const REGEX_SET_NEW: [&str; 3] = ["regex", "RegexSet", "new"]; pub const SERDE_DESERIALIZE: [&str; 3] = ["serde", "de", "Deserialize"]; pub const SERDE_DE_VISITOR: [&str; 3] = ["serde", "de", "Visitor"]; -pub const SLICE_FROM_RAW_PARTS: [&str; 4] = ["core", "slice", "raw", "from_raw_parts"]; -pub const SLICE_FROM_RAW_PARTS_MUT: [&str; 4] = ["core", "slice", "raw", "from_raw_parts_mut"]; pub const SLICE_GET: [&str; 4] = ["core", "slice", "", "get"]; pub const SLICE_INTO_VEC: [&str; 4] = ["alloc", "slice", "", "into_vec"]; pub const SLICE_INTO: [&str; 4] = ["core", "slice", "", "iter"]; -pub const SLICE_ITER: [&str; 4] = ["core", "slice", "iter", "Iter"]; -pub const STDERR: [&str; 4] = ["std", "io", "stdio", "stderr"]; -pub const STDOUT: [&str; 4] = ["std", "io", "stdio", "stdout"]; -pub const CONVERT_IDENTITY: [&str; 3] = ["core", "convert", "identity"]; -pub const STD_FS_CREATE_DIR: [&str; 3] = ["std", "fs", "create_dir"]; -pub const STD_IO_LINES: [&str; 3] = ["std", "io", "Lines"]; -pub const STD_IO_SEEK: [&str; 3] = ["std", "io", "Seek"]; pub const STD_IO_SEEK_FROM_CURRENT: [&str; 4] = ["std", "io", "SeekFrom", "Current"]; pub const STD_IO_SEEKFROM_START: [&str; 4] = ["std", "io", "SeekFrom", "Start"]; -pub const STD_PROCESS_COMMAND: [&str; 3] = ["std", "process", "Command"]; pub const STRING_AS_MUT_STR: [&str; 4] = ["alloc", "string", "String", "as_mut_str"]; pub const STRING_AS_STR: [&str; 4] = ["alloc", "string", "String", "as_str"]; pub const STRING_NEW: [&str; 4] = ["alloc", "string", "String", "new"]; @@ -124,25 +82,16 @@ pub const STR_CHARS: [&str; 4] = ["core", "str", "", "chars"]; pub const STR_ENDS_WITH: [&str; 4] = ["core", "str", "", "ends_with"]; pub const STR_LEN: [&str; 4] = ["core", "str", "", "len"]; pub const STR_STARTS_WITH: [&str; 4] = ["core", "str", "", "starts_with"]; -#[cfg(feature = "internal")] pub const SYMBOL: [&str; 3] = ["rustc_span", "symbol", "Symbol"]; -#[cfg(feature = "internal")] pub const SYMBOL_AS_STR: [&str; 4] = ["rustc_span", "symbol", "Symbol", "as_str"]; -#[cfg(feature = "internal")] pub const SYMBOL_INTERN: [&str; 4] = ["rustc_span", "symbol", "Symbol", "intern"]; -#[cfg(feature = "internal")] pub const SYMBOL_TO_IDENT_STRING: [&str; 4] = ["rustc_span", "symbol", "Symbol", "to_ident_string"]; -#[cfg(feature = "internal")] pub const SYM_MODULE: [&str; 3] = ["rustc_span", "symbol", "sym"]; -#[cfg(feature = "internal")] pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"]; -pub const TO_OWNED_METHOD: [&str; 4] = ["alloc", "borrow", "ToOwned", "to_owned"]; -pub const TO_STRING_METHOD: [&str; 4] = ["alloc", "string", "ToString", "to_string"]; #[expect(clippy::invalid_paths)] // internal lints do not know about all external crates pub const TOKIO_IO_ASYNCREADEXT: [&str; 5] = ["tokio", "io", "util", "async_read_ext", "AsyncReadExt"]; #[expect(clippy::invalid_paths)] // internal lints do not know about all external crates pub const TOKIO_IO_ASYNCWRITEEXT: [&str; 5] = ["tokio", "io", "util", "async_write_ext", "AsyncWriteExt"]; -pub const TRY_FROM: [&str; 4] = ["core", "convert", "TryFrom", "try_from"]; pub const VEC_AS_MUT_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_mut_slice"]; pub const VEC_AS_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_slice"]; pub const VEC_DEQUE_ITER: [&str; 5] = ["alloc", "collections", "vec_deque", "VecDeque", "iter"]; @@ -150,18 +99,12 @@ pub const VEC_FROM_ELEM: [&str; 3] = ["alloc", "vec", "from_elem"]; pub const VEC_NEW: [&str; 4] = ["alloc", "vec", "Vec", "new"]; pub const VEC_WITH_CAPACITY: [&str; 4] = ["alloc", "vec", "Vec", "with_capacity"]; pub const VEC_RESIZE: [&str; 4] = ["alloc", "vec", "Vec", "resize"]; -pub const WEAK_ARC: [&str; 3] = ["alloc", "sync", "Weak"]; -pub const WEAK_RC: [&str; 3] = ["alloc", "rc", "Weak"]; -pub const PTR_NON_NULL: [&str; 4] = ["core", "ptr", "non_null", "NonNull"]; pub const INSTANT_NOW: [&str; 4] = ["std", "time", "Instant", "now"]; -pub const INSTANT: [&str; 3] = ["std", "time", "Instant"]; pub const VEC_IS_EMPTY: [&str; 4] = ["alloc", "vec", "Vec", "is_empty"]; pub const VEC_POP: [&str; 4] = ["alloc", "vec", "Vec", "pop"]; +pub const WAKER: [&str; 4] = ["core", "task", "wake", "Waker"]; pub const OPTION_UNWRAP: [&str; 4] = ["core", "option", "Option", "unwrap"]; pub const OPTION_EXPECT: [&str; 4] = ["core", "option", "Option", "expect"]; -pub const FORMATTER: [&str; 3] = ["core", "fmt", "Formatter"]; -pub const DEBUG_STRUCT: [&str; 4] = ["core", "fmt", "builders", "DebugStruct"]; -pub const ORD_CMP: [&str; 4] = ["core", "cmp", "Ord", "cmp"]; #[expect(clippy::invalid_paths)] // not sure why it thinks this, it works so pub const BOOL_THEN: [&str; 4] = ["core", "bool", "", "then"]; -pub const ARRAY_INTO_ITER: [&str; 4] = ["core", "array", "iter", "IntoIter"]; +pub const ALLOCATOR_GLOBAL: [&str; 3] = ["alloc", "alloc", "Global"]; diff --git a/scout-audit-clippy-utils/src/qualify_min_const_fn.rs b/scout-audit-clippy-utils/src/qualify_min_const_fn.rs index 17233058..668ea9fc 100644 --- a/scout-audit-clippy-utils/src/qualify_min_const_fn.rs +++ b/scout-audit-clippy-utils/src/qualify_min_const_fn.rs @@ -3,8 +3,9 @@ // of terminologies might not be relevant in the context of Clippy. Note that its behavior might // differ from the time of `rustc` even if the name stays the same. -use crate::msrvs::Msrv; +use clippy_config::msrvs::Msrv; use hir::LangItem; +use rustc_attr::StableSince; use rustc_const_eval::transform::check_consts::ConstCx; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -272,6 +273,7 @@ fn check_place<'tcx>(tcx: TyCtxt<'tcx>, place: Place<'tcx>, span: Span, body: &B | ProjectionElem::Downcast(..) | ProjectionElem::Subslice { .. } | ProjectionElem::Deref + | ProjectionElem::Subtype(_) | ProjectionElem::Index(_) => {}, } } @@ -304,8 +306,8 @@ fn check_terminator<'tcx>( Ok(()) }, TerminatorKind::SwitchInt { discr, targets: _ } => check_operand(tcx, discr, span, body), - TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } => { - Err((span, "const fn generators are unstable".into())) + TerminatorKind::CoroutineDrop | TerminatorKind::Yield { .. } => { + Err((span, "const fn coroutines are unstable".into())) }, TerminatorKind::Call { func, @@ -369,19 +371,17 @@ fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool { // function could be removed if `rustc` provided a MSRV-aware version of `is_const_fn`. // as a part of an unimplemented MSRV check https://github.com/rust-lang/rust/issues/65262. - // HACK(nilstrieb): CURRENT_RUSTC_VERSION can return versions like 1.66.0-dev. `rustc-semver` - // doesn't accept the `-dev` version number so we have to strip it off. - let short_version = since - .as_str() - .split('-') - .next() - .expect("rustc_attr::StabilityLevel::Stable::since` is empty"); + let const_stab_rust_version = match since { + StableSince::Version(version) => version, + StableSince::Current => rustc_session::RustcVersion::CURRENT, + StableSince::Err => return false, + }; - let since = rustc_span::Symbol::intern(short_version); - - msrv.meets(RustcVersion::parse(since.as_str()).unwrap_or_else(|err| { - panic!("`rustc_attr::StabilityLevel::Stable::since` is ill-formatted: `{since}`, {err:?}") - })) + msrv.meets(RustcVersion::new( + u32::from(const_stab_rust_version.major), + u32::from(const_stab_rust_version.minor), + u32::from(const_stab_rust_version.patch), + )) } else { // Unstable const fn with the feature enabled. msrv.current().is_none() diff --git a/scout-audit-clippy-utils/src/source.rs b/scout-audit-clippy-utils/src/source.rs index bb9cdbbc..a4a6f8e1 100644 --- a/scout-audit-clippy-utils/src/source.rs +++ b/scout-audit-clippy-utils/src/source.rs @@ -70,9 +70,9 @@ pub fn expr_block( app: &mut Applicability, ) -> String { let (code, from_macro) = snippet_block_with_context(cx, expr.span, outer, default, indent_relative_to, app); - if !from_macro && - let ExprKind::Block(block, _) = expr.kind && - block.rules != BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) + if !from_macro + && let ExprKind::Block(block, _) = expr.kind + && block.rules != BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) { format!("{code}") } else { @@ -108,7 +108,7 @@ fn first_char_in_first_line(cx: &T, span: Span) -> Option StrIndex { /// Returns index of the first camel-case component of `s`. /// -/// ``` +/// ```no_run /// # use clippy_utils::str_utils::{camel_case_start, StrIndex}; /// assert_eq!(camel_case_start("AbcDef"), StrIndex::new(0, 0)); /// assert_eq!(camel_case_start("abcDef"), StrIndex::new(3, 3)); @@ -73,7 +73,7 @@ pub fn camel_case_start(s: &str) -> StrIndex { /// Returns `StrIndex` of the last camel-case component of `s[idx..]`. /// -/// ``` +/// ```no_run /// # use clippy_utils::str_utils::{camel_case_start_from_idx, StrIndex}; /// assert_eq!(camel_case_start_from_idx("AbcDef", 0), StrIndex::new(0, 0)); /// assert_eq!(camel_case_start_from_idx("AbcDef", 1), StrIndex::new(3, 3)); @@ -122,7 +122,7 @@ pub fn camel_case_start_from_idx(s: &str, start_idx: usize) -> StrIndex { /// Get the indexes of camel case components of a string `s` /// -/// ``` +/// ```no_run /// # use clippy_utils::str_utils::{camel_case_indices, StrIndex}; /// assert_eq!( /// camel_case_indices("AbcDef"), @@ -149,7 +149,7 @@ pub fn camel_case_indices(s: &str) -> Vec { /// Split camel case string into a vector of its components /// -/// ``` +/// ```no_run /// # use clippy_utils::str_utils::{camel_case_split, StrIndex}; /// assert_eq!(camel_case_split("AbcDef"), vec!["Abc", "Def"]); /// ``` @@ -181,7 +181,7 @@ impl StrCount { /// Returns the number of chars that match from the start /// -/// ``` +/// ```no_run /// # use clippy_utils::str_utils::{count_match_start, StrCount}; /// assert_eq!(count_match_start("hello_mouse", "hello_penguin"), StrCount::new(6, 6)); /// assert_eq!(count_match_start("hello_clippy", "bye_bugs"), StrCount::new(0, 0)); @@ -207,7 +207,7 @@ pub fn count_match_start(str1: &str, str2: &str) -> StrCount { /// Returns the number of chars and bytes that match from the end /// -/// ``` +/// ```no_run /// # use clippy_utils::str_utils::{count_match_end, StrCount}; /// assert_eq!(count_match_end("hello_cat", "bye_cat"), StrCount::new(4, 4)); /// assert_eq!(count_match_end("if_item_thing", "enum_value"), StrCount::new(0, 0)); @@ -236,6 +236,59 @@ pub fn count_match_end(str1: &str, str2: &str) -> StrCount { }) } +/// Returns a `snake_case` version of the input +/// ```no_run +/// use clippy_utils::str_utils::to_snake_case; +/// assert_eq!(to_snake_case("AbcDef"), "abc_def"); +/// assert_eq!(to_snake_case("ABCD"), "a_b_c_d"); +/// assert_eq!(to_snake_case("AbcDD"), "abc_d_d"); +/// assert_eq!(to_snake_case("Abc1DD"), "abc1_d_d"); +/// ``` +pub fn to_snake_case(name: &str) -> String { + let mut s = String::new(); + for (i, c) in name.chars().enumerate() { + if c.is_uppercase() { + // characters without capitalization are considered lowercase + if i != 0 { + s.push('_'); + } + s.extend(c.to_lowercase()); + } else { + s.push(c); + } + } + s +} +/// Returns a `CamelCase` version of the input +/// ```no_run +/// use clippy_utils::str_utils::to_camel_case; +/// assert_eq!(to_camel_case("abc_def"), "AbcDef"); +/// assert_eq!(to_camel_case("a_b_c_d"), "ABCD"); +/// assert_eq!(to_camel_case("abc_d_d"), "AbcDD"); +/// assert_eq!(to_camel_case("abc1_d_d"), "Abc1DD"); +/// ``` +pub fn to_camel_case(item_name: &str) -> String { + let mut s = String::new(); + let mut up = true; + for c in item_name.chars() { + if c.is_uppercase() { + // we only turn snake case text into CamelCase + return item_name.to_string(); + } + if c == '_' { + up = true; + continue; + } + if up { + up = false; + s.extend(c.to_uppercase()); + } else { + s.push(c); + } + } + s +} + #[cfg(test)] mod test { use super::*; diff --git a/scout-audit-clippy-utils/src/sugg.rs b/scout-audit-clippy-utils/src/sugg.rs index ae8ee371..9b2bc8df 100644 --- a/scout-audit-clippy-utils/src/sugg.rs +++ b/scout-audit-clippy-utils/src/sugg.rs @@ -16,7 +16,7 @@ use rustc_lint::{EarlyContext, LateContext, LintContext}; use rustc_middle::hir::place::ProjectionKind; use rustc_middle::mir::{FakeReadCause, Mutability}; use rustc_middle::ty; -use rustc_span::source_map::{BytePos, CharPos, Pos, Span, SyntaxContext}; +use rustc_span::{BytePos, CharPos, Pos, Span, SyntaxContext}; use std::borrow::Cow; use std::fmt::{self, Display, Write as _}; use std::ops::{Add, Neg, Not, Sub}; @@ -159,7 +159,7 @@ impl<'a> Sugg<'a> { Sugg::BinOp(hirbinop2assignop(op), get_snippet(lhs.span), get_snippet(rhs.span)) }, hir::ExprKind::Binary(op, lhs, rhs) => Sugg::BinOp( - AssocOp::from_ast_binop(op.node.into()), + AssocOp::from_ast_binop(op.node), get_snippet(lhs.span), get_snippet(rhs.span), ), @@ -190,7 +190,7 @@ impl<'a> Sugg<'a> { (snip, false) => Sugg::MaybeParen(snip), (snip, true) => Sugg::NonParen(snip), }, - ast::ExprKind::Async(..) + ast::ExprKind::Gen(..) | ast::ExprKind::Block(..) | ast::ExprKind::Break(..) | ast::ExprKind::Call(..) @@ -380,10 +380,7 @@ fn binop_to_string(op: AssocOp, lhs: &str, rhs: &str) -> String { | AssocOp::NotEqual | AssocOp::Greater | AssocOp::GreaterEqual => { - format!( - "{lhs} {} {rhs}", - op.to_ast_binop().expect("Those are AST ops").to_string() - ) + format!("{lhs} {} {rhs}", op.to_ast_binop().expect("Those are AST ops").as_str()) }, AssocOp::Assign => format!("{lhs} = {rhs}"), AssocOp::AssignOp(op) => { @@ -465,7 +462,10 @@ forward_binop_impls_to_ref!(impl Sub, sub for Sugg<'_>, type Output = Sugg<'stat impl Neg for Sugg<'_> { type Output = Sugg<'static>; fn neg(self) -> Sugg<'static> { - make_unop("-", self) + match &self { + Self::BinOp(AssocOp::As, ..) => Sugg::MaybeParen(format!("-({self})").into()), + _ => make_unop("-", self), + } } } diff --git a/scout-audit-clippy-utils/src/ty.rs b/scout-audit-clippy-utils/src/ty.rs index 604dc769..61d0663a 100644 --- a/scout-audit-clippy-utils/src/ty.rs +++ b/scout-audit-clippy-utils/src/ty.rs @@ -31,7 +31,7 @@ use rustc_trait_selection::traits::{Obligation, ObligationCause}; use std::assert_matches::debug_assert_matches; use std::iter; -use crate::{match_def_path, path_res, paths}; +use crate::{match_def_path, path_res}; mod type_certainty; pub use type_certainty::expr_type_is_certain; @@ -214,7 +214,17 @@ pub fn implements_trait<'tcx>( trait_id: DefId, args: &[GenericArg<'tcx>], ) -> bool { - implements_trait_with_env_from_iter(cx.tcx, cx.param_env, ty, trait_id, args.iter().map(|&x| Some(x))) + let callee_id = cx + .enclosing_body + .map(|body| cx.tcx.hir().body_owner(body).owner.to_def_id()); + implements_trait_with_env_from_iter( + cx.tcx, + cx.param_env, + ty, + trait_id, + callee_id, + args.iter().map(|&x| Some(x)), + ) } /// Same as `implements_trait` but allows using a `ParamEnv` different from the lint context. @@ -223,9 +233,17 @@ pub fn implements_trait_with_env<'tcx>( param_env: ParamEnv<'tcx>, ty: Ty<'tcx>, trait_id: DefId, + callee_id: DefId, args: &[GenericArg<'tcx>], ) -> bool { - implements_trait_with_env_from_iter(tcx, param_env, ty, trait_id, args.iter().map(|&x| Some(x))) + implements_trait_with_env_from_iter( + tcx, + param_env, + ty, + trait_id, + Some(callee_id), + args.iter().map(|&x| Some(x)), + ) } /// Same as `implements_trait_from_env` but takes the arguments as an iterator. @@ -234,6 +252,7 @@ pub fn implements_trait_with_env_from_iter<'tcx>( param_env: ParamEnv<'tcx>, ty: Ty<'tcx>, trait_id: DefId, + callee_id: Option, args: impl IntoIterator>>>, ) -> bool { // Clippy shouldn't have infer types @@ -245,20 +264,36 @@ pub fn implements_trait_with_env_from_iter<'tcx>( } let infcx = tcx.infer_ctxt().build(); + let args = args + .into_iter() + .map(|arg| { + arg.into().unwrap_or_else(|| { + let orig = TypeVariableOrigin { + kind: TypeVariableOriginKind::MiscVariable, + span: DUMMY_SP, + }; + infcx.next_ty_var(orig).into() + }) + }) + .collect::>(); + + // If an effect arg was not specified, we need to specify it. + let effect_arg = if tcx + .generics_of(trait_id) + .host_effect_index + .is_some_and(|x| args.get(x - 1).is_none()) + { + Some(GenericArg::from(callee_id.map_or(tcx.consts.true_, |def_id| { + tcx.expected_host_effect_param_for_body(def_id) + }))) + } else { + None + }; + let trait_ref = TraitRef::new( tcx, trait_id, - Some(GenericArg::from(ty)) - .into_iter() - .chain(args.into_iter().map(|arg| { - arg.into().unwrap_or_else(|| { - let orig = TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: DUMMY_SP, - }; - infcx.next_ty_var(orig).into() - }) - })), + Some(GenericArg::from(ty)).into_iter().chain(args).chain(effect_arg), ); debug_assert_matches!( @@ -461,10 +496,8 @@ pub fn needs_ordered_drop<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { else if is_type_lang_item(cx, ty, LangItem::OwnedBox) || matches!( get_type_diagnostic_name(cx, ty), - Some(sym::HashSet | sym::Rc | sym::Arc | sym::cstring_type) + Some(sym::HashSet | sym::Rc | sym::Arc | sym::cstring_type | sym::RcWeak | sym::ArcWeak) ) - || match_type(cx, ty, &paths::WEAK_RC) - || match_type(cx, ty, &paths::WEAK_ARC) { // Check all of the generic arguments. if let ty::Adt(_, subs) = ty.kind() { @@ -696,7 +729,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option { let decl = id .as_local() - .and_then(|id| cx.tcx.hir().fn_decl_by_hir_id(cx.tcx.hir().local_def_id_to_hir_id(id))); + .and_then(|id| cx.tcx.hir().fn_decl_by_hir_id(cx.tcx.local_def_id_to_hir_id(id))); Some(ExprFnSig::Closure(decl, subs.as_closure().sig())) }, ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).instantiate(cx.tcx, subs), Some(id))), @@ -892,7 +925,9 @@ pub fn for_each_top_level_late_bound_region( impl<'tcx, B, F: FnMut(BoundRegion) -> ControlFlow> TypeVisitor> for V { type BreakTy = B; fn visit_region(&mut self, r: Region<'tcx>) -> ControlFlow { - if let RegionKind::ReLateBound(idx, bound) = r.kind() && idx.as_u32() == self.index { + if let RegionKind::ReBound(idx, bound) = r.kind() + && idx.as_u32() == self.index + { (self.f)(bound) } else { ControlFlow::Continue(()) @@ -986,16 +1021,16 @@ pub fn ty_is_fn_once_param<'tcx>(tcx: TyCtxt<'_>, ty: Ty<'tcx>, predicates: &'tc .iter() .try_fold(false, |found, p| { if let ty::ClauseKind::Trait(p) = p.kind().skip_binder() - && let ty::Param(self_ty) = p.trait_ref.self_ty().kind() - && ty.index == self_ty.index - { - // This should use `super_traits_of`, but that's a private function. - if p.trait_ref.def_id == fn_once_id { - return Some(true); - } else if p.trait_ref.def_id == fn_mut_id || p.trait_ref.def_id == fn_id { - return None; + && let ty::Param(self_ty) = p.trait_ref.self_ty().kind() + && ty.index == self_ty.index + { + // This should use `super_traits_of`, but that's a private function. + if p.trait_ref.def_id == fn_once_id { + return Some(true); + } else if p.trait_ref.def_id == fn_mut_id || p.trait_ref.def_id == fn_id { + return None; + } } - } Some(found) }) .unwrap_or(false) @@ -1135,7 +1170,7 @@ pub fn make_projection<'tcx>( #[cfg(debug_assertions)] assert_generic_args_match(tcx, assoc_item.def_id, args); - Some(tcx.mk_alias_ty(assoc_item.def_id, args)) + Some(ty::AliasTy::new(tcx, assoc_item.def_id, args)) } helper( tcx, @@ -1160,11 +1195,16 @@ pub fn make_normalized_projection<'tcx>( ) -> Option> { fn helper<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: AliasTy<'tcx>) -> Option> { #[cfg(debug_assertions)] - if let Some((i, arg)) = ty.args.iter().enumerate().find(|(_, arg)| arg.has_late_bound_regions()) { + if let Some((i, arg)) = ty + .args + .iter() + .enumerate() + .find(|(_, arg)| arg.has_escaping_bound_vars()) + { debug_assert!( false, "args contain late-bound region at index `{i}` which can't be normalized.\n\ - use `TyCtxt::erase_late_bound_regions`\n\ + use `TyCtxt::instantiate_bound_regions_with_erased`\n\ note: arg is `{arg:#?}`", ); return None; @@ -1233,11 +1273,16 @@ pub fn make_normalized_projection_with_regions<'tcx>( ) -> Option> { fn helper<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: AliasTy<'tcx>) -> Option> { #[cfg(debug_assertions)] - if let Some((i, arg)) = ty.args.iter().enumerate().find(|(_, arg)| arg.has_late_bound_regions()) { + if let Some((i, arg)) = ty + .args + .iter() + .enumerate() + .find(|(_, arg)| arg.has_escaping_bound_vars()) + { debug_assert!( false, "args contain late-bound region at index `{i}` which can't be normalized.\n\ - use `TyCtxt::erase_late_bound_regions`\n\ + use `TyCtxt::instantiate_bound_regions_with_erased`\n\ note: arg is `{arg:#?}`", ); return None; @@ -1266,3 +1311,8 @@ pub fn normalize_with_regions<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx> Err(_) => ty, } } + +/// Checks if the type is `core::mem::ManuallyDrop<_>` +pub fn is_manually_drop(ty: Ty<'_>) -> bool { + ty.ty_adt_def().map_or(false, AdtDef::is_manually_drop) +} diff --git a/scout-audit-clippy-utils/src/ty/type_certainty/mod.rs b/scout-audit-clippy-utils/src/ty/type_certainty/mod.rs index d05d9e76..da71fc3a 100644 --- a/scout-audit-clippy-utils/src/ty/type_certainty/mod.rs +++ b/scout-audit-clippy-utils/src/ty/type_certainty/mod.rs @@ -170,19 +170,18 @@ fn qpath_certainty(cx: &LateContext<'_>, qpath: &QPath<'_>, resolves_to_type: bo path_segment_certainty(cx, type_certainty(cx, ty), path_segment, resolves_to_type) }, - QPath::LangItem(lang_item, _, _) => { - cx.tcx - .lang_items() - .get(*lang_item) - .map_or(Certainty::Uncertain, |def_id| { - let generics = cx.tcx.generics_of(def_id); - if generics.parent_count == 0 && generics.params.is_empty() { - Certainty::Certain(if resolves_to_type { Some(def_id) } else { None }) - } else { - Certainty::Uncertain - } - }) - }, + QPath::LangItem(lang_item, ..) => cx + .tcx + .lang_items() + .get(*lang_item) + .map_or(Certainty::Uncertain, |def_id| { + let generics = cx.tcx.generics_of(def_id); + if generics.parent_count == 0 && generics.params.is_empty() { + Certainty::Certain(if resolves_to_type { Some(def_id) } else { None }) + } else { + Certainty::Uncertain + } + }), }; debug_assert!(resolves_to_type || certainty.to_def_id().is_none()); certainty @@ -219,7 +218,7 @@ fn path_segment_certainty( // See the comment preceding `qpath_certainty`. `def_id` could refer to a type or a value. let certainty = lhs.join_clearing_def_ids(rhs); if resolves_to_type { - if let DefKind::TyAlias { .. } = cx.tcx.def_kind(def_id) { + if let DefKind::TyAlias = cx.tcx.def_kind(def_id) { adt_def_id(cx.tcx.type_of(def_id).instantiate_identity()) .map_or(certainty, |def_id| certainty.with_def_id(def_id)) } else { @@ -267,7 +266,9 @@ fn path_segment_certainty( /// For at least some `QPath::TypeRelative`, the path segment's `res` can be `Res::Err`. /// `update_res` tries to fix the resolution when `parent_certainty` is `Certain(Some(..))`. fn update_res(cx: &LateContext<'_>, parent_certainty: Certainty, path_segment: &PathSegment<'_>) -> Option { - if path_segment.res == Res::Err && let Some(def_id) = parent_certainty.to_def_id() { + if path_segment.res == Res::Err + && let Some(def_id) = parent_certainty.to_def_id() + { let mut def_path = cx.get_def_path(def_id); def_path.push(path_segment.ident.name); let reses = def_path_res(cx, &def_path.iter().map(Symbol::as_str).collect::>()); diff --git a/scout-audit-clippy-utils/src/visitors.rs b/scout-audit-clippy-utils/src/visitors.rs index 3b47a451..d752fe7d 100644 --- a/scout-audit-clippy-utils/src/visitors.rs +++ b/scout-audit-clippy-utils/src/visitors.rs @@ -62,6 +62,27 @@ where } } } +impl<'tcx, A, B> Visitable<'tcx> for (A, B) +where + A: Visitable<'tcx>, + B: Visitable<'tcx>, +{ + fn visit>(self, visitor: &mut V) { + let (a, b) = self; + a.visit(visitor); + b.visit(visitor); + } +} +impl<'tcx, T> Visitable<'tcx> for Option +where + T: Visitable<'tcx>, +{ + fn visit>(self, visitor: &mut V) { + if let Some(x) = self { + x.visit(visitor); + } + } +} macro_rules! visitable_ref { ($t:ident, $f:ident) => { impl<'tcx> Visitable<'tcx> for &'tcx $t<'tcx> { @@ -748,3 +769,26 @@ pub fn contains_break_or_continue(expr: &Expr<'_>) -> bool { }) .is_some() } + +/// If the local is only used once in `visitable` returns the path expression referencing the given +/// local +pub fn local_used_once<'tcx>( + cx: &LateContext<'tcx>, + visitable: impl Visitable<'tcx>, + id: HirId, +) -> Option<&'tcx Expr<'tcx>> { + let mut expr = None; + + let cf = for_each_expr_with_closures(cx, visitable, |e| { + if path_to_local_id(e, id) && expr.replace(e).is_some() { + ControlFlow::Break(()) + } else { + ControlFlow::Continue(()) + } + }); + if cf.is_some() { + return None; + } + + expr +} diff --git a/scout-audit-internal/rust-toolchain b/scout-audit-internal/rust-toolchain index 8811e92c..bcb80559 100644 --- a/scout-audit-internal/rust-toolchain +++ b/scout-audit-internal/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-09-29" +channel = "nightly-2023-12-16" components = ["llvm-tools-preview", "rustc-dev"] diff --git a/scout-audit-internal/src/detector.rs b/scout-audit-internal/src/detector.rs index 8e94b3de..a7d9d27f 100644 --- a/scout-audit-internal/src/detector.rs +++ b/scout-audit-internal/src/detector.rs @@ -21,9 +21,10 @@ use scout_audit_clippy_utils::diagnostics::{ #[cfg(feature = "lint_helper")] use serde_json::json; use strum::{Display, EnumIter}; - +//import serialize and deserialize from serde +use serde::{Deserialize, Serialize}; /// Available detectors. -#[derive(Debug, Display, Clone, EnumIter, PartialEq, Eq, Hash)] +#[derive(Debug, Display, Clone, EnumIter, PartialEq, Eq, Hash, Serialize, Deserialize)] #[strum(serialize_all = "kebab-case")] pub enum Detector { AssertViolation, diff --git a/scout-audit-internal/src/socket-protobuf/definition.proto b/scout-audit-internal/src/socket-protobuf/definition.proto new file mode 100644 index 00000000..275f7bc9 --- /dev/null +++ b/scout-audit-internal/src/socket-protobuf/definition.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; + +option java_multiple_files = true; +option java_package = "com.coinfabrik.scout"; +option java_outer_classname = "ScoutAudit"; + +package ScoutAudit; + +service ScoutAudit { + rpc PushFinding (FindingRequest) returns (FindingResponse) {} + rpc IsDetectorAvailable (DetectorRequest) returns (DetectorResponse) {} +} + +message FindingRequest { + string name = ""; + string description = ""; + string span = "" +} + +message DetectorRequest { + string detectorName = ""; +} + + +message FindingResponse { + bool message = false; +} + +message DetectorResponse { + bool habilitado = true; +} diff --git a/scout-audit-internal/src/socket.rs b/scout-audit-internal/src/socket.rs new file mode 100644 index 00000000..c437d3d0 --- /dev/null +++ b/scout-audit-internal/src/socket.rs @@ -0,0 +1,36 @@ +//extern crate rustc_lint; +//extern crate rustc_span; +use std::{ + net::{IpAddr, Ipv6Addr, SocketAddr}, + time::Duration, +}; + +use futures::{future, prelude::*}; +use rand::{ + distributions::{Distribution, Uniform}, + thread_rng, +}; +use tarpc::{ + context, + server::{self, incoming::Incoming, Channel}, + tokio_serde::formats::Json, +}; +use tokio::time; + +//use rustc_lint::{Lint, LintContext}; +//use rustc_span::Span; +use crate::detector::Detector; + +#[tarpc::service] +pub trait Findings { + async fn hello(name: String) -> String; +} +#[derive(Clone)] +pub struct FindingsServer(SocketAddr); + +#[tarpc::server] +impl Findings for FindingsServer { + async fn hello(self, _: context::Context, msg: String) -> String { + msg + } +} diff --git a/templates/detector/early-lint/rust-toolchain b/templates/detector/early-lint/rust-toolchain index 8811e92c..bcb80559 100644 --- a/templates/detector/early-lint/rust-toolchain +++ b/templates/detector/early-lint/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-09-29" +channel = "nightly-2023-12-16" components = ["llvm-tools-preview", "rustc-dev"] diff --git a/templates/detector/late-lint/rust-toolchain b/templates/detector/late-lint/rust-toolchain index 8811e92c..bcb80559 100644 --- a/templates/detector/late-lint/rust-toolchain +++ b/templates/detector/late-lint/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-09-29" +channel = "nightly-2023-12-16" components = ["llvm-tools-preview", "rustc-dev"] From 6adff6e2bb572b38b177794df9a6c326c6898078 Mon Sep 17 00:00:00 2001 From: Facundo Lerena Date: Fri, 8 Mar 2024 11:14:52 -0300 Subject: [PATCH 02/13] make fmt --- clippy_config/src/conf.rs | 85 +++++++++++++++++++--------- clippy_config/src/metadata.rs | 5 +- clippy_config/src/msrvs.rs | 16 ++++-- clippy_config/src/types.rs | 21 +++++-- scout-audit-internal/Cargo.toml | 1 + scout-audit-internal/src/detector.rs | 4 +- 6 files changed, 90 insertions(+), 42 deletions(-) diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 88611eb7..94a1e4d7 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -1,11 +1,3 @@ -use crate::msrvs::Msrv; -use crate::types::{DisallowedPath, MacroMatcher, MatchLintBehaviour, Rename}; -use crate::ClippyConfiguration; -use rustc_data_structures::fx::FxHashSet; -use rustc_session::Session; -use rustc_span::{BytePos, Pos, SourceFile, Span, SyntaxContext}; -use serde::de::{IgnoredAny, IntoDeserializer, MapAccess, Visitor}; -use serde::{Deserialize, Deserializer, Serialize}; use std::fmt::{Debug, Display, Formatter}; use std::ops::Range; use std::path::PathBuf; @@ -13,6 +5,16 @@ use std::str::FromStr; use std::sync::OnceLock; use std::{cmp, env, fmt, fs, io}; +use rustc_data_structures::fx::FxHashSet; +use rustc_session::Session; +use rustc_span::{BytePos, Pos, SourceFile, Span, SyntaxContext}; +use serde::de::{IgnoredAny, IntoDeserializer, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; + +use crate::msrvs::Msrv; +use crate::types::{DisallowedPath, MacroMatcher, MatchLintBehaviour, Rename}; +use crate::ClippyConfiguration; + #[rustfmt::skip] const DEFAULT_DOC_VALID_IDENTS: &[&str] = &[ "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", @@ -93,7 +95,9 @@ macro_rules! wrap_option { macro_rules! default_text { ($value:expr) => {{ let mut text = String::new(); - $value.serialize(toml::ser::ValueSerializer::new(&mut text)).unwrap(); + $value + .serialize(toml::ser::ValueSerializer::new(&mut text)) + .unwrap(); text }}; ($value:expr, $override:expr) => { @@ -572,9 +576,9 @@ pub fn lookup_conf_file() -> io::Result<(Option, Vec)> { for config_file_name in &CONFIG_FILE_NAMES { if let Ok(config_file) = current.join(config_file_name).canonicalize() { match fs::metadata(&config_file) { - Err(e) if e.kind() == io::ErrorKind::NotFound => {}, + Err(e) if e.kind() == io::ErrorKind::NotFound => {} Err(e) => return Err(e), - Ok(md) if md.is_dir() => {}, + Ok(md) if md.is_dir() => {} Ok(_) => { // warn if we happen to find two config files #8323 if let Some(ref found_config) = found_config { @@ -586,7 +590,7 @@ pub fn lookup_conf_file() -> io::Result<(Option, Vec)> { } else { found_config = Some(config_file); } - }, + } } } } @@ -603,19 +607,32 @@ pub fn lookup_conf_file() -> io::Result<(Option, Vec)> { } fn deserialize(file: &SourceFile) -> TryConf { - match toml::de::Deserializer::new(file.src.as_ref().unwrap()).deserialize_map(ConfVisitor(file)) { + match toml::de::Deserializer::new(file.src.as_ref().unwrap()).deserialize_map(ConfVisitor(file)) + { Ok(mut conf) => { - extend_vec_if_indicator_present(&mut conf.conf.doc_valid_idents, DEFAULT_DOC_VALID_IDENTS); - extend_vec_if_indicator_present(&mut conf.conf.disallowed_names, DEFAULT_DISALLOWED_NAMES); + extend_vec_if_indicator_present( + &mut conf.conf.doc_valid_idents, + DEFAULT_DOC_VALID_IDENTS, + ); + extend_vec_if_indicator_present( + &mut conf.conf.disallowed_names, + DEFAULT_DISALLOWED_NAMES, + ); // TODO: THIS SHOULD BE TESTED, this comment will be gone soon - if conf.conf.allowed_idents_below_min_chars.contains(&"..".to_owned()) { - conf.conf - .allowed_idents_below_min_chars - .extend(DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS.iter().map(ToString::to_string)); + if conf + .conf + .allowed_idents_below_min_chars + .contains(&"..".to_owned()) + { + conf.conf.allowed_idents_below_min_chars.extend( + DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS + .iter() + .map(ToString::to_string), + ); } conf - }, + } Err(e) => TryConf::from_toml_error(file, &e), } } @@ -627,7 +644,10 @@ fn extend_vec_if_indicator_present(vec: &mut Vec, default: &[&str]) { } impl Conf { - pub fn read(sess: &Session, path: &io::Result<(Option, Vec)>) -> &'static Conf { + pub fn read( + sess: &Session, + path: &io::Result<(Option, Vec)>, + ) -> &'static Conf { static CONF: OnceLock = OnceLock::new(); CONF.get_or_init(|| Conf::read_inner(sess, path)) } @@ -638,10 +658,12 @@ impl Conf { for warning in warnings { sess.warn(warning.clone()); } - }, + } Err(error) => { - sess.err(format!("error finding Clippy's configuration file: {error}")); - }, + sess.err(format!( + "error finding Clippy's configuration file: {error}" + )); + } } let TryConf { @@ -654,7 +676,7 @@ impl Conf { Err(error) => { sess.err(format!("failed to read `{}`: {error}", path.display())); TryConf::default() - }, + } }, _ => TryConf::default(), }; @@ -665,14 +687,20 @@ impl Conf { for error in errors { sess.span_err( error.span, - format!("error reading Clippy's configuration file: {}", error.message), + format!( + "error reading Clippy's configuration file: {}", + error.message + ), ); } for warning in warnings { sess.span_warn( warning.span, - format!("error reading Clippy's configuration file: {}", warning.message), + format!( + "error reading Clippy's configuration file: {}", + warning.message + ), ); } @@ -755,9 +783,10 @@ fn calculate_dimensions(fields: &[&str]) -> (usize, Vec) { #[cfg(test)] mod tests { + use std::fs; + use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use serde::de::IgnoredAny; - use std::fs; use walkdir::WalkDir; #[test] diff --git a/clippy_config/src/metadata.rs b/clippy_config/src/metadata.rs index 2451fbc9..3e625244 100644 --- a/clippy_config/src/metadata.rs +++ b/clippy_config/src/metadata.rs @@ -102,7 +102,10 @@ fn parse_config_field_doc(doc_comment: &str) -> Option<(Vec, String)> { // Format documentation correctly // split off leading `.` from lint name list and indent for correct formatting - documentation = documentation.trim_start_matches('.').trim().replace("\n ", "\n "); + documentation = documentation + .trim_start_matches('.') + .trim() + .replace("\n ", "\n "); Some((lints, documentation)) } else { diff --git a/clippy_config/src/msrvs.rs b/clippy_config/src/msrvs.rs index b3ef666e..367d5425 100644 --- a/clippy_config/src/msrvs.rs +++ b/clippy_config/src/msrvs.rs @@ -87,8 +87,8 @@ impl Msrv { "the MSRV in `clippy.toml` and `Cargo.toml` differ; using `{clippy_msrv}` from `clippy.toml`" )); } - }, - _ => {}, + } + _ => {} } } @@ -97,12 +97,15 @@ impl Msrv { } pub fn meets(&self, required: RustcVersion) -> bool { - self.current().map_or(true, |version| version.meets(required)) + self.current() + .map_or(true, |version| version.meets(required)) } fn parse_attr(sess: &Session, attrs: &[Attribute]) -> Option { let sym_msrv = Symbol::intern("msrv"); - let mut msrv_attrs = attrs.iter().filter(|attr| attr.path_matches(&[sym::clippy, sym_msrv])); + let mut msrv_attrs = attrs + .iter() + .filter(|attr| attr.path_matches(&[sym::clippy, sym_msrv])); if let Some(msrv_attr) = msrv_attrs.next() { if let Some(duplicate) = msrv_attrs.last() { @@ -116,7 +119,10 @@ impl Msrv { return Some(version); } - sess.span_err(msrv_attr.span, format!("`{msrv}` is not a valid Rust version")); + sess.span_err( + msrv_attr.span, + format!("`{msrv}` is not a valid Rust version"), + ); } else { sess.span_err(msrv_attr.span, "bad clippy attribute"); } diff --git a/clippy_config/src/types.rs b/clippy_config/src/types.rs index df48cc3f..9c617911 100644 --- a/clippy_config/src/types.rs +++ b/clippy_config/src/types.rs @@ -1,6 +1,7 @@ +use std::fmt; + use serde::de::{self, Deserializer, Visitor}; use serde::{ser, Deserialize, Serialize}; -use std::fmt; #[derive(Clone, Debug, Deserialize)] pub struct Rename { @@ -12,7 +13,10 @@ pub struct Rename { #[serde(untagged)] pub enum DisallowedPath { Simple(String), - WithReason { path: String, reason: Option }, + WithReason { + path: String, + reason: Option, + }, } impl DisallowedPath { @@ -25,7 +29,8 @@ impl DisallowedPath { pub fn reason(&self) -> Option { match self { Self::WithReason { - reason: Some(reason), .. + reason: Some(reason), + .. } => Some(format!("{reason} (from clippy.toml)")), _ => None, } @@ -77,13 +82,13 @@ impl<'de> Deserialize<'de> for MacroMatcher { return Err(de::Error::duplicate_field("name")); } name = Some(map.next_value()?); - }, + } Field::Brace => { if brace.is_some() { return Err(de::Error::duplicate_field("brace")); } brace = Some(map.next_value()?); - }, + } } } let name = name.ok_or_else(|| de::Error::missing_field("name"))?; @@ -94,7 +99,11 @@ impl<'de> Deserialize<'de> for MacroMatcher { .into_iter() .find(|b| b.0 == brace) .map(|(o, c)| (o.to_owned(), c.to_owned())) - .ok_or_else(|| de::Error::custom(format!("expected one of `(`, `{{`, `[` found `{brace}`")))?, + .ok_or_else(|| { + de::Error::custom(format!( + "expected one of `(`, `{{`, `[` found `{brace}`" + )) + })?, }) } } diff --git a/scout-audit-internal/Cargo.toml b/scout-audit-internal/Cargo.toml index a9b76d57..f25b3a2e 100644 --- a/scout-audit-internal/Cargo.toml +++ b/scout-audit-internal/Cargo.toml @@ -30,3 +30,4 @@ lint_helper = [ strum = { version = "0.25", features = ["derive"], optional = true } serde_json = { version = "1.0", optional = true } scout-audit-clippy-utils = { version = "=0.2.2", path = "../scout-audit-clippy-utils", optional = true } +serde = { version = "1.0.197", features = ["derive"] } \ No newline at end of file diff --git a/scout-audit-internal/src/detector.rs b/scout-audit-internal/src/detector.rs index a7d9d27f..0c2c9fec 100644 --- a/scout-audit-internal/src/detector.rs +++ b/scout-audit-internal/src/detector.rs @@ -18,11 +18,11 @@ use rustc_span::Span; use scout_audit_clippy_utils::diagnostics::{ span_lint as span_lint_clippy, span_lint_and_help as span_lint_and_help_clippy, }; +//import serialize and deserialize from serde +use serde::{Deserialize, Serialize}; #[cfg(feature = "lint_helper")] use serde_json::json; use strum::{Display, EnumIter}; -//import serialize and deserialize from serde -use serde::{Deserialize, Serialize}; /// Available detectors. #[derive(Debug, Display, Clone, EnumIter, PartialEq, Eq, Hash, Serialize, Deserialize)] #[strum(serialize_all = "kebab-case")] From 22f1c11db33a8084bd5d9a18a322509925465ea2 Mon Sep 17 00:00:00 2001 From: Facundo Lerena Date: Fri, 8 Mar 2024 11:19:04 -0300 Subject: [PATCH 03/13] update ci rust toolchain --- .github/workflows/general-rust.yml | 8 ++++---- .github/workflows/test-detectors.yml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/general-rust.yml b/.github/workflows/general-rust.yml index a3c87eb0..c3f95542 100644 --- a/.github/workflows/general-rust.yml +++ b/.github/workflows/general-rust.yml @@ -56,11 +56,11 @@ jobs: - name: Update Rust run: rustup update - - name: Install Rust nightly-2023-09-29 - run: rustup install nightly-2023-09-29 --profile minimal + - name: Install Rust nightly-2023-12-16 + run: rustup install nightly-2023-12-16 --profile minimal - - name: Install Clippy nightly-2023-09-29 - run: rustup component add clippy --toolchain nightly-2023-09-29 + - name: Install Clippy nightly-2023-12-16 + run: rustup component add clippy --toolchain nightly-2023-12-16 - name: Install dylint-link run: cargo install dylint-link diff --git a/.github/workflows/test-detectors.yml b/.github/workflows/test-detectors.yml index d2114681..ba66defb 100644 --- a/.github/workflows/test-detectors.yml +++ b/.github/workflows/test-detectors.yml @@ -73,8 +73,8 @@ jobs: detectors/Cargo.lock key: ${{ runner.os }}-cargo-scout-dependencies-${{ github.run_id }} - - name: Install Rust nightly-2023-09-29 - run: rustup install nightly-2023-09-29 --profile minimal + - name: Install Rust nightly-2023-12-16 + run: rustup install nightly-2023-12-16 --profile minimal - name: Install dylint-link run: cargo install dylint-link From c0e361b26446a1ce6da82bf1506cd627a454f906 Mon Sep 17 00:00:00 2001 From: Facundo Lerena Date: Fri, 8 Mar 2024 11:25:31 -0300 Subject: [PATCH 04/13] changed path for clippy_config --- apps/cargo-scout-audit/Cargo.lock | 39 ++++++++++++++++--------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/apps/cargo-scout-audit/Cargo.lock b/apps/cargo-scout-audit/Cargo.lock index a7f66284..cc92497b 100644 --- a/apps/cargo-scout-audit/Cargo.lock +++ b/apps/cargo-scout-audit/Cargo.lock @@ -123,7 +123,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.52", ] [[package]] @@ -418,7 +418,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.52", ] [[package]] @@ -2178,7 +2178,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.52", ] [[package]] @@ -2225,9 +2225,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -2243,9 +2243,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -2388,7 +2388,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.31", + "syn 2.0.52", "walkdir", ] @@ -2492,6 +2492,7 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" name = "scout-audit-internal" version = "0.2.2" dependencies = [ + "serde", "strum", ] @@ -2529,9 +2530,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.188" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] @@ -2548,13 +2549,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.52", ] [[package]] @@ -2725,7 +2726,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.31", + "syn 2.0.52", ] [[package]] @@ -2747,9 +2748,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.31" +version = "2.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" dependencies = [ "proc-macro2", "quote", @@ -2815,7 +2816,7 @@ checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.52", ] [[package]] @@ -3054,7 +3055,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.52", "wasm-bindgen-shared", ] @@ -3076,7 +3077,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.52", "wasm-bindgen-backend", "wasm-bindgen-shared", ] From 2521fd256684132bbe982c944566f96ec2d07aa1 Mon Sep 17 00:00:00 2001 From: Facundo Lerena Date: Fri, 8 Mar 2024 12:43:18 -0300 Subject: [PATCH 05/13] created socket service --- apps/cargo-scout-audit/Cargo.lock | 2168 +++++++++++++++++++------ apps/cargo-scout-audit/Cargo.toml | 5 + apps/cargo-scout-audit/src/startup.rs | 9 +- scout-audit-clippy-utils/Cargo.toml | 2 +- scout-audit-internal/Cargo.toml | 7 +- scout-audit-internal/src/lib.rs | 4 + scout-audit-internal/src/socket.rs | 81 +- 7 files changed, 1739 insertions(+), 537 deletions(-) diff --git a/apps/cargo-scout-audit/Cargo.lock b/apps/cargo-scout-audit/Cargo.lock index cc92497b..ac1627a5 100644 --- a/apps/cargo-scout-audit/Cargo.lock +++ b/apps/cargo-scout-audit/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + [[package]] name = "adler" version = "1.0.2" @@ -10,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ "getrandom", "once_cell", @@ -21,21 +30,22 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "getrandom", "once_cell", "version_check", + "zerocopy", ] [[package]] name = "aho-corasick" -version = "1.0.5" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] @@ -51,9 +61,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.5.0" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" dependencies = [ "anstyle", "anstyle-parse", @@ -65,49 +75,49 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.2" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anstyle-parse" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "2.1.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" [[package]] name = "arc-swap" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" +checksum = "7b3d0060af21e8d11a926981cc00c6c1541aa91dd64b9f881985c3da1094425f" [[package]] name = "arrayvec" @@ -117,9 +127,9 @@ checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" [[package]] name = "async-trait" -version = "0.1.73" +version = "0.1.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", @@ -132,6 +142,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base16ct" version = "0.2.0" @@ -146,9 +171,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.3" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" @@ -156,6 +181,15 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -164,9 +198,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "bitmaps" @@ -188,9 +222,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.6.2" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c2f7349907b712260e64b0afe2f84692af14a454be26187d9df565c7f69266a" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" dependencies = [ "memchr", "regex-automata", @@ -208,9 +242,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" [[package]] name = "bytes" @@ -240,7 +274,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "171aca76a3199e771ea0b94ec260984ed9cba62af8e478142974dbaa594d583b" dependencies = [ "anyhow", - "base64 0.21.3", + "base64 0.21.7", "bytesize", "cargo-platform", "cargo-util", @@ -254,8 +288,8 @@ dependencies = [ "fwdansi", "git2", "git2-curl", - "gix", - "gix-features", + "gix 0.44.1", + "gix-features 0.29.0", "glob", "hex", "hmac", @@ -292,8 +326,76 @@ dependencies = [ "tempfile", "termcolor", "time", - "toml 0.7.7", - "toml_edit", + "toml 0.7.8", + "toml_edit 0.19.15", + "unicode-width", + "unicode-xid", + "url", + "walkdir", + "windows-sys 0.48.0", +] + +[[package]] +name = "cargo" +version = "0.73.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a6fe1f5394d14b81d2f3f605832a3ce35ed0bf120bc7ef437ce27fd4929c6a" +dependencies = [ + "anyhow", + "base64 0.21.7", + "bytesize", + "cargo-platform", + "cargo-util", + "clap", + "crates-io", + "curl", + "curl-sys", + "env_logger", + "filetime", + "flate2", + "fwdansi", + "git2", + "git2-curl", + "gix 0.45.1", + "gix-features 0.30.0", + "glob", + "hex", + "hmac", + "home", + "http-auth", + "humantime", + "ignore", + "im-rc", + "indexmap 1.9.3", + "itertools 0.10.5", + "jobserver", + "lazycell", + "libc", + "libgit2-sys", + "log", + "memchr", + "opener", + "os_info", + "pasetors", + "pathdiff", + "pulldown-cmark", + "rand", + "rustfix", + "semver", + "serde", + "serde-value", + "serde_ignored", + "serde_json", + "sha1", + "shell-escape", + "strip-ansi-escapes", + "syn 2.0.52", + "tar", + "tempfile", + "termcolor", + "time", + "toml 0.7.8", + "toml_edit 0.19.15", "unicode-width", "unicode-xid", "url", @@ -303,9 +405,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.3" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cfa25e60aea747ec7e1124f238816749faa93759c6ff5b31f1ccdda137f4479" +checksum = "694c8807f2ae16faecc43dc17d74b3eb042482789fd0eb64b39a2e04e087053f" dependencies = [ "serde", ] @@ -316,8 +418,8 @@ version = "0.2.2" dependencies = [ "ansi_term", "anyhow", - "cargo", - "cargo_metadata", + "cargo 0.72.2", + "cargo_metadata 0.17.0", "clap", "colored", "config", @@ -331,29 +433,32 @@ dependencies = [ "scout-audit-internal", "serde", "serde_json", + "tarpc", "tempfile", + "tokio", ] [[package]] name = "cargo-util" -version = "0.2.5" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd54c8b94a0c851d687924460637361c355afafa72d973fe8644499fbdee8fae" +checksum = "74862c3c6e53a1c1f8f0178f9d38ab41e49746cd3a7cafc239b3d0248fd4e342" dependencies = [ "anyhow", "core-foundation", "filetime", "hex", + "ignore", "jobserver", "libc", - "log", "miow", "same-file", "sha2", "shell-escape", "tempfile", + "tracing", "walkdir", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -370,11 +475,25 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "cc" -version = "1.0.83" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" dependencies = [ "jobserver", "libc", @@ -388,9 +507,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.4.2" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a13b88d2c62ff462f88e4a121f17a82c1af05693a2f192b5c38d14de73c19f6" +checksum = "b230ab84b0ffdf890d5a10abdbc8b83ae1c4918275daea1ab8801f71536b2651" dependencies = [ "clap_builder", "clap_derive", @@ -398,9 +517,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.2" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstream", "anstyle", @@ -411,9 +530,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.2" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" dependencies = [ "heck", "proc-macro2", @@ -423,9 +542,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.5.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "clru" @@ -441,20 +560,19 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "colored" -version = "2.0.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" dependencies = [ - "is-terminal", "lazy_static", "windows-sys 0.48.0", ] [[package]] name = "config" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d379af7f68bfc21714c6c7dea883544201741d2ce8274bb12fa54f89507f52a7" +checksum = "23738e11972c7643e4ec947840fc463b6a571afcd3e735bdfce7d03c7a784aca" dependencies = [ "async-trait", "json5", @@ -471,15 +589,15 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -487,15 +605,15 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -516,37 +634,52 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] -name = "crossbeam-utils" -version = "0.8.16" +name = "crossbeam-deque" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", + "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.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + [[package]] name = "crypto-bigint" -version = "0.5.3" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", "rand_core", @@ -572,9 +705,9 @@ checksum = "f3b7eb4404b8195a9abb6356f4ac07d8ba267045c8d6d220ac4dc992e6cc75df" [[package]] name = "curl" -version = "0.4.44" +version = "0.4.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22" +checksum = "1e2161dd6eba090ff1594084e95fd67aeccf04382ffea77999ea94ed42ec67b6" dependencies = [ "curl-sys", "libc", @@ -582,14 +715,14 @@ dependencies = [ "openssl-sys", "schannel", "socket2", - "winapi", + "windows-sys 0.52.0", ] [[package]] name = "curl-sys" -version = "0.4.65+curl-8.2.1" +version = "0.4.72+curl-8.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "961ba061c9ef2fe34bbd12b807152d96f0badd2bebe7b90ce6c8c8b7572a0986" +checksum = "29cbdc8314c447d11e8fd156dcdd031d9e02a7a976163e396b548c03153bc9ea" dependencies = [ "cc", "libc", @@ -598,7 +731,7 @@ dependencies = [ "openssl-sys", "pkg-config", "vcpkg", - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -614,9 +747,12 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.8" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] [[package]] name = "digest" @@ -665,20 +801,20 @@ checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" [[package]] name = "dylint" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01428e3fad655202ec50df7b66015d59f7a66d76c9d0eba7148fc057c1008b08" +checksum = "683b9feb84cd2620b4b75119b7e914ac132dbd9e523f9a98821f3b3a7e355053" dependencies = [ "ansi_term", "anyhow", - "cargo", + "cargo 0.73.1", "cargo-platform", "cargo-util", - "cargo_metadata", + "cargo_metadata 0.18.1", + "curl-sys", "dirs", "dylint_internal", "glob", - "heck", "if_chain", "is-terminal", "log", @@ -687,19 +823,19 @@ dependencies = [ "serde", "serde_json", "tempfile", - "toml 0.7.7", + "toml 0.8.10", "walkdir", ] [[package]] name = "dylint_internal" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "510bc05a42055d62ed89ee9561d974f338d30bf786917da7c033146a860ceac1" +checksum = "4ede982d9261f23a19b92ed7dc4ddeefc8328fc21c88e2c79ffd6e071c7972be" dependencies = [ "ansi_term", "anyhow", - "cargo_metadata", + "cargo_metadata 0.18.1", "git2", "home", "if_chain", @@ -711,9 +847,9 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.16.8" +version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der", "digest", @@ -725,24 +861,36 @@ dependencies = [ [[package]] name = "ed25519-compact" -version = "2.0.4" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a3d382e8464107391c8706b4c14b087808ecb909f6c15c34114bc42e53a9e4c" +checksum = "e9b3460f44bea8cd47f45a0c70892f1eff856d97cd55358b2f73f663789f6190" dependencies = [ "getrandom", ] +[[package]] +name = "educe" +version = "0.4.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f0042ff8246a363dbe77d2ceedb073339e85a804b9a47636c6e016a9a32c05f" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "either" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" [[package]] name = "elliptic-curve" -version = "0.13.5" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", "crypto-bigint", @@ -759,11 +907,24 @@ dependencies = [ "zeroize", ] +[[package]] +name = "enum-ordinalize" +version = "3.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bf1fa3f06bbff1ea5b1a9c7b14aa992a39657db60a2759457328d7e058f49ee" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 2.0.52", +] + [[package]] name = "env_logger" -version = "0.10.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" dependencies = [ "humantime", "is-terminal", @@ -780,23 +941,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ - "cc", "libc", + "windows-sys 0.52.0", ] [[package]] @@ -810,9 +960,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "ff" @@ -826,27 +976,27 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.1.20" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" +checksum = "1676f435fc1dadde4d03e43f5d62b259e1ce5f40bd4ffb21db2b42ebe59c1382" [[package]] name = "filetime" -version = "0.2.22" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", - "windows-sys 0.48.0", + "redox_syscall", + "windows-sys 0.52.0", ] [[package]] name = "flate2" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" dependencies = [ "crc32fast", "libz-sys", @@ -861,13 +1011,102 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "fwdansi" version = "1.1.0" @@ -891,9 +1130,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "js-sys", @@ -902,6 +1141,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + [[package]] name = "git2" version = "0.17.2" @@ -935,42 +1180,92 @@ version = "0.44.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bf41b61f7df395284f7a579c0fa1a7e012c5aede655174d4e91299ef1cac643" dependencies = [ - "gix-actor", - "gix-attributes", - "gix-config", - "gix-credentials", + "gix-actor 0.20.0", + "gix-attributes 0.12.0", + "gix-config 0.22.0", + "gix-credentials 0.14.0", + "gix-date", + "gix-diff 0.29.0", + "gix-discover 0.18.1", + "gix-features 0.29.0", + "gix-fs 0.1.1", + "gix-glob 0.7.0", + "gix-hash", + "gix-hashtable", + "gix-ignore 0.2.0", + "gix-index 0.16.1", + "gix-lock 5.0.1", + "gix-mailmap 0.12.0", + "gix-object 0.29.2", + "gix-odb 0.45.0", + "gix-pack 0.35.0", + "gix-path", + "gix-prompt", + "gix-protocol 0.32.0", + "gix-ref 0.29.1", + "gix-refspec 0.10.1", + "gix-revision 0.13.0", + "gix-sec", + "gix-tempfile 5.0.3", + "gix-transport 0.31.0", + "gix-traverse 0.25.0", + "gix-url 0.18.0", + "gix-utils", + "gix-validate", + "gix-worktree 0.17.1", + "log", + "once_cell", + "prodash 23.1.2", + "signal-hook", + "smallvec", + "thiserror", + "unicode-normalization", +] + +[[package]] +name = "gix" +version = "0.45.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf2a03ec66ee24d1b2bae3ab718f8d14f141613810cb7ff6756f7db667f1cd82" +dependencies = [ + "gix-actor 0.21.0", + "gix-attributes 0.13.1", + "gix-commitgraph", + "gix-config 0.23.0", + "gix-credentials 0.15.0", "gix-date", - "gix-diff", - "gix-discover", - "gix-features", - "gix-fs", - "gix-glob", + "gix-diff 0.30.1", + "gix-discover 0.19.0", + "gix-features 0.30.0", + "gix-fs 0.2.0", + "gix-glob 0.8.0", "gix-hash", "gix-hashtable", - "gix-ignore", - "gix-index", - "gix-lock", - "gix-mailmap", - "gix-object", - "gix-odb", - "gix-pack", + "gix-ignore 0.3.0", + "gix-index 0.17.0", + "gix-lock 6.0.0", + "gix-mailmap 0.13.0", + "gix-negotiate", + "gix-object 0.30.0", + "gix-odb 0.46.0", + "gix-pack 0.36.0", "gix-path", "gix-prompt", - "gix-protocol", - "gix-ref", - "gix-refspec", - "gix-revision", + "gix-protocol 0.33.2", + "gix-ref 0.30.0", + "gix-refspec 0.11.0", + "gix-revision 0.15.2", "gix-sec", - "gix-tempfile", - "gix-transport", - "gix-traverse", - "gix-url", + "gix-tempfile 6.0.0", + "gix-transport 0.32.0", + "gix-traverse 0.26.0", + "gix-url 0.19.0", "gix-utils", "gix-validate", - "gix-worktree", + "gix-worktree 0.18.0", "log", "once_cell", - "prodash", + "prodash 25.0.2", "signal-hook", "smallvec", "thiserror", @@ -991,6 +1286,20 @@ dependencies = [ "thiserror", ] +[[package]] +name = "gix-actor" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fe73f9f6be1afbf1bd5be919a9636fa560e2f14d42262a934423ed6760cd838" +dependencies = [ + "bstr", + "btoi", + "gix-date", + "itoa", + "nom", + "thiserror", +] + [[package]] name = "gix-attributes" version = "0.12.0" @@ -998,7 +1307,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3015baa01ad2122fbcaab7863c857a603eb7b7ec12ac8141207c42c6439805e2" dependencies = [ "bstr", - "gix-glob", + "gix-glob 0.7.0", "gix-path", "gix-quote", "kstring", @@ -1009,32 +1318,63 @@ dependencies = [ ] [[package]] -name = "gix-bitmap" -version = "0.2.7" +name = "gix-attributes" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ccab4bc576844ddb51b78d81b4a42d73e6229660fa614dfc3d3999c874d1959" +checksum = "78b79590ac382f80d87e06416f5fcac6fee5d83dcb152a00ed0bdbaa988acc31" dependencies = [ - "thiserror", + "bstr", + "gix-glob 0.8.0", + "gix-path", + "gix-quote", + "kstring", + "log", + "smallvec", + "thiserror", + "unicode-bom", +] + +[[package]] +name = "gix-bitmap" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b6cd0f246180034ddafac9b00a112f19178135b21eb031b3f79355891f7325" +dependencies = [ + "thiserror", ] [[package]] name = "gix-chunk" -version = "0.4.4" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b42ea64420f7994000130328f3c7a2038f639120518870436d31b8bde704493" +checksum = "003ec6deacf68076a0c157271a127e0bb2c031c1a41f7168cbe5d248d9b85c78" dependencies = [ "thiserror", ] [[package]] name = "gix-command" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f28f654184b5f725c5737c7e4f466cbd8f0102ac352d5257eeab19647ee4256" +checksum = "3c576cfbf577f72c097b5f88aedea502cd62952bdc1fb3adcab4531d5525a4c7" dependencies = [ "bstr", ] +[[package]] +name = "gix-commitgraph" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8490ae1b3d55c47e6a71d247c082304a2f79f8d0332c1a2f5693d42a2021a09" +dependencies = [ + "bstr", + "gix-chunk", + "gix-features 0.30.0", + "gix-hash", + "memmap2", + "thiserror", +] + [[package]] name = "gix-config" version = "0.22.0" @@ -1043,10 +1383,32 @@ checksum = "1d252a0eddb6df74600d3d8872dc9fe98835a7da43110411d705b682f49d4ac1" dependencies = [ "bstr", "gix-config-value", - "gix-features", - "gix-glob", + "gix-features 0.29.0", + "gix-glob 0.7.0", "gix-path", - "gix-ref", + "gix-ref 0.29.1", + "gix-sec", + "log", + "memchr", + "nom", + "once_cell", + "smallvec", + "thiserror", + "unicode-bom", +] + +[[package]] +name = "gix-config" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51f310120ae1ba8f0ca52fb22876ce9bad5b15c8ffb3eb7302e4b64a3b9f681c" +dependencies = [ + "bstr", + "gix-config-value", + "gix-features 0.30.0", + "gix-glob 0.8.0", + "gix-path", + "gix-ref 0.30.0", "gix-sec", "log", "memchr", @@ -1063,7 +1425,7 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e874f41437441c02991dcea76990b9058fadfc54b02ab4dd06ab2218af43897" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.2", "bstr", "gix-path", "libc", @@ -1082,7 +1444,23 @@ dependencies = [ "gix-path", "gix-prompt", "gix-sec", - "gix-url", + "gix-url 0.18.0", + "thiserror", +] + +[[package]] +name = "gix-credentials" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6f89fea8acd28f5ef8fa5042146f1637afd4d834bc8f13439d8fd1e5aca0d65" +dependencies = [ + "bstr", + "gix-command", + "gix-config-value", + "gix-path", + "gix-prompt", + "gix-sec", + "gix-url 0.19.0", "thiserror", ] @@ -1105,7 +1483,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "644a0f2768bc42d7a69289ada80c9e15c589caefc6a315d2307202df83ed1186" dependencies = [ "gix-hash", - "gix-object", + "gix-object 0.29.2", + "imara-diff", + "thiserror", +] + +[[package]] +name = "gix-diff" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9029ad0083cc286a4bd2f5b3bf66bb66398abc26f2731a2824cd5edfc41a0e33" +dependencies = [ + "gix-hash", + "gix-object 0.30.0", "imara-diff", "thiserror", ] @@ -1120,7 +1510,22 @@ dependencies = [ "dunce", "gix-hash", "gix-path", - "gix-ref", + "gix-ref 0.29.1", + "gix-sec", + "thiserror", +] + +[[package]] +name = "gix-discover" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aba9c6c0d1f2b2efe65581de73de4305004612d49c83773e783202a7ef204f46" +dependencies = [ + "bstr", + "dunce", + "gix-hash", + "gix-path", + "gix-ref 0.30.0", "gix-sec", "thiserror", ] @@ -1139,7 +1544,27 @@ dependencies = [ "libc", "once_cell", "parking_lot", - "prodash", + "prodash 23.1.2", + "sha1_smol", + "thiserror", + "walkdir", +] + +[[package]] +name = "gix-features" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8c493409bf6060d408eec9bbdd1b12ea351266b50012e2a522f75dfc7b8314" +dependencies = [ + "bytes", + "crc32fast", + "crossbeam-channel", + "flate2", + "gix-hash", + "libc", + "once_cell", + "parking_lot", + "prodash 25.0.2", "sha1_smol", "thiserror", "walkdir", @@ -1151,7 +1576,16 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b37a1832f691fdc09910bd267f9a2e413737c1f9ec68c6e31f9e802616278a9" dependencies = [ - "gix-features", + "gix-features 0.29.0", +] + +[[package]] +name = "gix-fs" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30da8997008adb87f94e15beb7ee229f8a48e97af585a584bfee4a5a1880aab5" +dependencies = [ + "gix-features 0.30.0", ] [[package]] @@ -1160,9 +1594,21 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c07c98204529ac3f24b34754540a852593d2a4c7349008df389240266627a72a" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.2", + "bstr", + "gix-features 0.29.0", + "gix-path", +] + +[[package]] +name = "gix-glob" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0ade1e80ab1f079703d1824e1daf73009096386aa7fd2f0477f6e4ac0a558e" +dependencies = [ + "bitflags 2.4.2", "bstr", - "gix-features", + "gix-features 0.30.0", "gix-path", ] @@ -1183,7 +1629,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "385f4ce6ecf3692d313ca3aa9bd3b3d8490de53368d6d94bedff3af8b6d9c58d" dependencies = [ "gix-hash", - "hashbrown 0.14.0", + "hashbrown 0.14.3", "parking_lot", ] @@ -1194,7 +1640,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba205b6df563e2906768bb22834c82eb46c5fdfcd86ba2c347270bc8309a05b2" dependencies = [ "bstr", - "gix-glob", + "gix-glob 0.7.0", + "gix-path", + "unicode-bom", +] + +[[package]] +name = "gix-ignore" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc6f7f101a0ccce808dbf7008ba131dede94e20257e7bde7a44cbb2f8c775625" +dependencies = [ + "bstr", + "gix-glob 0.8.0", "gix-path", "unicode-bom", ] @@ -1205,16 +1663,38 @@ version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f39c1ccc8f1912cbbd5191efc28dbc5f0d0598042aa56bc09427b7c34efab3ba" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.2", + "bstr", + "btoi", + "filetime", + "gix-bitmap", + "gix-features 0.29.0", + "gix-hash", + "gix-lock 5.0.1", + "gix-object 0.29.2", + "gix-traverse 0.25.0", + "itoa", + "memmap2", + "smallvec", + "thiserror", +] + +[[package]] +name = "gix-index" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616ba958fabfb11263fa042c35690d48a6c7be4e9277e2c7e24ff263b3fe7b82" +dependencies = [ + "bitflags 2.4.2", "bstr", "btoi", "filetime", "gix-bitmap", - "gix-features", + "gix-features 0.30.0", "gix-hash", - "gix-lock", - "gix-object", - "gix-traverse", + "gix-lock 6.0.0", + "gix-object 0.30.0", + "gix-traverse 0.26.0", "itoa", "memmap2", "smallvec", @@ -1227,7 +1707,18 @@ version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c693d7f05730fa74a7c467150adc7cea393518410c65f0672f80226b8111555" dependencies = [ - "gix-tempfile", + "gix-tempfile 5.0.3", + "gix-utils", + "thiserror", +] + +[[package]] +name = "gix-lock" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ec5d5e6f07316d3553aa7425e3ecd935ec29882556021fe1696297a448af8d2" +dependencies = [ + "gix-tempfile 6.0.0", "gix-utils", "thiserror", ] @@ -1239,7 +1730,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8856cec3bdc3610c06970d28b6cb20a0c6621621cf9a8ec48cbd23f2630f362" dependencies = [ "bstr", - "gix-actor", + "gix-actor 0.20.0", + "thiserror", +] + +[[package]] +name = "gix-mailmap" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4653701922c920e009f1bc4309feaff14882ade017770788f9a150928da3fa6a" +dependencies = [ + "bstr", + "gix-actor 0.21.0", + "thiserror", +] + +[[package]] +name = "gix-negotiate" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "945c3ef1e912e44a5f405fc9e924edf42000566a1b257ed52cb1293300f6f08c" +dependencies = [ + "bitflags 2.4.2", + "gix-commitgraph", + "gix-hash", + "gix-object 0.30.0", + "gix-revision 0.15.2", + "smallvec", "thiserror", ] @@ -1251,8 +1768,27 @@ checksum = "2d96bd620fd08accdd37f70b2183cfa0b001b4f1c6ade8b7f6e15cb3d9e261ce" dependencies = [ "bstr", "btoi", - "gix-actor", - "gix-features", + "gix-actor 0.20.0", + "gix-features 0.29.0", + "gix-hash", + "gix-validate", + "hex", + "itoa", + "nom", + "smallvec", + "thiserror", +] + +[[package]] +name = "gix-object" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8926c8f51c44dec3e709cb5dbc93deb9e8d4064c43c9efc54c158dcdfe8446c7" +dependencies = [ + "bstr", + "btoi", + "gix-actor 0.21.0", + "gix-features 0.30.0", "gix-hash", "gix-validate", "hex", @@ -1269,10 +1805,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bca2f324aa67672b6d0f2c0fa93f96eb6a7029d260e4c1df5dce3c015f5e5add" dependencies = [ "arc-swap", - "gix-features", + "gix-features 0.29.0", + "gix-hash", + "gix-object 0.29.2", + "gix-pack 0.35.0", + "gix-path", + "gix-quote", + "parking_lot", + "tempfile", + "thiserror", +] + +[[package]] +name = "gix-odb" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b234d806278eeac2f907c8b5a105c4ba537230c1a9d9236d822bf0db291f8f3" +dependencies = [ + "arc-swap", + "gix-features 0.30.0", "gix-hash", - "gix-object", - "gix-pack", + "gix-object 0.30.0", + "gix-pack 0.36.0", "gix-path", "gix-quote", "parking_lot", @@ -1288,14 +1842,36 @@ checksum = "164a515900a83257ae4aa80e741655bee7a2e39113fb535d7a5ac623b445ff20" dependencies = [ "clru", "gix-chunk", - "gix-diff", - "gix-features", + "gix-diff 0.29.0", + "gix-features 0.29.0", "gix-hash", "gix-hashtable", - "gix-object", + "gix-object 0.29.2", "gix-path", - "gix-tempfile", - "gix-traverse", + "gix-tempfile 5.0.3", + "gix-traverse 0.25.0", + "memmap2", + "parking_lot", + "smallvec", + "thiserror", +] + +[[package]] +name = "gix-pack" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d2a14cb3156037eedb17d6cb7209b7180522b8949b21fd0fe3184c0a1d0af88" +dependencies = [ + "clru", + "gix-chunk", + "gix-diff 0.30.1", + "gix-features 0.30.0", + "gix-hash", + "gix-hashtable", + "gix-object 0.30.0", + "gix-path", + "gix-tempfile 6.0.0", + "gix-traverse 0.26.0", "memmap2", "parking_lot", "smallvec", @@ -1304,9 +1880,9 @@ dependencies = [ [[package]] name = "gix-packetline" -version = "0.16.5" +version = "0.16.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a374cb5eba089e3c123df4d996eb00da411bb90ec92cb35bffeeb2d22ee106a" +checksum = "8a8384b1e964151aff0d5632dd9b191059d07dff358b96bd940f1b452600d7ab" dependencies = [ "bstr", "faster-hex", @@ -1335,7 +1911,7 @@ dependencies = [ "gix-command", "gix-config-value", "parking_lot", - "rustix 0.38.11", + "rustix", "thiserror", ] @@ -1347,23 +1923,40 @@ checksum = "877e49417f1730f4dbc2f7d9a2ab0f8b2f49ef08f97270691403ecde3d961e3a" dependencies = [ "bstr", "btoi", - "gix-credentials", - "gix-features", + "gix-credentials 0.14.0", + "gix-features 0.29.0", "gix-hash", - "gix-transport", + "gix-transport 0.31.0", "maybe-async", "nom", "thiserror", ] [[package]] -name = "gix-quote" -version = "0.4.7" +name = "gix-protocol" +version = "0.33.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "475c86a97dd0127ba4465fbb239abac9ea10e68301470c9791a6dd5351cdc905" +checksum = "92a17058b45c461f0847528c5fb6ee6e76115e026979eb2d2202f98ee94f6c24" dependencies = [ "bstr", "btoi", + "gix-credentials 0.15.0", + "gix-features 0.30.0", + "gix-hash", + "gix-transport 0.32.0", + "maybe-async", + "nom", + "thiserror", +] + +[[package]] +name = "gix-quote" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d1b102957d975c6eb56c2b7ad9ac7f26d117299b910812b2e9bf086ec43496d" +dependencies = [ + "bstr", + "gix-utils", "thiserror", ] @@ -1373,14 +1966,34 @@ version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e03989e9d49954368e1b526578230fc7189d1634acdfbe79e9ba1de717e15d5" dependencies = [ - "gix-actor", - "gix-features", - "gix-fs", + "gix-actor 0.20.0", + "gix-features 0.29.0", + "gix-fs 0.1.1", + "gix-hash", + "gix-lock 5.0.1", + "gix-object 0.29.2", + "gix-path", + "gix-tempfile 5.0.3", + "gix-validate", + "memmap2", + "nom", + "thiserror", +] + +[[package]] +name = "gix-ref" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebdd999256f4ce8a5eefa89999879c159c263f3493a951d62aa5ce42c0397e1c" +dependencies = [ + "gix-actor 0.21.0", + "gix-features 0.30.0", + "gix-fs 0.2.0", "gix-hash", - "gix-lock", - "gix-object", + "gix-lock 6.0.0", + "gix-object 0.30.0", "gix-path", - "gix-tempfile", + "gix-tempfile 6.0.0", "gix-validate", "memmap2", "nom", @@ -1395,7 +2008,21 @@ checksum = "0a6ea733820df67e4cd7797deb12727905824d8f5b7c59d943c456d314475892" dependencies = [ "bstr", "gix-hash", - "gix-revision", + "gix-revision 0.13.0", + "gix-validate", + "smallvec", + "thiserror", +] + +[[package]] +name = "gix-refspec" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72bfd622abc86dd8ad1ec51b9eb77b4f1a766b94e3a1b87cf4a022c5b5570cf4" +dependencies = [ + "bstr", + "gix-hash", + "gix-revision 0.15.2", "gix-validate", "smallvec", "thiserror", @@ -1411,7 +2038,36 @@ dependencies = [ "gix-date", "gix-hash", "gix-hashtable", - "gix-object", + "gix-object 0.29.2", + "thiserror", +] + +[[package]] +name = "gix-revision" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5044f56cd7a487ce9b034cbe0252ae0b6b47ff56ca3dabd79bc30214d0932cd7" +dependencies = [ + "bstr", + "gix-date", + "gix-hash", + "gix-hashtable", + "gix-object 0.30.0", + "gix-revwalk", + "thiserror", +] + +[[package]] +name = "gix-revwalk" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc2623ba8747914f151f5e12b65adac576ab459dbed5f50a36c7a3e9cbf2d3ca" +dependencies = [ + "gix-commitgraph", + "gix-hash", + "gix-hashtable", + "gix-object 0.30.0", + "smallvec", "thiserror", ] @@ -1421,7 +2077,7 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9615cbd6b456898aeb942cd75e5810c382fbfc48dbbff2fa23ebd2d33dcbe9c7" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.2", "gix-path", "libc", "windows", @@ -1433,7 +2089,22 @@ version = "5.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71a0d32f34e71e86586124225caefd78dabc605d0486de580d717653addf182" dependencies = [ - "gix-fs", + "gix-fs 0.1.1", + "libc", + "once_cell", + "parking_lot", + "signal-hook", + "signal-hook-registry", + "tempfile", +] + +[[package]] +name = "gix-tempfile" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3785cb010e9dc5c446dfbf02bc1119fc17d3a48a27c029efcb3a3c32953eb10" +dependencies = [ + "gix-fs 0.2.0", "libc", "once_cell", "parking_lot", @@ -1444,9 +2115,9 @@ dependencies = [ [[package]] name = "gix-trace" -version = "0.1.3" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b6d623a1152c3facb79067d6e2ecdae48130030cf27d6eb21109f13bd7b836" +checksum = "02b202d766a7fefc596e2cc6a89cda8ad8ad733aed82da635ac120691112a9b1" [[package]] name = "gix-transport" @@ -1454,16 +2125,35 @@ version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f01c2bf7b989c679695ef635fc7d9e80072e08101be4b53193c8e8b649900102" dependencies = [ - "base64 0.21.3", + "base64 0.21.7", "bstr", "curl", "gix-command", - "gix-credentials", - "gix-features", + "gix-credentials 0.14.0", + "gix-features 0.29.0", "gix-packetline", "gix-quote", "gix-sec", - "gix-url", + "gix-url 0.18.0", + "thiserror", +] + +[[package]] +name = "gix-transport" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a39ffed9a9078ed700605e064b15d7c6ae50aa65e7faa36ca6919e8081df15" +dependencies = [ + "base64 0.21.7", + "bstr", + "curl", + "gix-command", + "gix-credentials 0.15.0", + "gix-features 0.30.0", + "gix-packetline", + "gix-quote", + "gix-sec", + "gix-url 0.19.0", "thiserror", ] @@ -1475,7 +2165,19 @@ checksum = "a5be1e807f288c33bb005075111886cceb43ed8a167b3182a0f62c186e2a0dd1" dependencies = [ "gix-hash", "gix-hashtable", - "gix-object", + "gix-object 0.29.2", + "thiserror", +] + +[[package]] +name = "gix-traverse" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0842e984cb4bf26339dc559f3a1b8bf8cdb83547799b2b096822a59f87f33d9" +dependencies = [ + "gix-hash", + "gix-hashtable", + "gix-object 0.30.0", "thiserror", ] @@ -1486,7 +2188,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfc77f89054297cc81491e31f1bab4027e554b5ef742a44bd7035db9a0f78b76" dependencies = [ "bstr", - "gix-features", + "gix-features 0.29.0", + "gix-path", + "home", + "thiserror", + "url", +] + +[[package]] +name = "gix-url" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1663df25ac42047a2547618d2a6979a26f478073f6306997429235d2cd4c863" +dependencies = [ + "bstr", + "gix-features 0.30.0", "gix-path", "home", "thiserror", @@ -1495,11 +2211,12 @@ dependencies = [ [[package]] name = "gix-utils" -version = "0.1.5" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b85d89dc728613e26e0ed952a19583744e7f5240fcd4aa30d6c824ffd8b52f0f" +checksum = "60157a15b9f14b11af1c6817ad7a93b10b50b4e5136d98a127c46a37ff16eeb6" dependencies = [ "fastrand", + "unicode-normalization", ] [[package]] @@ -1520,14 +2237,35 @@ checksum = "a69eaff0ae973a9d37c40f02ae5ae50fa726c8fc2fd3ab79d0a19eb61975aafa" dependencies = [ "bstr", "filetime", - "gix-attributes", - "gix-features", - "gix-fs", - "gix-glob", + "gix-attributes 0.12.0", + "gix-features 0.29.0", + "gix-fs 0.1.1", + "gix-glob 0.7.0", "gix-hash", - "gix-ignore", - "gix-index", - "gix-object", + "gix-ignore 0.2.0", + "gix-index 0.16.1", + "gix-object 0.29.2", + "gix-path", + "io-close", + "thiserror", +] + +[[package]] +name = "gix-worktree" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d388ad962e8854402734a7387af8790f6bdbc8d05349052dab16ca4a0def50f6" +dependencies = [ + "bstr", + "filetime", + "gix-attributes 0.13.1", + "gix-features 0.30.0", + "gix-fs 0.2.0", + "gix-glob 0.8.0", + "gix-hash", + "gix-ignore 0.3.0", + "gix-index 0.17.0", + "gix-object 0.30.0", "gix-path", "io-close", "thiserror", @@ -1541,15 +2279,15 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "globset" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" dependencies = [ "aho-corasick", "bstr", - "fnv", "log", - "regex", + "regex-automata", + "regex-syntax", ] [[package]] @@ -1569,14 +2307,14 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash 0.7.6", + "ahash 0.7.8", ] [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] name = "heck" @@ -1586,9 +2324,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -1598,9 +2336,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hkdf" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ "hmac", ] @@ -1616,18 +2354,18 @@ dependencies = [ [[package]] name = "home" -version = "0.5.5" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "http-auth" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5430cacd7a1f9a02fbeb350dfc81a0e5ed42d81f3398cb0ba184017f85bdcfbc" +checksum = "643c9bbf6a4ea8a656d6b4cd53d34f79e3f841ad5203c1a55fb7d761923bc255" dependencies = [ "memchr", ] @@ -1640,9 +2378,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -1656,17 +2394,16 @@ checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" [[package]] name = "ignore" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492" +checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" dependencies = [ + "crossbeam-deque", "globset", - "lazy_static", "log", "memchr", - "regex", + "regex-automata", "same-file", - "thread_local", "walkdir", "winapi-util", ] @@ -1691,7 +2428,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e98c1d0ad70fc91b8b9654b1f33db55e59579d3b3de2bffdced0fdb810570cb8" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.11", "hashbrown 0.12.3", ] @@ -1707,12 +2444,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.0" +version = "2.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" dependencies = [ "equivalent", - "hashbrown 0.14.0", + "hashbrown 0.14.3", ] [[package]] @@ -1725,26 +2462,15 @@ dependencies = [ "winapi", ] -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "is-terminal" -version = "0.4.9" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ "hermit-abi", - "rustix 0.38.11", - "windows-sys 0.48.0", + "libc", + "windows-sys 0.52.0", ] [[package]] @@ -1767,24 +2493,24 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jobserver" -version = "0.1.26" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -1823,9 +2549,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.147" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libgit2-sys" @@ -1843,14 +2569,25 @@ dependencies = [ [[package]] name = "libnghttp2-sys" -version = "0.1.8+1.55.1" +version = "0.1.9+1.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fae956c192dadcdb5dace96db71fa0b827333cce7c7b38dc71446f024d8a340" +checksum = "b57e858af2798e167e709b9d969325b6d8e9d50232fcbc494d7d54f976854a64" dependencies = [ "cc", "libc", ] +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.2", + "libc", + "redox_syscall", +] + [[package]] name = "libssh2-sys" version = "0.3.0" @@ -1867,9 +2604,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.12" +version = "1.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +checksum = "037731f5d3aaa87a5675e895b63ddff1a87624bc29f77004ea829809654e48f6" dependencies = [ "cc", "libc", @@ -1885,21 +2622,15 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" - -[[package]] -name = "linux-raw-sys" -version = "0.4.5" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -1907,26 +2638,26 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "maybe-async" -version = "0.2.7" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f1b8c13cb1f814b634a96b2c725449fe7ed464a7b8781de8688be5ffbd3f305" +checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.52", ] [[package]] name = "memchr" -version = "2.6.3" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "memmap2" @@ -1945,20 +2676,31 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", ] +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + [[package]] name = "miow" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ffbca2f655e33c08be35d87278e5b18b89550a37dbd598c20db92f6a471123" +checksum = "359f76430b20a79f9e20e115b3428614e654f04fab314482fc0fda0ebd3c6044" dependencies = [ - "windows-sys 0.42.0", + "windows-sys 0.48.0", ] [[package]] @@ -1971,29 +2713,74 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", ] +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "num_threads" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" dependencies = [ "libc", ] +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opener" @@ -2013,9 +2800,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.93" +version = "0.9.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" +checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" dependencies = [ "cc", "libc", @@ -2023,6 +2810,49 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "opentelemetry" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69d6c3d7288a106c0a363e4b0e8d308058d56902adefb16f4936f417ffef086e" +dependencies = [ + "opentelemetry_api", + "opentelemetry_sdk", +] + +[[package]] +name = "opentelemetry_api" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c24f96e21e7acc813c7a8394ee94978929db2bcc46cf6b5014fc612bf7760c22" +dependencies = [ + "futures-channel", + "futures-util", + "indexmap 1.9.3", + "js-sys", + "once_cell", + "pin-project-lite", + "thiserror", +] + +[[package]] +name = "opentelemetry_sdk" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ca41c4933371b61c2a2f214bf16931499af4ec90543604ec828f7a625c09113" +dependencies = [ + "async-trait", + "crossbeam-channel", + "futures-channel", + "futures-executor", + "futures-util", + "once_cell", + "opentelemetry_api", + "percent-encoding", + "rand", + "thiserror", +] + [[package]] name = "option-ext" version = "0.2.0" @@ -2031,9 +2861,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "ordered-float" -version = "2.10.0" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87" +checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" dependencies = [ "num-traits", ] @@ -2050,9 +2880,9 @@ dependencies = [ [[package]] name = "orion" -version = "0.17.5" +version = "0.17.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b11468cc6afd61a126fe3f91cc4cc8a0dbe7917d0a4b5e8357ba91cc47444462" +checksum = "7abdb10181903c8c4b016ba45d6d6d5af1a1e2a461aa4763a83b87f5df4695e5" dependencies = [ "fiat-crypto", "subtle", @@ -2094,22 +2924,22 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", + "redox_syscall", "smallvec", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] name = "pasetors" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba765699a309908d55950919a3445e9491453e89b2587b1b2abe4143a48894c0" +checksum = "6b36d47c66f2230dd1b7143d9afb2b4891879020210eddf2ccb624e529b96dba" dependencies = [ "ct-codecs", "ed25519-compact", @@ -2143,15 +2973,15 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.3" +version = "2.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a4d085fd991ac8d5b05a147b437791b4260b76326baf0fc60cf7c9c27ecd33" +checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8" dependencies = [ "memchr", "thiserror", @@ -2160,37 +2990,69 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.3" +version = "2.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bee7be22ce7918f641a33f08e3f43388c7656772244e2bbb2477f44cc9021a" +checksum = "b0d24f72393fd16ab6ac5738bc33cdb6a9aa73f8b902e8fe29cf4e67d7dd1026" dependencies = [ "pest", "pest_generator", ] [[package]] -name = "pest_generator" -version = "2.7.3" +name = "pest_generator" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc17e2a6c7d0a492f0158d7a4bd66cc17280308bbaff78d5bef566dca35ab80" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "pest_meta" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "934cd7631c050f4674352a6e835d5f6711ffbfb9345c2fc0107155ac495ae293" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1511785c5e98d79a05e8a6bc34b4ac2168a0e3e92161862030ad84daa223141" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ - "pest", - "pest_meta", "proc-macro2", "quote", "syn 2.0.52", ] [[package]] -name = "pest_meta" -version = "2.7.3" +name = "pin-project-lite" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42f0394d3123e33353ca5e1e89092e533d2cc490389f2bd6131c43c634ebc5f" -dependencies = [ - "once_cell", - "pest", - "sha2", -] +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkcs8" @@ -2204,9 +3066,15 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "powerfmt" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" @@ -2216,9 +3084,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "primeorder" -version = "0.13.2" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c2fcef82c0ec6eefcc179b978446c399b3cdf73c392c35604e399eee6df1ee3" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" dependencies = [ "elliptic-curve", ] @@ -2241,6 +3109,26 @@ dependencies = [ "parking_lot", ] +[[package]] +name = "prodash" +version = "25.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d67eb4220992a4a052a4bb03cf776e493ecb1a3a36bab551804153d63486af7" +dependencies = [ + "parking_lot", +] + +[[package]] +name = "pulldown-cmark" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" +dependencies = [ + "bitflags 2.4.2", + "memchr", + "unicase", +] + [[package]] name = "quote" version = "1.0.35" @@ -2291,38 +3179,29 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.3.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "redox_users" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" dependencies = [ "getrandom", - "redox_syscall 0.2.16", + "libredox", "thiserror", ] [[package]] name = "regex" -version = "1.9.5" +version = "1.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", @@ -2332,9 +3211,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.8" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", @@ -2343,9 +3222,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.5" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "rfc6979" @@ -2370,9 +3249,9 @@ dependencies = [ [[package]] name = "rust-embed" -version = "6.8.1" +version = "8.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a36224c3276f8c4ebc8c20f158eca7ca4359c8db89991c4925132aaaf6702661" +checksum = "fb78f46d0066053d16d4ca7b898e9343bc3530f71c61d5ad84cd404ada068745" dependencies = [ "rust-embed-impl", "rust-embed-utils", @@ -2381,9 +3260,9 @@ dependencies = [ [[package]] name = "rust-embed-impl" -version = "6.8.1" +version = "8.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b94b81e5b2c284684141a2fb9e2a31be90638caf040bf9afbc5a0416afe1ac" +checksum = "b91ac2a3c6c0520a3fb3dd89321177c3c692937c4eb21893378219da10c44fc8" dependencies = [ "proc-macro2", "quote", @@ -2394,9 +3273,9 @@ dependencies = [ [[package]] name = "rust-embed-utils" -version = "7.8.1" +version = "8.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d38ff6bf570dc3bb7100fce9f7b60c33fa71d80e88da3f2580df4ff2bdded74" +checksum = "86f69089032567ffff4eada41c573fc43ff466c7db7c5688b2e7969584345581" dependencies = [ "globset", "sha2", @@ -2413,6 +3292,12 @@ dependencies = [ "ordered-multimap", ] +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustfix" version = "0.6.1" @@ -2427,29 +3312,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" -dependencies = [ - "bitflags 1.3.2", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys 0.3.8", - "windows-sys 0.48.0", -] - -[[package]] -name = "rustix" -version = "0.38.11" +version = "0.38.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0c3dde1fc030af041adc40e79c0e7fbcf431dd24870053d187d7c66e4b87453" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.2", "errno", "libc", - "linux-raw-sys 0.4.5", - "windows-sys 0.48.0", + "linux-raw-sys", + "windows-sys 0.52.0", ] [[package]] @@ -2460,9 +3331,9 @@ checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "same-file" @@ -2475,11 +3346,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2492,8 +3363,13 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" name = "scout-audit-internal" version = "0.2.2" dependencies = [ + "anyhow", + "futures", + "rand", "serde", "strum", + "tarpc", + "tokio", ] [[package]] @@ -2521,9 +3397,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" dependencies = [ "serde", ] @@ -2560,18 +3436,18 @@ dependencies = [ [[package]] name = "serde_ignored" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80c31d5c53fd39f208e770f5a20a0bb214dee2a8d0d8adba18e19ad95a482ca5" +checksum = "a8e319a36d1b52126a0d608f24e93b2d81297091818cd70625fcf50a15d84ddf" dependencies = [ "serde", ] [[package]] name = "serde_json" -version = "1.0.105" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" dependencies = [ "itoa", "ryu", @@ -2580,18 +3456,18 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" dependencies = [ "serde", ] [[package]] name = "sha1" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures", @@ -2606,15 +3482,24 @@ checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", "digest", ] +[[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-escape" version = "0.1.5" @@ -2642,9 +3527,9 @@ dependencies = [ [[package]] name = "signature" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest", "rand_core", @@ -2660,27 +3545,36 @@ dependencies = [ "typenum", ] +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + [[package]] name = "smallvec" -version = "1.11.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "socket2" -version = "0.4.9" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" dependencies = [ "libc", - "winapi", + "windows-sys 0.52.0", ] [[package]] name = "spki" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", "der", @@ -2703,9 +3597,9 @@ dependencies = [ [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" [[package]] name = "strum" @@ -2718,9 +3612,9 @@ dependencies = [ [[package]] name = "strum_macros" -version = "0.25.2" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" dependencies = [ "heck", "proc-macro2", @@ -2767,52 +3661,86 @@ dependencies = [ "libc", ] +[[package]] +name = "tarpc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93a1870169fb9490fb3b37df7f50782986475c33cb90955f9f9b9ae659124200" +dependencies = [ + "anyhow", + "fnv", + "futures", + "humantime", + "opentelemetry", + "pin-project", + "rand", + "serde", + "static_assertions", + "tarpc-plugins", + "thiserror", + "tokio", + "tokio-serde", + "tokio-util", + "tracing", + "tracing-opentelemetry", +] + +[[package]] +name = "tarpc-plugins" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8302bea2fb8a2b01b025d23414b0b4ed32a783b95e5d818c3320a8bc4baada" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "tempfile" -version = "3.8.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand", - "redox_syscall 0.3.5", - "rustix 0.38.11", - "windows-sys 0.48.0", + "rustix", + "windows-sys 0.52.0", ] [[package]] name = "termcolor" -version = "1.2.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] [[package]] name = "terminal_size" -version = "0.2.6" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" dependencies = [ - "rustix 0.37.23", + "rustix", "windows-sys 0.48.0", ] [[package]] name = "thiserror" -version = "1.0.48" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.48" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", @@ -2821,9 +3749,9 @@ dependencies = [ [[package]] name = "thread_local" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ "cfg-if", "once_cell", @@ -2831,14 +3759,16 @@ dependencies = [ [[package]] name = "time" -version = "0.3.28" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" +checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" dependencies = [ "deranged", "itoa", "libc", + "num-conv", "num_threads", + "powerfmt", "serde", "time-core", "time-macros", @@ -2846,16 +3776,17 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.14" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" +checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" dependencies = [ + "num-conv", "time-core", ] @@ -2874,6 +3805,64 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tokio" +version = "1.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +dependencies = [ + "backtrace", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "tokio-serde" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "911a61637386b789af998ee23f50aa30d5fd7edcec8d6d3dedae5e5815205466" +dependencies = [ + "bincode", + "bytes", + "educe", + "futures-core", + "futures-sink", + "pin-project", + "serde", + "serde_json", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "slab", + "tokio", + "tracing", +] + [[package]] name = "toml" version = "0.5.11" @@ -2885,21 +3874,33 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.7" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.19.15", +] + +[[package]] +name = "toml" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0a3ab2091e52d7299a39d098e200114a972df0a7724add02a273aa9aada592" +checksum = "9a9aad4a3066010876e8dcf5a8a06e70a558751117a145c6ce2b82c2e2054290" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_edit 0.22.6", ] [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" dependencies = [ "serde", ] @@ -2910,18 +3911,88 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.0.0", + "indexmap 2.2.5", + "serde", + "serde_spanned", + "toml_datetime", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c1b5fd4128cc8d3e0cb74d4ed9a9cc7c7284becd4df68f5f940e1ad123606f6" +dependencies = [ + "indexmap 2.2.5", "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.6.5", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-opentelemetry" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21ebb87a95ea13271332df069020513ab70bdb5637ca42d6e492dc3bbbad48de" +dependencies = [ + "once_cell", + "opentelemetry", + "tracing", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "sharded-slab", + "thread_local", + "tracing-core", ] [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "ucd-trie" @@ -2929,38 +4000,47 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-bom" -version = "2.0.2" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98e90c70c9f0d4d1ee6d0a7d04aa06cb9bbd53d8cfbdd62a0269a7c2eb640552" +checksum = "7eec5d1121208364f6793f7d2e222bf75a915c19557537745b195b253dd64217" [[package]] name = "unicode-ident" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] [[package]] name = "unicode-width" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] name = "unicode-xid" @@ -2970,9 +4050,9 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "url" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", @@ -2985,6 +4065,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "vcpkg" version = "0.2.15" @@ -3020,9 +4106,9 @@ dependencies = [ [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -3036,9 +4122,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3046,9 +4132,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", @@ -3061,9 +4147,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3071,9 +4157,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", @@ -3084,9 +4170,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "winapi" @@ -3106,9 +4192,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] @@ -3125,31 +4211,25 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", ] [[package]] name = "windows-sys" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows-targets 0.48.5", ] [[package]] name = "windows-sys" -version = "0.48.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.4", ] [[package]] @@ -3168,10 +4248,19 @@ dependencies = [ ] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" +name = "windows-targets" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", +] [[package]] name = "windows_aarch64_gnullvm" @@ -3180,10 +4269,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" +name = "windows_aarch64_gnullvm" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" [[package]] name = "windows_aarch64_msvc" @@ -3192,10 +4281,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] -name = "windows_i686_gnu" -version = "0.42.2" +name = "windows_aarch64_msvc" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" [[package]] name = "windows_i686_gnu" @@ -3204,10 +4293,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] -name = "windows_i686_msvc" -version = "0.42.2" +name = "windows_i686_gnu" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" [[package]] name = "windows_i686_msvc" @@ -3216,10 +4305,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" +name = "windows_i686_msvc" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" [[package]] name = "windows_x86_64_gnu" @@ -3228,10 +4317,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" +name = "windows_x86_64_gnu" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" [[package]] name = "windows_x86_64_gnullvm" @@ -3240,10 +4329,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" +name = "windows_x86_64_gnullvm" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" [[package]] name = "windows_x86_64_msvc" @@ -3251,11 +4340,26 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + [[package]] name = "winnow" -version = "0.5.15" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" +checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" dependencies = [ "memchr", ] @@ -3269,8 +4373,28 @@ dependencies = [ "linked-hash-map", ] +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + [[package]] name = "zeroize" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/apps/cargo-scout-audit/Cargo.toml b/apps/cargo-scout-audit/Cargo.toml index 912bfb36..f9d322c1 100644 --- a/apps/cargo-scout-audit/Cargo.toml +++ b/apps/cargo-scout-audit/Cargo.toml @@ -42,6 +42,11 @@ tempfile = "3.8" regex = { version = "1.5", features = ["unicode"] } serde_json = "1.0" +tarpc = { version = "0.34", features = ["full"] } +tokio = { version = "1", features = ["macros", "net", "rt-multi-thread"] } + + + scout-audit-internal = { version = "=0.2.2", path = "../../scout-audit-internal", features = ["detector"] } [dev-dependencies] diff --git a/apps/cargo-scout-audit/src/startup.rs b/apps/cargo-scout-audit/src/startup.rs index 308ea47c..352a3b65 100644 --- a/apps/cargo-scout-audit/src/startup.rs +++ b/apps/cargo-scout-audit/src/startup.rs @@ -6,6 +6,7 @@ use cargo::Config; use cargo_metadata::MetadataCommand; use clap::{Parser, Subcommand, ValueEnum}; use dylint::Dylint; +use std::sync::{Arc, Mutex}; use crate::{ detectors::{get_detectors_configuration, get_local_detectors_configuration, Detectors}, @@ -156,8 +157,8 @@ pub fn run_scout(opts: Scout) -> Result<()> { Ok(()) } - -fn run_dylint(detectors_paths: Vec, opts: Scout) -> Result<()> { +#[tokio::main] +async fn run_dylint(detectors_paths: Vec, opts: Scout) -> Result<()> { // Convert detectors paths to string let detectors_paths: Vec = detectors_paths .iter() @@ -188,6 +189,10 @@ fn run_dylint(detectors_paths: Vec, opts: Scout) -> Result<()> { ..Default::default() }; + let findings: Arc>> = Arc::new(Mutex::new(Vec::new())); + + tokio::task::spawn(async { scout_audit_internal::detector_server(findings) }); + dylint::run(&options)?; // Format output and write to file (if necessary) diff --git a/scout-audit-clippy-utils/Cargo.toml b/scout-audit-clippy-utils/Cargo.toml index fd7bce96..d2954954 100644 --- a/scout-audit-clippy-utils/Cargo.toml +++ b/scout-audit-clippy-utils/Cargo.toml @@ -11,7 +11,7 @@ arrayvec = { version = "0.7", default-features = false } if_chain = "1.0" itertools = "0.10.1" rustc-semver = "1.1" -clippy_config = { path = "/home/flerena/coinfabrik/scout/rust-clippy/clippy_config" } +clippy_config = { path = "../clippy_config" } [features] deny-warnings = [] diff --git a/scout-audit-internal/Cargo.toml b/scout-audit-internal/Cargo.toml index f25b3a2e..8278a284 100644 --- a/scout-audit-internal/Cargo.toml +++ b/scout-audit-internal/Cargo.toml @@ -30,4 +30,9 @@ lint_helper = [ strum = { version = "0.25", features = ["derive"], optional = true } serde_json = { version = "1.0", optional = true } scout-audit-clippy-utils = { version = "=0.2.2", path = "../scout-audit-clippy-utils", optional = true } -serde = { version = "1.0.197", features = ["derive"] } \ No newline at end of file +serde = { version = "1.0.197", features = ["derive"] } +tarpc = { version = "0.34", features = ["full"] } +tokio = { version = "1", features = ["macros", "net", "rt-multi-thread"] } +anyhow = "1.0" +futures = "0.3" +rand = "0.8" diff --git a/scout-audit-internal/src/lib.rs b/scout-audit-internal/src/lib.rs index 51dd679a..a1ab5449 100644 --- a/scout-audit-internal/src/lib.rs +++ b/scout-audit-internal/src/lib.rs @@ -4,8 +4,12 @@ //! This library is for internal usage only by [`cargo_scout_audit`](https://crates.io/crates/cargo-scout-audit) #[cfg(feature = "detector")] mod detector; +#[cfg(feature = "detector")] +mod socket; #[cfg(feature = "detector")] pub use detector::Detector; #[cfg(feature = "detector")] +pub use socket::*; +#[cfg(feature = "detector")] pub use strum::IntoEnumIterator; diff --git a/scout-audit-internal/src/socket.rs b/scout-audit-internal/src/socket.rs index c437d3d0..1e3bfa5f 100644 --- a/scout-audit-internal/src/socket.rs +++ b/scout-audit-internal/src/socket.rs @@ -1,5 +1,9 @@ -//extern crate rustc_lint; -//extern crate rustc_span; +// Copyright 2018 Google LLC +// +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file or at +// https://opensource.org/licenses/MIT. + use std::{ net::{IpAddr, Ipv6Addr, SocketAddr}, time::Duration, @@ -16,21 +20,76 @@ use tarpc::{ tokio_serde::formats::Json, }; use tokio::time; +use std::sync::{Arc, Mutex}; -//use rustc_lint::{Lint, LintContext}; -//use rustc_span::Span; use crate::detector::Detector; - #[tarpc::service] -pub trait Findings { +pub trait DetectorSocket { async fn hello(name: String) -> String; + async fn is_up() -> bool; + async fn set_available_detectors(detectors: Vec); + async fn is_detector_available(detector: Detector) -> bool; + async fn push_finding(finding: String); + async fn get_findings() -> Vec; } + #[derive(Clone)] -pub struct FindingsServer(SocketAddr); +struct Server { + socket_addr: SocketAddr, + available_detectors: Vec, + findings: Arc>>, + +} -#[tarpc::server] -impl Findings for FindingsServer { - async fn hello(self, _: context::Context, msg: String) -> String { - msg +impl DetectorSocket for Server { + async fn hello(self, _: context::Context, name: String) -> String { + format!("Hello, {name}! You are connected from {}", self.socket_addr) } + async fn is_up(self, _: context::Context) -> bool { + true + } + async fn set_available_detectors(mut self, _: context::Context, detectors: Vec) { + self.available_detectors = detectors; + } + + async fn is_detector_available(self, _: context::Context, detector: Detector) -> bool { + self.available_detectors.contains(&detector) + } + + async fn push_finding(mut self, _: context::Context, finding: String) { + self.findings.lock().unwrap().push(finding); + } + + async fn get_findings(self, _: context::Context) -> Vec { + self.findings.lock().unwrap().clone() + } +} + +async fn spawn(fut: impl Future + Send + 'static) { + tokio::spawn(fut); +} + +pub async fn detector_server(findings: Arc>> +) -> anyhow::Result<()> { + let server_addr = (IpAddr::V6(Ipv6Addr::LOCALHOST), 1177); + + let mut listener = tarpc::serde_transport::tcp::listen(&server_addr, Json::default).await?; + listener.config_mut().max_frame_length(usize::MAX); + listener + .filter_map(|r| future::ready(r.ok())) + .map(server::BaseChannel::with_defaults) + .max_channels_per_key(1, |t| t.transport().peer_addr().unwrap().ip()) + .map(|channel| { + let server = Server { + socket_addr: channel.transport().peer_addr().unwrap(), + available_detectors: vec![], + findings: findings.clone(), + }; + channel.execute(server.serve()).for_each(spawn) + }) + .buffer_unordered(10) + .for_each(|_| async {}) + .await; + + Ok(()) } From 3d1b52762d0d9bbb3485faf22b75d46119161ce1 Mon Sep 17 00:00:00 2001 From: Facundo Lerena Date: Mon, 11 Mar 2024 18:52:06 -0300 Subject: [PATCH 06/13] minimal expression of the socket --- apps/cargo-scout-audit/Cargo.lock | 1 + apps/cargo-scout-audit/Cargo.toml | 2 +- .../src/output/html/build/category-filter.js | 19 + .../build/vulnerability-details-display.js | 20 + .../html/build/vulnerability-expansion.js | 14 + apps/cargo-scout-audit/src/output/html/lib.rs | 25 + apps/cargo-scout-audit/src/output/html/mod.rs | 3 + .../src/output/html/templates/base.html | 104 ++ .../src/output/html/templates/categories.html | 12 + .../output/html/templates/findings_list.html | 49 + .../src/output/html/templates/styles.css | 1253 +++++++++++++++++ .../html/templates/vulnerability_details.html | 74 + .../cargo-scout-audit/src/output/html/tera.rs | 21 + .../src/output/markdown/generator.rs | 124 ++ .../src/output/markdown/lib.rs | 28 + .../src/output/markdown/mod.rs | 4 + .../src/output/markdown/utils.rs | 11 + apps/cargo-scout-audit/src/output/mod.rs | 4 + apps/cargo-scout-audit/src/output/report.rs | 82 ++ apps/cargo-scout-audit/src/output/utils.rs | 18 + apps/cargo-scout-audit/src/startup.rs | 39 +- apps/cargo-scout-audit/src/utils/output.rs | 2 +- detectors/assert-violation/src/lib.rs | 4 +- detectors/ink-version/src/lib.rs | 4 +- scout-audit-internal/src/detector.rs | 199 ++- .../src/detector/ink_lint_message.rs | 33 + .../src/detector/lint_message.rs | 32 - .../src/detector/soroban_lint_message.rs | 19 + scout-audit-internal/src/lib.rs | 12 +- .../src/socket-protobuf/definition.proto | 31 - scout-audit-internal/src/socket.rs | 55 +- 31 files changed, 2153 insertions(+), 145 deletions(-) create mode 100644 apps/cargo-scout-audit/src/output/html/build/category-filter.js create mode 100644 apps/cargo-scout-audit/src/output/html/build/vulnerability-details-display.js create mode 100644 apps/cargo-scout-audit/src/output/html/build/vulnerability-expansion.js create mode 100644 apps/cargo-scout-audit/src/output/html/lib.rs create mode 100644 apps/cargo-scout-audit/src/output/html/mod.rs create mode 100644 apps/cargo-scout-audit/src/output/html/templates/base.html create mode 100644 apps/cargo-scout-audit/src/output/html/templates/categories.html create mode 100644 apps/cargo-scout-audit/src/output/html/templates/findings_list.html create mode 100644 apps/cargo-scout-audit/src/output/html/templates/styles.css create mode 100644 apps/cargo-scout-audit/src/output/html/templates/vulnerability_details.html create mode 100644 apps/cargo-scout-audit/src/output/html/tera.rs create mode 100644 apps/cargo-scout-audit/src/output/markdown/generator.rs create mode 100644 apps/cargo-scout-audit/src/output/markdown/lib.rs create mode 100644 apps/cargo-scout-audit/src/output/markdown/mod.rs create mode 100644 apps/cargo-scout-audit/src/output/markdown/utils.rs create mode 100644 apps/cargo-scout-audit/src/output/mod.rs create mode 100644 apps/cargo-scout-audit/src/output/report.rs create mode 100644 apps/cargo-scout-audit/src/output/utils.rs create mode 100644 scout-audit-internal/src/detector/ink_lint_message.rs delete mode 100644 scout-audit-internal/src/detector/lint_message.rs create mode 100644 scout-audit-internal/src/detector/soroban_lint_message.rs delete mode 100644 scout-audit-internal/src/socket-protobuf/definition.proto diff --git a/apps/cargo-scout-audit/Cargo.lock b/apps/cargo-scout-audit/Cargo.lock index ac1627a5..67a58f37 100644 --- a/apps/cargo-scout-audit/Cargo.lock +++ b/apps/cargo-scout-audit/Cargo.lock @@ -426,6 +426,7 @@ dependencies = [ "dunce", "dylint", "env_logger", + "futures", "home", "itertools 0.11.0", "log", diff --git a/apps/cargo-scout-audit/Cargo.toml b/apps/cargo-scout-audit/Cargo.toml index f9d322c1..7a109984 100644 --- a/apps/cargo-scout-audit/Cargo.toml +++ b/apps/cargo-scout-audit/Cargo.toml @@ -44,7 +44,7 @@ serde_json = "1.0" tarpc = { version = "0.34", features = ["full"] } tokio = { version = "1", features = ["macros", "net", "rt-multi-thread"] } - +futures = { version = "0.3.30"} scout-audit-internal = { version = "=0.2.2", path = "../../scout-audit-internal", features = ["detector"] } diff --git a/apps/cargo-scout-audit/src/output/html/build/category-filter.js b/apps/cargo-scout-audit/src/output/html/build/category-filter.js new file mode 100644 index 00000000..07deb69f --- /dev/null +++ b/apps/cargo-scout-audit/src/output/html/build/category-filter.js @@ -0,0 +1,19 @@ +document.addEventListener("DOMContentLoaded", () => { + const buttons = document.querySelectorAll(".category"); + buttons.forEach((button) => { + button.addEventListener("click", () => { + const category = button.getAttribute("data-category"); + const categorySections = document.querySelectorAll(".category-section"); + categorySections.forEach((section) => { + if ( + category === "all" || + section.getAttribute("data-category") === category + ) { + section.classList.remove("hidden"); + } else { + section.classList.add("hidden"); + } + }); + }); + }); +}); diff --git a/apps/cargo-scout-audit/src/output/html/build/vulnerability-details-display.js b/apps/cargo-scout-audit/src/output/html/build/vulnerability-details-display.js new file mode 100644 index 00000000..09852f49 --- /dev/null +++ b/apps/cargo-scout-audit/src/output/html/build/vulnerability-details-display.js @@ -0,0 +1,20 @@ +document.addEventListener("DOMContentLoaded", () => { + const findingsElements = document.querySelectorAll(".finding-detail"); + + findingsElements.forEach((element) => { + element.addEventListener("click", () => { + const detailId = element.getAttribute("finding-id"); + + document + .querySelectorAll("#vulnerabilityDetails > div") + .forEach((div) => { + div.classList.add("hidden"); + }); + + const detailElement = document.querySelector(`#detail-${detailId}`); + if (detailElement) { + detailElement.classList.remove("hidden"); + } + }); + }); +}); diff --git a/apps/cargo-scout-audit/src/output/html/build/vulnerability-expansion.js b/apps/cargo-scout-audit/src/output/html/build/vulnerability-expansion.js new file mode 100644 index 00000000..a0ffa3b8 --- /dev/null +++ b/apps/cargo-scout-audit/src/output/html/build/vulnerability-expansion.js @@ -0,0 +1,14 @@ +document.addEventListener("DOMContentLoaded", () => { + const expandDiv = document.querySelectorAll(".expand-div"); + + expandDiv.forEach((div) => { + div.addEventListener("click", function () { + const expandBtn = div.querySelector(".expand-btn"); + expandBtn.classList.toggle("rotate-90"); + const additionalDetailsDiv = this.closest(".vulnerability").querySelector( + ".additional-details" + ); + additionalDetailsDiv.classList.toggle("hidden"); + }); + }); +}); diff --git a/apps/cargo-scout-audit/src/output/html/lib.rs b/apps/cargo-scout-audit/src/output/html/lib.rs new file mode 100644 index 00000000..a70fe379 --- /dev/null +++ b/apps/cargo-scout-audit/src/output/html/lib.rs @@ -0,0 +1,25 @@ +use crate::output::{report::Report, utils::write_to_file}; + +use super::tera::{create_context, render_template}; +use anyhow::{Context, Result}; +use std::path::PathBuf; + +const BASE_TEMPLATE: &str = "base.html"; +const REPORT_HTML_PATH: &str = "build/report.html"; +const OUTPUT_CSS_PATH: &str = "build/output.css"; +const STYLES_CSS: &[u8] = include_bytes!("templates/styles.css"); + +// Generates an HTML report from a given `Report` object. +pub fn generate_html(report: &Report) -> Result<&'static str> { + let context = create_context(report); + let html = render_template(BASE_TEMPLATE, &context) + .with_context(|| format!("Failed to render template '{}'", BASE_TEMPLATE))?; + + write_to_file(&PathBuf::from(REPORT_HTML_PATH), html.as_bytes()) + .with_context(|| format!("Failed to write HTML to '{}'", REPORT_HTML_PATH))?; + + write_to_file(&PathBuf::from(OUTPUT_CSS_PATH), STYLES_CSS) + .with_context(|| format!("Failed to write CSS to '{}'", OUTPUT_CSS_PATH))?; + + Ok(REPORT_HTML_PATH) +} diff --git a/apps/cargo-scout-audit/src/output/html/mod.rs b/apps/cargo-scout-audit/src/output/html/mod.rs new file mode 100644 index 00000000..9888b87e --- /dev/null +++ b/apps/cargo-scout-audit/src/output/html/mod.rs @@ -0,0 +1,3 @@ +pub mod lib; +mod tera; +pub use lib::generate_html; diff --git a/apps/cargo-scout-audit/src/output/html/templates/base.html b/apps/cargo-scout-audit/src/output/html/templates/base.html new file mode 100644 index 00000000..cd10e905 --- /dev/null +++ b/apps/cargo-scout-audit/src/output/html/templates/base.html @@ -0,0 +1,104 @@ + + + + + + + Scout Audit Report + + + + +
+
+
+ + {{ report.name }} + + + + Date: {{ report.date }} + + + + Hash: {{ report.source_url | split(pat='#') | last }} + +
+ +
+ Summary: + Total: {{ + report.summary.total_vulnerabilities + }} + High: {{ + report.summary.by_severity.high + }} + Medium: {{ + report.summary.by_severity.medium + }} + Low: {{ + report.summary.by_severity.low + }} + Info: {{ + report.summary.by_severity.info + }} + + Code Quality: [Status] + +
+
+
+ +
+ {% include "categories.html" %} + {% include "findings_list.html" %} + {% include "vulnerability_details.html" %} +
+ +
+
+ Scout by Coinfabrik - Empowering blockchain security + About + Scout + © {{ now() | date(format="%Y") }} Coinfabrik. All rights reserved. +
+
+ + + + + + + + + \ No newline at end of file diff --git a/apps/cargo-scout-audit/src/output/html/templates/categories.html b/apps/cargo-scout-audit/src/output/html/templates/categories.html new file mode 100644 index 00000000..40a1c2c9 --- /dev/null +++ b/apps/cargo-scout-audit/src/output/html/templates/categories.html @@ -0,0 +1,12 @@ + + \ No newline at end of file diff --git a/apps/cargo-scout-audit/src/output/html/templates/findings_list.html b/apps/cargo-scout-audit/src/output/html/templates/findings_list.html new file mode 100644 index 00000000..b56f824e --- /dev/null +++ b/apps/cargo-scout-audit/src/output/html/templates/findings_list.html @@ -0,0 +1,49 @@ + +
+ {% for category in report.categories %} +
+

+ {{ category.name }} +

+ {% for vulnerability in category.vulnerabilities %} +
+
+ +
+
+ {{ vulnerability.name | replace(from="_", to=" ") | capitalize }} +
+
{{ vulnerability.short_message }}
+
+
+ + + +
+ {% endfor %} +
+ {% endfor %} +
\ No newline at end of file diff --git a/apps/cargo-scout-audit/src/output/html/templates/styles.css b/apps/cargo-scout-audit/src/output/html/templates/styles.css new file mode 100644 index 00000000..54024518 --- /dev/null +++ b/apps/cargo-scout-audit/src/output/html/templates/styles.css @@ -0,0 +1,1253 @@ +/* +! tailwindcss v3.4.1 | MIT License | https://tailwindcss.com +*/ + +/* +1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) +2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) +*/ + +*, +::before, +::after { + box-sizing: border-box; + /* 1 */ + border-width: 0; + /* 2 */ + border-style: solid; + /* 2 */ + border-color: #e5e7eb; + /* 2 */ +} + +::before, +::after { + --tw-content: ''; +} + +/* +1. Use a consistent sensible line-height in all browsers. +2. Prevent adjustments of font size after orientation changes in iOS. +3. Use a more readable tab size. +4. Use the user's configured `sans` font-family by default. +5. Use the user's configured `sans` font-feature-settings by default. +6. Use the user's configured `sans` font-variation-settings by default. +7. Disable tap highlights on iOS +*/ + +html, +:host { + line-height: 1.5; + /* 1 */ + -webkit-text-size-adjust: 100%; + /* 2 */ + -moz-tab-size: 4; + /* 3 */ + -o-tab-size: 4; + tab-size: 4; + /* 3 */ + font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + /* 4 */ + font-feature-settings: normal; + /* 5 */ + font-variation-settings: normal; + /* 6 */ + -webkit-tap-highlight-color: transparent; + /* 7 */ +} + +/* +1. Remove the margin in all browsers. +2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. +*/ + +body { + margin: 0; + /* 1 */ + line-height: inherit; + /* 2 */ +} + +/* +1. Add the correct height in Firefox. +2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) +3. Ensure horizontal rules are visible by default. +*/ + +hr { + height: 0; + /* 1 */ + color: inherit; + /* 2 */ + border-top-width: 1px; + /* 3 */ +} + +/* +Add the correct text decoration in Chrome, Edge, and Safari. +*/ + +abbr:where([title]) { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; +} + +/* +Remove the default font size and weight for headings. +*/ + +h1, +h2, +h3, +h4, +h5, +h6 { + font-size: inherit; + font-weight: inherit; +} + +/* +Reset links to optimize for opt-in styling instead of opt-out. +*/ + +a { + color: inherit; + text-decoration: inherit; +} + +/* +Add the correct font weight in Edge and Safari. +*/ + +b, +strong { + font-weight: bolder; +} + +/* +1. Use the user's configured `mono` font-family by default. +2. Use the user's configured `mono` font-feature-settings by default. +3. Use the user's configured `mono` font-variation-settings by default. +4. Correct the odd `em` font sizing in all browsers. +*/ + +code, +kbd, +samp, +pre { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + /* 1 */ + font-feature-settings: normal; + /* 2 */ + font-variation-settings: normal; + /* 3 */ + font-size: 1em; + /* 4 */ +} + +/* +Add the correct font size in all browsers. +*/ + +small { + font-size: 80%; +} + +/* +Prevent `sub` and `sup` elements from affecting the line height in all browsers. +*/ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* +1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) +2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) +3. Remove gaps between table borders by default. +*/ + +table { + text-indent: 0; + /* 1 */ + border-color: inherit; + /* 2 */ + border-collapse: collapse; + /* 3 */ +} + +/* +1. Change the font styles in all browsers. +2. Remove the margin in Firefox and Safari. +3. Remove default padding in all browsers. +*/ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; + /* 1 */ + font-feature-settings: inherit; + /* 1 */ + font-variation-settings: inherit; + /* 1 */ + font-size: 100%; + /* 1 */ + font-weight: inherit; + /* 1 */ + line-height: inherit; + /* 1 */ + color: inherit; + /* 1 */ + margin: 0; + /* 2 */ + padding: 0; + /* 3 */ +} + +/* +Remove the inheritance of text transform in Edge and Firefox. +*/ + +button, +select { + text-transform: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Remove default button styles. +*/ + +button, +[type='button'], +[type='reset'], +[type='submit'] { + -webkit-appearance: button; + /* 1 */ + background-color: transparent; + /* 2 */ + background-image: none; + /* 2 */ +} + +/* +Use the modern Firefox focus style for all focusable elements. +*/ + +:-moz-focusring { + outline: auto; +} + +/* +Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) +*/ + +:-moz-ui-invalid { + box-shadow: none; +} + +/* +Add the correct vertical alignment in Chrome and Firefox. +*/ + +progress { + vertical-align: baseline; +} + +/* +Correct the cursor style of increment and decrement buttons in Safari. +*/ + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; +} + +/* +1. Correct the odd appearance in Chrome and Safari. +2. Correct the outline style in Safari. +*/ + +[type='search'] { + -webkit-appearance: textfield; + /* 1 */ + outline-offset: -2px; + /* 2 */ +} + +/* +Remove the inner padding in Chrome and Safari on macOS. +*/ + +::-webkit-search-decoration { + -webkit-appearance: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Change font properties to `inherit` in Safari. +*/ + +::-webkit-file-upload-button { + -webkit-appearance: button; + /* 1 */ + font: inherit; + /* 2 */ +} + +/* +Add the correct display in Chrome and Safari. +*/ + +summary { + display: list-item; +} + +/* +Removes the default spacing and border for appropriate elements. +*/ + +blockquote, +dl, +dd, +h1, +h2, +h3, +h4, +h5, +h6, +hr, +figure, +p, +pre { + margin: 0; +} + +fieldset { + margin: 0; + padding: 0; +} + +legend { + padding: 0; +} + +ol, +ul, +menu { + list-style: none; + margin: 0; + padding: 0; +} + +/* +Reset default styling for dialogs. +*/ + +dialog { + padding: 0; +} + +/* +Prevent resizing textareas horizontally by default. +*/ + +textarea { + resize: vertical; +} + +/* +1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) +2. Set the default placeholder color to the user's configured gray 400 color. +*/ + +input::-moz-placeholder, textarea::-moz-placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +input::placeholder, +textarea::placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +/* +Set the default cursor for buttons. +*/ + +button, +[role="button"] { + cursor: pointer; +} + +/* +Make sure disabled buttons don't get the pointer cursor. +*/ + +:disabled { + cursor: default; +} + +/* +1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) +2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) + This can trigger a poorly considered lint error in some tools but is included by design. +*/ + +img, +svg, +video, +canvas, +audio, +iframe, +embed, +object { + display: block; + /* 1 */ + vertical-align: middle; + /* 2 */ +} + +/* +Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) +*/ + +img, +video { + max-width: 100%; + height: auto; +} + +/* Make elements with the HTML hidden attribute stay hidden by default */ + +[hidden] { + display: none; +} + +*, ::before, ::after { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; +} + +::backdrop { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; +} + +.container { + width: 100%; +} + +@media (min-width: 640px) { + .container { + max-width: 640px; + } +} + +@media (min-width: 768px) { + .container { + max-width: 768px; + } +} + +@media (min-width: 1024px) { + .container { + max-width: 1024px; + } +} + +@media (min-width: 1280px) { + .container { + max-width: 1280px; + } +} + +@media (min-width: 1536px) { + .container { + max-width: 1536px; + } +} + +.absolute { + position: absolute; +} + +.relative { + position: relative; +} + +.mx-auto { + margin-left: auto; + margin-right: auto; +} + +.my-2 { + margin-top: 0.5rem; + margin-bottom: 0.5rem; +} + +.my-4 { + margin-top: 1rem; + margin-bottom: 1rem; +} + +.mx-2 { + margin-left: 0.5rem; + margin-right: 0.5rem; +} + +.my-auto { + margin-top: auto; + margin-bottom: auto; +} + +.mb-5 { + margin-bottom: 1.25rem; +} + +.ml-4 { + margin-left: 1rem; +} + +.mr-2 { + margin-right: 0.5rem; +} + +.mt-2 { + margin-top: 0.5rem; +} + +.mt-3 { + margin-top: 0.75rem; +} + +.mt-4 { + margin-top: 1rem; +} + +.mb-4 { + margin-bottom: 1rem; +} + +.mr-4 { + margin-right: 1rem; +} + +.ml-2 { + margin-left: 0.5rem; +} + +.mt-0 { + margin-top: 0px; +} + +.block { + display: block; +} + +.inline-block { + display: inline-block; +} + +.flex { + display: flex; +} + +.table { + display: table; +} + +.grid { + display: grid; +} + +.hidden { + display: none; +} + +.h-8 { + height: 2rem; +} + +.h-screen { + height: 100vh; +} + +.h-6 { + height: 1.5rem; +} + +.w-4 { + width: 1rem; +} + +.w-8 { + width: 2rem; +} + +.w-fit { + width: -moz-fit-content; + width: fit-content; +} + +.w-full { + width: 100%; +} + +.w-1\/3 { + width: 33.333333%; +} + +.max-w-4xl { + max-width: 56rem; +} + +.flex-none { + flex: none; +} + +.flex-grow { + flex-grow: 1; +} + +.table-auto { + table-layout: auto; +} + +.rotate-90 { + --tw-rotate: 90deg; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.cursor-pointer { + cursor: pointer; +} + +.grid-cols-1 { + grid-template-columns: repeat(1, minmax(0, 1fr)); +} + +.flex-row { + flex-direction: row; +} + +.flex-col { + flex-direction: column; +} + +.flex-wrap { + flex-wrap: wrap; +} + +.items-center { + align-items: center; +} + +.justify-normal { + justify-content: normal; +} + +.justify-start { + justify-content: flex-start; +} + +.justify-center { + justify-content: center; +} + +.justify-between { + justify-content: space-between; +} + +.gap-4 { + gap: 1rem; +} + +.space-y-4 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(1rem * var(--tw-space-y-reverse)); +} + +.space-x-2 > :not([hidden]) ~ :not([hidden]) { + --tw-space-x-reverse: 0; + margin-right: calc(0.5rem * var(--tw-space-x-reverse)); + margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse))); +} + +.divide-y > :not([hidden]) ~ :not([hidden]) { + --tw-divide-y-reverse: 0; + border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse))); + border-bottom-width: calc(1px * var(--tw-divide-y-reverse)); +} + +.divide-gray-600 > :not([hidden]) ~ :not([hidden]) { + --tw-divide-opacity: 1; + border-color: rgb(75 85 99 / var(--tw-divide-opacity)); +} + +.overflow-auto { + overflow: auto; +} + +.overflow-hidden { + overflow: hidden; +} + +.overflow-y-auto { + overflow-y: auto; +} + +.truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.rounded { + border-radius: 0.25rem; +} + +.rounded-full { + border-radius: 9999px; +} + +.rounded-lg { + border-radius: 0.5rem; +} + +.rounded-md { + border-radius: 0.375rem; +} + +.rounded-t-md { + border-top-left-radius: 0.375rem; + border-top-right-radius: 0.375rem; +} + +.rounded-t-none { + border-top-left-radius: 0px; + border-top-right-radius: 0px; +} + +.border { + border-width: 1px; +} + +.border-b { + border-bottom-width: 1px; +} + +.border-r { + border-right-width: 1px; +} + +.border-t { + border-top-width: 1px; +} + +.border-t-0 { + border-top-width: 0px; +} + +.border-l { + border-left-width: 1px; +} + +.border-l-2 { + border-left-width: 2px; +} + +.border-gray-200 { + --tw-border-opacity: 1; + border-color: rgb(229 231 235 / var(--tw-border-opacity)); +} + +.border-gray-600 { + --tw-border-opacity: 1; + border-color: rgb(75 85 99 / var(--tw-border-opacity)); +} + +.border-gray-700 { + --tw-border-opacity: 1; + border-color: rgb(55 65 81 / var(--tw-border-opacity)); +} + +.border-gray-400 { + --tw-border-opacity: 1; + border-color: rgb(156 163 175 / var(--tw-border-opacity)); +} + +.bg-blue-500 { + --tw-bg-opacity: 1; + background-color: rgb(59 130 246 / var(--tw-bg-opacity)); +} + +.bg-gray-500 { + --tw-bg-opacity: 1; + background-color: rgb(107 114 128 / var(--tw-bg-opacity)); +} + +.bg-gray-700 { + --tw-bg-opacity: 1; + background-color: rgb(55 65 81 / var(--tw-bg-opacity)); +} + +.bg-gray-800 { + --tw-bg-opacity: 1; + background-color: rgb(31 41 55 / var(--tw-bg-opacity)); +} + +.bg-green-500 { + --tw-bg-opacity: 1; + background-color: rgb(34 197 94 / var(--tw-bg-opacity)); +} + +.bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); +} + +.bg-yellow-500 { + --tw-bg-opacity: 1; + background-color: rgb(234 179 8 / var(--tw-bg-opacity)); +} + +.bg-red-600 { + --tw-bg-opacity: 1; + background-color: rgb(220 38 38 / var(--tw-bg-opacity)); +} + +.bg-blue-600 { + --tw-bg-opacity: 1; + background-color: rgb(37 99 235 / var(--tw-bg-opacity)); +} + +.bg-green-600 { + --tw-bg-opacity: 1; + background-color: rgb(22 163 74 / var(--tw-bg-opacity)); +} + +.bg-gradient-to-r { + background-image: linear-gradient(to right, var(--tw-gradient-stops)); +} + +.from-gray-700 { + --tw-gradient-from: #374151 var(--tw-gradient-from-position); + --tw-gradient-to: rgb(55 65 81 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); +} + +.to-gray-900 { + --tw-gradient-to: #111827 var(--tw-gradient-to-position); +} + +.p-2 { + padding: 0.5rem; +} + +.p-3 { + padding: 0.75rem; +} + +.p-4 { + padding: 1rem; +} + +.p-6 { + padding: 1.5rem; +} + +.px-2 { + padding-left: 0.5rem; + padding-right: 0.5rem; +} + +.px-3 { + padding-left: 0.75rem; + padding-right: 0.75rem; +} + +.px-4 { + padding-left: 1rem; + padding-right: 1rem; +} + +.py-1 { + padding-top: 0.25rem; + padding-bottom: 0.25rem; +} + +.py-2 { + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + +.pb-0 { + padding-bottom: 0px; +} + +.text-left { + text-align: left; +} + +.text-center { + text-align: center; +} + +.text-right { + text-align: right; +} + +.font-mono { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; +} + +.text-lg { + font-size: 1.125rem; + line-height: 1.75rem; +} + +.text-sm { + font-size: 0.875rem; + line-height: 1.25rem; +} + +.text-xl { + font-size: 1.25rem; + line-height: 1.75rem; +} + +.text-xs { + font-size: 0.75rem; + line-height: 1rem; +} + +.text-2xl { + font-size: 1.5rem; + line-height: 2rem; +} + +.font-bold { + font-weight: 700; +} + +.font-semibold { + font-weight: 600; +} + +.font-medium { + font-weight: 500; +} + +.uppercase { + text-transform: uppercase; +} + +.capitalize { + text-transform: capitalize; +} + +.text-blue-100 { + --tw-text-opacity: 1; + color: rgb(219 234 254 / var(--tw-text-opacity)); +} + +.text-blue-400 { + --tw-text-opacity: 1; + color: rgb(96 165 250 / var(--tw-text-opacity)); +} + +.text-gray-100 { + --tw-text-opacity: 1; + color: rgb(243 244 246 / var(--tw-text-opacity)); +} + +.text-gray-200 { + --tw-text-opacity: 1; + color: rgb(229 231 235 / var(--tw-text-opacity)); +} + +.text-gray-300 { + --tw-text-opacity: 1; + color: rgb(209 213 219 / var(--tw-text-opacity)); +} + +.text-gray-400 { + --tw-text-opacity: 1; + color: rgb(156 163 175 / var(--tw-text-opacity)); +} + +.text-gray-900 { + --tw-text-opacity: 1; + color: rgb(17 24 39 / var(--tw-text-opacity)); +} + +.text-green-400 { + --tw-text-opacity: 1; + color: rgb(74 222 128 / var(--tw-text-opacity)); +} + +.text-white { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); +} + +.shadow-lg { + --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.filter { + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); +} + +.transition { + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.duration-150 { + transition-duration: 150ms; +} + +.ease-in-out { + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} + +.hover\:bg-blue-600:hover { + --tw-bg-opacity: 1; + background-color: rgb(37 99 235 / var(--tw-bg-opacity)); +} + +.hover\:bg-blue-700:hover { + --tw-bg-opacity: 1; + background-color: rgb(29 78 216 / var(--tw-bg-opacity)); +} + +.hover\:bg-gray-600:hover { + --tw-bg-opacity: 1; + background-color: rgb(75 85 99 / var(--tw-bg-opacity)); +} + +.hover\:bg-gray-700:hover { + --tw-bg-opacity: 1; + background-color: rgb(55 65 81 / var(--tw-bg-opacity)); +} + +.hover\:bg-green-500:hover { + --tw-bg-opacity: 1; + background-color: rgb(34 197 94 / var(--tw-bg-opacity)); +} + +.hover\:text-blue-300:hover { + --tw-text-opacity: 1; + color: rgb(147 197 253 / var(--tw-text-opacity)); +} + +.hover\:underline:hover { + text-decoration-line: underline; +} + +.hover\:underline-offset-1:hover { + text-underline-offset: 1px; +} + +@media (min-width: 640px) { + .sm\:mt-0 { + margin-top: 0px; + } + + .sm\:block { + display: block; + } + + .sm\:w-1\/6 { + width: 16.666667%; + } + + .sm\:w-2\/6 { + width: 33.333333%; + } + + .sm\:flex-row { + flex-direction: row; + } + + .sm\:flex-col { + flex-direction: column; + } + + .sm\:justify-start { + justify-content: flex-start; + } + + .sm\:border-0 { + border-width: 0px; + } + + .sm\:border-r { + border-right-width: 1px; + } + + .sm\:py-0 { + padding-top: 0px; + padding-bottom: 0px; + } + + .sm\:text-base { + font-size: 1rem; + line-height: 1.5rem; + } +} + +@media (min-width: 768px) { + .md\:mb-0 { + margin-bottom: 0px; + } + + .md\:grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .md\:flex-row { + flex-direction: row; + } + + .md\:text-2xl { + font-size: 1.5rem; + line-height: 2rem; + } + + .md\:text-xl { + font-size: 1.25rem; + line-height: 1.75rem; + } +} + +@media (min-width: 1024px) { + .lg\:grid-cols-4 { + grid-template-columns: repeat(4, minmax(0, 1fr)); + } +} + +@media (prefers-color-scheme: dark) { + .dark\:bg-gray-800 { + --tw-bg-opacity: 1; + background-color: rgb(31 41 55 / var(--tw-bg-opacity)); + } +} \ No newline at end of file diff --git a/apps/cargo-scout-audit/src/output/html/templates/vulnerability_details.html b/apps/cargo-scout-audit/src/output/html/templates/vulnerability_details.html new file mode 100644 index 00000000..0c5c6969 --- /dev/null +++ b/apps/cargo-scout-audit/src/output/html/templates/vulnerability_details.html @@ -0,0 +1,74 @@ + + + + +
+ {% for finding in report.findings %} + {% set category = report.categories | filter(attribute="id", value=finding.category_id) | first %} + {% set vulnerability = category.vulnerabilities | filter(attribute="id", value=finding.vulnerability_id) | first %} + + {% endfor %} +
\ No newline at end of file diff --git a/apps/cargo-scout-audit/src/output/html/tera.rs b/apps/cargo-scout-audit/src/output/html/tera.rs new file mode 100644 index 00000000..beb84e61 --- /dev/null +++ b/apps/cargo-scout-audit/src/output/html/tera.rs @@ -0,0 +1,21 @@ +extern crate tera; + +use tera::{Context, Tera, Result}; + +lazy_static! { + pub static ref TEMPLATES: Option = Tera::new("templates/**/*").ok(); +} + +pub fn render_template(template_name: &str, context: &Context) -> Result { + if let Some(tera) = &*TEMPLATES { + tera.render(template_name, context) + } else { + Err("Template engine was not initialized".into()) + } +} + +pub fn create_context(report: impl serde::Serialize) -> Context { + let mut context = Context::new(); + context.insert("report", &report); + context +} diff --git a/apps/cargo-scout-audit/src/output/markdown/generator.rs b/apps/cargo-scout-audit/src/output/markdown/generator.rs new file mode 100644 index 00000000..d68dbfea --- /dev/null +++ b/apps/cargo-scout-audit/src/output/markdown/generator.rs @@ -0,0 +1,124 @@ +use std::collections::HashMap; + +use chrono::NaiveDate; + +use crate::output::report::{Category, Finding}; + +use super::utils; + +const BANNER_URL: &str = "https://www.example.com/banner.png"; + +// Generate the header for the report +pub fn generate_header(date: NaiveDate) -> String { + format!( + "![Banner Scout report]({})\n# Scout Report - {}\n\n", + BANNER_URL, date + ) +} + +// Generate the summary for the report +pub fn generate_summary(categories: &[Category], findings: &[Finding]) -> String { + let mut summary_markdown = String::from("## Summary\n"); + let findings_summary = summarize_findings(categories, findings); + + for category in categories { + if let Some((count, severity)) = findings_summary.get(&category.id) { + summary_markdown.push_str(&format!( + " - [{}]({}) ({} results) ({})\n", + category.name, + utils::sanitize_category_name(&category.name), + count, + severity + )); + } + } + + summary_markdown.push('\n'); + summary_markdown +} + +// This function summarizes the findings by category +fn summarize_findings( + categories: &[Category], + findings: &[Finding], +) -> HashMap { + let mut summary = HashMap::new(); + + for finding in findings { + if let Some(category) = categories.iter().find(|c| c.id == finding.category_id) { + let severity = category + .vulnerabilities + .first() + .map(|v| utils::capitalize(&v.severity)) + .unwrap_or_default(); + let entry = summary.entry(category.id.clone()).or_insert((0, severity)); + entry.0 += 1; + } + } + + summary +} + +// Generate the body for the report +pub fn generate_body(categories: &[Category], findings: &[Finding]) -> String { + categories + .iter() + .map(|category| { + let category_markdown = generate_category(category); + let table = generate_table_for_category(category, findings); + format!("{}{}", category_markdown, table) + }) + .collect::>() + .join("\n") +} + +// Function to generate Markdown for a category +fn generate_category(category: &Category) -> String { + let mut category_markdown = format!("## {}\n\n", category.name); + for vulnerability in &category.vulnerabilities { + category_markdown.push_str(&format!("### {}\n\n", vulnerability.name)); + category_markdown.push_str(&format!( + "**Impact:** {}\n\n", + utils::capitalize(&vulnerability.severity) + )); + category_markdown.push_str(&format!( + "**Description:** {}\n\n", + vulnerability.short_message + )); + category_markdown.push_str(&format!( + "**More about:** [here]({})\n\n", + vulnerability.help + )); + } + category_markdown +} + +// Function to generate a table for a category +fn generate_table_for_category(category: &Category, findings: &[Finding]) -> String { + let table_header = "\ + \ + \ + \ + \n"; + let table_body: String = findings + .iter() + .filter(|finding| finding.category_id == category.id) + .map(generate_finding) + .collect(); + format!( + "{}{}{}
IDDetectionStatus
\n\n", + table_header, table_body, "\n\n" + ) +} + +// Function to generate Markdown for a finding +fn generate_finding(finding: &Finding) -> String { + let status_options = "
  • - [ ] False Positive
  • \ +
  • - [ ] Acknowledged
  • \ +
  • - [ ] Resolved
"; + + format!( + "{}{}{}\n", + finding.id, "link-to-github", finding.span, status_options + ) +} diff --git a/apps/cargo-scout-audit/src/output/markdown/lib.rs b/apps/cargo-scout-audit/src/output/markdown/lib.rs new file mode 100644 index 00000000..8c70b36a --- /dev/null +++ b/apps/cargo-scout-audit/src/output/markdown/lib.rs @@ -0,0 +1,28 @@ +use std::path::PathBuf; + +use anyhow::{Context, Result}; + +use crate::output::{report::Report, utils::write_to_file}; + +use super::generator::{generate_body, generate_header, generate_summary}; + +const REPORT_MD_PATH: &str = "build/report.md"; + +// Generates a markdown report from a given `Report` object. +pub fn generate_markdown(report: &Report) -> Result<&'static str> { + let mut report_markdown = String::new(); + + // Header + report_markdown.push_str(&generate_header(report.date)); + + // Summary + report_markdown.push_str(&generate_summary(&report.categories, &report.findings)); + + // Body + report_markdown.push_str(&generate_body(&report.categories, &report.findings)); + + write_to_file(&PathBuf::from(REPORT_MD_PATH), report_markdown.as_bytes()) + .with_context(|| format!("Failed to write markdown to '{}'", REPORT_MD_PATH))?; + + Ok(REPORT_MD_PATH) +} diff --git a/apps/cargo-scout-audit/src/output/markdown/mod.rs b/apps/cargo-scout-audit/src/output/markdown/mod.rs new file mode 100644 index 00000000..8c097345 --- /dev/null +++ b/apps/cargo-scout-audit/src/output/markdown/mod.rs @@ -0,0 +1,4 @@ +mod generator; +pub mod lib; +mod utils; +pub use lib::generate_markdown; diff --git a/apps/cargo-scout-audit/src/output/markdown/utils.rs b/apps/cargo-scout-audit/src/output/markdown/utils.rs new file mode 100644 index 00000000..14477b53 --- /dev/null +++ b/apps/cargo-scout-audit/src/output/markdown/utils.rs @@ -0,0 +1,11 @@ +// Helper function to capitalize the first letter of a string +pub fn capitalize(s: &str) -> String { + s.chars() + .enumerate() + .map(|(i, c)| if i == 0 { c.to_ascii_uppercase() } else { c }) + .collect() +} + +pub fn sanitize_category_name(name: &str) -> String { + name.to_lowercase().replace(' ', "-") +} diff --git a/apps/cargo-scout-audit/src/output/mod.rs b/apps/cargo-scout-audit/src/output/mod.rs new file mode 100644 index 00000000..c34b7f4e --- /dev/null +++ b/apps/cargo-scout-audit/src/output/mod.rs @@ -0,0 +1,4 @@ +pub mod html; +pub mod markdown; +pub mod report; +pub mod utils; diff --git a/apps/cargo-scout-audit/src/output/report.rs b/apps/cargo-scout-audit/src/output/report.rs new file mode 100644 index 00000000..25f39b22 --- /dev/null +++ b/apps/cargo-scout-audit/src/output/report.rs @@ -0,0 +1,82 @@ +use anyhow::Result; +use chrono::NaiveDate; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +use super::{html, markdown}; + +#[derive(Serialize, Deserialize, Debug)] +pub struct Report { + pub name: String, + pub description: String, + pub date: NaiveDate, + pub source_url: String, + pub summary: Summary, + pub categories: Vec, + pub findings: Vec, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Summary { + pub total_vulnerabilities: u32, + pub by_severity: HashMap, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Category { + pub id: String, + pub name: String, + pub vulnerabilities: Vec, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Vulnerability { + pub id: String, + pub name: String, + pub short_message: String, + pub long_message: String, + pub severity: String, + pub help: String, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Finding { + pub id: u32, + pub occurrence_index: u32, + pub category_id: String, + pub vulnerability_id: String, + pub error_message: String, + pub span: String, + pub code_snippet: String, + pub file: String, +} + +impl Report { + pub fn new( + name: String, + description: String, + date: NaiveDate, + source_url: String, + summary: Summary, + categories: Vec, + findings: Vec, + ) -> Self { + Report { + name, + description, + date, + source_url, + summary, + categories, + findings, + } + } + + pub fn generate_html(&self) -> Result<&'static str> { + html::generate_html(self) + } + + pub fn generate_markdown(&self) -> Result<&'static str> { + markdown::generate_markdown(self) + } +} diff --git a/apps/cargo-scout-audit/src/output/utils.rs b/apps/cargo-scout-audit/src/output/utils.rs new file mode 100644 index 00000000..c0c05fe1 --- /dev/null +++ b/apps/cargo-scout-audit/src/output/utils.rs @@ -0,0 +1,18 @@ +use std::io::Write; +use std::{ + fs::{rename, File}, + path::PathBuf, +}; + +// Writes data to a file at the specified path. +pub fn write_to_file(path: &PathBuf, data: &[u8]) -> Result<(), std::io::Error> { + // Write to a temporary file first + let temp_path = path.with_extension("tmp"); + let mut temp_file = File::create(&temp_path)?; + temp_file.write_all(data)?; + + // Rename temporary file to the target path + rename(temp_path, path)?; + + Ok(()) +} diff --git a/apps/cargo-scout-audit/src/startup.rs b/apps/cargo-scout-audit/src/startup.rs index 352a3b65..c9217917 100644 --- a/apps/cargo-scout-audit/src/startup.rs +++ b/apps/cargo-scout-audit/src/startup.rs @@ -1,12 +1,17 @@ use core::panic; -use std::{fs, path::PathBuf}; +use std::{ + fs, + net::{IpAddr, Ipv4Addr}, + path::PathBuf, + sync::{Arc, Mutex}, +}; use anyhow::{bail, Context, Result}; use cargo::Config; use cargo_metadata::MetadataCommand; use clap::{Parser, Subcommand, ValueEnum}; use dylint::Dylint; -use std::sync::{Arc, Mutex}; +use futures::prelude::*; use crate::{ detectors::{get_detectors_configuration, get_local_detectors_configuration, Detectors}, @@ -15,7 +20,6 @@ use crate::{ output::{format_into_html, format_into_json, format_into_sarif}, }, }; - #[derive(Debug, Parser)] #[clap(display_name = "cargo")] pub struct Cli { @@ -91,7 +95,23 @@ pub struct Scout { pub verbose: bool, } -pub fn run_scout(opts: Scout) -> Result<()> { +#[tokio::main] +pub async fn run_scout(opts: Scout) -> Result<()> { + let findings_storage: Arc>> = Arc::new(Mutex::new(Vec::new())); + let findings = findings_storage.clone(); + + tokio::spawn( + scout_audit_internal::detector_server( + (IpAddr::V4(Ipv4Addr::LOCALHOST), 1177), + findings_storage, + ) + .map(|r| { + if let Err(e) = r { + eprintln!("Server failed: {:?}", e); + } + }), + ); + // Validations if opts.filter.is_some() && opts.exclude.is_some() { panic!("You can't use `--exclude` and `--filter` at the same time."); @@ -155,10 +175,13 @@ pub fn run_scout(opts: Scout) -> Result<()> { // Run dylint run_dylint(detectors_paths, opts).context("Failed to run dylint")?; + println!("Scout audit finished."); + println!("Findings: {:?}", findings.lock().unwrap()); + Ok(()) } -#[tokio::main] -async fn run_dylint(detectors_paths: Vec, opts: Scout) -> Result<()> { + +fn run_dylint(detectors_paths: Vec, opts: Scout) -> Result<()> { // Convert detectors paths to string let detectors_paths: Vec = detectors_paths .iter() @@ -189,10 +212,6 @@ async fn run_dylint(detectors_paths: Vec, opts: Scout) -> Result<()> { ..Default::default() }; - let findings: Arc>> = Arc::new(Mutex::new(Vec::new())); - - tokio::task::spawn(async { scout_audit_internal::detector_server(findings) }); - dylint::run(&options)?; // Format output and write to file (if necessary) diff --git a/apps/cargo-scout-audit/src/utils/output.rs b/apps/cargo-scout-audit/src/utils/output.rs index dfbb366e..eee4c378 100644 --- a/apps/cargo-scout-audit/src/utils/output.rs +++ b/apps/cargo-scout-audit/src/utils/output.rs @@ -5,7 +5,7 @@ use std::vec; use anyhow::Context; use regex::RegexBuilder; -use scout_audit_internal::{Detector, IntoEnumIterator}; +use scout_audit_internal::{InkDetector as Detector, DetectorImpl, IntoEnumIterator}; use serde_json::{json, Value}; pub fn format_into_json(scout_output: File, internals: File) -> anyhow::Result { diff --git a/detectors/assert-violation/src/lib.rs b/detectors/assert-violation/src/lib.rs index 8c19eef4..4428bda7 100644 --- a/detectors/assert-violation/src/lib.rs +++ b/detectors/assert-violation/src/lib.rs @@ -12,7 +12,7 @@ use rustc_ast::{ use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_span::{sym, Span}; use scout_audit_clippy_utils::sym; -use scout_audit_internal::Detector; +use scout_audit_internal::{InkDetector as Detector, DetectorImpl}; dylint_linting::impl_pre_expansion_lint! { /// ### What it does @@ -47,7 +47,7 @@ dylint_linting::impl_pre_expansion_lint! { pub ASSERT_VIOLATION, Warn, - Detector::AssertViolation.get_lint_message(), + scout_audit_internal::ink_lint_message::INK_ASSERT_VIOLATION_LINT_MESSAGE, AssertViolation::default() } diff --git a/detectors/ink-version/src/lib.rs b/detectors/ink-version/src/lib.rs index b4800f14..149d1c2e 100644 --- a/detectors/ink-version/src/lib.rs +++ b/detectors/ink-version/src/lib.rs @@ -7,7 +7,7 @@ extern crate rustc_span; use std::fs; use rustc_lint::EarlyLintPass; -use scout_audit_internal::Detector; +use scout_audit_internal::{InkDetector as Detector, DetectorImpl}; use semver::*; dylint_linting::declare_early_lint! { @@ -18,7 +18,7 @@ dylint_linting::declare_early_lint! { ///``` pub CHECK_INK_VERSION, Warn, - Detector::InkVersion.get_lint_message() + scout_audit_internal::ink_lint_message::INK_INK_VERSION_LINT_MESSAGE, } impl EarlyLintPass for CheckInkVersion { diff --git a/scout-audit-internal/src/detector.rs b/scout-audit-internal/src/detector.rs index 0c2c9fec..dfe57f90 100644 --- a/scout-audit-internal/src/detector.rs +++ b/scout-audit-internal/src/detector.rs @@ -7,9 +7,13 @@ extern crate rustc_lint; #[cfg(feature = "lint_helper")] extern crate rustc_span; -mod lint_message; +pub mod ink_lint_message; +pub mod soroban_lint_message; -use lint_message::*; +#[cfg(feature = "lint_helper")] +use std::net::{IpAddr, Ipv4Addr}; + +use ink_lint_message::*; #[cfg(feature = "lint_helper")] use rustc_lint::{Lint, LintContext}; #[cfg(feature = "lint_helper")] @@ -18,15 +22,45 @@ use rustc_span::Span; use scout_audit_clippy_utils::diagnostics::{ span_lint as span_lint_clippy, span_lint_and_help as span_lint_and_help_clippy, }; -//import serialize and deserialize from serde -use serde::{Deserialize, Serialize}; #[cfg(feature = "lint_helper")] use serde_json::json; +use soroban_lint_message::*; use strum::{Display, EnumIter}; -/// Available detectors. +#[cfg(feature = "lint_helper")] +use tarpc::{client, context, tokio_serde::formats::Json}; + +#[cfg(feature = "lint_helper")] +use crate::DetectorSocketClient; + +#[derive(Debug, Copy, Clone)] +pub enum BlockChain { + Ink, + Soroban, +} +use serde::{Deserialize, Serialize}; + +/// Available detectors for Soroban #[derive(Debug, Display, Clone, EnumIter, PartialEq, Eq, Hash, Serialize, Deserialize)] #[strum(serialize_all = "kebab-case")] -pub enum Detector { +pub enum SorobanDetector { + AvoidCoreMemForget, + AvoidPanicError, + AvoidUnsafeBlock, + DivideBeforeMultiply, + DosUnboundedOperation, + InsufficientlyRandomValues, + OverflowCheck, + SetContractStorage, + SorobanVersion, + UnprotectedUpdateCurrentContractWasm, + UnsafeExpect, + UnsafeUnwrap, +} + +// Available detectors for Ink +#[derive(Debug, Display, Clone, EnumIter, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[strum(serialize_all = "kebab-case")] +pub enum InkDetector { AssertViolation, AvoidCoreMemForget, AvoidFormatString, @@ -55,58 +89,151 @@ pub enum Detector { ZeroOrTestAddress, } -impl Detector { +/* +This trait should be implemented by every enum of detectors (for each blockchain) +We cannot use this trait because it's not possible to make CONST functions in traits! +If in the future this is possible, we can use this trait to enforce the implementation of the functions +*/ +pub trait DetectorImpl: std::fmt::Display { + fn get_lint_message(&self) -> &'static str; + + #[cfg(feature = "lint_helper")] + fn span_lint_and_help( + &self, + cx: &T, + lint: &'static Lint, + span: Span, + help: &str, + ); + + #[cfg(feature = "lint_helper")] + fn span_lint(&self, cx: &T, lint: &'static Lint, span: Span); +} + +impl DetectorImpl for SorobanDetector { + fn get_lint_message(&self) -> &'static str { + match self { + SorobanDetector::AvoidCoreMemForget => SOROBAN_AVOID_CORE_MEM_FORGET_LINT_MESSAGE, + SorobanDetector::InsufficientlyRandomValues => { + SOROBAN_INSUFFICIENTLY_RANDOM_VALUES_LINT_MESSAGE + } + SorobanDetector::DivideBeforeMultiply => SOROBAN_DIVIDE_BEFORE_MULTIPLY_LINT_MESSAGE, + SorobanDetector::OverflowCheck => SOROBAN_OVERFLOW_CHECK_LINT_MESSAGE, + SorobanDetector::SetContractStorage => SOROBAN_SET_CONTRACT_STORAGE_LINT_MESSAGE, + SorobanDetector::UnprotectedUpdateCurrentContractWasm => { + SOROBAN_UNPROTECTED_UPDATE_CURRENT_CONTRACT_LINT_MESSAGE + } + SorobanDetector::UnsafeExpect => SOROBAN_UNSAFE_EXPECT_LINT_MESSAGE, + SorobanDetector::UnsafeUnwrap => SOROBAN_UNSAFE_UNWRAP_LINT_MESSAGE, + SorobanDetector::AvoidPanicError => SOROBAN_AVOID_PANIC_ERROR_LINT_MESSAGE, + SorobanDetector::AvoidUnsafeBlock => SOROBAN_AVOID_UNSAFE_BLOCK_LINT_MESSAGE, + SorobanDetector::DosUnboundedOperation => SOROBAN_DOS_UNBOUNDED_OPERATION_LINT_MESSAGE, + SorobanDetector::SorobanVersion => SOROBAN_SOROBAN_VERSION_LINT_MESSAGE, + } + } + + #[cfg(feature = "lint_helper")] + fn span_lint_and_help( + &self, + cx: &T, + lint: &'static Lint, + span: Span, + help: &str, + ) { + send_to_server(); + print_scout_output(*lint, span); + span_lint_and_help_clippy(cx, lint, span, self.get_lint_message(), None, help); + } + + #[cfg(feature = "lint_helper")] + fn span_lint(&self, cx: &T, lint: &'static Lint, span: Span) { + send_to_server(); + print_scout_output(*lint, span); + span_lint_clippy(cx, lint, span, self.get_lint_message()); + } +} + +impl DetectorImpl for InkDetector { /// Returns the lint message for the detector. - pub const fn get_lint_message(&self) -> &'static str { + fn get_lint_message(&self) -> &'static str { match self { - Detector::AssertViolation => ASSERT_VIOLATION_LINT_MESSAGE, - Detector::AvoidCoreMemForget => AVOID_CORE_MEM_FORGET_LINT_MESSAGE, - Detector::AvoidFormatString => AVOID_FORMAT_STRING_LINT_MESSAGE, - Detector::DelegateCall => DELEGATE_CALL_LINT_MESSAGE, - Detector::DivideBeforeMultiply => DIVIDE_BEFORE_MULTIPLY_LINT_MESSAGE, - Detector::DosUnboundedOperation => DOS_UNBOUNDED_OPERATION_LINT_MESSAGE, - Detector::DosUnexpectedRevertWithVector => { - DOS_UNEXPECTED_REVERT_WITH_VECTOR_LINT_MESSAGE + InkDetector::AssertViolation => INK_ASSERT_VIOLATION_LINT_MESSAGE, + InkDetector::AvoidCoreMemForget => INK_AVOID_CORE_MEM_FORGET_LINT_MESSAGE, + InkDetector::AvoidFormatString => INK_AVOID_FORMAT_STRING_LINT_MESSAGE, + InkDetector::DelegateCall => INK_DELEGATE_CALL_LINT_MESSAGE, + InkDetector::DivideBeforeMultiply => INK_DIVIDE_BEFORE_MULTIPLY_LINT_MESSAGE, + InkDetector::DosUnboundedOperation => INK_DOS_UNBOUNDED_OPERATION_LINT_MESSAGE, + InkDetector::DosUnexpectedRevertWithVector => { + INK_DOS_UNEXPECTED_REVERT_WITH_VECTOR_LINT_MESSAGE + } + InkDetector::InkVersion => INK_INK_VERSION_LINT_MESSAGE, + InkDetector::InsufficientlyRandomValues => { + INK_INSUFFICIENTLY_RANDOM_VALUES_LINT_MESSAGE + } + InkDetector::IntegerOverflowOrUnderflow => { + INK_INTEGER_OVERFLOW_OR_UNDERFLOW_LINT_MESSAGE + } + InkDetector::IteratorsOverIndexing => INK_ITERATORS_OVER_INDEXING_LINT_MESSAGE, + InkDetector::LazyDelegate => INK_LAZY_DELEGATE_LINT_MESSAGE, + InkDetector::PanicError => INK_PANIC_ERROR_LINT_MESSAGE, + InkDetector::Reentrancy1 => INK_REENTRANCY_LINT_MESSAGE, + InkDetector::Reentrancy2 => INK_REENTRANCY_LINT_MESSAGE, + InkDetector::SetCodeHash => INK_SET_CODE_HASH_LINT_MESSAGE, + InkDetector::SetContractStorage => INK_SET_CONTRACT_STORAGE_LINT_MESSAGE, + InkDetector::UnprotectedMappingOperation => { + INK_UNPROTECTED_MAPPING_OPERATION_LINT_MESSAGE } - Detector::InkVersion => INK_VERSION_LINT_MESSAGE, - Detector::InsufficientlyRandomValues => INSUFFICIENTLY_RANDOM_VALUES_LINT_MESSAGE, - Detector::IntegerOverflowOrUnderflow => INTEGER_OVERFLOW_OR_UNDERFLOW_LINT_MESSAGE, - Detector::IteratorsOverIndexing => ITERATORS_OVER_INDEXING_LINT_MESSAGE, - Detector::LazyDelegate => LAZY_DELEGATE_LINT_MESSAGE, - Detector::PanicError => PANIC_ERROR_LINT_MESSAGE, - Detector::Reentrancy1 => REENTRANCY_LINT_MESSAGE, - Detector::Reentrancy2 => REENTRANCY_LINT_MESSAGE, - Detector::SetCodeHash => SET_CODE_HASH_LINT_MESSAGE, - Detector::SetContractStorage => SET_CONTRACT_STORAGE_LINT_MESSAGE, - Detector::UnprotectedMappingOperation => UNPROTECTED_MAPPING_OPERATION_LINT_MESSAGE, - Detector::UnprotectedSelfDestruct => UNPROTECTED_SELF_DESTRUCT_LINT_MESSAGE, - Detector::UnrestrictedTransferFrom => UNRESTRICTED_TRANSFER_FROM_LINT_MESSAGE, - Detector::UnsafeExpect => UNSAFE_EXPECT_LINT_MESSAGE, - Detector::UnsafeUnwrap => UNSAFE_UNWRAP_LINT_MESSAGE, - Detector::UnusedReturnEnum => UNUSED_RETURN_ENUM_LINT_MESSAGE, - Detector::ZeroOrTestAddress => ZERO_OR_TEST_ADDRESS_LINT_MESSAGE, + InkDetector::UnprotectedSelfDestruct => INK_UNPROTECTED_SELF_DESTRUCT_LINT_MESSAGE, + InkDetector::UnrestrictedTransferFrom => INK_UNRESTRICTED_TRANSFER_FROM_LINT_MESSAGE, + InkDetector::UnsafeExpect => INK_UNSAFE_EXPECT_LINT_MESSAGE, + InkDetector::UnsafeUnwrap => INK_UNSAFE_UNWRAP_LINT_MESSAGE, + InkDetector::UnusedReturnEnum => INK_UNUSED_RETURN_ENUM_LINT_MESSAGE, + InkDetector::ZeroOrTestAddress => INK_ZERO_OR_TEST_ADDRESS_LINT_MESSAGE, } } #[cfg(feature = "lint_helper")] - pub fn span_lint_and_help( + fn span_lint_and_help( &self, cx: &T, lint: &'static Lint, span: Span, help: &str, ) { + send_to_server(); print_scout_output(*lint, span); span_lint_and_help_clippy(cx, lint, span, self.get_lint_message(), None, help); } #[cfg(feature = "lint_helper")] - pub fn span_lint(&self, cx: &T, lint: &'static Lint, span: Span) { + fn span_lint(&self, cx: &T, lint: &'static Lint, span: Span) { + send_to_server(); print_scout_output(*lint, span); span_lint_clippy(cx, lint, span, self.get_lint_message()); } } + + +#[cfg(feature = "lint_helper")] +#[tokio::main] +async fn send_to_server() -> anyhow::Result<()> { + use crate::DetectorSocketClient; + + let server_addr = (IpAddr::V4(Ipv4Addr::LOCALHOST), 1177); + + let mut transport = tarpc::serde_transport::tcp::connect(server_addr, Json::default); + transport.config_mut().max_frame_length(usize::MAX); + let client = + DetectorSocketClient::new(client::Config::default(), transport.await.unwrap()).spawn(); + client + .push_finding(context::current(), format!("{}1", "juan")) + .await + .unwrap(); + + Ok(()) +} + #[cfg(feature = "lint_helper")] fn print_scout_output(lint: Lint, span: Span) { let span_debug_string: Vec = format!("{:?}", span) @@ -114,7 +241,7 @@ fn print_scout_output(lint: Lint, span: Span) { .map(|s| s.trim().to_string()) .collect(); - let no_span_detectors = ["CHECK_INK_VERSION"]; + let no_span_detectors = ["OVERFLOW_CHECK"]; if no_span_detectors.contains(&lint.name.to_owned().as_str()) { let span = json!({ diff --git a/scout-audit-internal/src/detector/ink_lint_message.rs b/scout-audit-internal/src/detector/ink_lint_message.rs new file mode 100644 index 00000000..882c3d0e --- /dev/null +++ b/scout-audit-internal/src/detector/ink_lint_message.rs @@ -0,0 +1,33 @@ +pub const INK_ASSERT_VIOLATION_LINT_MESSAGE: &str = + "Assert causes panic. Instead, return a proper error."; +pub const INK_AVOID_CORE_MEM_FORGET_LINT_MESSAGE: &str = + "Using `core::mem::forget` is not recommended."; +pub const INK_AVOID_FORMAT_STRING_LINT_MESSAGE: &str = "The format! macro should not be used."; +pub const INK_DELEGATE_CALL_LINT_MESSAGE: &str = "Passing arguments to the target of a delegate call is not safe, as it allows the caller to set a malicious hash as the target."; +pub const INK_DIVIDE_BEFORE_MULTIPLY_LINT_MESSAGE: &str = + "Division before multiplication might result in a loss of precision"; +pub const INK_DOS_UNBOUNDED_OPERATION_LINT_MESSAGE: &str = + "In order to prevent a single transaction from consuming all the gas in a block, unbounded operations must be avoided"; +pub const INK_DOS_UNEXPECTED_REVERT_WITH_VECTOR_LINT_MESSAGE: &str = + "This vector operation is called without access control"; +pub const INK_INK_VERSION_LINT_MESSAGE: &str = "Use the latest version of ink!"; +pub const INK_INSUFFICIENTLY_RANDOM_VALUES_LINT_MESSAGE: &str = "In order to prevent randomness manipulations by validators block_timestamp should not be used as random number source"; +pub const INK_INTEGER_OVERFLOW_OR_UNDERFLOW_LINT_MESSAGE: &str = "Potential for integer arithmetic overflow/underflow. Consider checked, wrapping or saturating arithmetic."; +pub const INK_ITERATORS_OVER_INDEXING_LINT_MESSAGE: &str = + "Hardcoding an index could lead to panic if the top bound is out of bounds."; +pub const INK_LAZY_DELEGATE_LINT_MESSAGE: &str = "Delegate call with non-lazy, non-mapping storage"; +pub const INK_PANIC_ERROR_LINT_MESSAGE: &str = "The panic! macro is used to stop execution when a condition is not met. This is useful for testing and prototyping, but should be avoided in production code"; +pub const INK_REENTRANCY_LINT_MESSAGE:&str = "External calls could open the opportunity for a malicious contract to execute any arbitrary code"; +pub const INK_SET_CODE_HASH_LINT_MESSAGE: &str = + "This set_code_hash is called without access control"; +pub const INK_SET_CONTRACT_STORAGE_LINT_MESSAGE:&str = "Abitrary users should not have control over keys because it implies writing any value of left mapping, lazy variable, or the main struct of the contract located in position 0 of the storage"; +pub const INK_UNPROTECTED_MAPPING_OPERATION_LINT_MESSAGE: &str = "This mapping operation is called without access control on a different key than the caller's address"; +pub const INK_UNPROTECTED_SELF_DESTRUCT_LINT_MESSAGE: &str = + "This terminate_contract is called without access control"; +pub const INK_UNRESTRICTED_TRANSFER_FROM_LINT_MESSAGE: &str = + "This argument comes from a user-supplied argument"; +pub const INK_UNSAFE_EXPECT_LINT_MESSAGE: &str = "Unsafe usage of `expect`"; +pub const INK_UNSAFE_UNWRAP_LINT_MESSAGE: &str = "Unsafe usage of `unwrap`"; +pub const INK_UNUSED_RETURN_ENUM_LINT_MESSAGE: &str = "Unused return enum"; +pub const INK_ZERO_OR_TEST_ADDRESS_LINT_MESSAGE: &str = + "Not checking for a zero-address could lead to a locked contract"; diff --git a/scout-audit-internal/src/detector/lint_message.rs b/scout-audit-internal/src/detector/lint_message.rs deleted file mode 100644 index 0f80e415..00000000 --- a/scout-audit-internal/src/detector/lint_message.rs +++ /dev/null @@ -1,32 +0,0 @@ -pub const ASSERT_VIOLATION_LINT_MESSAGE: &str = - "Assert causes panic. Instead, return a proper error."; -pub const AVOID_CORE_MEM_FORGET_LINT_MESSAGE: &str = - "Using `core::mem::forget` is not recommended."; -pub const AVOID_FORMAT_STRING_LINT_MESSAGE: &str = "The format! macro should not be used."; -pub const DELEGATE_CALL_LINT_MESSAGE: &str = "Passing arguments to the target of a delegate call is not safe, as it allows the caller to set a malicious hash as the target."; -pub const DIVIDE_BEFORE_MULTIPLY_LINT_MESSAGE: &str = - "Division before multiplication might result in a loss of precision"; -pub const DOS_UNBOUNDED_OPERATION_LINT_MESSAGE: &str = -"In order to prevent a single transaction from consuming all the gas in a block, unbounded operations must be avoided"; -pub const DOS_UNEXPECTED_REVERT_WITH_VECTOR_LINT_MESSAGE: &str = - "This vector operation is called without access control"; -pub const INK_VERSION_LINT_MESSAGE: &str = "Use the latest version of ink!"; -pub const INSUFFICIENTLY_RANDOM_VALUES_LINT_MESSAGE: &str = "In order to prevent randomness manipulations by validators block_timestamp should not be used as random number source"; -pub const INTEGER_OVERFLOW_OR_UNDERFLOW_LINT_MESSAGE: &str = "Potential for integer arithmetic overflow/underflow. Consider checked, wrapping or saturating arithmetic."; -pub const ITERATORS_OVER_INDEXING_LINT_MESSAGE: &str = - "Hardcoding an index could lead to panic if the top bound is out of bounds."; -pub const LAZY_DELEGATE_LINT_MESSAGE: &str = "Delegate call with non-lazy, non-mapping storage"; -pub const PANIC_ERROR_LINT_MESSAGE: &str = "The panic! macro is used to stop execution when a condition is not met. This is useful for testing and prototyping, but should be avoided in production code"; -pub const REENTRANCY_LINT_MESSAGE:&str = "External calls could open the opportunity for a malicious contract to execute any arbitrary code"; -pub const SET_CODE_HASH_LINT_MESSAGE: &str = "This set_code_hash is called without access control"; -pub const SET_CONTRACT_STORAGE_LINT_MESSAGE:&str = "Abitrary users should not have control over keys because it implies writing any value of left mapping, lazy variable, or the main struct of the contract located in position 0 of the storage"; -pub const UNPROTECTED_MAPPING_OPERATION_LINT_MESSAGE: &str = "This mapping operation is called without access control on a different key than the caller's address"; -pub const UNPROTECTED_SELF_DESTRUCT_LINT_MESSAGE: &str = - "This terminate_contract is called without access control"; -pub const UNRESTRICTED_TRANSFER_FROM_LINT_MESSAGE: &str = - "This argument comes from a user-supplied argument"; -pub const UNSAFE_EXPECT_LINT_MESSAGE: &str = "Unsafe usage of `expect`"; -pub const UNSAFE_UNWRAP_LINT_MESSAGE: &str = "Unsafe usage of `unwrap`"; -pub const UNUSED_RETURN_ENUM_LINT_MESSAGE: &str = "Unused return enum"; -pub const ZERO_OR_TEST_ADDRESS_LINT_MESSAGE: &str = - "Not checking for a zero-address could lead to a locked contract"; diff --git a/scout-audit-internal/src/detector/soroban_lint_message.rs b/scout-audit-internal/src/detector/soroban_lint_message.rs new file mode 100644 index 00000000..d3600ee0 --- /dev/null +++ b/scout-audit-internal/src/detector/soroban_lint_message.rs @@ -0,0 +1,19 @@ +pub const SOROBAN_AVOID_CORE_MEM_FORGET_LINT_MESSAGE: &str = + "Use the `let _ = ...` pattern or `.drop()` method to forget the value"; +pub const SOROBAN_AVOID_UNSAFE_BLOCK_LINT_MESSAGE: &str = + "Avoid using unsafe blocks as it may lead to undefined behavior"; +pub const SOROBAN_INSUFFICIENTLY_RANDOM_VALUES_LINT_MESSAGE: &str = + "Use env.prng() to generate random numbers, and remember that all random numbers are under the control of validators"; +pub const SOROBAN_AVOID_PANIC_ERROR_LINT_MESSAGE: &str = "The panic! macro is used to stop execution when a condition is not met. Even when this does not break the execution of the contract, it is recommended to use Result instead of panic! because it will stop the execution of the caller contract"; +pub const SOROBAN_DIVIDE_BEFORE_MULTIPLY_LINT_MESSAGE: &str = + "Division before multiplication might result in a loss of precision"; +pub const SOROBAN_DOS_UNBOUNDED_OPERATION_LINT_MESSAGE: &str = + "In order to prevent a single transaction from consuming all the gas in a block, unbounded operations must be avoided"; +pub const SOROBAN_OVERFLOW_CHECK_LINT_MESSAGE: &str = + "Use `overflow-checks = true` in Cargo.toml profile"; +pub const SOROBAN_SET_CONTRACT_STORAGE_LINT_MESSAGE:&str = "Abitrary users should not have control over keys because it implies writing any value of left mapping, lazy variable, or the main struct of the contract located in position 0 of the storage"; +pub const SOROBAN_SOROBAN_VERSION_LINT_MESSAGE: &str = "Use the latest version of Soroban"; +pub const SOROBAN_UNPROTECTED_UPDATE_CURRENT_CONTRACT_LINT_MESSAGE: &str = + "This update_current_contract_wasm is called without access control"; +pub const SOROBAN_UNSAFE_EXPECT_LINT_MESSAGE: &str = "Unsafe usage of `expect`"; +pub const SOROBAN_UNSAFE_UNWRAP_LINT_MESSAGE: &str = "Unsafe usage of `unwrap`"; diff --git a/scout-audit-internal/src/lib.rs b/scout-audit-internal/src/lib.rs index a1ab5449..73c6ff02 100644 --- a/scout-audit-internal/src/lib.rs +++ b/scout-audit-internal/src/lib.rs @@ -1,3 +1,4 @@ +#![feature(const_trait_impl)] #![cfg_attr(feature = "lint_helper", feature(rustc_private))] //! # Scout Audit Internal //! @@ -8,8 +9,15 @@ mod detector; mod socket; #[cfg(feature = "detector")] -pub use detector::Detector; +pub use detector::DetectorImpl; #[cfg(feature = "detector")] -pub use socket::*; +pub use detector::InkDetector; +#[cfg(feature = "detector")] +pub use detector::SorobanDetector; #[cfg(feature = "detector")] pub use strum::IntoEnumIterator; +#[cfg(feature = "detector")] +pub use socket::*; +#[cfg(feature = "detector")] +pub use detector::*; + diff --git a/scout-audit-internal/src/socket-protobuf/definition.proto b/scout-audit-internal/src/socket-protobuf/definition.proto deleted file mode 100644 index 275f7bc9..00000000 --- a/scout-audit-internal/src/socket-protobuf/definition.proto +++ /dev/null @@ -1,31 +0,0 @@ -syntax = "proto3"; - -option java_multiple_files = true; -option java_package = "com.coinfabrik.scout"; -option java_outer_classname = "ScoutAudit"; - -package ScoutAudit; - -service ScoutAudit { - rpc PushFinding (FindingRequest) returns (FindingResponse) {} - rpc IsDetectorAvailable (DetectorRequest) returns (DetectorResponse) {} -} - -message FindingRequest { - string name = ""; - string description = ""; - string span = "" -} - -message DetectorRequest { - string detectorName = ""; -} - - -message FindingResponse { - bool message = false; -} - -message DetectorResponse { - bool habilitado = true; -} diff --git a/scout-audit-internal/src/socket.rs b/scout-audit-internal/src/socket.rs index 1e3bfa5f..a2a80033 100644 --- a/scout-audit-internal/src/socket.rs +++ b/scout-audit-internal/src/socket.rs @@ -1,28 +1,22 @@ -// Copyright 2018 Google LLC -// -// Use of this source code is governed by an MIT-style -// license that can be found in the LICENSE file or at -// https://opensource.org/licenses/MIT. - -use std::{ - net::{IpAddr, Ipv6Addr, SocketAddr}, - time::Duration, -}; +use std::net::{IpAddr, SocketAddr}; use futures::{future, prelude::*}; -use rand::{ - distributions::{Distribution, Uniform}, - thread_rng, -}; + +use std::sync::{Arc, Mutex}; use tarpc::{ context, server::{self, incoming::Incoming, Channel}, tokio_serde::formats::Json, }; -use tokio::time; -use std::sync::{Arc, Mutex}; +use serde::{Deserialize, Serialize}; + +use crate::detector::*; +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +pub enum Detector { + Soroban(SorobanDetector), + Ink(InkDetector), +} -use crate::detector::Detector; #[tarpc::service] pub trait DetectorSocket { async fn hello(name: String) -> String; @@ -38,12 +32,11 @@ struct Server { socket_addr: SocketAddr, available_detectors: Vec, findings: Arc>>, - } impl DetectorSocket for Server { async fn hello(self, _: context::Context, name: String) -> String { - format!("Hello, {name}! You are connected from {}", self.socket_addr) + format!("HOLA, {name}! {}", self.socket_addr) } async fn is_up(self, _: context::Context) -> bool { true @@ -56,7 +49,8 @@ impl DetectorSocket for Server { self.available_detectors.contains(&detector) } - async fn push_finding(mut self, _: context::Context, finding: String) { + async fn push_finding(self, _: context::Context, finding: String) { + println!("Finding: {} was added", finding); self.findings.lock().unwrap().push(finding); } @@ -69,17 +63,20 @@ async fn spawn(fut: impl Future + Send + 'static) { tokio::spawn(fut); } -pub async fn detector_server(findings: Arc>> +pub async fn detector_server( + server_addr: (IpAddr, u16), + findings: Arc>>, ) -> anyhow::Result<()> { - let server_addr = (IpAddr::V6(Ipv6Addr::LOCALHOST), 1177); - - let mut listener = tarpc::serde_transport::tcp::listen(&server_addr, Json::default).await?; - listener.config_mut().max_frame_length(usize::MAX); + let listener = tarpc::serde_transport::tcp::listen(&server_addr, Json::default).await?; listener .filter_map(|r| future::ready(r.ok())) .map(server::BaseChannel::with_defaults) - .max_channels_per_key(1, |t| t.transport().peer_addr().unwrap().ip()) + .max_channels_per_key(100, |t| t.transport().peer_addr().unwrap().ip()) .map(|channel| { + println!( + "Incoming connection from: {}", + channel.transport().peer_addr().unwrap() + ); let server = Server { socket_addr: channel.transport().peer_addr().unwrap(), available_detectors: vec![], @@ -87,8 +84,10 @@ pub async fn detector_server(findings: Arc>> }; channel.execute(server.serve()).for_each(spawn) }) - .buffer_unordered(10) - .for_each(|_| async {}) + .buffer_unordered(100) + .for_each(|_| async { + tokio::time::sleep(std::time::Duration::from_secs(1)).await; + }) .await; Ok(()) From 73302d329d11eef102eb3ab203f7794d7616e71a Mon Sep 17 00:00:00 2001 From: Facundo Lerena Date: Tue, 12 Mar 2024 17:00:17 -0300 Subject: [PATCH 07/13] updated detectors --- apps/cargo-scout-audit/src/startup.rs | 24 ++- detectors/avoid-core-mem-forget/src/lib.rs | 4 +- detectors/avoid-format-string/src/lib.rs | 4 +- detectors/delegate-call/src/lib.rs | 4 +- detectors/divide-before-multiply/src/lib.rs | 4 +- detectors/dos-unbounded-operation/src/lib.rs | 4 +- .../src/lib.rs | 4 +- detectors/ink-version/src/lib.rs | 2 +- .../insufficiently-random-values/src/lib.rs | 4 +- .../integer-overflow-or-underflow/src/lib.rs | 4 +- detectors/iterators-over-indexing/src/lib.rs | 4 +- detectors/lazy-delegate/src/lib.rs | 4 +- detectors/panic-error/src/lib.rs | 4 +- detectors/reentrancy-1/src/lib.rs | 4 +- detectors/reentrancy-2/src/lib.rs | 4 +- detectors/set-code-hash/src/lib.rs | 4 +- detectors/set-contract-storage/src/lib.rs | 4 +- .../unprotected-mapping-operation/src/lib.rs | 4 +- .../unprotected-self-destruct/src/lib.rs | 4 +- .../unrestricted-transfer-from/src/lib.rs | 4 +- detectors/unsafe-expect/src/lib.rs | 4 +- detectors/unsafe-unwrap/src/lib.rs | 4 +- detectors/unused-return-enum/src/lib.rs | 4 +- detectors/zero-or-test-address/src/lib.rs | 4 +- scout-audit-internal/src/detector.rs | 125 ++++++++++-- .../src/detector/ink_vulnerability_info.rs | 186 ++++++++++++++++++ scout-audit-internal/src/socket.rs | 23 ++- 27 files changed, 366 insertions(+), 82 deletions(-) create mode 100644 scout-audit-internal/src/detector/ink_vulnerability_info.rs diff --git a/apps/cargo-scout-audit/src/startup.rs b/apps/cargo-scout-audit/src/startup.rs index c9217917..a032afd6 100644 --- a/apps/cargo-scout-audit/src/startup.rs +++ b/apps/cargo-scout-audit/src/startup.rs @@ -1,6 +1,7 @@ use core::panic; use std::{ fs, + io::Read, net::{IpAddr, Ipv4Addr}, path::PathBuf, sync::{Arc, Mutex}, @@ -96,8 +97,9 @@ pub struct Scout { } #[tokio::main] -pub async fn run_scout(opts: Scout) -> Result<()> { - let findings_storage: Arc>> = Arc::new(Mutex::new(Vec::new())); +pub async fn run_scout(mut opts: Scout) -> Result<()> { + let findings_storage: Arc>> = + Arc::new(Mutex::new(Vec::new())); let findings = findings_storage.clone(); tokio::spawn( @@ -175,13 +177,10 @@ pub async fn run_scout(opts: Scout) -> Result<()> { // Run dylint run_dylint(detectors_paths, opts).context("Failed to run dylint")?; - println!("Scout audit finished."); - println!("Findings: {:?}", findings.lock().unwrap()); - Ok(()) } -fn run_dylint(detectors_paths: Vec, opts: Scout) -> Result<()> { +fn run_dylint(detectors_paths: Vec, mut opts: Scout) -> Result<()> { // Convert detectors paths to string let detectors_paths: Vec = detectors_paths .iter() @@ -195,6 +194,11 @@ fn run_dylint(detectors_paths: Vec, opts: Scout) -> Result<()> { let is_output_stdout = opts.output_format == OutputFormat::Text && opts.output_path.is_none(); let is_output_stdout_json = opts.args.contains(&"--message-format=json".to_string()); + // todo: !is_output_stdout && !is_output_stdout_json + if opts.output_format == OutputFormat::Html && !is_output_stdout_json { + opts.args.push("--message-format=json".to_string()); + } + let pipe_stdout = Some(stdout_temp_file.path().to_string_lossy().to_string()); let pipe_stderr = if is_output_stdout && !is_output_stdout_json { None @@ -212,6 +216,8 @@ fn run_dylint(detectors_paths: Vec, opts: Scout) -> Result<()> { ..Default::default() }; + dbg!(options.clone()); + dylint::run(&options)?; // Format output and write to file (if necessary) @@ -238,9 +244,13 @@ fn run_dylint(detectors_paths: Vec, opts: Scout) -> Result<()> { Some(path) => fs::File::create(path)?, None => fs::File::create("report.html")?, }; + let buf: &mut Vec = &mut Vec::new(); + stdout_file.read_to_end(buf); + std::io::Write::write_all( &mut html_file, - format_into_html(stderr_file, stdout_file)?.as_bytes(), + &buf, + //format_into_html(stderr_file, stdout_file)?.as_bytes(), )?; } OutputFormat::Text => { diff --git a/detectors/avoid-core-mem-forget/src/lib.rs b/detectors/avoid-core-mem-forget/src/lib.rs index dfff043d..35d8c63e 100644 --- a/detectors/avoid-core-mem-forget/src/lib.rs +++ b/detectors/avoid-core-mem-forget/src/lib.rs @@ -8,7 +8,7 @@ use if_chain::if_chain; use rustc_ast::{Expr, ExprKind, Item, NodeId}; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_span::sym; -use scout_audit_internal::Detector; +use scout_audit_internal::{DetectorImpl, InkDetector as Detector}; dylint_linting::impl_pre_expansion_lint! { /// ### What it does @@ -45,7 +45,7 @@ dylint_linting::impl_pre_expansion_lint! { pub AVOID_STD_CORE_MEM_FORGET, Warn, - Detector::AvoidCoreMemForget.get_lint_message(), + scout_audit_internal::ink_lint_message::INK_AVOID_CORE_MEM_FORGET_LINT_MESSAGE, AvoidStdCoreMemForget::default() } diff --git a/detectors/avoid-format-string/src/lib.rs b/detectors/avoid-format-string/src/lib.rs index 618273a6..0bb21d9f 100644 --- a/detectors/avoid-format-string/src/lib.rs +++ b/detectors/avoid-format-string/src/lib.rs @@ -12,7 +12,7 @@ use rustc_ast::{ use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_span::{sym, Span}; use scout_audit_clippy_utils::sym; -use scout_audit_internal::Detector; +use scout_audit_internal::{DetectorImpl, InkDetector as Detector}; dylint_linting::impl_pre_expansion_lint! { /// ### What it does @@ -45,7 +45,7 @@ dylint_linting::impl_pre_expansion_lint! { /// ``` pub AVOID_FORMAT_STRING, Warn, - Detector::AvoidFormatString.get_lint_message(), + scout_audit_internal::ink_lint_message::INK_AVOID_FORMAT_STRING_LINT_MESSAGE, AvoidFormatString::default() } diff --git a/detectors/delegate-call/src/lib.rs b/detectors/delegate-call/src/lib.rs index 5088bc44..22844686 100644 --- a/detectors/delegate-call/src/lib.rs +++ b/detectors/delegate-call/src/lib.rs @@ -13,7 +13,7 @@ use rustc_hir::{Body, FnDecl}; use rustc_hir::{Expr, ExprKind, PatKind, QPath}; use rustc_lint::{LateContext, LateLintPass}; use rustc_span::Span; -use scout_audit_internal::Detector; +use scout_audit_internal::{DetectorImpl, InkDetector as Detector}; dylint_linting::declare_late_lint! { /// ### What it does /// Checks for delegated calls to contracts passed as arguments. @@ -61,7 +61,7 @@ dylint_linting::declare_late_lint! { pub DELEGATE_CALL, Warn, - Detector::DelegateCall.get_lint_message() + scout_audit_internal::ink_lint_message::INK_DELEGATE_CALL_LINT_MESSAGE } impl<'tcx> LateLintPass<'tcx> for DelegateCall { fn check_fn( diff --git a/detectors/divide-before-multiply/src/lib.rs b/detectors/divide-before-multiply/src/lib.rs index 40e30d88..201a19a1 100644 --- a/detectors/divide-before-multiply/src/lib.rs +++ b/detectors/divide-before-multiply/src/lib.rs @@ -21,7 +21,7 @@ use rustc_middle::mir::{ use rustc_middle::ty::TyKind; use rustc_span::def_id::DefId; use rustc_span::Span; -use scout_audit_internal::Detector; +use scout_audit_internal::{DetectorImpl, InkDetector as Detector}; dylint_linting::declare_late_lint! { /// ### What it does @@ -46,7 +46,7 @@ dylint_linting::declare_late_lint! { /// ``` pub DIVIDE_BEFORE_MULTIPLY, Warn, - Detector::DivideBeforeMultiply.get_lint_message() + scout_audit_internal::ink_lint_message::INK_DIVIDE_BEFORE_MULTIPLY_LINT_MESSAGE } fn get_divisions_inside_expr(expr: &Expr<'_>) -> Vec { diff --git a/detectors/dos-unbounded-operation/src/lib.rs b/detectors/dos-unbounded-operation/src/lib.rs index d3ef0a09..968b34c9 100644 --- a/detectors/dos-unbounded-operation/src/lib.rs +++ b/detectors/dos-unbounded-operation/src/lib.rs @@ -11,7 +11,7 @@ use rustc_hir::{ }; use rustc_lint::{LateContext, LateLintPass}; use rustc_span::{def_id::LocalDefId, Span}; -use scout_audit_internal::Detector; +use scout_audit_internal::{DetectorImpl, InkDetector as Detector}; dylint_linting::declare_late_lint! { /// ### What it does @@ -38,7 +38,7 @@ dylint_linting::declare_late_lint! { /// ``` pub DOS_UNBOUNDED_OPERATION, Warn, - Detector::DosUnboundedOperation.get_lint_message() + scout_audit_internal::ink_lint_message::INK_DOS_UNBOUNDED_OPERATION_LINT_MESSAGE } struct ForLoopVisitor { diff --git a/detectors/dos-unexpected-revert-with-vector/src/lib.rs b/detectors/dos-unexpected-revert-with-vector/src/lib.rs index 3c25cff3..743f19e6 100644 --- a/detectors/dos-unexpected-revert-with-vector/src/lib.rs +++ b/detectors/dos-unexpected-revert-with-vector/src/lib.rs @@ -20,7 +20,7 @@ use rustc_middle::mir::{ use rustc_middle::ty::{Ty, TyKind}; use rustc_span::def_id::DefId; use rustc_span::Span; -use scout_audit_internal::Detector; +use scout_audit_internal::{DetectorImpl, InkDetector as Detector}; dylint_linting::impl_late_lint! { /// ### What it does @@ -52,7 +52,7 @@ dylint_linting::impl_late_lint! { /// ``` pub UNEXPECTED_REVERT_WARN, Warn, - Detector::DosUnexpectedRevertWithVector.get_lint_message(), + scout_audit_internal::ink_lint_message::INK_DOS_UNEXPECTED_REVERT_WITH_VECTOR_LINT_MESSAGE, UnexpectedRevertWarn::default() } diff --git a/detectors/ink-version/src/lib.rs b/detectors/ink-version/src/lib.rs index 149d1c2e..ab4209ea 100644 --- a/detectors/ink-version/src/lib.rs +++ b/detectors/ink-version/src/lib.rs @@ -18,7 +18,7 @@ dylint_linting::declare_early_lint! { ///``` pub CHECK_INK_VERSION, Warn, - scout_audit_internal::ink_lint_message::INK_INK_VERSION_LINT_MESSAGE, + scout_audit_internal::ink_lint_message::INK_INK_VERSION_LINT_MESSAGE } impl EarlyLintPass for CheckInkVersion { diff --git a/detectors/insufficiently-random-values/src/lib.rs b/detectors/insufficiently-random-values/src/lib.rs index b719638d..ef4aa220 100644 --- a/detectors/insufficiently-random-values/src/lib.rs +++ b/detectors/insufficiently-random-values/src/lib.rs @@ -5,7 +5,7 @@ extern crate rustc_hir; use if_chain::if_chain; use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; -use scout_audit_internal::Detector; +use scout_audit_internal::{DetectorImpl, InkDetector as Detector}; dylint_linting::declare_late_lint! { /// ### What it does @@ -21,7 +21,7 @@ dylint_linting::declare_late_lint! { /// pub INSUFFICIENTLY_RANDOM_VALUES, Warn, - Detector::InsufficientlyRandomValues.get_lint_message() + scout_audit_internal::ink_lint_message::INK_INSUFFICIENTLY_RANDOM_VALUES_LINT_MESSAGE } impl<'tcx> LateLintPass<'tcx> for InsufficientlyRandomValues { diff --git a/detectors/integer-overflow-or-underflow/src/lib.rs b/detectors/integer-overflow-or-underflow/src/lib.rs index 0803e331..d0fd257b 100644 --- a/detectors/integer-overflow-or-underflow/src/lib.rs +++ b/detectors/integer-overflow-or-underflow/src/lib.rs @@ -9,7 +9,7 @@ use rustc_lint::LateLintPass; use rustc_span::Span; use scout_audit_clippy_utils::consts::constant_simple; use scout_audit_clippy_utils::is_integer_literal; -use scout_audit_internal::Detector; +use scout_audit_internal::{DetectorImpl, InkDetector as Detector}; dylint_linting::impl_late_lint! { /// ### What it does @@ -33,7 +33,7 @@ dylint_linting::impl_late_lint! { /// ``` pub INTEGER_OVERFLOW_UNDERFLOW, Warn, - Detector::IntegerOverflowOrUnderflow.get_lint_message(), + scout_audit_internal::ink_lint_message::INK_INTEGER_OVERFLOW_OR_UNDERFLOW_LINT_MESSAGE, IntegerOverflowUnderflow::default() } diff --git a/detectors/iterators-over-indexing/src/lib.rs b/detectors/iterators-over-indexing/src/lib.rs index 7579e7a9..7dcb8353 100644 --- a/detectors/iterators-over-indexing/src/lib.rs +++ b/detectors/iterators-over-indexing/src/lib.rs @@ -13,12 +13,12 @@ use rustc_hir::{ }; use rustc_lint::LateLintPass; use rustc_span::Span; -use scout_audit_internal::Detector; +use scout_audit_internal::{DetectorImpl, InkDetector as Detector}; dylint_linting::declare_late_lint! { pub ITERATOR_OVER_INDEXING, Warn, - Detector::IteratorsOverIndexing.get_lint_message() + scout_audit_internal::ink_lint_message::INK_ITERATORS_OVER_INDEXING_LINT_MESSAGE } struct ForLoopVisitor { diff --git a/detectors/lazy-delegate/src/lib.rs b/detectors/lazy-delegate/src/lib.rs index 568b3033..b4da279d 100644 --- a/detectors/lazy-delegate/src/lib.rs +++ b/detectors/lazy-delegate/src/lib.rs @@ -12,7 +12,7 @@ use rustc_ast::{ }; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_span::Span; -use scout_audit_internal::Detector; +use scout_audit_internal::{DetectorImpl, InkDetector as Detector}; dylint_linting::impl_pre_expansion_lint! { /// ### What it does @@ -39,7 +39,7 @@ dylint_linting::impl_pre_expansion_lint! { ///``` pub LAZY_DELEGATE, Warn, - Detector::LazyDelegate.get_lint_message(), + scout_audit_internal::ink_lint_message::INK_LAZY_DELEGATE_LINT_MESSAGE, LazyDelegate::default() } diff --git a/detectors/panic-error/src/lib.rs b/detectors/panic-error/src/lib.rs index e6f6b35f..e39be8f6 100644 --- a/detectors/panic-error/src/lib.rs +++ b/detectors/panic-error/src/lib.rs @@ -14,7 +14,7 @@ use rustc_ast::{ use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_span::{sym, Span}; use scout_audit_clippy_utils::sym; -use scout_audit_internal::Detector; +use scout_audit_internal::{DetectorImpl, InkDetector as Detector}; dylint_linting::impl_pre_expansion_lint! { /// ### What it does @@ -48,7 +48,7 @@ dylint_linting::impl_pre_expansion_lint! { /// ``` pub PANIC_ERROR, Warn, - Detector::PanicError.get_lint_message(), + scout_audit_internal::ink_lint_message::INK_PANIC_ERROR_LINT_MESSAGE, PanicError::default() } diff --git a/detectors/reentrancy-1/src/lib.rs b/detectors/reentrancy-1/src/lib.rs index 7a0b68b2..031e76bb 100644 --- a/detectors/reentrancy-1/src/lib.rs +++ b/detectors/reentrancy-1/src/lib.rs @@ -12,7 +12,7 @@ use rustc_hir::{Body, FnDecl, Stmt}; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_span::Span; -use scout_audit_internal::Detector; +use scout_audit_internal::{DetectorImpl, InkDetector as Detector}; dylint_linting::declare_late_lint! { /// ### What it does @@ -78,7 +78,7 @@ dylint_linting::declare_late_lint! { /// ``` pub REENTRANCY_1, Warn, - Detector::Reentrancy1.get_lint_message() + scout_audit_internal::ink_lint_message::INK_REENTRANCY_LINT_MESSAGE } impl<'tcx> LateLintPass<'tcx> for Reentrancy1 { diff --git a/detectors/reentrancy-2/src/lib.rs b/detectors/reentrancy-2/src/lib.rs index f065722e..de9573ac 100644 --- a/detectors/reentrancy-2/src/lib.rs +++ b/detectors/reentrancy-2/src/lib.rs @@ -22,7 +22,7 @@ use rustc_middle::ty::TyKind; use rustc_span::def_id::LocalDefId; use rustc_span::{Span, Symbol}; use rustc_target::abi::VariantIdx; -use scout_audit_internal::Detector; +use scout_audit_internal::{DetectorImpl, InkDetector as Detector}; dylint_linting::declare_late_lint! { /// ### What it does @@ -88,7 +88,7 @@ dylint_linting::declare_late_lint! { /// ``` pub REENTRANCY_2, Warn, - Detector::Reentrancy2.get_lint_message() + scout_audit_internal::ink_lint_message::INK_REENTRANCY_LINT_MESSAGE } const SET_ALLOW_REENTRY: &str = "set_allow_reentry"; diff --git a/detectors/set-code-hash/src/lib.rs b/detectors/set-code-hash/src/lib.rs index 67608745..bf70023b 100644 --- a/detectors/set-code-hash/src/lib.rs +++ b/detectors/set-code-hash/src/lib.rs @@ -20,12 +20,12 @@ use rustc_middle::mir::{ use rustc_middle::ty::TyKind; use rustc_span::def_id::DefId; use rustc_span::Span; -use scout_audit_internal::Detector; +use scout_audit_internal::{DetectorImpl, InkDetector as Detector}; dylint_linting::impl_late_lint! { pub UNPROTECTED_SET_CODE_HASH, Warn, - Detector::SetCodeHash.get_lint_message(), + scout_audit_internal::ink_lint_message::INK_SET_CODE_HASH_LINT_MESSAGE, UnprotectedSetCodeHash::default() } diff --git a/detectors/set-contract-storage/src/lib.rs b/detectors/set-contract-storage/src/lib.rs index 2f01160a..095f6261 100644 --- a/detectors/set-contract-storage/src/lib.rs +++ b/detectors/set-contract-storage/src/lib.rs @@ -13,7 +13,7 @@ use rustc_hir::{Body, FnDecl}; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_span::Span; -use scout_audit_internal::Detector; +use scout_audit_internal::{DetectorImpl, InkDetector as Detector}; dylint_linting::declare_late_lint! { /// ### What it does @@ -53,7 +53,7 @@ dylint_linting::declare_late_lint! { /// ``` pub SET_STORAGE_WARN, Warn, - Detector::SetContractStorage.get_lint_message() + scout_audit_internal::ink_lint_message::INK_SET_CONTRACT_STORAGE_LINT_MESSAGE } fn expr_check_owner(expr: &Expr) -> bool { diff --git a/detectors/unprotected-mapping-operation/src/lib.rs b/detectors/unprotected-mapping-operation/src/lib.rs index 5fdf2ce5..3769f010 100644 --- a/detectors/unprotected-mapping-operation/src/lib.rs +++ b/detectors/unprotected-mapping-operation/src/lib.rs @@ -21,12 +21,12 @@ use rustc_middle::mir::{ use rustc_middle::ty::TyKind; use rustc_span::def_id::DefId; use rustc_span::Span; -use scout_audit_internal::Detector; +use scout_audit_internal::{DetectorImpl, InkDetector as Detector}; dylint_linting::impl_late_lint! { pub UNPROTECTED_MAPPING_OPERATION, Warn, - Detector::UnprotectedMappingOperation.get_lint_message(), + scout_audit_internal::ink_lint_message::INK_UNPROTECTED_MAPPING_OPERATION_LINT_MESSAGE, UnprotectedMappingOperation::default() } diff --git a/detectors/unprotected-self-destruct/src/lib.rs b/detectors/unprotected-self-destruct/src/lib.rs index f9786af4..1b9ac607 100644 --- a/detectors/unprotected-self-destruct/src/lib.rs +++ b/detectors/unprotected-self-destruct/src/lib.rs @@ -18,12 +18,12 @@ use rustc_middle::mir::{ use rustc_middle::ty::TyKind; use rustc_span::def_id::DefId; use rustc_span::Span; -use scout_audit_internal::Detector; +use scout_audit_internal::{DetectorImpl, InkDetector as Detector}; dylint_linting::impl_late_lint! { pub UNPROTECTED_SELF_DESTRUCT, Warn, - Detector::UnprotectedSelfDestruct.get_lint_message(), + scout_audit_internal::ink_lint_message::INK_UNPROTECTED_SELF_DESTRUCT_LINT_MESSAGE, UnprotectedSelfDestruct::default() } diff --git a/detectors/unrestricted-transfer-from/src/lib.rs b/detectors/unrestricted-transfer-from/src/lib.rs index 7fdab3e9..a82c617f 100644 --- a/detectors/unrestricted-transfer-from/src/lib.rs +++ b/detectors/unrestricted-transfer-from/src/lib.rs @@ -17,12 +17,12 @@ use rustc_hir::{PatKind, QPath}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::mir::{BasicBlock, BasicBlocks, Local, Operand, StatementKind, TerminatorKind}; use rustc_span::Span; -use scout_audit_internal::Detector; +use scout_audit_internal::{DetectorImpl, InkDetector as Detector}; dylint_linting::impl_late_lint! { pub UNRESTRICTED_TRANSFER_FROM, Warn, - Detector::UnrestrictedTransferFrom.get_lint_message(), + scout_audit_internal::ink_lint_message::INK_UNRESTRICTED_TRANSFER_FROM_LINT_MESSAGE, UnrestrictedTransferFrom::default() } diff --git a/detectors/unsafe-expect/src/lib.rs b/detectors/unsafe-expect/src/lib.rs index 9b20182e..378ac212 100644 --- a/detectors/unsafe-expect/src/lib.rs +++ b/detectors/unsafe-expect/src/lib.rs @@ -10,7 +10,7 @@ use rustc_hir::{ }; use rustc_lint::LateLintPass; use rustc_span::{Span, Symbol}; -use scout_audit_internal::Detector; +use scout_audit_internal::{DetectorImpl, InkDetector as Detector}; dylint_linting::declare_late_lint! { /// ### What it does @@ -45,7 +45,7 @@ dylint_linting::declare_late_lint! { /// ``` pub UNSAFE_EXPECT, Warn, - Detector::UnsafeExpect.get_lint_message() + scout_audit_internal::ink_lint_message::INK_UNSAFE_EXPECT_LINT_MESSAGE } impl<'tcx> LateLintPass<'tcx> for UnsafeExpect { diff --git a/detectors/unsafe-unwrap/src/lib.rs b/detectors/unsafe-unwrap/src/lib.rs index 08849cc8..78ea5506 100644 --- a/detectors/unsafe-unwrap/src/lib.rs +++ b/detectors/unsafe-unwrap/src/lib.rs @@ -10,7 +10,7 @@ use rustc_hir::{ }; use rustc_lint::LateLintPass; use rustc_span::{Span, Symbol}; -use scout_audit_internal::Detector; +use scout_audit_internal::{DetectorImpl, InkDetector as Detector}; dylint_linting::declare_late_lint! { /// ### What it does @@ -45,7 +45,7 @@ dylint_linting::declare_late_lint! { /// ``` pub UNSAFE_UNWRAP, Warn, - Detector::UnsafeUnwrap.get_lint_message() + scout_audit_internal::ink_lint_message::INK_UNSAFE_UNWRAP_LINT_MESSAGE } impl<'tcx> LateLintPass<'tcx> for UnsafeUnwrap { diff --git a/detectors/unused-return-enum/src/lib.rs b/detectors/unused-return-enum/src/lib.rs index 8fecfea2..f6dcc383 100644 --- a/detectors/unused-return-enum/src/lib.rs +++ b/detectors/unused-return-enum/src/lib.rs @@ -10,7 +10,7 @@ use rustc_hir::intravisit::{walk_expr, FnKind, Visitor}; use rustc_hir::{Expr, ExprKind, QPath, TyKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_span::Span; -use scout_audit_internal::Detector; +use scout_audit_internal::{DetectorImpl, InkDetector as Detector}; dylint_linting::declare_late_lint! { /// ### What it does @@ -63,7 +63,7 @@ dylint_linting::declare_late_lint! { /// ``` pub UNUSED_RETURN_ENUM, Warn, - Detector::UnusedReturnEnum.get_lint_message() + scout_audit_internal::ink_lint_message::INK_UNUSED_RETURN_ENUM_LINT_MESSAGE } struct CounterVisitor { diff --git a/detectors/zero-or-test-address/src/lib.rs b/detectors/zero-or-test-address/src/lib.rs index 4532ddf9..8076c120 100644 --- a/detectors/zero-or-test-address/src/lib.rs +++ b/detectors/zero-or-test-address/src/lib.rs @@ -19,7 +19,7 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::LocalDefId; use rustc_span::Span; -use scout_audit_internal::Detector; +use scout_audit_internal::{DetectorImpl, InkDetector as Detector}; dylint_linting::declare_late_lint! { /// ### What it does @@ -51,7 +51,7 @@ dylint_linting::declare_late_lint! { /// ``` pub ZERO_OR_TEST_ADDRESS, Warn, - Detector::ZeroOrTestAddress.get_lint_message() + scout_audit_internal::ink_lint_message::INK_ZERO_OR_TEST_ADDRESS_LINT_MESSAGE } impl<'tcx> LateLintPass<'tcx> for ZeroOrTestAddress { diff --git a/scout-audit-internal/src/detector.rs b/scout-audit-internal/src/detector.rs index dfe57f90..e94aabf5 100644 --- a/scout-audit-internal/src/detector.rs +++ b/scout-audit-internal/src/detector.rs @@ -8,8 +8,10 @@ extern crate rustc_lint; extern crate rustc_span; pub mod ink_lint_message; +pub mod ink_vulnerability_info; pub mod soroban_lint_message; +use std::borrow::Cow; #[cfg(feature = "lint_helper")] use std::net::{IpAddr, Ipv4Addr}; @@ -25,10 +27,14 @@ use scout_audit_clippy_utils::diagnostics::{ #[cfg(feature = "lint_helper")] use serde_json::json; use soroban_lint_message::*; +#[cfg(feature = "lint_helper")] +use soroban_lint_message::*; use strum::{Display, EnumIter}; #[cfg(feature = "lint_helper")] use tarpc::{client, context, tokio_serde::formats::Json}; +#[cfg(feature = "lint_helper")] +use crate::ink_vulnerability_info::*; #[cfg(feature = "lint_helper")] use crate::DetectorSocketClient; @@ -89,6 +95,40 @@ pub enum InkDetector { ZeroOrTestAddress, } +//#[cfg(feature = "lint_helper")] +#[derive(Debug, Clone)] +pub struct DetectorRawInfo { + pub vuln_name: &'static str, + pub severity: &'static str, + pub vuln_category: &'static str, + pub vuln_short_msg: &'static str, + pub vuln_long_msg: &'static str, +} +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct DetectorInfo { + pub vuln_name: String, + pub severity: String, + pub vuln_category: String, + pub vuln_short_msg: String, + pub vuln_long_msg: String, + pub span: String, + pub help: Option, +} + +impl DetectorInfo { + fn from_raw(raw_info: DetectorRawInfo, span: String, help: Option<&str>) -> Self { + Self { + vuln_name: raw_info.vuln_name.to_string(), + severity: raw_info.severity.to_string(), + vuln_category: raw_info.vuln_category.to_string(), + vuln_short_msg: raw_info.vuln_short_msg.to_string(), + vuln_long_msg: raw_info.vuln_long_msg.to_string(), + span, + help: help.map(|s| s.to_string()), + } + } +} + /* This trait should be implemented by every enum of detectors (for each blockchain) We cannot use this trait because it's not possible to make CONST functions in traits! @@ -97,6 +137,9 @@ If in the future this is possible, we can use this trait to enforce the implemen pub trait DetectorImpl: std::fmt::Display { fn get_lint_message(&self) -> &'static str; + #[cfg(feature = "lint_helper")] + fn get_detector_info(&self) -> DetectorRawInfo; + #[cfg(feature = "lint_helper")] fn span_lint_and_help( &self, @@ -131,6 +174,10 @@ impl DetectorImpl for SorobanDetector { SorobanDetector::SorobanVersion => SOROBAN_SOROBAN_VERSION_LINT_MESSAGE, } } + #[cfg(feature = "lint_helper")] + fn get_detector_info(&self) -> DetectorRawInfo { + todo!() + } #[cfg(feature = "lint_helper")] fn span_lint_and_help( @@ -140,15 +187,15 @@ impl DetectorImpl for SorobanDetector { span: Span, help: &str, ) { - send_to_server(); - print_scout_output(*lint, span); + send_to_server(span.clone(), Some(help), self.get_detector_info()); + //print_scout_output(*lint, span); span_lint_and_help_clippy(cx, lint, span, self.get_lint_message(), None, help); } #[cfg(feature = "lint_helper")] fn span_lint(&self, cx: &T, lint: &'static Lint, span: Span) { - send_to_server(); - print_scout_output(*lint, span); + send_to_server(span.clone(), None, self.get_detector_info()); + //print_scout_output(*lint, span); span_lint_clippy(cx, lint, span, self.get_lint_message()); } } @@ -192,6 +239,38 @@ impl DetectorImpl for InkDetector { } } + #[cfg(feature = "lint_helper")] + fn get_detector_info(&self) -> DetectorRawInfo { + match self { + InkDetector::AssertViolation => INK_ASSERT_VIOLATION_LINT_INFO, + InkDetector::AvoidCoreMemForget => INK_AVOID_CORE_MEM_FORGET_LINT_INFO, + InkDetector::AvoidFormatString => INK_AVOID_FORMAT_STRING_LINT_INFO, + InkDetector::DelegateCall => INK_DELEGATE_CALL_LINT_INFO, + InkDetector::DivideBeforeMultiply => INK_DIVIDE_BEFORE_MULTIPLY_LINT_INFO, + InkDetector::DosUnboundedOperation => INK_DOS_UNBOUNDED_OPERATION_LINT_INFO, + InkDetector::DosUnexpectedRevertWithVector => { + INK_DOS_UNEXPECTED_REVERT_WITH_VECTOR_LINT_INFO + } + InkDetector::InkVersion => INK_INK_VERSION_LINT_INFO, + InkDetector::InsufficientlyRandomValues => INK_INSUFFICIENTLY_RANDOM_VALUES_LINT_INFO, + InkDetector::IntegerOverflowOrUnderflow => INK_INTEGER_OVERFLOW_OR_UNDERFLOW_LINT_INFO, + InkDetector::IteratorsOverIndexing => INK_ITERATORS_OVER_INDEXING_LINT_INFO, + InkDetector::LazyDelegate => INK_LAZY_DELEGATE_LINT_INFO, + InkDetector::PanicError => INK_PANIC_ERROR_LINT_INFO, + InkDetector::Reentrancy1 => INK_REENTRANCY_LINT_INFO, + InkDetector::Reentrancy2 => INK_REENTRANCY_LINT_INFO, + InkDetector::SetCodeHash => INK_SET_CODE_HASH_LINT_INFO, + InkDetector::SetContractStorage => INK_SET_CONTRACT_STORAGE_LINT_INFO, + InkDetector::UnprotectedMappingOperation => INK_UNPROTECTED_MAPPING_OPERATION_LINT_INFO, + InkDetector::UnprotectedSelfDestruct => INK_UNPROTECTED_SELF_DESTRUCT_LINT_INFO, + InkDetector::UnrestrictedTransferFrom => INK_UNRESTRICTED_TRANSFER_FROM_LINT_INFO, + InkDetector::UnsafeExpect => INK_UNSAFE_EXPECT_LINT_INFO, + InkDetector::UnsafeUnwrap => INK_UNSAFE_UNWRAP_LINT_INFO, + InkDetector::UnusedReturnEnum => INK_UNUSED_RETURN_ENUM_LINT_INFO, + InkDetector::ZeroOrTestAddress => INK_ZERO_OR_TEST_ADDRESS_LINT_INFO, + } + } + #[cfg(feature = "lint_helper")] fn span_lint_and_help( &self, @@ -200,24 +279,28 @@ impl DetectorImpl for InkDetector { span: Span, help: &str, ) { - send_to_server(); - print_scout_output(*lint, span); + send_to_server(span.clone(), Some(help), self.get_detector_info()); + //print_scout_output(*lint, span); span_lint_and_help_clippy(cx, lint, span, self.get_lint_message(), None, help); } #[cfg(feature = "lint_helper")] fn span_lint(&self, cx: &T, lint: &'static Lint, span: Span) { - send_to_server(); - print_scout_output(*lint, span); + send_to_server(span.clone(), None, self.get_detector_info()); + //print_scout_output(*lint, span); span_lint_clippy(cx, lint, span, self.get_lint_message()); } } - - #[cfg(feature = "lint_helper")] #[tokio::main] -async fn send_to_server() -> anyhow::Result<()> { +async fn send_to_server( + span: Span, + help: Option<&str>, + detector: DetectorRawInfo, +) -> anyhow::Result<()> { + use std::fmt::format; + use crate::DetectorSocketClient; let server_addr = (IpAddr::V4(Ipv4Addr::LOCALHOST), 1177); @@ -227,12 +310,16 @@ async fn send_to_server() -> anyhow::Result<()> { let client = DetectorSocketClient::new(client::Config::default(), transport.await.unwrap()).spawn(); client - .push_finding(context::current(), format!("{}1", "juan")) + .push_finding( + context::current(), + DetectorInfo::from_raw(detector, format!("{:?}", span), help), + ) .await .unwrap(); Ok(()) } +/* #[cfg(feature = "lint_helper")] fn print_scout_output(lint: Lint, span: Span) { @@ -241,7 +328,7 @@ fn print_scout_output(lint: Lint, span: Span) { .map(|s| s.trim().to_string()) .collect(); - let no_span_detectors = ["OVERFLOW_CHECK"]; + let no_span_detectors = ["OVERFLOW_CHECK", "INK_VERSION", "SOROBAN_VERSION"]; if no_span_detectors.contains(&lint.name.to_owned().as_str()) { let span = json!({ @@ -268,11 +355,13 @@ fn print_scout_output(lint: Lint, span: Span) { "uri": span_debug_string[0], }, "region": { - "startLine": span_debug_string[1].parse::().unwrap(), - "startColumn": span_debug_string[2].parse::().unwrap(), - "endLine": span_debug_string[3].parse::().unwrap(), - "endColumn": span_debug_string[4].split(' ').collect::>()[0].trim().parse::().unwrap(), } - } + "startLine": 0, + "startColumn": 0, + "endLine": 0, + "endColumn": 0, } + } }); println!("scout-internal:{}@{}", lint.name, span); } + +*/ \ No newline at end of file diff --git a/scout-audit-internal/src/detector/ink_vulnerability_info.rs b/scout-audit-internal/src/detector/ink_vulnerability_info.rs new file mode 100644 index 00000000..ba66d8b5 --- /dev/null +++ b/scout-audit-internal/src/detector/ink_vulnerability_info.rs @@ -0,0 +1,186 @@ +#[cfg(feature = "lint_helper")] +use crate::detector::DetectorRawInfo; +#[cfg(feature = "lint_helper")] +pub const INK_ASSERT_VIOLATION_LINT_INFO: DetectorRawInfo = DetectorRawInfo { + vuln_name: "", + severity: "", + vuln_category: "", + vuln_long_msg: "", + vuln_short_msg: "", +}; +#[cfg(feature = "lint_helper")] +pub const INK_AVOID_CORE_MEM_FORGET_LINT_INFO: DetectorRawInfo = DetectorRawInfo { + vuln_name: "", + severity: "", + vuln_category: "", + vuln_long_msg: "", + vuln_short_msg: "", +}; +#[cfg(feature = "lint_helper")] +pub const INK_AVOID_FORMAT_STRING_LINT_INFO: DetectorRawInfo = DetectorRawInfo { + vuln_name: "", + severity: "", + vuln_category: "", + vuln_long_msg: "", + vuln_short_msg: "", +}; +#[cfg(feature = "lint_helper")] +pub const INK_DELEGATE_CALL_LINT_INFO: DetectorRawInfo = DetectorRawInfo { + vuln_name: "", + severity: "", + vuln_category: "", + vuln_long_msg: "", + vuln_short_msg: "", +}; +#[cfg(feature = "lint_helper")] +pub const INK_DIVIDE_BEFORE_MULTIPLY_LINT_INFO: DetectorRawInfo = DetectorRawInfo { + vuln_name: "", + severity: "", + vuln_category: "", + vuln_long_msg: "", + vuln_short_msg: "", +}; +#[cfg(feature = "lint_helper")] +pub const INK_DOS_UNBOUNDED_OPERATION_LINT_INFO: DetectorRawInfo = DetectorRawInfo { + vuln_name: "", + severity: "", + vuln_category: "", + vuln_long_msg: "", + vuln_short_msg: "", +}; +#[cfg(feature = "lint_helper")] +pub const INK_DOS_UNEXPECTED_REVERT_WITH_VECTOR_LINT_INFO: DetectorRawInfo = DetectorRawInfo { + vuln_name: "", + severity: "", + vuln_category: "", + vuln_long_msg: "", + vuln_short_msg: "", +}; +#[cfg(feature = "lint_helper")] +pub const INK_INK_VERSION_LINT_INFO: DetectorRawInfo = DetectorRawInfo { + vuln_name: "", + severity: "", + vuln_category: "", + vuln_long_msg: "", + vuln_short_msg: "", +}; +#[cfg(feature = "lint_helper")] +pub const INK_INSUFFICIENTLY_RANDOM_VALUES_LINT_INFO: DetectorRawInfo = DetectorRawInfo { + vuln_name: "", + severity: "", + vuln_category: "", + vuln_long_msg: "", + vuln_short_msg: "", +}; +#[cfg(feature = "lint_helper")] +pub const INK_INTEGER_OVERFLOW_OR_UNDERFLOW_LINT_INFO: DetectorRawInfo = DetectorRawInfo { + vuln_name: "", + severity: "", + vuln_category: "", + vuln_long_msg: "", + vuln_short_msg: "", +}; +#[cfg(feature = "lint_helper")] +pub const INK_ITERATORS_OVER_INDEXING_LINT_INFO: DetectorRawInfo = DetectorRawInfo { + vuln_name: "", + severity: "", + vuln_category: "", + vuln_long_msg: "", + vuln_short_msg: "", +}; +#[cfg(feature = "lint_helper")] +pub const INK_LAZY_DELEGATE_LINT_INFO: DetectorRawInfo = DetectorRawInfo { + vuln_name: "", + severity: "", + vuln_category: "", + vuln_long_msg: "", + vuln_short_msg: "", +}; +#[cfg(feature = "lint_helper")] +pub const INK_PANIC_ERROR_LINT_INFO: DetectorRawInfo = DetectorRawInfo { + vuln_name: "", + severity: "", + vuln_category: "", + vuln_long_msg: "", + vuln_short_msg: "", +}; +#[cfg(feature = "lint_helper")] +pub const INK_REENTRANCY_LINT_INFO: DetectorRawInfo = DetectorRawInfo { + vuln_name: "", + severity: "", + vuln_category: "", + vuln_long_msg: "", + vuln_short_msg: "", +}; +#[cfg(feature = "lint_helper")] +pub const INK_SET_CODE_HASH_LINT_INFO: DetectorRawInfo = DetectorRawInfo { + vuln_name: "", + severity: "", + vuln_category: "", + vuln_long_msg: "", + vuln_short_msg: "", +}; +#[cfg(feature = "lint_helper")] +pub const INK_SET_CONTRACT_STORAGE_LINT_INFO: DetectorRawInfo = DetectorRawInfo { + vuln_name: "", + severity: "", + vuln_category: "", + vuln_long_msg: "", + vuln_short_msg: "", +}; +#[cfg(feature = "lint_helper")] +pub const INK_UNPROTECTED_MAPPING_OPERATION_LINT_INFO: DetectorRawInfo = DetectorRawInfo { + vuln_name: "", + severity: "", + vuln_category: "", + vuln_long_msg: "", + vuln_short_msg: "", +}; +#[cfg(feature = "lint_helper")] +pub const INK_UNPROTECTED_SELF_DESTRUCT_LINT_INFO: DetectorRawInfo = DetectorRawInfo { + vuln_name: "", + severity: "", + vuln_category: "", + vuln_long_msg: "", + vuln_short_msg: "", +}; +#[cfg(feature = "lint_helper")] +pub const INK_UNRESTRICTED_TRANSFER_FROM_LINT_INFO: DetectorRawInfo = DetectorRawInfo { + vuln_name: "", + severity: "", + vuln_category: "", + vuln_long_msg: "", + vuln_short_msg: "", +}; +#[cfg(feature = "lint_helper")] +pub const INK_UNSAFE_EXPECT_LINT_INFO: DetectorRawInfo = DetectorRawInfo { + vuln_name: "", + severity: "", + vuln_category: "", + vuln_long_msg: "", + vuln_short_msg: "", +}; +#[cfg(feature = "lint_helper")] +pub const INK_UNSAFE_UNWRAP_LINT_INFO: DetectorRawInfo = DetectorRawInfo { + vuln_name: "", + severity: "", + vuln_category: "", + vuln_long_msg: "", + vuln_short_msg: "", +}; +#[cfg(feature = "lint_helper")] +pub const INK_UNUSED_RETURN_ENUM_LINT_INFO: DetectorRawInfo = DetectorRawInfo { + vuln_name: "", + severity: "", + vuln_category: "", + vuln_long_msg: "", + vuln_short_msg: "", +}; +#[cfg(feature = "lint_helper")] +pub const INK_ZERO_OR_TEST_ADDRESS_LINT_INFO: DetectorRawInfo = DetectorRawInfo { + vuln_name: "", + severity: "", + vuln_category: "", + vuln_long_msg: "", + vuln_short_msg: "", +}; diff --git a/scout-audit-internal/src/socket.rs b/scout-audit-internal/src/socket.rs index a2a80033..2ffb6239 100644 --- a/scout-audit-internal/src/socket.rs +++ b/scout-audit-internal/src/socket.rs @@ -1,14 +1,13 @@ use std::net::{IpAddr, SocketAddr}; +use std::sync::{Arc, Mutex}; use futures::{future, prelude::*}; - -use std::sync::{Arc, Mutex}; +use serde::{Deserialize, Serialize}; use tarpc::{ context, server::{self, incoming::Incoming, Channel}, tokio_serde::formats::Json, }; -use serde::{Deserialize, Serialize}; use crate::detector::*; #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] @@ -23,15 +22,15 @@ pub trait DetectorSocket { async fn is_up() -> bool; async fn set_available_detectors(detectors: Vec); async fn is_detector_available(detector: Detector) -> bool; - async fn push_finding(finding: String); - async fn get_findings() -> Vec; + async fn push_finding(finding: DetectorInfo); + async fn get_findings() -> Vec; } #[derive(Clone)] struct Server { socket_addr: SocketAddr, available_detectors: Vec, - findings: Arc>>, + findings: Arc>>, } impl DetectorSocket for Server { @@ -49,12 +48,12 @@ impl DetectorSocket for Server { self.available_detectors.contains(&detector) } - async fn push_finding(self, _: context::Context, finding: String) { - println!("Finding: {} was added", finding); + async fn push_finding(self, _: context::Context, finding: DetectorInfo) { + println!("Finding: {:?} was added", finding); self.findings.lock().unwrap().push(finding); } - async fn get_findings(self, _: context::Context) -> Vec { + async fn get_findings(self, _: context::Context) -> Vec { self.findings.lock().unwrap().clone() } } @@ -65,7 +64,7 @@ async fn spawn(fut: impl Future + Send + 'static) { pub async fn detector_server( server_addr: (IpAddr, u16), - findings: Arc>>, + findings: Arc>>, ) -> anyhow::Result<()> { let listener = tarpc::serde_transport::tcp::listen(&server_addr, Json::default).await?; listener @@ -73,10 +72,10 @@ pub async fn detector_server( .map(server::BaseChannel::with_defaults) .max_channels_per_key(100, |t| t.transport().peer_addr().unwrap().ip()) .map(|channel| { - println!( + /*println!( "Incoming connection from: {}", channel.transport().peer_addr().unwrap() - ); + );*/ let server = Server { socket_addr: channel.transport().peer_addr().unwrap(), available_detectors: vec![], From 70486ad949803bca78643e37552d0f9cd5415c76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Losiggio?= Date: Wed, 13 Mar 2024 13:52:34 -0300 Subject: [PATCH 08/13] scout-audit-clippy-utils and scout-audit-clippy-utils moved and imported from scout-audit repo (WIP path imports) --- apps/cargo-scout-audit/Cargo.lock | 1733 +++------ apps/cargo-scout-audit/src/scout_config.rs | 56 + detectors/Cargo.toml | 6 +- scout-audit-clippy-utils/Cargo.lock | 46 - scout-audit-clippy-utils/Cargo.toml | 22 - scout-audit-clippy-utils/README.md | 9 - scout-audit-clippy-utils/rust-toolchain | 3 - scout-audit-clippy-utils/src/ast_utils.rs | 799 ---- .../src/ast_utils/ident_iter.rs | 45 - scout-audit-clippy-utils/src/attrs.rs | 158 - .../src/check_proc_macro.rs | 438 --- scout-audit-clippy-utils/src/comparisons.rs | 36 - scout-audit-clippy-utils/src/consts.rs | 808 ---- scout-audit-clippy-utils/src/diagnostics.rs | 244 -- scout-audit-clippy-utils/src/eager_or_lazy.rs | 324 -- scout-audit-clippy-utils/src/higher.rs | 466 --- scout-audit-clippy-utils/src/hir_utils.rs | 1204 ------ scout-audit-clippy-utils/src/lib.rs | 3258 ----------------- scout-audit-clippy-utils/src/macros.rs | 548 --- scout-audit-clippy-utils/src/mir/mod.rs | 201 - .../src/mir/possible_borrower.rs | 243 -- .../src/mir/possible_origin.rs | 59 - .../src/mir/transitive_relation.rs | 29 - .../src/numeric_literal.rs | 247 -- scout-audit-clippy-utils/src/paths.rs | 110 - scout-audit-clippy-utils/src/ptr.rs | 52 - .../src/qualify_min_const_fn.rs | 429 --- scout-audit-clippy-utils/src/source.rs | 598 --- scout-audit-clippy-utils/src/str_utils.rs | 378 -- scout-audit-clippy-utils/src/sugg.rs | 1111 ------ scout-audit-clippy-utils/src/sym_helper.rs | 7 - scout-audit-clippy-utils/src/ty.rs | 1318 ------- .../src/ty/type_certainty/certainty.rs | 122 - .../src/ty/type_certainty/mod.rs | 322 -- scout-audit-clippy-utils/src/usage.rs | 210 -- scout-audit-clippy-utils/src/visitors.rs | 794 ---- scout-audit-internal/Cargo.toml | 38 - scout-audit-internal/rust-toolchain | 3 - scout-audit-internal/src/detector.rs | 367 -- .../src/detector/ink_lint_message.rs | 33 - .../src/detector/ink_vulnerability_info.rs | 186 - .../src/detector/soroban_lint_message.rs | 19 - scout-audit-internal/src/lib.rs | 23 - scout-audit-internal/src/socket.rs | 93 - 44 files changed, 601 insertions(+), 16594 deletions(-) create mode 100644 apps/cargo-scout-audit/src/scout_config.rs delete mode 100644 scout-audit-clippy-utils/Cargo.lock delete mode 100644 scout-audit-clippy-utils/Cargo.toml delete mode 100644 scout-audit-clippy-utils/README.md delete mode 100644 scout-audit-clippy-utils/rust-toolchain delete mode 100644 scout-audit-clippy-utils/src/ast_utils.rs delete mode 100644 scout-audit-clippy-utils/src/ast_utils/ident_iter.rs delete mode 100644 scout-audit-clippy-utils/src/attrs.rs delete mode 100644 scout-audit-clippy-utils/src/check_proc_macro.rs delete mode 100644 scout-audit-clippy-utils/src/comparisons.rs delete mode 100644 scout-audit-clippy-utils/src/consts.rs delete mode 100644 scout-audit-clippy-utils/src/diagnostics.rs delete mode 100644 scout-audit-clippy-utils/src/eager_or_lazy.rs delete mode 100644 scout-audit-clippy-utils/src/higher.rs delete mode 100644 scout-audit-clippy-utils/src/hir_utils.rs delete mode 100644 scout-audit-clippy-utils/src/lib.rs delete mode 100644 scout-audit-clippy-utils/src/macros.rs delete mode 100644 scout-audit-clippy-utils/src/mir/mod.rs delete mode 100644 scout-audit-clippy-utils/src/mir/possible_borrower.rs delete mode 100644 scout-audit-clippy-utils/src/mir/possible_origin.rs delete mode 100644 scout-audit-clippy-utils/src/mir/transitive_relation.rs delete mode 100644 scout-audit-clippy-utils/src/numeric_literal.rs delete mode 100644 scout-audit-clippy-utils/src/paths.rs delete mode 100644 scout-audit-clippy-utils/src/ptr.rs delete mode 100644 scout-audit-clippy-utils/src/qualify_min_const_fn.rs delete mode 100644 scout-audit-clippy-utils/src/source.rs delete mode 100644 scout-audit-clippy-utils/src/str_utils.rs delete mode 100644 scout-audit-clippy-utils/src/sugg.rs delete mode 100644 scout-audit-clippy-utils/src/sym_helper.rs delete mode 100644 scout-audit-clippy-utils/src/ty.rs delete mode 100644 scout-audit-clippy-utils/src/ty/type_certainty/certainty.rs delete mode 100644 scout-audit-clippy-utils/src/ty/type_certainty/mod.rs delete mode 100644 scout-audit-clippy-utils/src/usage.rs delete mode 100644 scout-audit-clippy-utils/src/visitors.rs delete mode 100644 scout-audit-internal/Cargo.toml delete mode 100644 scout-audit-internal/rust-toolchain delete mode 100644 scout-audit-internal/src/detector.rs delete mode 100644 scout-audit-internal/src/detector/ink_lint_message.rs delete mode 100644 scout-audit-internal/src/detector/ink_vulnerability_info.rs delete mode 100644 scout-audit-internal/src/detector/soroban_lint_message.rs delete mode 100644 scout-audit-internal/src/lib.rs delete mode 100644 scout-audit-internal/src/socket.rs diff --git a/apps/cargo-scout-audit/Cargo.lock b/apps/cargo-scout-audit/Cargo.lock index 67a58f37..8ee71f41 100644 --- a/apps/cargo-scout-audit/Cargo.lock +++ b/apps/cargo-scout-audit/Cargo.lock @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.8" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ "getrandom", "once_cell", @@ -30,22 +30,21 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.11" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ "cfg-if", "getrandom", "once_cell", "version_check", - "zerocopy", ] [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" dependencies = [ "memchr", ] @@ -61,9 +60,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.13" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" dependencies = [ "anstyle", "anstyle-parse", @@ -75,49 +74,49 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.48.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.48.0", ] [[package]] name = "anyhow" -version = "1.0.80" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "arc-swap" -version = "1.7.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b3d0060af21e8d11a926981cc00c6c1541aa91dd64b9f881985c3da1094425f" +checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" [[package]] name = "arrayvec" @@ -127,9 +126,9 @@ checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", @@ -171,9 +170,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.7" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53" [[package]] name = "base64ct" @@ -198,9 +197,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" [[package]] name = "bitmaps" @@ -222,9 +221,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.9.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" +checksum = "4c2f7349907b712260e64b0afe2f84692af14a454be26187d9df565c7f69266a" dependencies = [ "memchr", "regex-automata", @@ -242,9 +241,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.15.4" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" [[package]] name = "bytes" @@ -274,7 +273,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "171aca76a3199e771ea0b94ec260984ed9cba62af8e478142974dbaa594d583b" dependencies = [ "anyhow", - "base64 0.21.7", + "base64 0.21.3", "bytesize", "cargo-platform", "cargo-util", @@ -288,8 +287,8 @@ dependencies = [ "fwdansi", "git2", "git2-curl", - "gix 0.44.1", - "gix-features 0.29.0", + "gix", + "gix-features", "glob", "hex", "hmac", @@ -326,76 +325,8 @@ dependencies = [ "tempfile", "termcolor", "time", - "toml 0.7.8", - "toml_edit 0.19.15", - "unicode-width", - "unicode-xid", - "url", - "walkdir", - "windows-sys 0.48.0", -] - -[[package]] -name = "cargo" -version = "0.73.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a6fe1f5394d14b81d2f3f605832a3ce35ed0bf120bc7ef437ce27fd4929c6a" -dependencies = [ - "anyhow", - "base64 0.21.7", - "bytesize", - "cargo-platform", - "cargo-util", - "clap", - "crates-io", - "curl", - "curl-sys", - "env_logger", - "filetime", - "flate2", - "fwdansi", - "git2", - "git2-curl", - "gix 0.45.1", - "gix-features 0.30.0", - "glob", - "hex", - "hmac", - "home", - "http-auth", - "humantime", - "ignore", - "im-rc", - "indexmap 1.9.3", - "itertools 0.10.5", - "jobserver", - "lazycell", - "libc", - "libgit2-sys", - "log", - "memchr", - "opener", - "os_info", - "pasetors", - "pathdiff", - "pulldown-cmark", - "rand", - "rustfix", - "semver", - "serde", - "serde-value", - "serde_ignored", - "serde_json", - "sha1", - "shell-escape", - "strip-ansi-escapes", - "syn 2.0.52", - "tar", - "tempfile", - "termcolor", - "time", - "toml 0.7.8", - "toml_edit 0.19.15", + "toml 0.7.7", + "toml_edit", "unicode-width", "unicode-xid", "url", @@ -405,9 +336,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.7" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "694c8807f2ae16faecc43dc17d74b3eb042482789fd0eb64b39a2e04e087053f" +checksum = "2cfa25e60aea747ec7e1124f238816749faa93759c6ff5b31f1ccdda137f4479" dependencies = [ "serde", ] @@ -418,8 +349,8 @@ version = "0.2.2" dependencies = [ "ansi_term", "anyhow", - "cargo 0.72.2", - "cargo_metadata 0.17.0", + "cargo", + "cargo_metadata", "clap", "colored", "config", @@ -441,25 +372,24 @@ dependencies = [ [[package]] name = "cargo-util" -version = "0.2.9" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74862c3c6e53a1c1f8f0178f9d38ab41e49746cd3a7cafc239b3d0248fd4e342" +checksum = "dd54c8b94a0c851d687924460637361c355afafa72d973fe8644499fbdee8fae" dependencies = [ "anyhow", "core-foundation", "filetime", "hex", - "ignore", "jobserver", "libc", + "log", "miow", "same-file", "sha2", "shell-escape", "tempfile", - "tracing", "walkdir", - "windows-sys 0.52.0", + "windows-sys 0.48.0", ] [[package]] @@ -476,25 +406,11 @@ dependencies = [ "thiserror", ] -[[package]] -name = "cargo_metadata" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" -dependencies = [ - "camino", - "cargo-platform", - "semver", - "serde", - "serde_json", - "thiserror", -] - [[package]] name = "cc" -version = "1.0.90" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "jobserver", "libc", @@ -508,9 +424,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.2" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b230ab84b0ffdf890d5a10abdbc8b83ae1c4918275daea1ab8801f71536b2651" +checksum = "6a13b88d2c62ff462f88e4a121f17a82c1af05693a2f192b5c38d14de73c19f6" dependencies = [ "clap_builder", "clap_derive", @@ -518,9 +434,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08" dependencies = [ "anstream", "anstyle", @@ -531,9 +447,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.0" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" +checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" dependencies = [ "heck", "proc-macro2", @@ -543,9 +459,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" [[package]] name = "clru" @@ -561,19 +477,20 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "colored" -version = "2.1.0" +version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" dependencies = [ + "is-terminal", "lazy_static", "windows-sys 0.48.0", ] [[package]] name = "config" -version = "0.13.4" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23738e11972c7643e4ec947840fc463b6a571afcd3e735bdfce7d03c7a784aca" +checksum = "d379af7f68bfc21714c6c7dea883544201741d2ce8274bb12fa54f89507f52a7" dependencies = [ "async-trait", "json5", @@ -590,15 +507,15 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.6" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "core-foundation" -version = "0.9.4" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" dependencies = [ "core-foundation-sys", "libc", @@ -606,15 +523,15 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] @@ -635,52 +552,37 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.4.0" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.5" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" dependencies = [ - "crossbeam-epoch", + "cfg-if", "crossbeam-utils", ] [[package]] -name = "crossbeam-epoch" -version = "0.9.18" +name = "crossbeam-utils" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" dependencies = [ - "crossbeam-utils", + "cfg-if", ] -[[package]] -name = "crossbeam-utils" -version = "0.8.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" - [[package]] name = "crypto-bigint" -version = "0.5.5" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" dependencies = [ "generic-array", "rand_core", @@ -706,24 +608,24 @@ checksum = "f3b7eb4404b8195a9abb6356f4ac07d8ba267045c8d6d220ac4dc992e6cc75df" [[package]] name = "curl" -version = "0.4.46" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e2161dd6eba090ff1594084e95fd67aeccf04382ffea77999ea94ed42ec67b6" +checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22" dependencies = [ "curl-sys", "libc", "openssl-probe", "openssl-sys", "schannel", - "socket2", - "windows-sys 0.52.0", + "socket2 0.4.9", + "winapi", ] [[package]] name = "curl-sys" -version = "0.4.72+curl-8.6.0" +version = "0.4.65+curl-8.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29cbdc8314c447d11e8fd156dcdd031d9e02a7a976163e396b548c03153bc9ea" +checksum = "961ba061c9ef2fe34bbd12b807152d96f0badd2bebe7b90ce6c8c8b7572a0986" dependencies = [ "cc", "libc", @@ -732,7 +634,7 @@ dependencies = [ "openssl-sys", "pkg-config", "vcpkg", - "windows-sys 0.52.0", + "winapi", ] [[package]] @@ -748,12 +650,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.11" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" -dependencies = [ - "powerfmt", -] +checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" [[package]] name = "digest" @@ -802,20 +701,20 @@ checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" [[package]] name = "dylint" -version = "2.5.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683b9feb84cd2620b4b75119b7e914ac132dbd9e523f9a98821f3b3a7e355053" +checksum = "01428e3fad655202ec50df7b66015d59f7a66d76c9d0eba7148fc057c1008b08" dependencies = [ "ansi_term", "anyhow", - "cargo 0.73.1", + "cargo", "cargo-platform", "cargo-util", - "cargo_metadata 0.18.1", - "curl-sys", + "cargo_metadata", "dirs", "dylint_internal", "glob", + "heck", "if_chain", "is-terminal", "log", @@ -824,19 +723,19 @@ dependencies = [ "serde", "serde_json", "tempfile", - "toml 0.8.10", + "toml 0.7.7", "walkdir", ] [[package]] name = "dylint_internal" -version = "2.5.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ede982d9261f23a19b92ed7dc4ddeefc8328fc21c88e2c79ffd6e071c7972be" +checksum = "510bc05a42055d62ed89ee9561d974f338d30bf786917da7c033146a860ceac1" dependencies = [ "ansi_term", "anyhow", - "cargo_metadata 0.18.1", + "cargo_metadata", "git2", "home", "if_chain", @@ -848,9 +747,9 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.16.9" +version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ "der", "digest", @@ -862,9 +761,9 @@ dependencies = [ [[package]] name = "ed25519-compact" -version = "2.1.1" +version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9b3460f44bea8cd47f45a0c70892f1eff856d97cd55358b2f73f663789f6190" +checksum = "6a3d382e8464107391c8706b4c14b087808ecb909f6c15c34114bc42e53a9e4c" dependencies = [ "getrandom", ] @@ -883,15 +782,15 @@ dependencies = [ [[package]] name = "either" -version = "1.10.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" -version = "0.13.8" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" dependencies = [ "base16ct", "crypto-bigint", @@ -923,9 +822,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.10.2" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" dependencies = [ "humantime", "is-terminal", @@ -942,12 +841,23 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" dependencies = [ + "cc", "libc", - "windows-sys 0.52.0", ] [[package]] @@ -961,9 +871,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" [[package]] name = "ff" @@ -977,27 +887,27 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.2.6" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1676f435fc1dadde4d03e43f5d62b259e1ce5f40bd4ffb21db2b42ebe59c1382" +checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" [[package]] name = "filetime" -version = "0.2.23" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" dependencies = [ "cfg-if", "libc", - "redox_syscall", - "windows-sys 0.52.0", + "redox_syscall 0.3.5", + "windows-sys 0.48.0", ] [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" dependencies = [ "crc32fast", "libz-sys", @@ -1012,9 +922,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" dependencies = [ "percent-encoding", ] @@ -1131,9 +1041,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "js-sys", @@ -1181,92 +1091,42 @@ version = "0.44.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bf41b61f7df395284f7a579c0fa1a7e012c5aede655174d4e91299ef1cac643" dependencies = [ - "gix-actor 0.20.0", - "gix-attributes 0.12.0", - "gix-config 0.22.0", - "gix-credentials 0.14.0", - "gix-date", - "gix-diff 0.29.0", - "gix-discover 0.18.1", - "gix-features 0.29.0", - "gix-fs 0.1.1", - "gix-glob 0.7.0", - "gix-hash", - "gix-hashtable", - "gix-ignore 0.2.0", - "gix-index 0.16.1", - "gix-lock 5.0.1", - "gix-mailmap 0.12.0", - "gix-object 0.29.2", - "gix-odb 0.45.0", - "gix-pack 0.35.0", - "gix-path", - "gix-prompt", - "gix-protocol 0.32.0", - "gix-ref 0.29.1", - "gix-refspec 0.10.1", - "gix-revision 0.13.0", - "gix-sec", - "gix-tempfile 5.0.3", - "gix-transport 0.31.0", - "gix-traverse 0.25.0", - "gix-url 0.18.0", - "gix-utils", - "gix-validate", - "gix-worktree 0.17.1", - "log", - "once_cell", - "prodash 23.1.2", - "signal-hook", - "smallvec", - "thiserror", - "unicode-normalization", -] - -[[package]] -name = "gix" -version = "0.45.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf2a03ec66ee24d1b2bae3ab718f8d14f141613810cb7ff6756f7db667f1cd82" -dependencies = [ - "gix-actor 0.21.0", - "gix-attributes 0.13.1", - "gix-commitgraph", - "gix-config 0.23.0", - "gix-credentials 0.15.0", + "gix-actor", + "gix-attributes", + "gix-config", + "gix-credentials", "gix-date", - "gix-diff 0.30.1", - "gix-discover 0.19.0", - "gix-features 0.30.0", - "gix-fs 0.2.0", - "gix-glob 0.8.0", + "gix-diff", + "gix-discover", + "gix-features", + "gix-fs", + "gix-glob", "gix-hash", "gix-hashtable", - "gix-ignore 0.3.0", - "gix-index 0.17.0", - "gix-lock 6.0.0", - "gix-mailmap 0.13.0", - "gix-negotiate", - "gix-object 0.30.0", - "gix-odb 0.46.0", - "gix-pack 0.36.0", + "gix-ignore", + "gix-index", + "gix-lock", + "gix-mailmap", + "gix-object", + "gix-odb", + "gix-pack", "gix-path", "gix-prompt", - "gix-protocol 0.33.2", - "gix-ref 0.30.0", - "gix-refspec 0.11.0", - "gix-revision 0.15.2", + "gix-protocol", + "gix-ref", + "gix-refspec", + "gix-revision", "gix-sec", - "gix-tempfile 6.0.0", - "gix-transport 0.32.0", - "gix-traverse 0.26.0", - "gix-url 0.19.0", + "gix-tempfile", + "gix-transport", + "gix-traverse", + "gix-url", "gix-utils", "gix-validate", - "gix-worktree 0.18.0", + "gix-worktree", "log", "once_cell", - "prodash 25.0.2", + "prodash", "signal-hook", "smallvec", "thiserror", @@ -1287,20 +1147,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "gix-actor" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fe73f9f6be1afbf1bd5be919a9636fa560e2f14d42262a934423ed6760cd838" -dependencies = [ - "bstr", - "btoi", - "gix-date", - "itoa", - "nom", - "thiserror", -] - [[package]] name = "gix-attributes" version = "0.12.0" @@ -1308,24 +1154,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3015baa01ad2122fbcaab7863c857a603eb7b7ec12ac8141207c42c6439805e2" dependencies = [ "bstr", - "gix-glob 0.7.0", - "gix-path", - "gix-quote", - "kstring", - "log", - "smallvec", - "thiserror", - "unicode-bom", -] - -[[package]] -name = "gix-attributes" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b79590ac382f80d87e06416f5fcac6fee5d83dcb152a00ed0bdbaa988acc31" -dependencies = [ - "bstr", - "gix-glob 0.8.0", + "gix-glob", "gix-path", "gix-quote", "kstring", @@ -1337,43 +1166,29 @@ dependencies = [ [[package]] name = "gix-bitmap" -version = "0.2.10" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b6cd0f246180034ddafac9b00a112f19178135b21eb031b3f79355891f7325" +checksum = "0ccab4bc576844ddb51b78d81b4a42d73e6229660fa614dfc3d3999c874d1959" dependencies = [ "thiserror", ] [[package]] name = "gix-chunk" -version = "0.4.7" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "003ec6deacf68076a0c157271a127e0bb2c031c1a41f7168cbe5d248d9b85c78" +checksum = "5b42ea64420f7994000130328f3c7a2038f639120518870436d31b8bde704493" dependencies = [ "thiserror", ] [[package]] name = "gix-command" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c576cfbf577f72c097b5f88aedea502cd62952bdc1fb3adcab4531d5525a4c7" -dependencies = [ - "bstr", -] - -[[package]] -name = "gix-commitgraph" -version = "0.16.0" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8490ae1b3d55c47e6a71d247c082304a2f79f8d0332c1a2f5693d42a2021a09" +checksum = "0f28f654184b5f725c5737c7e4f466cbd8f0102ac352d5257eeab19647ee4256" dependencies = [ "bstr", - "gix-chunk", - "gix-features 0.30.0", - "gix-hash", - "memmap2", - "thiserror", ] [[package]] @@ -1384,32 +1199,10 @@ checksum = "1d252a0eddb6df74600d3d8872dc9fe98835a7da43110411d705b682f49d4ac1" dependencies = [ "bstr", "gix-config-value", - "gix-features 0.29.0", - "gix-glob 0.7.0", - "gix-path", - "gix-ref 0.29.1", - "gix-sec", - "log", - "memchr", - "nom", - "once_cell", - "smallvec", - "thiserror", - "unicode-bom", -] - -[[package]] -name = "gix-config" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51f310120ae1ba8f0ca52fb22876ce9bad5b15c8ffb3eb7302e4b64a3b9f681c" -dependencies = [ - "bstr", - "gix-config-value", - "gix-features 0.30.0", - "gix-glob 0.8.0", + "gix-features", + "gix-glob", "gix-path", - "gix-ref 0.30.0", + "gix-ref", "gix-sec", "log", "memchr", @@ -1426,7 +1219,7 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e874f41437441c02991dcea76990b9058fadfc54b02ab4dd06ab2218af43897" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.4.0", "bstr", "gix-path", "libc", @@ -1445,23 +1238,7 @@ dependencies = [ "gix-path", "gix-prompt", "gix-sec", - "gix-url 0.18.0", - "thiserror", -] - -[[package]] -name = "gix-credentials" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6f89fea8acd28f5ef8fa5042146f1637afd4d834bc8f13439d8fd1e5aca0d65" -dependencies = [ - "bstr", - "gix-command", - "gix-config-value", - "gix-path", - "gix-prompt", - "gix-sec", - "gix-url 0.19.0", + "gix-url", "thiserror", ] @@ -1484,19 +1261,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "644a0f2768bc42d7a69289ada80c9e15c589caefc6a315d2307202df83ed1186" dependencies = [ "gix-hash", - "gix-object 0.29.2", - "imara-diff", - "thiserror", -] - -[[package]] -name = "gix-diff" -version = "0.30.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9029ad0083cc286a4bd2f5b3bf66bb66398abc26f2731a2824cd5edfc41a0e33" -dependencies = [ - "gix-hash", - "gix-object 0.30.0", + "gix-object", "imara-diff", "thiserror", ] @@ -1511,22 +1276,7 @@ dependencies = [ "dunce", "gix-hash", "gix-path", - "gix-ref 0.29.1", - "gix-sec", - "thiserror", -] - -[[package]] -name = "gix-discover" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aba9c6c0d1f2b2efe65581de73de4305004612d49c83773e783202a7ef204f46" -dependencies = [ - "bstr", - "dunce", - "gix-hash", - "gix-path", - "gix-ref 0.30.0", + "gix-ref", "gix-sec", "thiserror", ] @@ -1545,27 +1295,7 @@ dependencies = [ "libc", "once_cell", "parking_lot", - "prodash 23.1.2", - "sha1_smol", - "thiserror", - "walkdir", -] - -[[package]] -name = "gix-features" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a8c493409bf6060d408eec9bbdd1b12ea351266b50012e2a522f75dfc7b8314" -dependencies = [ - "bytes", - "crc32fast", - "crossbeam-channel", - "flate2", - "gix-hash", - "libc", - "once_cell", - "parking_lot", - "prodash 25.0.2", + "prodash", "sha1_smol", "thiserror", "walkdir", @@ -1577,16 +1307,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b37a1832f691fdc09910bd267f9a2e413737c1f9ec68c6e31f9e802616278a9" dependencies = [ - "gix-features 0.29.0", -] - -[[package]] -name = "gix-fs" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30da8997008adb87f94e15beb7ee229f8a48e97af585a584bfee4a5a1880aab5" -dependencies = [ - "gix-features 0.30.0", + "gix-features", ] [[package]] @@ -1595,21 +1316,9 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c07c98204529ac3f24b34754540a852593d2a4c7349008df389240266627a72a" dependencies = [ - "bitflags 2.4.2", - "bstr", - "gix-features 0.29.0", - "gix-path", -] - -[[package]] -name = "gix-glob" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0ade1e80ab1f079703d1824e1daf73009096386aa7fd2f0477f6e4ac0a558e" -dependencies = [ - "bitflags 2.4.2", + "bitflags 2.4.0", "bstr", - "gix-features 0.30.0", + "gix-features", "gix-path", ] @@ -1630,7 +1339,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "385f4ce6ecf3692d313ca3aa9bd3b3d8490de53368d6d94bedff3af8b6d9c58d" dependencies = [ "gix-hash", - "hashbrown 0.14.3", + "hashbrown 0.14.0", "parking_lot", ] @@ -1641,19 +1350,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba205b6df563e2906768bb22834c82eb46c5fdfcd86ba2c347270bc8309a05b2" dependencies = [ "bstr", - "gix-glob 0.7.0", - "gix-path", - "unicode-bom", -] - -[[package]] -name = "gix-ignore" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc6f7f101a0ccce808dbf7008ba131dede94e20257e7bde7a44cbb2f8c775625" -dependencies = [ - "bstr", - "gix-glob 0.8.0", + "gix-glob", "gix-path", "unicode-bom", ] @@ -1664,38 +1361,16 @@ version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f39c1ccc8f1912cbbd5191efc28dbc5f0d0598042aa56bc09427b7c34efab3ba" dependencies = [ - "bitflags 2.4.2", - "bstr", - "btoi", - "filetime", - "gix-bitmap", - "gix-features 0.29.0", - "gix-hash", - "gix-lock 5.0.1", - "gix-object 0.29.2", - "gix-traverse 0.25.0", - "itoa", - "memmap2", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-index" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616ba958fabfb11263fa042c35690d48a6c7be4e9277e2c7e24ff263b3fe7b82" -dependencies = [ - "bitflags 2.4.2", + "bitflags 2.4.0", "bstr", "btoi", "filetime", "gix-bitmap", - "gix-features 0.30.0", + "gix-features", "gix-hash", - "gix-lock 6.0.0", - "gix-object 0.30.0", - "gix-traverse 0.26.0", + "gix-lock", + "gix-object", + "gix-traverse", "itoa", "memmap2", "smallvec", @@ -1708,18 +1383,7 @@ version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c693d7f05730fa74a7c467150adc7cea393518410c65f0672f80226b8111555" dependencies = [ - "gix-tempfile 5.0.3", - "gix-utils", - "thiserror", -] - -[[package]] -name = "gix-lock" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ec5d5e6f07316d3553aa7425e3ecd935ec29882556021fe1696297a448af8d2" -dependencies = [ - "gix-tempfile 6.0.0", + "gix-tempfile", "gix-utils", "thiserror", ] @@ -1731,33 +1395,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8856cec3bdc3610c06970d28b6cb20a0c6621621cf9a8ec48cbd23f2630f362" dependencies = [ "bstr", - "gix-actor 0.20.0", - "thiserror", -] - -[[package]] -name = "gix-mailmap" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4653701922c920e009f1bc4309feaff14882ade017770788f9a150928da3fa6a" -dependencies = [ - "bstr", - "gix-actor 0.21.0", - "thiserror", -] - -[[package]] -name = "gix-negotiate" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "945c3ef1e912e44a5f405fc9e924edf42000566a1b257ed52cb1293300f6f08c" -dependencies = [ - "bitflags 2.4.2", - "gix-commitgraph", - "gix-hash", - "gix-object 0.30.0", - "gix-revision 0.15.2", - "smallvec", + "gix-actor", "thiserror", ] @@ -1769,27 +1407,8 @@ checksum = "2d96bd620fd08accdd37f70b2183cfa0b001b4f1c6ade8b7f6e15cb3d9e261ce" dependencies = [ "bstr", "btoi", - "gix-actor 0.20.0", - "gix-features 0.29.0", - "gix-hash", - "gix-validate", - "hex", - "itoa", - "nom", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-object" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8926c8f51c44dec3e709cb5dbc93deb9e8d4064c43c9efc54c158dcdfe8446c7" -dependencies = [ - "bstr", - "btoi", - "gix-actor 0.21.0", - "gix-features 0.30.0", + "gix-actor", + "gix-features", "gix-hash", "gix-validate", "hex", @@ -1806,28 +1425,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bca2f324aa67672b6d0f2c0fa93f96eb6a7029d260e4c1df5dce3c015f5e5add" dependencies = [ "arc-swap", - "gix-features 0.29.0", - "gix-hash", - "gix-object 0.29.2", - "gix-pack 0.35.0", - "gix-path", - "gix-quote", - "parking_lot", - "tempfile", - "thiserror", -] - -[[package]] -name = "gix-odb" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b234d806278eeac2f907c8b5a105c4ba537230c1a9d9236d822bf0db291f8f3" -dependencies = [ - "arc-swap", - "gix-features 0.30.0", + "gix-features", "gix-hash", - "gix-object 0.30.0", - "gix-pack 0.36.0", + "gix-object", + "gix-pack", "gix-path", "gix-quote", "parking_lot", @@ -1843,36 +1444,14 @@ checksum = "164a515900a83257ae4aa80e741655bee7a2e39113fb535d7a5ac623b445ff20" dependencies = [ "clru", "gix-chunk", - "gix-diff 0.29.0", - "gix-features 0.29.0", - "gix-hash", - "gix-hashtable", - "gix-object 0.29.2", - "gix-path", - "gix-tempfile 5.0.3", - "gix-traverse 0.25.0", - "memmap2", - "parking_lot", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-pack" -version = "0.36.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d2a14cb3156037eedb17d6cb7209b7180522b8949b21fd0fe3184c0a1d0af88" -dependencies = [ - "clru", - "gix-chunk", - "gix-diff 0.30.1", - "gix-features 0.30.0", + "gix-diff", + "gix-features", "gix-hash", "gix-hashtable", - "gix-object 0.30.0", + "gix-object", "gix-path", - "gix-tempfile 6.0.0", - "gix-traverse 0.26.0", + "gix-tempfile", + "gix-traverse", "memmap2", "parking_lot", "smallvec", @@ -1881,9 +1460,9 @@ dependencies = [ [[package]] name = "gix-packetline" -version = "0.16.7" +version = "0.16.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a8384b1e964151aff0d5632dd9b191059d07dff358b96bd940f1b452600d7ab" +checksum = "2a374cb5eba089e3c123df4d996eb00da411bb90ec92cb35bffeeb2d22ee106a" dependencies = [ "bstr", "faster-hex", @@ -1912,7 +1491,7 @@ dependencies = [ "gix-command", "gix-config-value", "parking_lot", - "rustix", + "rustix 0.38.11", "thiserror", ] @@ -1924,27 +1503,10 @@ checksum = "877e49417f1730f4dbc2f7d9a2ab0f8b2f49ef08f97270691403ecde3d961e3a" dependencies = [ "bstr", "btoi", - "gix-credentials 0.14.0", - "gix-features 0.29.0", - "gix-hash", - "gix-transport 0.31.0", - "maybe-async", - "nom", - "thiserror", -] - -[[package]] -name = "gix-protocol" -version = "0.33.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92a17058b45c461f0847528c5fb6ee6e76115e026979eb2d2202f98ee94f6c24" -dependencies = [ - "bstr", - "btoi", - "gix-credentials 0.15.0", - "gix-features 0.30.0", + "gix-credentials", + "gix-features", "gix-hash", - "gix-transport 0.32.0", + "gix-transport", "maybe-async", "nom", "thiserror", @@ -1952,12 +1514,12 @@ dependencies = [ [[package]] name = "gix-quote" -version = "0.4.11" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d1b102957d975c6eb56c2b7ad9ac7f26d117299b910812b2e9bf086ec43496d" +checksum = "475c86a97dd0127ba4465fbb239abac9ea10e68301470c9791a6dd5351cdc905" dependencies = [ "bstr", - "gix-utils", + "btoi", "thiserror", ] @@ -1967,34 +1529,14 @@ version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e03989e9d49954368e1b526578230fc7189d1634acdfbe79e9ba1de717e15d5" dependencies = [ - "gix-actor 0.20.0", - "gix-features 0.29.0", - "gix-fs 0.1.1", - "gix-hash", - "gix-lock 5.0.1", - "gix-object 0.29.2", - "gix-path", - "gix-tempfile 5.0.3", - "gix-validate", - "memmap2", - "nom", - "thiserror", -] - -[[package]] -name = "gix-ref" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebdd999256f4ce8a5eefa89999879c159c263f3493a951d62aa5ce42c0397e1c" -dependencies = [ - "gix-actor 0.21.0", - "gix-features 0.30.0", - "gix-fs 0.2.0", + "gix-actor", + "gix-features", + "gix-fs", "gix-hash", - "gix-lock 6.0.0", - "gix-object 0.30.0", + "gix-lock", + "gix-object", "gix-path", - "gix-tempfile 6.0.0", + "gix-tempfile", "gix-validate", "memmap2", "nom", @@ -2009,21 +1551,7 @@ checksum = "0a6ea733820df67e4cd7797deb12727905824d8f5b7c59d943c456d314475892" dependencies = [ "bstr", "gix-hash", - "gix-revision 0.13.0", - "gix-validate", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-refspec" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72bfd622abc86dd8ad1ec51b9eb77b4f1a766b94e3a1b87cf4a022c5b5570cf4" -dependencies = [ - "bstr", - "gix-hash", - "gix-revision 0.15.2", + "gix-revision", "gix-validate", "smallvec", "thiserror", @@ -2039,36 +1567,7 @@ dependencies = [ "gix-date", "gix-hash", "gix-hashtable", - "gix-object 0.29.2", - "thiserror", -] - -[[package]] -name = "gix-revision" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5044f56cd7a487ce9b034cbe0252ae0b6b47ff56ca3dabd79bc30214d0932cd7" -dependencies = [ - "bstr", - "gix-date", - "gix-hash", - "gix-hashtable", - "gix-object 0.30.0", - "gix-revwalk", - "thiserror", -] - -[[package]] -name = "gix-revwalk" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc2623ba8747914f151f5e12b65adac576ab459dbed5f50a36c7a3e9cbf2d3ca" -dependencies = [ - "gix-commitgraph", - "gix-hash", - "gix-hashtable", - "gix-object 0.30.0", - "smallvec", + "gix-object", "thiserror", ] @@ -2078,7 +1577,7 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9615cbd6b456898aeb942cd75e5810c382fbfc48dbbff2fa23ebd2d33dcbe9c7" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.4.0", "gix-path", "libc", "windows", @@ -2090,71 +1589,37 @@ version = "5.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71a0d32f34e71e86586124225caefd78dabc605d0486de580d717653addf182" dependencies = [ - "gix-fs 0.1.1", - "libc", - "once_cell", - "parking_lot", - "signal-hook", - "signal-hook-registry", - "tempfile", -] - -[[package]] -name = "gix-tempfile" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3785cb010e9dc5c446dfbf02bc1119fc17d3a48a27c029efcb3a3c32953eb10" -dependencies = [ - "gix-fs 0.2.0", + "gix-fs", "libc", - "once_cell", - "parking_lot", - "signal-hook", - "signal-hook-registry", - "tempfile", -] - -[[package]] -name = "gix-trace" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b202d766a7fefc596e2cc6a89cda8ad8ad733aed82da635ac120691112a9b1" - -[[package]] -name = "gix-transport" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f01c2bf7b989c679695ef635fc7d9e80072e08101be4b53193c8e8b649900102" -dependencies = [ - "base64 0.21.7", - "bstr", - "curl", - "gix-command", - "gix-credentials 0.14.0", - "gix-features 0.29.0", - "gix-packetline", - "gix-quote", - "gix-sec", - "gix-url 0.18.0", - "thiserror", + "once_cell", + "parking_lot", + "signal-hook", + "signal-hook-registry", + "tempfile", ] +[[package]] +name = "gix-trace" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b6d623a1152c3facb79067d6e2ecdae48130030cf27d6eb21109f13bd7b836" + [[package]] name = "gix-transport" -version = "0.32.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a39ffed9a9078ed700605e064b15d7c6ae50aa65e7faa36ca6919e8081df15" +checksum = "f01c2bf7b989c679695ef635fc7d9e80072e08101be4b53193c8e8b649900102" dependencies = [ - "base64 0.21.7", + "base64 0.21.3", "bstr", "curl", "gix-command", - "gix-credentials 0.15.0", - "gix-features 0.30.0", + "gix-credentials", + "gix-features", "gix-packetline", "gix-quote", "gix-sec", - "gix-url 0.19.0", + "gix-url", "thiserror", ] @@ -2166,19 +1631,7 @@ checksum = "a5be1e807f288c33bb005075111886cceb43ed8a167b3182a0f62c186e2a0dd1" dependencies = [ "gix-hash", "gix-hashtable", - "gix-object 0.29.2", - "thiserror", -] - -[[package]] -name = "gix-traverse" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0842e984cb4bf26339dc559f3a1b8bf8cdb83547799b2b096822a59f87f33d9" -dependencies = [ - "gix-hash", - "gix-hashtable", - "gix-object 0.30.0", + "gix-object", "thiserror", ] @@ -2189,21 +1642,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfc77f89054297cc81491e31f1bab4027e554b5ef742a44bd7035db9a0f78b76" dependencies = [ "bstr", - "gix-features 0.29.0", - "gix-path", - "home", - "thiserror", - "url", -] - -[[package]] -name = "gix-url" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1663df25ac42047a2547618d2a6979a26f478073f6306997429235d2cd4c863" -dependencies = [ - "bstr", - "gix-features 0.30.0", + "gix-features", "gix-path", "home", "thiserror", @@ -2212,12 +1651,11 @@ dependencies = [ [[package]] name = "gix-utils" -version = "0.1.10" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60157a15b9f14b11af1c6817ad7a93b10b50b4e5136d98a127c46a37ff16eeb6" +checksum = "b85d89dc728613e26e0ed952a19583744e7f5240fcd4aa30d6c824ffd8b52f0f" dependencies = [ "fastrand", - "unicode-normalization", ] [[package]] @@ -2238,35 +1676,14 @@ checksum = "a69eaff0ae973a9d37c40f02ae5ae50fa726c8fc2fd3ab79d0a19eb61975aafa" dependencies = [ "bstr", "filetime", - "gix-attributes 0.12.0", - "gix-features 0.29.0", - "gix-fs 0.1.1", - "gix-glob 0.7.0", - "gix-hash", - "gix-ignore 0.2.0", - "gix-index 0.16.1", - "gix-object 0.29.2", - "gix-path", - "io-close", - "thiserror", -] - -[[package]] -name = "gix-worktree" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d388ad962e8854402734a7387af8790f6bdbc8d05349052dab16ca4a0def50f6" -dependencies = [ - "bstr", - "filetime", - "gix-attributes 0.13.1", - "gix-features 0.30.0", - "gix-fs 0.2.0", - "gix-glob 0.8.0", + "gix-attributes", + "gix-features", + "gix-fs", + "gix-glob", "gix-hash", - "gix-ignore 0.3.0", - "gix-index 0.17.0", - "gix-object 0.30.0", + "gix-ignore", + "gix-index", + "gix-object", "gix-path", "io-close", "thiserror", @@ -2280,15 +1697,15 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "globset" -version = "0.4.14" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d" dependencies = [ "aho-corasick", "bstr", + "fnv", "log", - "regex-automata", - "regex-syntax", + "regex", ] [[package]] @@ -2308,14 +1725,14 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash 0.7.8", + "ahash 0.7.6", ] [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" [[package]] name = "heck" @@ -2325,9 +1742,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.9" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" [[package]] name = "hex" @@ -2337,9 +1754,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hkdf" -version = "0.12.4" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" dependencies = [ "hmac", ] @@ -2355,18 +1772,18 @@ dependencies = [ [[package]] name = "home" -version = "0.5.9" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.48.0", ] [[package]] name = "http-auth" -version = "0.1.9" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643c9bbf6a4ea8a656d6b4cd53d34f79e3f841ad5203c1a55fb7d761923bc255" +checksum = "5430cacd7a1f9a02fbeb350dfc81a0e5ed42d81f3398cb0ba184017f85bdcfbc" dependencies = [ "memchr", ] @@ -2379,9 +1796,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "idna" -version = "0.5.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -2395,16 +1812,17 @@ checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" [[package]] name = "ignore" -version = "0.4.22" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" +checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492" dependencies = [ - "crossbeam-deque", "globset", + "lazy_static", "log", "memchr", - "regex-automata", + "regex", "same-file", + "thread_local", "walkdir", "winapi-util", ] @@ -2429,7 +1847,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e98c1d0ad70fc91b8b9654b1f33db55e59579d3b3de2bffdced0fdb810570cb8" dependencies = [ - "ahash 0.8.11", + "ahash 0.8.3", "hashbrown 0.12.3", ] @@ -2445,12 +1863,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.5" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.14.0", ] [[package]] @@ -2464,14 +1882,25 @@ dependencies = [ ] [[package]] -name = "is-terminal" -version = "0.4.12" +name = "io-lifetimes" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.52.0", + "windows-sys 0.48.0", +] + +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi", + "rustix 0.38.11", + "windows-sys 0.48.0", ] [[package]] @@ -2494,24 +1923,24 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "jobserver" -version = "0.1.28" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] @@ -2550,9 +1979,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "libgit2-sys" @@ -2570,25 +1999,14 @@ dependencies = [ [[package]] name = "libnghttp2-sys" -version = "0.1.9+1.58.0" +version = "0.1.8+1.55.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b57e858af2798e167e709b9d969325b6d8e9d50232fcbc494d7d54f976854a64" +checksum = "4fae956c192dadcdb5dace96db71fa0b827333cce7c7b38dc71446f024d8a340" dependencies = [ "cc", "libc", ] -[[package]] -name = "libredox" -version = "0.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" -dependencies = [ - "bitflags 2.4.2", - "libc", - "redox_syscall", -] - [[package]] name = "libssh2-sys" version = "0.3.0" @@ -2605,9 +2023,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.15" +version = "1.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037731f5d3aaa87a5675e895b63ddff1a87624bc29f77004ea829809654e48f6" +checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" dependencies = [ "cc", "libc", @@ -2623,15 +2041,21 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "linux-raw-sys" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" dependencies = [ "autocfg", "scopeguard", @@ -2639,26 +2063,26 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "maybe-async" -version = "0.2.10" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" +checksum = "0f1b8c13cb1f814b634a96b2c725449fe7ed464a7b8781de8688be5ffbd3f305" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 1.0.109", ] [[package]] name = "memchr" -version = "2.7.1" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" [[package]] name = "memmap2" @@ -2677,18 +2101,18 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.11" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", "wasi", @@ -2697,11 +2121,11 @@ dependencies = [ [[package]] name = "miow" -version = "0.6.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "359f76430b20a79f9e20e115b3428614e654f04fab314482fc0fda0ebd3c6044" +checksum = "52ffbca2f655e33c08be35d87278e5b18b89550a37dbd598c20db92f6a471123" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.42.0", ] [[package]] @@ -2725,12 +2149,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - [[package]] name = "num-integer" version = "0.1.46" @@ -2742,9 +2160,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", ] @@ -2761,9 +2179,9 @@ dependencies = [ [[package]] name = "num_threads" -version = "0.1.7" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" dependencies = [ "libc", ] @@ -2779,9 +2197,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opener" @@ -2801,9 +2219,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.101" +version = "0.9.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" +checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" dependencies = [ "cc", "libc", @@ -2862,9 +2280,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "ordered-float" -version = "2.10.1" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" +checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87" dependencies = [ "num-traits", ] @@ -2881,9 +2299,9 @@ dependencies = [ [[package]] name = "orion" -version = "0.17.6" +version = "0.17.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abdb10181903c8c4b016ba45d6d6d5af1a1e2a461aa4763a83b87f5df4695e5" +checksum = "b11468cc6afd61a126fe3f91cc4cc8a0dbe7917d0a4b5e8357ba91cc47444462" dependencies = [ "fiat-crypto", "subtle", @@ -2925,22 +2343,22 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.3.5", "smallvec", - "windows-targets 0.48.5", + "windows-targets", ] [[package]] name = "pasetors" -version = "0.6.8" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b36d47c66f2230dd1b7143d9afb2b4891879020210eddf2ccb624e529b96dba" +checksum = "ba765699a309908d55950919a3445e9491453e89b2587b1b2abe4143a48894c0" dependencies = [ "ct-codecs", "ed25519-compact", @@ -2974,15 +2392,15 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pest" -version = "2.7.8" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8" +checksum = "d7a4d085fd991ac8d5b05a147b437791b4260b76326baf0fc60cf7c9c27ecd33" dependencies = [ "memchr", "thiserror", @@ -2991,9 +2409,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.8" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0d24f72393fd16ab6ac5738bc33cdb6a9aa73f8b902e8fe29cf4e67d7dd1026" +checksum = "a2bee7be22ce7918f641a33f08e3f43388c7656772244e2bbb2477f44cc9021a" dependencies = [ "pest", "pest_generator", @@ -3001,9 +2419,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.8" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc17e2a6c7d0a492f0158d7a4bd66cc17280308bbaff78d5bef566dca35ab80" +checksum = "d1511785c5e98d79a05e8a6bc34b4ac2168a0e3e92161862030ad84daa223141" dependencies = [ "pest", "pest_meta", @@ -3014,9 +2432,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.7.8" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934cd7631c050f4674352a6e835d5f6711ffbfb9345c2fc0107155ac495ae293" +checksum = "b42f0394d3123e33353ca5e1e89092e533d2cc490389f2bd6131c43c634ebc5f" dependencies = [ "once_cell", "pest", @@ -3067,15 +2485,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" - -[[package]] -name = "powerfmt" -version = "0.2.0" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "ppv-lite86" @@ -3085,18 +2497,18 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "primeorder" -version = "0.13.6" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +checksum = "3c2fcef82c0ec6eefcc179b978446c399b3cdf73c392c35604e399eee6df1ee3" dependencies = [ "elliptic-curve", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] @@ -3110,26 +2522,6 @@ dependencies = [ "parking_lot", ] -[[package]] -name = "prodash" -version = "25.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d67eb4220992a4a052a4bb03cf776e493ecb1a3a36bab551804153d63486af7" -dependencies = [ - "parking_lot", -] - -[[package]] -name = "pulldown-cmark" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" -dependencies = [ - "bitflags 2.4.2", - "memchr", - "unicase", -] - [[package]] name = "quote" version = "1.0.35" @@ -3180,29 +2572,38 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "redox_users" -version = "0.4.4" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ "getrandom", - "libredox", + "redox_syscall 0.2.16", "thiserror", ] [[package]] name = "regex" -version = "1.10.3" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" dependencies = [ "aho-corasick", "memchr", @@ -3212,9 +2613,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" dependencies = [ "aho-corasick", "memchr", @@ -3223,9 +2624,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "rfc6979" @@ -3250,9 +2651,9 @@ dependencies = [ [[package]] name = "rust-embed" -version = "8.3.0" +version = "6.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb78f46d0066053d16d4ca7b898e9343bc3530f71c61d5ad84cd404ada068745" +checksum = "a36224c3276f8c4ebc8c20f158eca7ca4359c8db89991c4925132aaaf6702661" dependencies = [ "rust-embed-impl", "rust-embed-utils", @@ -3261,9 +2662,9 @@ dependencies = [ [[package]] name = "rust-embed-impl" -version = "8.3.0" +version = "6.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91ac2a3c6c0520a3fb3dd89321177c3c692937c4eb21893378219da10c44fc8" +checksum = "49b94b81e5b2c284684141a2fb9e2a31be90638caf040bf9afbc5a0416afe1ac" dependencies = [ "proc-macro2", "quote", @@ -3274,9 +2675,9 @@ dependencies = [ [[package]] name = "rust-embed-utils" -version = "8.3.0" +version = "7.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f69089032567ffff4eada41c573fc43ff466c7db7c5688b2e7969584345581" +checksum = "9d38ff6bf570dc3bb7100fce9f7b60c33fa71d80e88da3f2580df4ff2bdded74" dependencies = [ "globset", "sha2", @@ -3313,15 +2714,29 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.31" +version = "0.37.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "c0c3dde1fc030af041adc40e79c0e7fbcf431dd24870053d187d7c66e4b87453" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.4.0", "errno", "libc", - "linux-raw-sys", - "windows-sys 0.52.0", + "linux-raw-sys 0.4.5", + "windows-sys 0.48.0", ] [[package]] @@ -3332,9 +2747,9 @@ checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "same-file" @@ -3347,11 +2762,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.48.0", ] [[package]] @@ -3398,9 +2813,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.22" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" dependencies = [ "serde", ] @@ -3437,18 +2852,18 @@ dependencies = [ [[package]] name = "serde_ignored" -version = "0.1.10" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8e319a36d1b52126a0d608f24e93b2d81297091818cd70625fcf50a15d84ddf" +checksum = "80c31d5c53fd39f208e770f5a20a0bb214dee2a8d0d8adba18e19ad95a482ca5" dependencies = [ "serde", ] [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" dependencies = [ "itoa", "ryu", @@ -3457,18 +2872,18 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" dependencies = [ "serde", ] [[package]] name = "sha1" -version = "0.10.6" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" dependencies = [ "cfg-if", "cpufeatures", @@ -3483,9 +2898,9 @@ checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ "cfg-if", "cpufeatures", @@ -3528,9 +2943,9 @@ dependencies = [ [[package]] name = "signature" -version = "2.2.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ "digest", "rand_core", @@ -3557,25 +2972,35 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" [[package]] name = "socket2" -version = "0.5.6" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.48.0", ] [[package]] name = "spki" -version = "0.7.3" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", "der", @@ -3598,9 +3023,9 @@ dependencies = [ [[package]] name = "strsim" -version = "0.11.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "strum" @@ -3613,9 +3038,9 @@ dependencies = [ [[package]] name = "strum_macros" -version = "0.25.3" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" dependencies = [ "heck", "proc-macro2", @@ -3699,49 +3124,50 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.10.1" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ "cfg-if", "fastrand", - "rustix", - "windows-sys 0.52.0", + "redox_syscall 0.3.5", + "rustix 0.38.11", + "windows-sys 0.48.0", ] [[package]] name = "termcolor" -version = "1.4.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" dependencies = [ "winapi-util", ] [[package]] name = "terminal_size" -version = "0.3.0" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237" dependencies = [ - "rustix", + "rustix 0.37.23", "windows-sys 0.48.0", ] [[package]] name = "thiserror" -version = "1.0.57" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" +checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.57" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" +checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", @@ -3750,9 +3176,9 @@ dependencies = [ [[package]] name = "thread_local" -version = "1.1.8" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" dependencies = [ "cfg-if", "once_cell", @@ -3760,16 +3186,14 @@ dependencies = [ [[package]] name = "time" -version = "0.3.34" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" dependencies = [ "deranged", "itoa", "libc", - "num-conv", "num_threads", - "powerfmt", "serde", "time-core", "time-macros", @@ -3777,17 +3201,16 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.17" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" +checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" dependencies = [ - "num-conv", "time-core", ] @@ -3808,25 +3231,25 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.36.0" +version = "1.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" dependencies = [ "backtrace", "libc", "mio", "num_cpus", "pin-project-lite", - "socket2", + "socket2 0.5.4", "tokio-macros", "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", @@ -3875,33 +3298,21 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit 0.19.15", -] - -[[package]] -name = "toml" -version = "0.8.10" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a9aad4a3066010876e8dcf5a8a06e70a558751117a145c6ce2b82c2e2054290" +checksum = "de0a3ab2091e52d7299a39d098e200114a972df0a7724add02a273aa9aada592" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.6", + "toml_edit", ] [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" dependencies = [ "serde", ] @@ -3912,24 +3323,11 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.2.5", - "serde", - "serde_spanned", - "toml_datetime", - "winnow 0.5.40", -] - -[[package]] -name = "toml_edit" -version = "0.22.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1b5fd4128cc8d3e0cb74d4ed9a9cc7c7284becd4df68f5f940e1ad123606f6" -dependencies = [ - "indexmap 2.2.5", + "indexmap 2.0.0", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.5", + "winnow", ] [[package]] @@ -3991,9 +3389,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.17.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "ucd-trie" @@ -4001,47 +3399,38 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" -[[package]] -name = "unicase" -version = "2.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] - [[package]] name = "unicode-bidi" -version = "0.3.15" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-bom" -version = "2.0.3" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eec5d1121208364f6793f7d2e222bf75a915c19557537745b195b253dd64217" +checksum = "98e90c70c9f0d4d1ee6d0a7d04aa06cb9bbd53d8cfbdd62a0269a7c2eb640552" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" [[package]] name = "unicode-xid" @@ -4051,9 +3440,9 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "url" -version = "2.5.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" dependencies = [ "form_urlencoded", "idna", @@ -4107,9 +3496,9 @@ dependencies = [ [[package]] name = "walkdir" -version = "2.5.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" dependencies = [ "same-file", "winapi-util", @@ -4123,9 +3512,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -4133,9 +3522,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", @@ -4148,9 +3537,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4158,9 +3547,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", @@ -4171,9 +3560,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "winapi" @@ -4193,9 +3582,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ "winapi", ] @@ -4212,25 +3601,31 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets 0.48.5", + "windows-targets", ] [[package]] name = "windows-sys" -version = "0.48.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows-targets 0.48.5", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] name = "windows-sys" -version = "0.52.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.52.4", + "windows-targets", ] [[package]] @@ -4249,19 +3644,10 @@ dependencies = [ ] [[package]] -name = "windows-targets" -version = "0.52.4" +name = "windows_aarch64_gnullvm" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" -dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", -] +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_gnullvm" @@ -4270,10 +3656,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.4" +name = "windows_aarch64_msvc" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" @@ -4282,10 +3668,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] -name = "windows_aarch64_msvc" -version = "0.52.4" +name = "windows_i686_gnu" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" @@ -4294,10 +3680,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] -name = "windows_i686_gnu" -version = "0.52.4" +name = "windows_i686_msvc" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" @@ -4306,10 +3692,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] -name = "windows_i686_msvc" -version = "0.52.4" +name = "windows_x86_64_gnu" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" @@ -4318,10 +3704,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] -name = "windows_x86_64_gnu" -version = "0.52.4" +name = "windows_x86_64_gnullvm" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_gnullvm" @@ -4330,10 +3716,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.4" +name = "windows_x86_64_msvc" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" @@ -4341,26 +3727,11 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" - -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - [[package]] name = "winnow" -version = "0.6.5" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" +checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" dependencies = [ "memchr", ] @@ -4374,28 +3745,8 @@ dependencies = [ "linked-hash-map", ] -[[package]] -name = "zerocopy" -version = "0.7.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - [[package]] name = "zeroize" -version = "1.7.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/apps/cargo-scout-audit/src/scout_config.rs b/apps/cargo-scout-audit/src/scout_config.rs new file mode 100644 index 00000000..93fe6045 --- /dev/null +++ b/apps/cargo-scout-audit/src/scout_config.rs @@ -0,0 +1,56 @@ +use std::{ + env::{self, VarError}, + fs::{self, File, OpenOptions}, + io::{ErrorKind, Read, Write}, + path::PathBuf, +}; + +fn create_default_config(file_path: PathBuf) -> anyhow::Result { + let mut file = OpenOptions::new() + .read(true) + .write(true) + .create(true) + .open(file_path)?; + let default_config: toml::Table = toml::toml! { + [developer] + [developer.soroban] + enabled = true + [developer.ink] + enabled = true + + [auditor] + [auditor.soroban] + enabled = true + [auditor.ink] + enabled = true + }; + let str = toml::to_string_pretty::(&default_config)?; + file.write_all(str.as_bytes())?; + Ok(file) +} + +fn read_config() -> anyhow::Result<()> { + let base_path = match std::env::consts::OS { + "windows" => env::var("USERPROFILE")? + "/scout/", + _ => "~/.config/scout/".to_string(), + }; + let path = PathBuf::from(base_path); + if let Err(_metadata) = fs::metadata(&path) { + fs::create_dir_all(&path)?; + } + let file_path = path.as_path().join("config.toml"); + let res_file = File::open(&file_path); + let mut file = if res_file + .as_ref() + .is_err_and(|f| f.kind() == ErrorKind::NotFound) + { + create_default_config(file_path)? + } else { + res_file? + }; + let mut toml_str = String::new(); + file.read_to_string(&mut toml_str)?; + let config: toml::Table = toml::from_str(&toml_str)?; + + Ok(()) +} diff --git a/detectors/Cargo.toml b/detectors/Cargo.toml index abd2f151..bc8adc8b 100644 --- a/detectors/Cargo.toml +++ b/detectors/Cargo.toml @@ -3,9 +3,9 @@ members = ["*"] exclude = [".cargo", "target"] [workspace.dependencies] -dylint_linting = "2.1.5" dylint_testing = "2.1.5" if_chain = "1.0.2" -scout-audit-clippy-utils = { version = "=0.2.2", path = "../scout-audit-clippy-utils" } -scout-audit-internal = { path = "../scout-audit-internal", features = ["detector", "lint_helper"] } +scout-audit-clippy-utils = { version = "=0.2.2", path = "../../scout-audit/scout-audit-clippy-utils" } +scout-audit-internal = { path = "../../scout-audit/scout-audit-internal", features = ["detector", "lint_helper"] } +dylint_linting = { package = "scout-audit-dylint-linting", path = "../../scout-audit/scout-audit-dylint-linting" } diff --git a/scout-audit-clippy-utils/Cargo.lock b/scout-audit-clippy-utils/Cargo.lock deleted file mode 100644 index b3fddfea..00000000 --- a/scout-audit-clippy-utils/Cargo.lock +++ /dev/null @@ -1,46 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - -[[package]] -name = "either" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" - -[[package]] -name = "if_chain" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "rustc-semver" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be1bdc7edf596692617627bbfeaba522131b18e06ca4df2b6b689e3c5d5ce84" - -[[package]] -name = "scout-audit-clippy-utils" -version = "0.2.0" -dependencies = [ - "arrayvec", - "if_chain", - "itertools", - "rustc-semver", -] diff --git a/scout-audit-clippy-utils/Cargo.toml b/scout-audit-clippy-utils/Cargo.toml deleted file mode 100644 index d2954954..00000000 --- a/scout-audit-clippy-utils/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -name = "scout-audit-clippy-utils" -version = "0.2.2" -edition = "2021" -license = "MIT" -repository = "https://github.com/rust-lang/rust-clippy" -description = "For internal usage by cargo-scout-audit." - -[dependencies] -arrayvec = { version = "0.7", default-features = false } -if_chain = "1.0" -itertools = "0.10.1" -rustc-semver = "1.1" -clippy_config = { path = "../clippy_config" } - -[features] -deny-warnings = [] -internal = [] - -[package.metadata.rust-analyzer] -# This crate uses #[feature(rustc_private)] -rustc_private = true diff --git a/scout-audit-clippy-utils/README.md b/scout-audit-clippy-utils/README.md deleted file mode 100644 index 8aca32ce..00000000 --- a/scout-audit-clippy-utils/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Scout Audit Clippy Utils - -This crate is a copy of `clippy_utils` crate found on the [rust-clippy](https://github.com/rust-lang/rust-clippy/tree/master) repository. - -This crate is used to allow publishing `scout-audit-internal` to crates.io given `clippy_utils` itself is not published. - -## Version - -Commit `7671c283a50b5d1168841f3014b14000f01dd204`. diff --git a/scout-audit-clippy-utils/rust-toolchain b/scout-audit-clippy-utils/rust-toolchain deleted file mode 100644 index d575da6d..00000000 --- a/scout-audit-clippy-utils/rust-toolchain +++ /dev/null @@ -1,3 +0,0 @@ -[toolchain] -channel = "nightly-2023-12-16" -components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] diff --git a/scout-audit-clippy-utils/src/ast_utils.rs b/scout-audit-clippy-utils/src/ast_utils.rs deleted file mode 100644 index e36f2fa8..00000000 --- a/scout-audit-clippy-utils/src/ast_utils.rs +++ /dev/null @@ -1,799 +0,0 @@ -//! Utilities for manipulating and extracting information from `rustc_ast::ast`. -//! -//! - The `eq_foobar` functions test for semantic equality but ignores `NodeId`s and `Span`s. - -#![allow(clippy::similar_names, clippy::wildcard_imports, clippy::enum_glob_use)] - -use crate::{both, over}; -use rustc_ast::ptr::P; -use rustc_ast::{self as ast, *}; -use rustc_span::symbol::Ident; -use std::mem; - -pub mod ident_iter; -pub use ident_iter::IdentIter; - -pub fn is_useless_with_eq_exprs(kind: BinOpKind) -> bool { - use BinOpKind::*; - matches!( - kind, - Sub | Div | Eq | Lt | Le | Gt | Ge | Ne | And | Or | BitXor | BitAnd | BitOr - ) -} - -/// Checks if each element in the first slice is contained within the latter as per `eq_fn`. -pub fn unordered_over(left: &[X], right: &[X], mut eq_fn: impl FnMut(&X, &X) -> bool) -> bool { - left.len() == right.len() && left.iter().all(|l| right.iter().any(|r| eq_fn(l, r))) -} - -pub fn eq_id(l: Ident, r: Ident) -> bool { - l.name == r.name -} - -pub fn eq_pat(l: &Pat, r: &Pat) -> bool { - use PatKind::*; - match (&l.kind, &r.kind) { - (Paren(l), _) => eq_pat(l, r), - (_, Paren(r)) => eq_pat(l, r), - (Wild, Wild) | (Rest, Rest) => true, - (Lit(l), Lit(r)) => eq_expr(l, r), - (Ident(b1, i1, s1), Ident(b2, i2, s2)) => b1 == b2 && eq_id(*i1, *i2) && both(s1, s2, |l, r| eq_pat(l, r)), - (Range(lf, lt, le), Range(rf, rt, re)) => { - eq_expr_opt(lf, rf) && eq_expr_opt(lt, rt) && eq_range_end(&le.node, &re.node) - }, - (Box(l), Box(r)) - | (Ref(l, Mutability::Not), Ref(r, Mutability::Not)) - | (Ref(l, Mutability::Mut), Ref(r, Mutability::Mut)) => eq_pat(l, r), - (Tuple(l), Tuple(r)) | (Slice(l), Slice(r)) => over(l, r, |l, r| eq_pat(l, r)), - (Path(lq, lp), Path(rq, rp)) => both(lq, rq, eq_qself) && eq_path(lp, rp), - (TupleStruct(lqself, lp, lfs), TupleStruct(rqself, rp, rfs)) => { - eq_maybe_qself(lqself, rqself) && eq_path(lp, rp) && over(lfs, rfs, |l, r| eq_pat(l, r)) - }, - (Struct(lqself, lp, lfs, lr), Struct(rqself, rp, rfs, rr)) => { - lr == rr && eq_maybe_qself(lqself, rqself) && eq_path(lp, rp) && unordered_over(lfs, rfs, eq_field_pat) - }, - (Or(ls), Or(rs)) => unordered_over(ls, rs, |l, r| eq_pat(l, r)), - (MacCall(l), MacCall(r)) => eq_mac_call(l, r), - _ => false, - } -} - -pub fn eq_range_end(l: &RangeEnd, r: &RangeEnd) -> bool { - match (l, r) { - (RangeEnd::Excluded, RangeEnd::Excluded) => true, - (RangeEnd::Included(l), RangeEnd::Included(r)) => { - matches!(l, RangeSyntax::DotDotEq) == matches!(r, RangeSyntax::DotDotEq) - }, - _ => false, - } -} - -pub fn eq_field_pat(l: &PatField, r: &PatField) -> bool { - l.is_placeholder == r.is_placeholder - && eq_id(l.ident, r.ident) - && eq_pat(&l.pat, &r.pat) - && over(&l.attrs, &r.attrs, eq_attr) -} - -pub fn eq_qself(l: &P, r: &P) -> bool { - l.position == r.position && eq_ty(&l.ty, &r.ty) -} - -pub fn eq_maybe_qself(l: &Option>, r: &Option>) -> bool { - match (l, r) { - (Some(l), Some(r)) => eq_qself(l, r), - (None, None) => true, - _ => false, - } -} - -pub fn eq_path(l: &Path, r: &Path) -> bool { - over(&l.segments, &r.segments, eq_path_seg) -} - -pub fn eq_path_seg(l: &PathSegment, r: &PathSegment) -> bool { - eq_id(l.ident, r.ident) && both(&l.args, &r.args, |l, r| eq_generic_args(l, r)) -} - -pub fn eq_generic_args(l: &GenericArgs, r: &GenericArgs) -> bool { - match (l, r) { - (GenericArgs::AngleBracketed(l), GenericArgs::AngleBracketed(r)) => over(&l.args, &r.args, eq_angle_arg), - (GenericArgs::Parenthesized(l), GenericArgs::Parenthesized(r)) => { - over(&l.inputs, &r.inputs, |l, r| eq_ty(l, r)) && eq_fn_ret_ty(&l.output, &r.output) - }, - _ => false, - } -} - -pub fn eq_angle_arg(l: &AngleBracketedArg, r: &AngleBracketedArg) -> bool { - match (l, r) { - (AngleBracketedArg::Arg(l), AngleBracketedArg::Arg(r)) => eq_generic_arg(l, r), - (AngleBracketedArg::Constraint(l), AngleBracketedArg::Constraint(r)) => eq_assoc_constraint(l, r), - _ => false, - } -} - -pub fn eq_generic_arg(l: &GenericArg, r: &GenericArg) -> bool { - match (l, r) { - (GenericArg::Lifetime(l), GenericArg::Lifetime(r)) => eq_id(l.ident, r.ident), - (GenericArg::Type(l), GenericArg::Type(r)) => eq_ty(l, r), - (GenericArg::Const(l), GenericArg::Const(r)) => eq_expr(&l.value, &r.value), - _ => false, - } -} - -pub fn eq_expr_opt(l: &Option>, r: &Option>) -> bool { - both(l, r, |l, r| eq_expr(l, r)) -} - -pub fn eq_struct_rest(l: &StructRest, r: &StructRest) -> bool { - match (l, r) { - (StructRest::Base(lb), StructRest::Base(rb)) => eq_expr(lb, rb), - (StructRest::Rest(_), StructRest::Rest(_)) | (StructRest::None, StructRest::None) => true, - _ => false, - } -} - -pub fn eq_expr(l: &Expr, r: &Expr) -> bool { - use ExprKind::*; - if !over(&l.attrs, &r.attrs, eq_attr) { - return false; - } - match (&l.kind, &r.kind) { - (Paren(l), _) => eq_expr(l, r), - (_, Paren(r)) => eq_expr(l, r), - (Err, Err) => true, - (Try(l), Try(r)) | (Await(l, _), Await(r, _)) => eq_expr(l, r), - (Array(l), Array(r)) => over(l, r, |l, r| eq_expr(l, r)), - (Tup(l), Tup(r)) => over(l, r, |l, r| eq_expr(l, r)), - (Repeat(le, ls), Repeat(re, rs)) => eq_expr(le, re) && eq_expr(&ls.value, &rs.value), - (Call(lc, la), Call(rc, ra)) => eq_expr(lc, rc) && over(la, ra, |l, r| eq_expr(l, r)), - ( - MethodCall(box ast::MethodCall { - seg: ls, - receiver: lr, - args: la, - .. - }), - MethodCall(box ast::MethodCall { - seg: rs, - receiver: rr, - args: ra, - .. - }), - ) => eq_path_seg(ls, rs) && eq_expr(lr, rr) && over(la, ra, |l, r| eq_expr(l, r)), - (Binary(lo, ll, lr), Binary(ro, rl, rr)) => lo.node == ro.node && eq_expr(ll, rl) && eq_expr(lr, rr), - (Unary(lo, l), Unary(ro, r)) => mem::discriminant(lo) == mem::discriminant(ro) && eq_expr(l, r), - (Lit(l), Lit(r)) => l == r, - (Cast(l, lt), Cast(r, rt)) | (Type(l, lt), Type(r, rt)) => eq_expr(l, r) && eq_ty(lt, rt), - (Let(lp, le, _, _), Let(rp, re, _, _)) => eq_pat(lp, rp) && eq_expr(le, re), - (If(lc, lt, le), If(rc, rt, re)) => eq_expr(lc, rc) && eq_block(lt, rt) && eq_expr_opt(le, re), - (While(lc, lt, ll), While(rc, rt, rl)) => eq_label(ll, rl) && eq_expr(lc, rc) && eq_block(lt, rt), - (ForLoop(lp, li, lt, ll), ForLoop(rp, ri, rt, rl)) => { - eq_label(ll, rl) && eq_pat(lp, rp) && eq_expr(li, ri) && eq_block(lt, rt) - }, - (Loop(lt, ll, _), Loop(rt, rl, _)) => eq_label(ll, rl) && eq_block(lt, rt), - (Block(lb, ll), Block(rb, rl)) => eq_label(ll, rl) && eq_block(lb, rb), - (TryBlock(l), TryBlock(r)) => eq_block(l, r), - (Yield(l), Yield(r)) | (Ret(l), Ret(r)) => eq_expr_opt(l, r), - (Break(ll, le), Break(rl, re)) => eq_label(ll, rl) && eq_expr_opt(le, re), - (Continue(ll), Continue(rl)) => eq_label(ll, rl), - (Assign(l1, l2, _), Assign(r1, r2, _)) | (Index(l1, l2, _), Index(r1, r2, _)) => { - eq_expr(l1, r1) && eq_expr(l2, r2) - }, - (AssignOp(lo, lp, lv), AssignOp(ro, rp, rv)) => lo.node == ro.node && eq_expr(lp, rp) && eq_expr(lv, rv), - (Field(lp, lf), Field(rp, rf)) => eq_id(*lf, *rf) && eq_expr(lp, rp), - (Match(ls, la), Match(rs, ra)) => eq_expr(ls, rs) && over(la, ra, eq_arm), - ( - Closure(box ast::Closure { - binder: lb, - capture_clause: lc, - coroutine_kind: la, - movability: lm, - fn_decl: lf, - body: le, - .. - }), - Closure(box ast::Closure { - binder: rb, - capture_clause: rc, - coroutine_kind: ra, - movability: rm, - fn_decl: rf, - body: re, - .. - }), - ) => { - eq_closure_binder(lb, rb) - && lc == rc - && la.map_or(false, CoroutineKind::is_async) == ra.map_or(false, CoroutineKind::is_async) - && lm == rm - && eq_fn_decl(lf, rf) - && eq_expr(le, re) - }, - (Gen(lc, lb, lk), Gen(rc, rb, rk)) => lc == rc && eq_block(lb, rb) && lk == rk, - (Range(lf, lt, ll), Range(rf, rt, rl)) => ll == rl && eq_expr_opt(lf, rf) && eq_expr_opt(lt, rt), - (AddrOf(lbk, lm, le), AddrOf(rbk, rm, re)) => lbk == rbk && lm == rm && eq_expr(le, re), - (Path(lq, lp), Path(rq, rp)) => both(lq, rq, eq_qself) && eq_path(lp, rp), - (MacCall(l), MacCall(r)) => eq_mac_call(l, r), - (Struct(lse), Struct(rse)) => { - eq_maybe_qself(&lse.qself, &rse.qself) - && eq_path(&lse.path, &rse.path) - && eq_struct_rest(&lse.rest, &rse.rest) - && unordered_over(&lse.fields, &rse.fields, eq_field) - }, - _ => false, - } -} - -pub fn eq_field(l: &ExprField, r: &ExprField) -> bool { - l.is_placeholder == r.is_placeholder - && eq_id(l.ident, r.ident) - && eq_expr(&l.expr, &r.expr) - && over(&l.attrs, &r.attrs, eq_attr) -} - -pub fn eq_arm(l: &Arm, r: &Arm) -> bool { - l.is_placeholder == r.is_placeholder - && eq_pat(&l.pat, &r.pat) - && eq_expr_opt(&l.body, &r.body) - && eq_expr_opt(&l.guard, &r.guard) - && over(&l.attrs, &r.attrs, eq_attr) -} - -pub fn eq_label(l: &Option