-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement flake8-bandit rule S108
#1644
Changes from 2 commits
7705ba2
86b702b
9db9e7b
0607199
f8023ff
92cfb48
d0cbb9f
c10b60c
de0f4cd
a01ca93
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# ok | ||
with open("/abc/tmp", "w") as f: | ||
f.write("def") | ||
|
||
with open("/tmp/abc", "w") as f: | ||
f.write("def") | ||
|
||
with open("/var/tmp/123", "w") as f: | ||
f.write("def") | ||
|
||
with open("/dev/shm/unit/test", "w") as f: | ||
f.write("def") | ||
|
||
# not ok by config | ||
with open("/foo/bar", "w") as f: | ||
f.write("def") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
use rustpython_ast::Expr; | ||
|
||
use crate::ast::types::Range; | ||
use crate::registry::{Check, CheckKind}; | ||
|
||
/// S108 | ||
pub fn hardcoded_tmp_dir<'a>( | ||
expr: &Expr, | ||
value: &str, | ||
prefixes: &mut impl Iterator<Item = &'a String>, | ||
) -> Option<Check> { | ||
if prefixes.any(|prefix| value.starts_with(prefix)) { | ||
Some(Check::new( | ||
CheckKind::HardcodedTempFile(value.to_string()), | ||
Range::from_located(expr), | ||
)) | ||
} else { | ||
None | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
//! Settings for the `flake8-bandit` plugin. | ||
|
||
use ruff_macros::ConfigurationOptions; | ||
use schemars::JsonSchema; | ||
use serde::{Deserialize, Serialize}; | ||
|
||
fn default_tmp_dirs() -> Vec<String> { | ||
["/tmp", "/var/tmp", "/dev/shm"] | ||
.map(std::string::ToString::to_string) | ||
.to_vec() | ||
} | ||
|
||
#[derive( | ||
Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions, JsonSchema, | ||
)] | ||
#[serde( | ||
deny_unknown_fields, | ||
rename_all = "kebab-case", | ||
rename = "Flake8BanditOptions" | ||
)] | ||
pub struct Options { | ||
#[option( | ||
default = "[\"/tmp\", \"/var/tmp\", \"/dev/shm\"]", | ||
value_type = "Vec<String>", | ||
example = "hardcoded_tmp_directory = [\"/foo/bar\"]" | ||
)] | ||
/// List of directories that are considered temporary. | ||
pub hardcoded_tmp_directory: Option<Vec<String>>, | ||
#[option( | ||
default = "[]", | ||
value_type = "Vec<String>", | ||
example = "extend_hardcoded_tmp_directory = [\"/foo/bar\"]" | ||
)] | ||
/// List of directories that are considered temporary. | ||
/// These directories are added to the list in | ||
/// `hardcoded_tmp_directory`. | ||
pub hardcoded_tmp_directory_extend: Option<Vec<String>>, | ||
} | ||
|
||
#[derive(Debug, Hash)] | ||
pub struct Settings { | ||
pub hardcoded_tmp_directory: Vec<String>, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could consider just having There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, that makes sense. |
||
pub hardcoded_tmp_directory_extend: Vec<String>, | ||
} | ||
|
||
impl From<Options> for Settings { | ||
fn from(options: Options) -> Self { | ||
Self { | ||
hardcoded_tmp_directory: options | ||
.hardcoded_tmp_directory | ||
.unwrap_or_else(default_tmp_dirs), | ||
hardcoded_tmp_directory_extend: options | ||
.hardcoded_tmp_directory_extend | ||
.unwrap_or_default(), | ||
} | ||
} | ||
} | ||
impl From<Settings> for Options { | ||
fn from(settings: Settings) -> Self { | ||
Self { | ||
hardcoded_tmp_directory: Some(settings.hardcoded_tmp_directory), | ||
hardcoded_tmp_directory_extend: Some(settings.hardcoded_tmp_directory_extend), | ||
} | ||
} | ||
} | ||
|
||
impl Default for Settings { | ||
fn default() -> Self { | ||
Self { | ||
hardcoded_tmp_directory: default_tmp_dirs(), | ||
hardcoded_tmp_directory_extend: Vec::new(), | ||
} | ||
} | ||
} | ||
|
||
impl Settings { | ||
/// Returns an iterator over all directories that are considered temporary. | ||
pub fn all_hardcoded_tmp_directories(&'_ self) -> impl Iterator<Item = &'_ String> { | ||
self.hardcoded_tmp_directory | ||
.iter() | ||
.chain(self.hardcoded_tmp_directory_extend.iter()) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks reasonable to me. For other plugins, we tend to use the default, and create dedicated test-cases for overridden settings. But this is cool too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the feedback. These were a bit unreadable so I refactored them.