-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
210 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
use clippy_utils::diagnostics::span_lint_and_sugg; | ||
use clippy_utils::source::{snippet_opt, snippet_with_applicability}; | ||
use clippy_utils::ty::match_type; | ||
use clippy_utils::{match_def_path, paths}; | ||
use if_chain::if_chain; | ||
use rustc_errors::Applicability; | ||
use rustc_hir::{Expr, ExprKind}; | ||
use rustc_lint::{LateContext, LateLintPass}; | ||
use rustc_session::{declare_lint_pass, declare_tool_lint}; | ||
|
||
declare_clippy_lint! { | ||
/// **What it does:** Checks for non-octal values used to set Unix file permissions. | ||
/// | ||
/// **Why is this bad?** They will be converted into octal, creating potentially | ||
/// unintended file permissions. | ||
/// | ||
/// **Known problems:** None. | ||
/// | ||
/// **Example:** | ||
/// | ||
/// ```rust | ||
/// use std::fs::OpenOptions; | ||
/// use std::os::unix::fs::OpenOptionsExt; | ||
/// | ||
/// let mut options = OpenOptions::new(); | ||
/// options.mode(644); | ||
/// ``` | ||
/// Use instead: | ||
/// ```rust | ||
/// use std::fs::OpenOptions; | ||
/// use std::os::unix::fs::OpenOptionsExt; | ||
/// | ||
/// let mut options = OpenOptions::new(); | ||
/// options.mode(0o644); | ||
/// ``` | ||
pub NON_OCTAL_UNIX_PERMISSIONS, | ||
correctness, | ||
"use of non-octal value to set unix file permissions, which will be translated into octal" | ||
} | ||
|
||
declare_lint_pass!(NonOctalUnixPermissions => [NON_OCTAL_UNIX_PERMISSIONS]); | ||
|
||
impl LateLintPass<'_> for NonOctalUnixPermissions { | ||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { | ||
match &expr.kind { | ||
ExprKind::MethodCall(path, _, [func, param], _) => { | ||
let obj_ty = cx.typeck_results().expr_ty(&func).peel_refs(); | ||
|
||
if_chain! { | ||
if (path.ident.name == sym!(mode) | ||
&& (match_type(cx, obj_ty, &paths::OPEN_OPTIONS) | ||
|| match_type(cx, obj_ty, &paths::DIR_BUILDER))) | ||
|| (path.ident.name == sym!(set_mode) && match_type(cx, obj_ty, &paths::PERMISSIONS)); | ||
if let ExprKind::Lit(_) = param.kind; | ||
|
||
then { | ||
let snip = match snippet_opt(cx, param.span) { | ||
Some(s) => s, | ||
_ => return, | ||
}; | ||
|
||
if !snip.starts_with("0o") { | ||
show_error(cx, param); | ||
} | ||
} | ||
} | ||
}, | ||
ExprKind::Call(ref func, [param]) => { | ||
if_chain! { | ||
if let ExprKind::Path(ref path) = func.kind; | ||
if let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id(); | ||
if match_def_path(cx, def_id, &paths::PERMISSIONS_FROM_MODE); | ||
if let ExprKind::Lit(_) = param.kind; | ||
|
||
then { | ||
let snip = match snippet_opt(cx, param.span) { | ||
Some(s) => s, | ||
_ => return, | ||
}; | ||
|
||
if !snip.starts_with("0o") { | ||
show_error(cx, param); | ||
} | ||
} | ||
} | ||
}, | ||
_ => {}, | ||
}; | ||
} | ||
} | ||
|
||
fn show_error(cx: &LateContext<'_>, param: &Expr<'_>) { | ||
let mut applicability = Applicability::MachineApplicable; | ||
span_lint_and_sugg( | ||
cx, | ||
NON_OCTAL_UNIX_PERMISSIONS, | ||
param.span, | ||
"using a non-octal value to set unix file permissions", | ||
"consider using an octal literal instead", | ||
format!( | ||
"0o{}", | ||
snippet_with_applicability(cx, param.span, "0o..", &mut applicability,), | ||
), | ||
applicability, | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// ignore-windows | ||
// run-rustfix | ||
#![warn(clippy::non_octal_unix_permissions)] | ||
use std::fs::{DirBuilder, File, OpenOptions, Permissions}; | ||
use std::os::unix::fs::{DirBuilderExt, OpenOptionsExt, PermissionsExt}; | ||
|
||
fn main() { | ||
let permissions = 0o760; | ||
|
||
// OpenOptionsExt::mode | ||
let mut options = OpenOptions::new(); | ||
options.mode(0o440); | ||
options.mode(0o400); | ||
options.mode(permissions); | ||
|
||
// PermissionsExt::from_mode | ||
let _permissions = Permissions::from_mode(0o647); | ||
let _permissions = Permissions::from_mode(0o000); | ||
let _permissions = Permissions::from_mode(permissions); | ||
|
||
// PermissionsExt::set_mode | ||
let f = File::create("foo.txt").unwrap(); | ||
let metadata = f.metadata().unwrap(); | ||
let mut permissions = metadata.permissions(); | ||
|
||
permissions.set_mode(0o644); | ||
permissions.set_mode(0o704); | ||
|
||
// DirBuilderExt::mode | ||
let mut builder = DirBuilder::new(); | ||
builder.mode(0o755); | ||
builder.mode(0o406); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// ignore-windows | ||
// run-rustfix | ||
#![warn(clippy::non_octal_unix_permissions)] | ||
use std::fs::{DirBuilder, File, OpenOptions, Permissions}; | ||
use std::os::unix::fs::{DirBuilderExt, OpenOptionsExt, PermissionsExt}; | ||
|
||
fn main() { | ||
let permissions = 0o760; | ||
|
||
// OpenOptionsExt::mode | ||
let mut options = OpenOptions::new(); | ||
options.mode(440); | ||
options.mode(0o400); | ||
options.mode(permissions); | ||
|
||
// PermissionsExt::from_mode | ||
let _permissions = Permissions::from_mode(647); | ||
let _permissions = Permissions::from_mode(0o000); | ||
let _permissions = Permissions::from_mode(permissions); | ||
|
||
// PermissionsExt::set_mode | ||
let f = File::create("foo.txt").unwrap(); | ||
let metadata = f.metadata().unwrap(); | ||
let mut permissions = metadata.permissions(); | ||
|
||
permissions.set_mode(644); | ||
permissions.set_mode(0o704); | ||
|
||
// DirBuilderExt::mode | ||
let mut builder = DirBuilder::new(); | ||
builder.mode(755); | ||
builder.mode(0o406); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
error: using a non-octal value to set unix file permissions | ||
--> $DIR/non_octal_unix_permissions.rs:12:18 | ||
| | ||
LL | options.mode(440); | ||
| ^^^ help: consider using an octal literal instead: `0o440` | ||
| | ||
= note: `-D clippy::non-octal-unix-permissions` implied by `-D warnings` | ||
|
||
error: using a non-octal value to set unix file permissions | ||
--> $DIR/non_octal_unix_permissions.rs:17:47 | ||
| | ||
LL | let _permissions = Permissions::from_mode(647); | ||
| ^^^ help: consider using an octal literal instead: `0o647` | ||
|
||
error: using a non-octal value to set unix file permissions | ||
--> $DIR/non_octal_unix_permissions.rs:26:26 | ||
| | ||
LL | permissions.set_mode(644); | ||
| ^^^ help: consider using an octal literal instead: `0o644` | ||
|
||
error: using a non-octal value to set unix file permissions | ||
--> $DIR/non_octal_unix_permissions.rs:31:18 | ||
| | ||
LL | builder.mode(755); | ||
| ^^^ help: consider using an octal literal instead: `0o755` | ||
|
||
error: aborting due to 4 previous errors | ||
|