eric6/Plugins/CheckerPlugins/CodeStyleChecker/Security/SecurityNodeVisitor.py

changeset 7613
382f89c11e27
parent 7612
ca1ce1e0fcff
child 7651
ca87b7490449
equal deleted inserted replaced
7612:ca1ce1e0fcff 7613:382f89c11e27
16 class SecurityNodeVisitor(object): 16 class SecurityNodeVisitor(object):
17 """ 17 """
18 Class implementing an AST node visitor for security checks. 18 Class implementing an AST node visitor for security checks.
19 """ 19 """
20 def __init__(self, checker, secCheckers, filename): 20 def __init__(self, checker, secCheckers, filename):
21 """
22 Constructor
23
24 @param checker reference to the main security checker object
25 @type SecurityChecker
26 @param secCheckers dictionary containing the available checker routines
27 @type dict
28 @param filename name of the checked file
29 @type str
30 """
21 self.__checker = checker 31 self.__checker = checker
22 self.__securityCheckers = secCheckers 32 self.__securityCheckers = secCheckers
23 33
24 self.seen = 0 34 self.seen = 0
25 self.depth = 0 35 self.depth = 0
34 self.namespace = "" 44 self.namespace = ""
35 45
36 def __runChecks(self, checkType): 46 def __runChecks(self, checkType):
37 """ 47 """
38 Private method to run all enabled checks for a given check type. 48 Private method to run all enabled checks for a given check type.
49
50 @param checkType type of checks to be run
51 @type str
39 """ 52 """
40 if checkType in self.__securityCheckers: 53 if checkType in self.__securityCheckers:
41 for check in self.__securityCheckers[checkType]: 54 for check in self.__securityCheckers[checkType]:
42 check(self.__checker.reportError, 55 check(self.__checker.reportError,
43 SecurityContext(self.__context), 56 SecurityContext(self.__context),
95 name = qualname.split('.')[-1] 108 name = qualname.split('.')[-1]
96 self.__context['qualname'] = qualname 109 self.__context['qualname'] = qualname
97 self.__context['name'] = name 110 self.__context['name'] = name
98 self.__runChecks("Call") 111 self.__runChecks("Call")
99 112
113 def visit_Import(self, node):
114 """
115 Public method defining a visitor for AST Import nodes.
116
117 @param node reference to the node being inspected
118 @type ast.Import
119 """
120 for nodename in node.names:
121 if nodename.asname:
122 self.import_aliases[nodename.asname] = nodename.name
123 self.imports.add(nodename.name)
124 self.__context['module'] = nodename.name
125 self.__runChecks("Import")
126
127 def visit_ImportFrom(self, node):
128 """
129 Public method defining a visitor for AST Import nodes.
130
131 This adds relevant information about the node to
132 the context for use in tests which inspect imports.
133
134 @param node reference to the node being inspected
135 @type ast.ImportFrom
136 """
137 module = node.module
138 if module is None:
139 self.visit_Import(node)
140 return
141
142 for nodename in node.names:
143 if nodename.asname:
144 self.import_aliases[nodename.asname] = (
145 module + "." + nodename.name
146 )
147 else:
148 # Even if import is not aliased we need an entry that maps
149 # name to module.name. For example, with 'from a import b'
150 # b should be aliased to the qualified name a.b
151 self.import_aliases[nodename.name] = (
152 module + '.' + nodename.name)
153 self.imports.add(module + "." + nodename.name)
154 self.__context['module'] = module
155 self.__context['name'] = nodename.name
156 self.__runChecks("ImportFrom")
157
158 def visit_Constant(self, node):
159 """
160 Public method defining a visitor for Constant nodes.
161
162 This calls the appropriate method for the node type.
163 It maintains compatibility with <3.6 and 3.8+
164
165 @param node reference to the node being inspected
166 @type ast.Constant
167 """
168 if isinstance(node.value, str):
169 self.visit_Str(node)
170 elif isinstance(node.value, bytes):
171 self.visit_Bytes(node)
172
173 def visit_Str(self, node):
174 """
175 Public method defining a visitor for String nodes.
176
177 This adds relevant information about node to
178 the context for use in tests which inspect strings.
179
180 @param node reference to the node being inspected
181 @type ast.Str
182 """
183 self.__context['str'] = node.s
184 if not isinstance(node._securityParent, ast.Expr): # docstring
185 self.__context['linerange'] = SecurityUtils.linerange_fix(
186 node._securityParent
187 )
188 self.__runChecks("Str")
189
190 def visit_Bytes(self, node):
191 """
192 Public method defining a visitor for Bytes nodes.
193
194 This adds relevant information about node to
195 the context for use in tests which inspect strings.
196
197 @param node reference to the node being inspected
198 @type ast.Bytes
199 """
200 self.__context['bytes'] = node.s
201 if not isinstance(node._securityParent, ast.Expr): # docstring
202 self.__context['linerange'] = SecurityUtils.linerange_fix(
203 node._securityParent
204 )
205 self.__runChecks("Bytes")
206
100 def __preVisit(self, node): 207 def __preVisit(self, node):
101 """ 208 """
102 Private method to set up a context for the visit method. 209 Private method to set up a context for the visit method.
103 210
104 @param node node to base the context on 211 @param node node to base the context on
105 @type ast.AST 212 @type ast.AST
213 @return flag indicating to visit the node
214 @rtype bool
106 """ 215 """
107 self.__context = {} 216 self.__context = {}
108 self.__context['imports'] = self.imports 217 self.__context['imports'] = self.imports
109 self.__context['import_aliases'] = self.import_aliases 218 self.__context['import_aliases'] = self.import_aliases
110 219
111 if hasattr(node, 'lineno'): 220 if hasattr(node, 'lineno'):
112 self.__context['lineno'] = node.lineno 221 self.__context['lineno'] = node.lineno
113 ## 222 ##
114 ## if node.lineno in self.nosec_lines: 223 ## if node.lineno in self.nosec_lines:
115 ## LOG.debug("skipped, nosec") 224 ## LOG.debug("skipped, nosec")
116 ## self.metrics.note_nosec() 225 ## self.metrics.note_nosec()
117 ## return False 226 ## return False
118 227

eric ide

mercurial