new regex syntax lint, fixes #597
This commit is contained in:
parent
b90288eced
commit
3d85cc24e7
7 changed files with 81 additions and 4 deletions
|
|
@ -28,6 +28,9 @@ extern crate unicode_normalization;
|
|||
// for semver check in attrs.rs
|
||||
extern crate semver;
|
||||
|
||||
// for regex checking
|
||||
extern crate regex_syntax;
|
||||
|
||||
extern crate rustc_plugin;
|
||||
|
||||
use rustc_plugin::Registry;
|
||||
|
|
@ -82,6 +85,7 @@ pub mod derive;
|
|||
pub mod print;
|
||||
pub mod vec;
|
||||
pub mod drop_ref;
|
||||
pub mod regex;
|
||||
|
||||
mod reexport {
|
||||
pub use syntax::ast::{Name, NodeId};
|
||||
|
|
@ -150,7 +154,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
|
|||
reg.register_late_lint_pass(box vec::UselessVec);
|
||||
reg.register_late_lint_pass(box drop_ref::DropRefPass);
|
||||
reg.register_late_lint_pass(box types::AbsurdUnsignedComparisons);
|
||||
|
||||
reg.register_late_lint_pass(box regex::RegexPass);
|
||||
|
||||
reg.register_lint_group("clippy_pedantic", vec![
|
||||
matches::SINGLE_MATCH_ELSE,
|
||||
|
|
@ -163,7 +167,6 @@ pub fn plugin_registrar(reg: &mut Registry) {
|
|||
shadow::SHADOW_REUSE,
|
||||
shadow::SHADOW_SAME,
|
||||
shadow::SHADOW_UNRELATED,
|
||||
strings::STRING_ADD,
|
||||
strings::STRING_ADD_ASSIGN,
|
||||
types::CAST_POSSIBLE_TRUNCATION,
|
||||
types::CAST_POSSIBLE_WRAP,
|
||||
|
|
@ -250,6 +253,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
|
|||
ptr_arg::PTR_ARG,
|
||||
ranges::RANGE_STEP_BY_ZERO,
|
||||
ranges::RANGE_ZIP_WITH_LEN,
|
||||
regex::INVALID_REGEX,
|
||||
returns::LET_AND_RETURN,
|
||||
returns::NEEDLESS_RETURN,
|
||||
strings::STRING_LIT_AS_BYTES,
|
||||
|
|
|
|||
53
src/regex.rs
Normal file
53
src/regex.rs
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
use regex_syntax;
|
||||
use std::error::Error;
|
||||
use syntax::codemap::{Span, BytePos, Pos};
|
||||
use rustc_front::hir::*;
|
||||
use rustc::middle::const_eval::{eval_const_expr_partial, ConstVal};
|
||||
use rustc::middle::const_eval::EvalHint::ExprTypeChecked;
|
||||
use rustc::lint::*;
|
||||
|
||||
use utils::{match_path, REGEX_NEW_PATH, span_lint};
|
||||
|
||||
/// **What it does:** This lint checks `Regex::new(_)` invocations for correct regex syntax. It is `deny` by default.
|
||||
///
|
||||
/// **Why is this bad?** This will lead to a runtime panic.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:** `Regex::new("|")`
|
||||
declare_lint! {
|
||||
pub INVALID_REGEX,
|
||||
Deny,
|
||||
"finds invalid regular expressions in `Regex::new(_)` invocations"
|
||||
}
|
||||
|
||||
#[derive(Copy,Clone)]
|
||||
pub struct RegexPass;
|
||||
|
||||
impl LintPass for RegexPass {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(INVALID_REGEX)
|
||||
}
|
||||
}
|
||||
|
||||
impl LateLintPass for RegexPass {
|
||||
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
if_let_chain!{[
|
||||
let ExprCall(ref fun, ref args) = expr.node,
|
||||
let ExprPath(_, ref path) = fun.node,
|
||||
match_path(path, ®EX_NEW_PATH) && args.len() == 1,
|
||||
let Ok(ConstVal::Str(r)) = eval_const_expr_partial(cx.tcx,
|
||||
&*args[0],
|
||||
ExprTypeChecked,
|
||||
None),
|
||||
let Err(e) = regex_syntax::Expr::parse(&r)
|
||||
], {
|
||||
let lo = args[0].span.lo + BytePos::from_usize(e.position());
|
||||
let span = Span{ lo: lo, hi: lo, expn_id: args[0].span.expn_id };
|
||||
span_lint(cx,
|
||||
INVALID_REGEX,
|
||||
span,
|
||||
&format!("Regex syntax error: {}", e.description()));
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
|
@ -36,6 +36,7 @@ pub const LL_PATH: [&'static str; 3] = ["collections", "linked_list", "LinkedLis
|
|||
pub const MUTEX_PATH: [&'static str; 4] = ["std", "sync", "mutex", "Mutex"];
|
||||
pub const OPEN_OPTIONS_PATH: [&'static str; 3] = ["std", "fs", "OpenOptions"];
|
||||
pub const OPTION_PATH: [&'static str; 3] = ["core", "option", "Option"];
|
||||
pub const REGEX_NEW_PATH: [&'static str; 3] = ["regex", "Regex", "new"];
|
||||
pub const RESULT_PATH: [&'static str; 3] = ["core", "result", "Result"];
|
||||
pub const STRING_PATH: [&'static str; 3] = ["collections", "string", "String"];
|
||||
pub const VEC_FROM_ELEM_PATH: [&'static str; 3] = ["std", "vec", "from_elem"];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue