Skip to content

Commit

Permalink
Merge pull request #258 from CoinFabrik/fix-unsafe-block
Browse files Browse the repository at this point in the history
Fix unsafe block
  • Loading branch information
tenuki authored Apr 26, 2024
2 parents ba2723c + 7a18104 commit 5fbdd3c
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 54 deletions.
64 changes: 12 additions & 52 deletions detectors/avoid-unsafe-block/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,76 +1,36 @@
#![feature(rustc_private)]
#![warn(unused_extern_crates)]
#![feature(let_chains)]
extern crate rustc_hir;
extern crate rustc_ast;
extern crate rustc_span;

use std::vec::Vec;

use rustc_hir::{
intravisit::{walk_expr, Visitor},
BlockCheckMode, Expr, ExprKind,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_span::Span;
use scout_audit_clippy_utils::diagnostics;
use rustc_ast::{BlockCheckMode, Expr, ExprKind, UnsafeSource};
use rustc_lint::{EarlyContext, EarlyLintPass};
use scout_audit_clippy_utils::diagnostics::span_lint;

const LINT_MESSAGE: &str = "Avoid using unsafe blocks as it may lead to undefined behavior.";
dylint_linting::impl_late_lint! {
dylint_linting::impl_pre_expansion_lint! {
pub AVOID_UNSAFE_BLOCK,
Warn,
LINT_MESSAGE,
AvoidUnsafeBlock::default(),
{
name: "Avoid unsafe block",
long_message: "The unsafe block is used to bypass Rust's safety checks. It is recommended to avoid using unsafe blocks as much as possible, and to use them only when necessary. ",
long_message: "The unsafe block is used to bypass Rust's safety checks. It is recommended to avoid using unsafe blocks as much as possible, and to use them only when necessary.",
severity: "Enhancement",
help: "https://coinfabrik.github.io/scout/docs/vulnerabilities/avoid-unsafe-block",
vulnerability_class: "Best practices",
}
}

#[derive(Default)]
struct AvoidUnsafeBlock {}

impl<'tcx> LateLintPass<'tcx> for AvoidUnsafeBlock {
fn check_fn(
&mut self,
cx: &LateContext<'tcx>,
_: rustc_hir::intravisit::FnKind<'tcx>,
_: &'tcx rustc_hir::FnDecl<'tcx>,
body: &'tcx rustc_hir::Body<'tcx>,
_: rustc_span::Span,
_: rustc_span::def_id::LocalDefId,
) {
let mut unsafety = AvoidUnsafeBlockVisitor {
is_unsafe: false,
span: Vec::new(),
};

walk_expr(&mut unsafety, body.value);

if unsafety.is_unsafe {
for var in unsafety.span.iter() {
diagnostics::span_lint(cx, AVOID_UNSAFE_BLOCK, *var, LINT_MESSAGE)
}
}
}
}
pub struct AvoidUnsafeBlock {}

struct AvoidUnsafeBlockVisitor {
is_unsafe: bool,
span: Vec<Span>,
}

impl<'tcx> Visitor<'tcx> for AvoidUnsafeBlockVisitor {
fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
if let ExprKind::Block(block, _) = expr.kind
&& let BlockCheckMode::UnsafeBlock(_) = block.rules
impl EarlyLintPass for AvoidUnsafeBlock {
fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) {
if let ExprKind::Block(block, ..) = &expr.kind
&& block.rules == BlockCheckMode::Unsafe(UnsafeSource::UserProvided)
{
self.is_unsafe = true;
self.span.push(expr.span);
span_lint(cx, AVOID_UNSAFE_BLOCK, expr.span, LINT_MESSAGE)
}

walk_expr(self, expr)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "avoid-unsafe-block-remediated"
name = "avoid-unsafe-block-remediated-1"
version = "0.1.0"
authors = ["[your_name] <[your_email]>"]
edition = "2021"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "avoid-unsafe-block-vulnerable"
name = "avoid-unsafe-block-vulnerable-1"
version = "0.1.0"
authors = ["[your_name] <[your_email]>"]
edition = "2021"
Expand Down

0 comments on commit 5fbdd3c

Please sign in to comment.