mirror of https://github.com/astral-sh/ruff
[`flake8-bandit`] Add Rule S110 (try/except/pass) (#2197)
This commit is contained in:
parent
b692921160
commit
dd15c69181
19
README.md
19
README.md
|
|
@ -826,6 +826,7 @@ For more, see [flake8-bandit](https://pypi.org/project/flake8-bandit/) on PyPI.
|
||||||
| S106 | hardcoded-password-func-arg | Possible hardcoded password: "{}" | |
|
| S106 | hardcoded-password-func-arg | Possible hardcoded password: "{}" | |
|
||||||
| S107 | hardcoded-password-default | Possible hardcoded password: "{}" | |
|
| S107 | hardcoded-password-default | Possible hardcoded password: "{}" | |
|
||||||
| S108 | hardcoded-temp-file | Probable insecure usage of temporary file or directory: "{}" | |
|
| S108 | hardcoded-temp-file | Probable insecure usage of temporary file or directory: "{}" | |
|
||||||
|
| S110 | try-except-pass | `try`-`except`-`pass` detected, consider logging the exception | |
|
||||||
| S113 | request-without-timeout | Probable use of requests call with timeout set to `{value}` | |
|
| S113 | request-without-timeout | Probable use of requests call with timeout set to `{value}` | |
|
||||||
| S324 | hashlib-insecure-hash-function | Probable use of insecure hash functions in `hashlib`: "{}" | |
|
| S324 | hashlib-insecure-hash-function | Probable use of insecure hash functions in `hashlib`: "{}" | |
|
||||||
| S501 | request-with-no-cert-validation | Probable use of `{string}` call with `verify=False` disabling SSL certificate checks | |
|
| S501 | request-with-no-cert-validation | Probable use of `{string}` call with `verify=False` disabling SSL certificate checks | |
|
||||||
|
|
@ -2682,6 +2683,24 @@ suppress-none-returning = true
|
||||||
|
|
||||||
### `flake8-bandit`
|
### `flake8-bandit`
|
||||||
|
|
||||||
|
#### [`check-typed-exception`](#check-typed-exception)
|
||||||
|
|
||||||
|
Whether to disallow `try`-`except`-`pass` (`S110`) for specific exception types. By default,
|
||||||
|
`try`-`except`-`pass` is only disallowed for `Exception` and `BaseException`.
|
||||||
|
|
||||||
|
**Default value**: `false`
|
||||||
|
|
||||||
|
**Type**: `bool`
|
||||||
|
|
||||||
|
**Example usage**:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[tool.ruff.flake8-bandit]
|
||||||
|
check-typed-exception = true
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
#### [`hardcoded-tmp-directory`](#hardcoded-tmp-directory)
|
#### [`hardcoded-tmp-directory`](#hardcoded-tmp-directory)
|
||||||
|
|
||||||
A list of directories to consider temporary.
|
A list of directories to consider temporary.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
try:
|
||||||
|
pass
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
pass
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
@ -578,6 +578,13 @@
|
||||||
"Flake8BanditOptions": {
|
"Flake8BanditOptions": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"check-typed-exception": {
|
||||||
|
"description": "Whether to disallow `try`-`except`-`pass` (`S110`) for specific exception types. By default, `try`-`except`-`pass` is only disallowed for `Exception` and `BaseException`.",
|
||||||
|
"type": [
|
||||||
|
"boolean",
|
||||||
|
"null"
|
||||||
|
]
|
||||||
|
},
|
||||||
"hardcoded-tmp-directory": {
|
"hardcoded-tmp-directory": {
|
||||||
"description": "A list of directories to consider temporary.",
|
"description": "A list of directories to consider temporary.",
|
||||||
"type": [
|
"type": [
|
||||||
|
|
@ -1753,6 +1760,7 @@
|
||||||
"S107",
|
"S107",
|
||||||
"S108",
|
"S108",
|
||||||
"S11",
|
"S11",
|
||||||
|
"S110",
|
||||||
"S113",
|
"S113",
|
||||||
"S3",
|
"S3",
|
||||||
"S32",
|
"S32",
|
||||||
|
|
|
||||||
|
|
@ -3447,6 +3447,15 @@ where
|
||||||
body,
|
body,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if self.settings.rules.enabled(&Rule::TryExceptPass) {
|
||||||
|
flake8_bandit::rules::try_except_pass(
|
||||||
|
self,
|
||||||
|
type_.as_deref(),
|
||||||
|
name.as_deref(),
|
||||||
|
body,
|
||||||
|
self.settings.flake8_bandit.check_typed_exception,
|
||||||
|
);
|
||||||
|
}
|
||||||
if self.settings.rules.enabled(&Rule::ReraiseNoCause) {
|
if self.settings.rules.enabled(&Rule::ReraiseNoCause) {
|
||||||
tryceratops::rules::reraise_no_cause(self, body);
|
tryceratops::rules::reraise_no_cause(self, body);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -333,6 +333,7 @@ ruff_macros::define_rule_mapping!(
|
||||||
S106 => violations::HardcodedPasswordFuncArg,
|
S106 => violations::HardcodedPasswordFuncArg,
|
||||||
S107 => violations::HardcodedPasswordDefault,
|
S107 => violations::HardcodedPasswordDefault,
|
||||||
S108 => violations::HardcodedTempFile,
|
S108 => violations::HardcodedTempFile,
|
||||||
|
S110 => rules::flake8_bandit::rules::TryExceptPass,
|
||||||
S113 => violations::RequestWithoutTimeout,
|
S113 => violations::RequestWithoutTimeout,
|
||||||
S324 => violations::HashlibInsecureHashFunction,
|
S324 => violations::HashlibInsecureHashFunction,
|
||||||
S501 => violations::RequestWithNoCertValidation,
|
S501 => violations::RequestWithNoCertValidation,
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ mod tests {
|
||||||
#[test_case(Rule::SnmpWeakCryptography, Path::new("S509.py"); "S509")]
|
#[test_case(Rule::SnmpWeakCryptography, Path::new("S509.py"); "S509")]
|
||||||
#[test_case(Rule::LoggingConfigInsecureListen, Path::new("S612.py"); "S612")]
|
#[test_case(Rule::LoggingConfigInsecureListen, Path::new("S612.py"); "S612")]
|
||||||
#[test_case(Rule::Jinja2AutoescapeFalse, Path::new("S701.py"); "S701")]
|
#[test_case(Rule::Jinja2AutoescapeFalse, Path::new("S701.py"); "S701")]
|
||||||
|
#[test_case(Rule::TryExceptPass, Path::new("S110.py"); "S110")]
|
||||||
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
|
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||||
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
|
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
|
||||||
let diagnostics = test_path(
|
let diagnostics = test_path(
|
||||||
|
|
@ -55,6 +56,7 @@ mod tests {
|
||||||
"/dev/shm".to_string(),
|
"/dev/shm".to_string(),
|
||||||
"/foo".to_string(),
|
"/foo".to_string(),
|
||||||
],
|
],
|
||||||
|
check_typed_exception: false,
|
||||||
},
|
},
|
||||||
..Settings::for_rule(Rule::HardcodedTempFile)
|
..Settings::for_rule(Rule::HardcodedTempFile)
|
||||||
},
|
},
|
||||||
|
|
@ -62,4 +64,20 @@ mod tests {
|
||||||
assert_yaml_snapshot!("S108_extend", diagnostics);
|
assert_yaml_snapshot!("S108_extend", diagnostics);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_typed_exception() -> Result<()> {
|
||||||
|
let diagnostics = test_path(
|
||||||
|
Path::new("./resources/test/fixtures/flake8_bandit/S110.py"),
|
||||||
|
&Settings {
|
||||||
|
flake8_bandit: super::settings::Settings {
|
||||||
|
check_typed_exception: true,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
..Settings::for_rule(Rule::TryExceptPass)
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
assert_yaml_snapshot!("S110_typed", diagnostics);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ pub use request_with_no_cert_validation::request_with_no_cert_validation;
|
||||||
pub use request_without_timeout::request_without_timeout;
|
pub use request_without_timeout::request_without_timeout;
|
||||||
pub use snmp_insecure_version::snmp_insecure_version;
|
pub use snmp_insecure_version::snmp_insecure_version;
|
||||||
pub use snmp_weak_cryptography::snmp_weak_cryptography;
|
pub use snmp_weak_cryptography::snmp_weak_cryptography;
|
||||||
|
pub use try_except_pass::{try_except_pass, TryExceptPass};
|
||||||
pub use unsafe_yaml_load::unsafe_yaml_load;
|
pub use unsafe_yaml_load::unsafe_yaml_load;
|
||||||
|
|
||||||
mod assert_used;
|
mod assert_used;
|
||||||
|
|
@ -34,4 +35,5 @@ mod request_with_no_cert_validation;
|
||||||
mod request_without_timeout;
|
mod request_without_timeout;
|
||||||
mod snmp_insecure_version;
|
mod snmp_insecure_version;
|
||||||
mod snmp_weak_cryptography;
|
mod snmp_weak_cryptography;
|
||||||
|
mod try_except_pass;
|
||||||
mod unsafe_yaml_load;
|
mod unsafe_yaml_load;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
|
use rustpython_ast::{Expr, Stmt, StmtKind};
|
||||||
|
|
||||||
|
use crate::ast::types::Range;
|
||||||
|
use crate::checkers::ast::Checker;
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::registry::Diagnostic;
|
||||||
|
use crate::violation::Violation;
|
||||||
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct TryExceptPass;
|
||||||
|
);
|
||||||
|
impl Violation for TryExceptPass {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("`try`-`except`-`pass` detected, consider logging the exception")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// S110
|
||||||
|
pub fn try_except_pass(
|
||||||
|
checker: &mut Checker,
|
||||||
|
type_: Option<&Expr>,
|
||||||
|
_name: Option<&str>,
|
||||||
|
body: &[Stmt],
|
||||||
|
check_typed_exception: bool,
|
||||||
|
) {
|
||||||
|
if body.len() == 1
|
||||||
|
&& body[0].node == StmtKind::Pass
|
||||||
|
&& (check_typed_exception
|
||||||
|
|| type_.map_or(true, |type_| {
|
||||||
|
checker.resolve_call_path(type_).map_or(true, |call_path| {
|
||||||
|
call_path.as_slice() == ["", "Exception"]
|
||||||
|
|| call_path.as_slice() == ["", "BaseException"]
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
|
TryExceptPass,
|
||||||
|
Range::from_located(&body[0]),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -34,11 +34,20 @@ pub struct Options {
|
||||||
/// A list of directories to consider temporary, in addition to those
|
/// A list of directories to consider temporary, in addition to those
|
||||||
/// specified by `hardcoded-tmp-directory`.
|
/// specified by `hardcoded-tmp-directory`.
|
||||||
pub hardcoded_tmp_directory_extend: Option<Vec<String>>,
|
pub hardcoded_tmp_directory_extend: Option<Vec<String>>,
|
||||||
|
#[option(
|
||||||
|
default = "false",
|
||||||
|
value_type = "bool",
|
||||||
|
example = "check-typed-exception = true"
|
||||||
|
)]
|
||||||
|
/// Whether to disallow `try`-`except`-`pass` (`S110`) for specific exception types. By default,
|
||||||
|
/// `try`-`except`-`pass` is only disallowed for `Exception` and `BaseException`.
|
||||||
|
pub check_typed_exception: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Hash)]
|
#[derive(Debug, Hash)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
pub hardcoded_tmp_directory: Vec<String>,
|
pub hardcoded_tmp_directory: Vec<String>,
|
||||||
|
pub check_typed_exception: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Options> for Settings {
|
impl From<Options> for Settings {
|
||||||
|
|
@ -55,6 +64,7 @@ impl From<Options> for Settings {
|
||||||
.into_iter(),
|
.into_iter(),
|
||||||
)
|
)
|
||||||
.collect(),
|
.collect(),
|
||||||
|
check_typed_exception: options.check_typed_exception.unwrap_or(false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -64,6 +74,7 @@ impl From<Settings> for Options {
|
||||||
Self {
|
Self {
|
||||||
hardcoded_tmp_directory: Some(settings.hardcoded_tmp_directory),
|
hardcoded_tmp_directory: Some(settings.hardcoded_tmp_directory),
|
||||||
hardcoded_tmp_directory_extend: None,
|
hardcoded_tmp_directory_extend: None,
|
||||||
|
check_typed_exception: Some(settings.check_typed_exception),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -72,6 +83,7 @@ impl Default for Settings {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
hardcoded_tmp_directory: default_tmp_dirs(),
|
hardcoded_tmp_directory: default_tmp_dirs(),
|
||||||
|
check_typed_exception: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
---
|
||||||
|
source: src/rules/flake8_bandit/mod.rs
|
||||||
|
expression: diagnostics
|
||||||
|
---
|
||||||
|
- kind:
|
||||||
|
TryExceptPass: ~
|
||||||
|
location:
|
||||||
|
row: 4
|
||||||
|
column: 4
|
||||||
|
end_location:
|
||||||
|
row: 4
|
||||||
|
column: 8
|
||||||
|
fix: ~
|
||||||
|
parent: ~
|
||||||
|
- kind:
|
||||||
|
TryExceptPass: ~
|
||||||
|
location:
|
||||||
|
row: 9
|
||||||
|
column: 4
|
||||||
|
end_location:
|
||||||
|
row: 9
|
||||||
|
column: 8
|
||||||
|
fix: ~
|
||||||
|
parent: ~
|
||||||
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
---
|
||||||
|
source: src/rules/flake8_bandit/mod.rs
|
||||||
|
expression: diagnostics
|
||||||
|
---
|
||||||
|
- kind:
|
||||||
|
TryExceptPass: ~
|
||||||
|
location:
|
||||||
|
row: 4
|
||||||
|
column: 4
|
||||||
|
end_location:
|
||||||
|
row: 4
|
||||||
|
column: 8
|
||||||
|
fix: ~
|
||||||
|
parent: ~
|
||||||
|
- kind:
|
||||||
|
TryExceptPass: ~
|
||||||
|
location:
|
||||||
|
row: 9
|
||||||
|
column: 4
|
||||||
|
end_location:
|
||||||
|
row: 9
|
||||||
|
column: 8
|
||||||
|
fix: ~
|
||||||
|
parent: ~
|
||||||
|
- kind:
|
||||||
|
TryExceptPass: ~
|
||||||
|
location:
|
||||||
|
row: 14
|
||||||
|
column: 4
|
||||||
|
end_location:
|
||||||
|
row: 14
|
||||||
|
column: 8
|
||||||
|
fix: ~
|
||||||
|
parent: ~
|
||||||
|
|
||||||
Loading…
Reference in New Issue