solidhunter_lib/rules/security/
state_visibility.rs

1use crate::linter::SolidFile;
2use crate::rules::types::*;
3use crate::types::*;
4use osmium_libs_solidity_ast_extractor::*;
5
6// global
7pub const RULE_ID: &str = "state-visibility";
8
9// specific
10const DEFAULT_SEVERITY: Severity = Severity::WARNING;
11const DEFAULT_MESSAGE: &str = "Explicitly mark visibility of state";
12
13pub struct StateVisibility {
14    data: RuleEntry,
15}
16
17impl StateVisibility {
18    fn create_diag(&self, location: (LineColumn, LineColumn), file: &SolidFile) -> LintDiag {
19        LintDiag {
20            id: RULE_ID.to_string(),
21            range: Range {
22                start: Position {
23                    line: location.0.line,
24                    character: location.0.column,
25                },
26                end: Position {
27                    line: location.1.line,
28                    character: location.1.column,
29                },
30            },
31            message: DEFAULT_MESSAGE.to_string(),
32            severity: self.data.severity,
33            code: None,
34            source: None,
35            uri: file.path.clone(),
36        }
37    }
38}
39
40impl RuleType for StateVisibility {
41    fn diagnose(&self, file: &SolidFile, _files: &[SolidFile]) -> Vec<LintDiag> {
42        let mut res = Vec::new();
43        let contracts = retriever::retrieve_contract_nodes(&file.data);
44
45        for contract in contracts.iter() {
46            for node_var in contract.body.iter() {
47                if let Item::Variable(var) = node_var {
48                    if var.attributes.visibility().is_none() {
49                        let span = var.name.span();
50                        res.push(self.create_diag((span.start(), span.end()), file));
51                    }
52                }
53            }
54        }
55        res
56    }
57}
58
59impl StateVisibility {
60    pub(crate) fn create(data: RuleEntry) -> Box<dyn RuleType> {
61        let rule = StateVisibility { data };
62        Box::new(rule)
63    }
64
65    pub(crate) fn create_default() -> RuleEntry {
66        RuleEntry {
67            id: RULE_ID.to_string(),
68            severity: DEFAULT_SEVERITY,
69            data: None,
70        }
71    }
72}