Skip to content

Commit 521e6de

Browse files
Fix eval detection for suspicious-eval-usage (#5506)
Closes #5505.
1 parent 0b963dd commit 521e6de

File tree

7 files changed

+52
-15
lines changed

7 files changed

+52
-15
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import os
2+
3+
print(eval("1+1")) # S307
4+
print(eval("os.getcwd()")) # S307
5+
6+
7+
class Class(object):
8+
def eval(self):
9+
print("hi")
10+
11+
def foo(self):
12+
self.eval() # OK

crates/ruff/src/checkers/ast/mod.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -2584,9 +2584,7 @@ where
25842584
flake8_pie::rules::unnecessary_dict_kwargs(self, expr, keywords);
25852585
}
25862586
if self.enabled(Rule::ExecBuiltin) {
2587-
if let Some(diagnostic) = flake8_bandit::rules::exec_used(expr, func) {
2588-
self.diagnostics.push(diagnostic);
2589-
}
2587+
flake8_bandit::rules::exec_used(self, func);
25902588
}
25912589
if self.enabled(Rule::BadFilePermissions) {
25922590
flake8_bandit::rules::bad_file_permissions(self, func, args, keywords);

crates/ruff/src/rules/flake8_bandit/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ mod tests {
3939
#[test_case(Rule::SubprocessPopenWithShellEqualsTrue, Path::new("S602.py"))]
4040
#[test_case(Rule::SubprocessWithoutShellEqualsTrue, Path::new("S603.py"))]
4141
#[test_case(Rule::SuspiciousPickleUsage, Path::new("S301.py"))]
42+
#[test_case(Rule::SuspiciousEvalUsage, Path::new("S307.py"))]
4243
#[test_case(Rule::SuspiciousTelnetUsage, Path::new("S312.py"))]
4344
#[test_case(Rule::TryExceptContinue, Path::new("S112.py"))]
4445
#[test_case(Rule::TryExceptPass, Path::new("S110.py"))]
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
use rustpython_parser::ast::{self, Expr, Ranged};
1+
use rustpython_parser::ast::{Expr, Ranged};
22

33
use ruff_diagnostics::{Diagnostic, Violation};
44
use ruff_macros::{derive_message_formats, violation};
55

6+
use crate::checkers::ast::Checker;
7+
68
#[violation]
79
pub struct ExecBuiltin;
810

@@ -14,12 +16,16 @@ impl Violation for ExecBuiltin {
1416
}
1517

1618
/// S102
17-
pub(crate) fn exec_used(expr: &Expr, func: &Expr) -> Option<Diagnostic> {
18-
let Expr::Name(ast::ExprName { id, .. }) = func else {
19-
return None;
20-
};
21-
if id != "exec" {
22-
return None;
19+
pub(crate) fn exec_used(checker: &mut Checker, func: &Expr) {
20+
if checker
21+
.semantic()
22+
.resolve_call_path(func)
23+
.map_or(false, |call_path| {
24+
matches!(call_path.as_slice(), ["" | "builtin", "exec"])
25+
})
26+
{
27+
checker
28+
.diagnostics
29+
.push(Diagnostic::new(ExecBuiltin, func.range()));
2330
}
24-
Some(Diagnostic::new(ExecBuiltin, expr.range()))
2531
}

crates/ruff/src/rules/flake8_bandit/rules/suspicious_function_call.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ impl Violation for SuspiciousFTPLibUsage {
219219
}
220220
}
221221

222-
/// S001
222+
/// S301, S302, S303, S304, S305, S306, S307, S308, S310, S311, S312, S313, S314, S315, S316, S317, S318, S319, S320, S321, S323
223223
pub(crate) fn suspicious_function_call(checker: &mut Checker, expr: &Expr) {
224224
let Expr::Call(ast::ExprCall { func, .. }) = expr else {
225225
return;
@@ -246,7 +246,7 @@ pub(crate) fn suspicious_function_call(checker: &mut Checker, expr: &Expr) {
246246
// Mktemp
247247
["tempfile", "mktemp"] => Some(SuspiciousMktempUsage.into()),
248248
// Eval
249-
["eval"] => Some(SuspiciousEvalUsage.into()),
249+
["" | "builtins", "eval"] => Some(SuspiciousEvalUsage.into()),
250250
// MarkSafe
251251
["django", "utils", "safestring", "mark_safe"] => Some(SuspiciousMarkSafeUsage.into()),
252252
// URLOpen

crates/ruff/src/rules/flake8_bandit/snapshots/ruff__rules__flake8_bandit__tests__S102_S102.py.snap

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ S102.py:3:5: S102 Use of `exec` detected
66
1 | def fn():
77
2 | # Error
88
3 | exec('x = 2')
9-
| ^^^^^^^^^^^^^ S102
9+
| ^^^^ S102
1010
4 |
1111
5 | exec('y = 3')
1212
|
@@ -16,7 +16,7 @@ S102.py:5:1: S102 Use of `exec` detected
1616
3 | exec('x = 2')
1717
4 |
1818
5 | exec('y = 3')
19-
| ^^^^^^^^^^^^^ S102
19+
| ^^^^ S102
2020
|
2121

2222

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
source: crates/ruff/src/rules/flake8_bandit/mod.rs
3+
---
4+
S307.py:3:7: S307 Use of possibly insecure function; consider using `ast.literal_eval`
5+
|
6+
1 | import os
7+
2 |
8+
3 | print(eval("1+1")) # S307
9+
| ^^^^^^^^^^^ S307
10+
4 | print(eval("os.getcwd()")) # S307
11+
|
12+
13+
S307.py:4:7: S307 Use of possibly insecure function; consider using `ast.literal_eval`
14+
|
15+
3 | print(eval("1+1")) # S307
16+
4 | print(eval("os.getcwd()")) # S307
17+
| ^^^^^^^^^^^^^^^^^^^ S307
18+
|
19+
20+

0 commit comments

Comments
 (0)