Reduce unnecessary allocations for keyword detection (#5817)

This commit is contained in:
Charlie Marsh 2023-07-16 22:22:30 -04:00 committed by GitHub
parent 1c0376a72d
commit 94998aedef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 70 additions and 77 deletions

View file

@ -2623,7 +2623,7 @@ where
}
}
if self.enabled(Rule::NoExplicitStacklevel) {
flake8_bugbear::rules::no_explicit_stacklevel(self, func, args, keywords);
flake8_bugbear::rules::no_explicit_stacklevel(self, func, keywords);
}
if self.enabled(Rule::UnnecessaryDictKwargs) {
flake8_pie::rules::unnecessary_dict_kwargs(self, expr, keywords);
@ -2647,7 +2647,7 @@ where
flake8_bandit::rules::snmp_weak_cryptography(self, func, args, keywords);
}
if self.enabled(Rule::Jinja2AutoescapeFalse) {
flake8_bandit::rules::jinja2_autoescape_false(self, func, args, keywords);
flake8_bandit::rules::jinja2_autoescape_false(self, func, keywords);
}
if self.enabled(Rule::HardcodedPasswordFuncArg) {
flake8_bandit::rules::hardcoded_password_func_arg(self, keywords);
@ -2661,15 +2661,13 @@ where
);
}
if self.enabled(Rule::RequestWithoutTimeout) {
flake8_bandit::rules::request_without_timeout(self, func, args, keywords);
flake8_bandit::rules::request_without_timeout(self, func, keywords);
}
if self.enabled(Rule::ParamikoCall) {
flake8_bandit::rules::paramiko_call(self, func);
}
if self.enabled(Rule::LoggingConfigInsecureListen) {
flake8_bandit::rules::logging_config_insecure_listen(
self, func, args, keywords,
);
flake8_bandit::rules::logging_config_insecure_listen(self, func, keywords);
}
if self.any_enabled(&[
Rule::SubprocessWithoutShellEqualsTrue,

View file

@ -2,7 +2,6 @@ use rustpython_parser::ast::{self, Constant, Expr, Keyword, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::helpers::SimpleCallArgs;
use crate::checkers::ast::Checker;
@ -30,12 +29,7 @@ impl Violation for Jinja2AutoescapeFalse {
}
/// S701
pub(crate) fn jinja2_autoescape_false(
checker: &mut Checker,
func: &Expr,
args: &[Expr],
keywords: &[Keyword],
) {
pub(crate) fn jinja2_autoescape_false(checker: &mut Checker, func: &Expr, keywords: &[Keyword]) {
if checker
.semantic()
.resolve_call_path(func)
@ -43,10 +37,13 @@ pub(crate) fn jinja2_autoescape_false(
matches!(call_path.as_slice(), ["jinja2", "Environment"])
})
{
let call_args = SimpleCallArgs::new(args, keywords);
if let Some(autoescape_arg) = call_args.keyword_argument("autoescape") {
match autoescape_arg {
if let Some(keyword) = keywords.iter().find(|keyword| {
keyword
.arg
.as_ref()
.map_or(false, |arg| arg.as_str() == "autoescape")
}) {
match &keyword.value {
Expr::Constant(ast::ExprConstant {
value: Constant::Bool(true),
..
@ -56,14 +53,14 @@ pub(crate) fn jinja2_autoescape_false(
if id != "select_autoescape" {
checker.diagnostics.push(Diagnostic::new(
Jinja2AutoescapeFalse { value: true },
autoescape_arg.range(),
keyword.range(),
));
}
}
}
_ => checker.diagnostics.push(Diagnostic::new(
Jinja2AutoescapeFalse { value: true },
autoescape_arg.range(),
keyword.range(),
)),
}
} else {

View file

@ -2,7 +2,6 @@ use rustpython_parser::ast::{Expr, Keyword, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::helpers::SimpleCallArgs;
use crate::checkers::ast::Checker;
@ -20,7 +19,6 @@ impl Violation for LoggingConfigInsecureListen {
pub(crate) fn logging_config_insecure_listen(
checker: &mut Checker,
func: &Expr,
args: &[Expr],
keywords: &[Keyword],
) {
if checker
@ -30,12 +28,17 @@ pub(crate) fn logging_config_insecure_listen(
matches!(call_path.as_slice(), ["logging", "config", "listen"])
})
{
let call_args = SimpleCallArgs::new(args, keywords);
if keywords.iter().any(|keyword| {
keyword
.arg
.as_ref()
.map_or(false, |arg| arg.as_str() == "verify")
}) {
return;
}
if call_args.keyword_argument("verify").is_none() {
checker
.diagnostics
.push(Diagnostic::new(LoggingConfigInsecureListen, func.range()));
}
}
}

View file

@ -63,18 +63,18 @@ pub(crate) fn request_with_no_cert_validation(
_ => None,
})
{
if let Some(arg) = keywords.iter().find(|keyword| {
if let Some(keyword) = keywords.iter().find(|keyword| {
keyword
.arg
.as_ref()
.map_or(false, |arg| arg.as_str() == "verify")
}) {
if is_const_false(&arg.value) {
if is_const_false(&keyword.value) {
checker.diagnostics.push(Diagnostic::new(
RequestWithNoCertValidation {
string: target.to_string(),
},
arg.range(),
keyword.range(),
));
}
}

View file

@ -2,7 +2,7 @@ use rustpython_parser::ast::{Expr, Keyword, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::helpers::{is_const_none, SimpleCallArgs};
use ruff_python_ast::helpers::is_const_none;
use crate::checkers::ast::Checker;
@ -49,12 +49,7 @@ impl Violation for RequestWithoutTimeout {
}
/// S113
pub(crate) fn request_without_timeout(
checker: &mut Checker,
func: &Expr,
args: &[Expr],
keywords: &[Keyword],
) {
pub(crate) fn request_without_timeout(checker: &mut Checker, func: &Expr, keywords: &[Keyword]) {
if checker
.semantic()
.resolve_call_path(func)
@ -68,12 +63,16 @@ pub(crate) fn request_without_timeout(
)
})
{
let call_args = SimpleCallArgs::new(args, keywords);
if let Some(timeout) = call_args.keyword_argument("timeout") {
if is_const_none(timeout) {
if let Some(keyword) = keywords.iter().find(|keyword| {
keyword
.arg
.as_ref()
.map_or(false, |arg| arg.as_str() == "timeout")
}) {
if is_const_none(&keyword.value) {
checker.diagnostics.push(Diagnostic::new(
RequestWithoutTimeout { implicit: false },
timeout.range(),
keyword.range(),
));
}
} else {

View file

@ -50,7 +50,7 @@ pub(crate) fn snmp_insecure_version(checker: &mut Checker, func: &Expr, keywords
matches!(call_path.as_slice(), ["pysnmp", "hlapi", "CommunityData"])
})
{
if let Some(arg) = keywords.iter().find(|keyword| {
if let Some(keyword) = keywords.iter().find(|keyword| {
keyword
.arg
.as_ref()
@ -59,12 +59,12 @@ pub(crate) fn snmp_insecure_version(checker: &mut Checker, func: &Expr, keywords
if let Expr::Constant(ast::ExprConstant {
value: Constant::Int(value),
..
}) = &arg.value
}) = &keyword.value
{
if value.is_zero() || value.is_one() {
checker
.diagnostics
.push(Diagnostic::new(SnmpInsecureVersion, arg.range()));
.push(Diagnostic::new(SnmpInsecureVersion, keyword.range()));
}
}
}

View file

@ -11,11 +11,11 @@ S113.py:3:1: S113 Probable use of requests call without timeout
5 | requests.get('https://gmail.com', timeout=5)
|
S113.py:4:43: S113 Probable use of requests call with timeout set to `None`
S113.py:4:35: S113 Probable use of requests call with timeout set to `None`
|
3 | requests.get('https://gmail.com')
4 | requests.get('https://gmail.com', timeout=None)
| ^^^^ S113
| ^^^^^^^^^^^^ S113
5 | requests.get('https://gmail.com', timeout=5)
6 | requests.post('https://gmail.com')
|
@ -30,12 +30,12 @@ S113.py:6:1: S113 Probable use of requests call without timeout
8 | requests.post('https://gmail.com', timeout=5)
|
S113.py:7:44: S113 Probable use of requests call with timeout set to `None`
S113.py:7:36: S113 Probable use of requests call with timeout set to `None`
|
5 | requests.get('https://gmail.com', timeout=5)
6 | requests.post('https://gmail.com')
7 | requests.post('https://gmail.com', timeout=None)
| ^^^^ S113
| ^^^^^^^^^^^^ S113
8 | requests.post('https://gmail.com', timeout=5)
9 | requests.put('https://gmail.com')
|
@ -50,12 +50,12 @@ S113.py:9:1: S113 Probable use of requests call without timeout
11 | requests.put('https://gmail.com', timeout=5)
|
S113.py:10:43: S113 Probable use of requests call with timeout set to `None`
S113.py:10:35: S113 Probable use of requests call with timeout set to `None`
|
8 | requests.post('https://gmail.com', timeout=5)
9 | requests.put('https://gmail.com')
10 | requests.put('https://gmail.com', timeout=None)
| ^^^^ S113
| ^^^^^^^^^^^^ S113
11 | requests.put('https://gmail.com', timeout=5)
12 | requests.delete('https://gmail.com')
|
@ -70,12 +70,12 @@ S113.py:12:1: S113 Probable use of requests call without timeout
14 | requests.delete('https://gmail.com', timeout=5)
|
S113.py:13:46: S113 Probable use of requests call with timeout set to `None`
S113.py:13:38: S113 Probable use of requests call with timeout set to `None`
|
11 | requests.put('https://gmail.com', timeout=5)
12 | requests.delete('https://gmail.com')
13 | requests.delete('https://gmail.com', timeout=None)
| ^^^^ S113
| ^^^^^^^^^^^^ S113
14 | requests.delete('https://gmail.com', timeout=5)
15 | requests.patch('https://gmail.com')
|
@ -90,12 +90,12 @@ S113.py:15:1: S113 Probable use of requests call without timeout
17 | requests.patch('https://gmail.com', timeout=5)
|
S113.py:16:45: S113 Probable use of requests call with timeout set to `None`
S113.py:16:37: S113 Probable use of requests call with timeout set to `None`
|
14 | requests.delete('https://gmail.com', timeout=5)
15 | requests.patch('https://gmail.com')
16 | requests.patch('https://gmail.com', timeout=None)
| ^^^^ S113
| ^^^^^^^^^^^^ S113
17 | requests.patch('https://gmail.com', timeout=5)
18 | requests.options('https://gmail.com')
|
@ -110,12 +110,12 @@ S113.py:18:1: S113 Probable use of requests call without timeout
20 | requests.options('https://gmail.com', timeout=5)
|
S113.py:19:47: S113 Probable use of requests call with timeout set to `None`
S113.py:19:39: S113 Probable use of requests call with timeout set to `None`
|
17 | requests.patch('https://gmail.com', timeout=5)
18 | requests.options('https://gmail.com')
19 | requests.options('https://gmail.com', timeout=None)
| ^^^^ S113
| ^^^^^^^^^^^^ S113
20 | requests.options('https://gmail.com', timeout=5)
21 | requests.head('https://gmail.com')
|
@ -130,12 +130,12 @@ S113.py:21:1: S113 Probable use of requests call without timeout
23 | requests.head('https://gmail.com', timeout=5)
|
S113.py:22:44: S113 Probable use of requests call with timeout set to `None`
S113.py:22:36: S113 Probable use of requests call with timeout set to `None`
|
20 | requests.options('https://gmail.com', timeout=5)
21 | requests.head('https://gmail.com')
22 | requests.head('https://gmail.com', timeout=None)
| ^^^^ S113
| ^^^^^^^^^^^^ S113
23 | requests.head('https://gmail.com', timeout=5)
|

View file

@ -1,32 +1,32 @@
---
source: crates/ruff/src/rules/flake8_bandit/mod.rs
---
S701.py:9:68: S701 Using jinja2 templates with `autoescape=False` is dangerous and can lead to XSS. Ensure `autoescape=True` or use the `select_autoescape` function.
S701.py:9:57: S701 Using jinja2 templates with `autoescape=False` is dangerous and can lead to XSS. Ensure `autoescape=True` or use the `select_autoescape` function.
|
7 | templateEnv = jinja2.Environment(autoescape=True,
8 | loader=templateLoader )
9 | Environment(loader=templateLoader, load=templateLoader, autoescape=something) # S701
| ^^^^^^^^^ S701
| ^^^^^^^^^^^^^^^^^^^^ S701
10 | templateEnv = jinja2.Environment(autoescape=False, loader=templateLoader ) # S701
11 | Environment(loader=templateLoader,
|
S701.py:10:45: S701 Using jinja2 templates with `autoescape=False` is dangerous and can lead to XSS. Ensure `autoescape=True` or use the `select_autoescape` function.
S701.py:10:34: S701 Using jinja2 templates with `autoescape=False` is dangerous and can lead to XSS. Ensure `autoescape=True` or use the `select_autoescape` function.
|
8 | loader=templateLoader )
9 | Environment(loader=templateLoader, load=templateLoader, autoescape=something) # S701
10 | templateEnv = jinja2.Environment(autoescape=False, loader=templateLoader ) # S701
| ^^^^^ S701
| ^^^^^^^^^^^^^^^^ S701
11 | Environment(loader=templateLoader,
12 | load=templateLoader,
|
S701.py:13:24: S701 Using jinja2 templates with `autoescape=False` is dangerous and can lead to XSS. Ensure `autoescape=True` or use the `select_autoescape` function.
S701.py:13:13: S701 Using jinja2 templates with `autoescape=False` is dangerous and can lead to XSS. Ensure `autoescape=True` or use the `select_autoescape` function.
|
11 | Environment(loader=templateLoader,
12 | load=templateLoader,
13 | autoescape=False) # S701
| ^^^^^ S701
| ^^^^^^^^^^^^^^^^ S701
14 |
15 | Environment(loader=templateLoader, # S701
|
@ -40,12 +40,12 @@ S701.py:15:1: S701 By default, jinja2 sets `autoescape` to `False`. Consider usi
16 | load=templateLoader)
|
S701.py:29:47: S701 Using jinja2 templates with `autoescape=False` is dangerous and can lead to XSS. Ensure `autoescape=True` or use the `select_autoescape` function.
S701.py:29:36: S701 Using jinja2 templates with `autoescape=False` is dangerous and can lead to XSS. Ensure `autoescape=True` or use the `select_autoescape` function.
|
27 | def fake_func():
28 | return 'foobar'
29 | Environment(loader=templateLoader, autoescape=fake_func()) # S701
| ^^^^^^^^^^^ S701
| ^^^^^^^^^^^^^^^^^^^^^^ S701
|

View file

@ -2,7 +2,6 @@ use rustpython_parser::ast::{Expr, Keyword, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::helpers::SimpleCallArgs;
use crate::checkers::ast::Checker;
@ -38,12 +37,7 @@ impl Violation for NoExplicitStacklevel {
}
/// B028
pub(crate) fn no_explicit_stacklevel(
checker: &mut Checker,
func: &Expr,
args: &[Expr],
keywords: &[Keyword],
) {
pub(crate) fn no_explicit_stacklevel(checker: &mut Checker, func: &Expr, keywords: &[Keyword]) {
if !checker
.semantic()
.resolve_call_path(func)
@ -54,10 +48,12 @@ pub(crate) fn no_explicit_stacklevel(
return;
}
if SimpleCallArgs::new(args, keywords)
.keyword_argument("stacklevel")
.is_some()
{
if keywords.iter().any(|keyword| {
keyword
.arg
.as_ref()
.map_or(false, |arg| arg.as_str() == "stacklevel")
}) {
return;
}