diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 57fcb6a..d5f84d2 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -5,41 +5,44 @@ on: branches: [master] pull_request: +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +env: + CARGO_TERM_COLOR: always + jobs: ci: - name: Continuous Integration + name: Dylint (nightly) runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - - name: Install system dependencies - run: | - sudo apt-get update - sudo apt-get install -y \ - pkg-config \ - libssl-dev \ - libgit2-dev \ - libcurl4-openssl-dev \ - build-essential - - - uses: dtolnay/rust-toolchain@nightly + - uses: dtolnay/rust-toolchain@v1 with: - components: rustc-dev,rust-src,llvm-tools-preview + toolchain: nightly + components: rustfmt, clippy, rustc-dev, rust-src, llvm-tools-preview - - uses: actions/cache@v4 - with: - path: | - ~/.cargo/registry - ~/.cargo/git - target - ~/.dylint_drivers - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-cargo- - - - name: Install Dylint - run: cargo install cargo-dylint dylint-link --locked - - - name: Run Dylint - run: cargo dylint --workspace --all + - name: Ensure cargo in PATH + run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH + + - uses: Swatinem/rust-cache@v2 + + - uses: cargo-bins/cargo-binstall@main + + - name: Install dependencies + run: | + cargo binstall -y \ + cargo-make \ + cargo-deny \ + cargo-audit \ + cargo-dylint \ + dylint-link + + - name: Run CI + run: cargo make ci diff --git a/.gitignore b/.gitignore index ad67955..4782745 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +# OS generated files +.DS_Store +Thumbs.db + # Generated by Cargo # will have compiled files and executables debug diff --git a/.vscode/settings.json b/.vscode/settings.json index 4d3b473..ebfed16 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -30,6 +30,7 @@ "dylint", "krate", "qpath", + "rustflags", "rustsec", "rustup", "typeck", diff --git a/Makefile.toml b/Makefile.toml index 35f775e..53f22b3 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -115,5 +115,6 @@ args = [ "ubuntu-latest=ghcr.io/catthehacker/ubuntu:full-latest", "--container-architecture", "linux/amd64", + "--rm", ] workspace = false diff --git a/deny.toml b/deny.toml index 1faf1e1..15a591c 100644 --- a/deny.toml +++ b/deny.toml @@ -3,12 +3,7 @@ confidence-threshold = 0.9 allow = [ "MIT", "Apache-2.0", - "BSD-2-Clause", - "BSD-3-Clause", - "ISC", - "Zlib", "Unicode-3.0", - "CDLA-Permissive-2.0", ] [bans] diff --git a/rules/indexing_usage/src/lib.rs b/rules/indexing_usage/src/lib.rs index ac50efc..c65927c 100644 --- a/rules/indexing_usage/src/lib.rs +++ b/rules/indexing_usage/src/lib.rs @@ -33,51 +33,47 @@ impl<'tcx> LateLintPass<'tcx> for SecurityIndexingUsage { context: &LateContext<'tcx>, expression: &'tcx Expr<'tcx>, ) { - match &expression.kind { - ExprKind::Index(_, index_expr, _) => { - match &index_expr.kind { - // Literal indexing: array[0]. - ExprKind::Lit(_) => { - context.span_lint( - SECURITY_INDEXING_USAGE, - expression.span, - |diagnostic: &mut Diag<'_, ()>| { - diagnostic.primary_message( - "Usage of indexing operation detected.", - ); - }, - ); - }, + if let ExprKind::Index(_, index_expr, _) = &expression.kind { + match &index_expr.kind { + // Literal indexing: array[0]. + ExprKind::Lit(_) => { + context.span_lint( + SECURITY_INDEXING_USAGE, + expression.span, + |diagnostic: &mut Diag<'_, ()>| { + diagnostic.primary_message( + "Usage of indexing operation detected.", + ); + }, + ); + }, - // Range slicing: array[1..], array[..], array[a..b]. - ExprKind::Struct(_, _, _) => { - context.span_lint( - SECURITY_INDEXING_USAGE, - expression.span, - |diagnostic: &mut Diag<'_, ()>| { - diagnostic.primary_message( - "Usage of slicing operation detected.", - ); - }, - ); - }, + // Range slicing: array[1..], array[..], array[a..b]. + ExprKind::Struct(_, _, _) => { + context.span_lint( + SECURITY_INDEXING_USAGE, + expression.span, + |diagnostic: &mut Diag<'_, ()>| { + diagnostic.primary_message( + "Usage of slicing operation detected.", + ); + }, + ); + }, - // Any other dynamic indexing: array[i]. - _ => { - context.span_lint( - SECURITY_INDEXING_USAGE, - expression.span, - |diagnostic: &mut Diag<'_, ()>| { - diagnostic.primary_message( - "Usage of indexing operation detected.", - ); - }, - ); - }, - } - }, - - _ => {}, + // Any other dynamic indexing: array[i]. + _ => { + context.span_lint( + SECURITY_INDEXING_USAGE, + expression.span, + |diagnostic: &mut Diag<'_, ()>| { + diagnostic.primary_message( + "Usage of indexing operation detected.", + ); + }, + ); + }, + } } } @@ -97,20 +93,18 @@ impl<'tcx> LateLintPass<'tcx> for SecurityIndexingUsage { if let ItemKind::Impl(implementation) = &item.kind && let Some(trait_ref) = implementation.of_trait && let Some(def_id) = trait_ref.trait_ref.path.res.opt_def_id() + && (context.tcx.lang_items().index_trait() == Some(def_id) + || context.tcx.lang_items().index_mut_trait() == Some(def_id)) { - if context.tcx.lang_items().index_trait() == Some(def_id) - || context.tcx.lang_items().index_mut_trait() == Some(def_id) - { - context.span_lint( - SECURITY_INDEXING_USAGE, - item.span, - |diagnostic: &mut Diag<'_, ()>| { - diagnostic.primary_message( - "Implementation of Index/IndexMut trait detected.", - ); - }, - ); - } + context.span_lint( + SECURITY_INDEXING_USAGE, + item.span, + |diagnostic: &mut Diag<'_, ()>| { + diagnostic.primary_message( + "Implementation of Index/IndexMut trait detected.", + ); + }, + ); } } } diff --git a/rules/missing_type/src/lib.rs b/rules/missing_type/src/lib.rs index 531d8e5..a0a50db 100644 --- a/rules/missing_type/src/lib.rs +++ b/rules/missing_type/src/lib.rs @@ -5,9 +5,10 @@ extern crate rustc_hir; extern crate rustc_lint; extern crate rustc_middle; extern crate rustc_session; +extern crate rustc_span; use rustc_errors::Diag; -use rustc_hir::{Body, Expr, ExprKind, LetStmt, PatKind}; +use rustc_hir::{Body, BodyId, Expr, ExprKind, LetStmt, PatKind}; use rustc_lint::{LateContext, LateLintPass, LintContext, LintStore}; use rustc_middle::ty::TyCtxt; use rustc_session::{Session, declare_lint, declare_lint_pass}; @@ -55,6 +56,17 @@ impl<'tcx> LateLintPass<'tcx> for MissingType { if matches!(local.pat.kind, PatKind::Wild) { return; } + + let Some(body_id): Option = context.enclosing_body else { + return; + }; + + // Skip if the let statement is from a macro expansion, as it may not + // be possible to determine the type annotation in that case. + if context.tcx.hir_body(body_id).value.span.from_expansion() { + return; + } + // Skip if the let statement is from a macro expansion, as it may not // be possible to determine the type annotation in that case. // Ignore anything coming from macro expansion (async_trait, derives, diff --git a/rules/panic_usage/src/lib.rs b/rules/panic_usage/src/lib.rs index 367941a..453a029 100644 --- a/rules/panic_usage/src/lib.rs +++ b/rules/panic_usage/src/lib.rs @@ -75,22 +75,20 @@ impl<'tcx> LateLintPass<'tcx> for SecurityPanicUsage { && let Some(def_id) = context .typeck_results() .type_dependent_def_id(expression.hir_id) - { - if context.tcx.is_diagnostic_item(sym::unwrap, def_id) + && (context.tcx.is_diagnostic_item(sym::unwrap, def_id) || context.tcx.is_diagnostic_item(sym::option_unwrap, def_id) || context.tcx.is_diagnostic_item(sym::except, def_id) - || context.tcx.is_diagnostic_item(sym::option_expect, def_id) - { - context.span_lint( - SECURITY_PANIC_USAGE, - expression.span, - |diagnostic: &mut Diag<'_, ()>| { - diagnostic.primary_message( - "Call to panic backend `unwrap/expect` detected.", - ); - }, - ); - } + || context.tcx.is_diagnostic_item(sym::option_expect, def_id)) + { + context.span_lint( + SECURITY_PANIC_USAGE, + expression.span, + |diagnostic: &mut Diag<'_, ()>| { + diagnostic.primary_message( + "Call to panic backend `unwrap/expect` detected.", + ); + }, + ); } // Detect calls to panic-related functions in the standard library.