1
1
use clippy_utils:: diagnostics:: span_lint_and_sugg;
2
+ use clippy_utils:: numeric_literal:: { NumericLiteral , Radix } ;
2
3
use clippy_utils:: source:: { snippet_opt, snippet_with_applicability} ;
3
4
use clippy_utils:: { match_def_path, paths} ;
5
+ use rustc_ast:: LitKind ;
4
6
use rustc_errors:: Applicability ;
5
7
use rustc_hir:: { Expr , ExprKind } ;
6
8
use rustc_lint:: { LateContext , LateLintPass } ;
@@ -39,6 +41,24 @@ declare_clippy_lint! {
39
41
40
42
declare_lint_pass ! ( NonOctalUnixPermissions => [ NON_OCTAL_UNIX_PERMISSIONS ] ) ;
41
43
44
+ fn check_binary_unix_permissions ( lit_kind : & LitKind , snip : & str ) -> bool {
45
+ // support binary unix permissions
46
+ if let Some ( num_lit) = NumericLiteral :: from_lit_kind ( snip, lit_kind) {
47
+ if num_lit. radix != Radix :: Binary {
48
+ return false ;
49
+ }
50
+
51
+ let group_sizes: Vec < usize > = num_lit. integer . split ( '_' ) . map ( str:: len) . collect ( ) ;
52
+ // check whether is binary format unix permissions
53
+ if group_sizes. len ( ) != 3 {
54
+ return false ;
55
+ }
56
+ group_sizes. iter ( ) . all ( |len| * len == 3 )
57
+ } else {
58
+ false
59
+ }
60
+ }
61
+
42
62
impl < ' tcx > LateLintPass < ' tcx > for NonOctalUnixPermissions {
43
63
fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' tcx > ) {
44
64
match & expr. kind {
@@ -51,26 +71,22 @@ impl<'tcx> LateLintPass<'tcx> for NonOctalUnixPermissions {
51
71
) )
52
72
|| ( path. ident . name == sym ! ( set_mode)
53
73
&& cx. tcx . is_diagnostic_item ( sym:: FsPermissions , adt. did ( ) ) ) )
54
- && let ExprKind :: Lit ( _ ) = param. kind
74
+ && let ExprKind :: Lit ( lit_kind ) = param. kind
55
75
&& param. span . eq_ctxt ( expr. span )
76
+ && let Some ( snip) = snippet_opt ( cx, param. span )
77
+ && !( snip. starts_with ( "0o" ) || check_binary_unix_permissions ( & lit_kind. node , & snip) )
56
78
{
57
- let Some ( snip) = snippet_opt ( cx, param. span ) else {
58
- return ;
59
- } ;
60
-
61
- if !snip. starts_with ( "0o" ) {
62
- show_error ( cx, param) ;
63
- }
79
+ show_error ( cx, param) ;
64
80
}
65
81
} ,
66
82
ExprKind :: Call ( func, [ param] ) => {
67
83
if let ExprKind :: Path ( ref path) = func. kind
68
84
&& let Some ( def_id) = cx. qpath_res ( path, func. hir_id ) . opt_def_id ( )
69
85
&& match_def_path ( cx, def_id, & paths:: PERMISSIONS_FROM_MODE )
70
- && let ExprKind :: Lit ( _ ) = param. kind
86
+ && let ExprKind :: Lit ( lit_kind ) = param. kind
71
87
&& param. span . eq_ctxt ( expr. span )
72
88
&& let Some ( snip) = snippet_opt ( cx, param. span )
73
- && !snip. starts_with ( "0o" )
89
+ && !( snip. starts_with ( "0o" ) || check_binary_unix_permissions ( & lit_kind . node , & snip ) )
74
90
{
75
91
show_error ( cx, param) ;
76
92
}
0 commit comments