codeanalyzer-python 1.5.3__py3-none-any.whl → 1.5.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- codeanalyzer/dataflow/sdg.py +26 -8
- codeanalyzer/entrypoints/matching.py +5 -1
- {codeanalyzer_python-1.5.3.dist-info → codeanalyzer_python-1.5.4.dist-info}/METADATA +1 -1
- {codeanalyzer_python-1.5.3.dist-info → codeanalyzer_python-1.5.4.dist-info}/RECORD +8 -8
- {codeanalyzer_python-1.5.3.dist-info → codeanalyzer_python-1.5.4.dist-info}/WHEEL +0 -0
- {codeanalyzer_python-1.5.3.dist-info → codeanalyzer_python-1.5.4.dist-info}/entry_points.txt +0 -0
- {codeanalyzer_python-1.5.3.dist-info → codeanalyzer_python-1.5.4.dist-info}/licenses/LICENSE +0 -0
- {codeanalyzer_python-1.5.3.dist-info → codeanalyzer_python-1.5.4.dist-info}/licenses/NOTICE +0 -0
codeanalyzer/dataflow/sdg.py
CHANGED
|
@@ -142,6 +142,26 @@ class _FunctionAssembler:
|
|
|
142
142
|
|
|
143
143
|
# ---------------------------------------------------------------- formals
|
|
144
144
|
|
|
145
|
+
def formal_for(self, var: str) -> Optional[int]:
|
|
146
|
+
"""The ``formal_in`` vertex that defines ``var`` in this callable.
|
|
147
|
+
|
|
148
|
+
A parameter, a capture and a read global are all defined at a
|
|
149
|
+
``formal_in`` port, not at the synthetic CFG ENTRY node. Reaching-def
|
|
150
|
+
analysis reports ENTRY as the source for all three, so every place that
|
|
151
|
+
consumes a raw def source has to remap it here, or the SDG loses the
|
|
152
|
+
hop from the parameter to whatever uses it. Returns ``None`` when
|
|
153
|
+
``var`` is not one of this callable's formals, so a caller can keep the
|
|
154
|
+
original source.
|
|
155
|
+
"""
|
|
156
|
+
b = base_of(var)
|
|
157
|
+
if b in self.formal_in:
|
|
158
|
+
return self.formal_in[b]
|
|
159
|
+
if CAPTURE_PREFIX + b in self.formal_in:
|
|
160
|
+
return self.formal_in[CAPTURE_PREFIX + b]
|
|
161
|
+
if "::" in b and GLOBAL_PREFIX + b in self.formal_in:
|
|
162
|
+
return self.formal_in[GLOBAL_PREFIX + b]
|
|
163
|
+
return None
|
|
164
|
+
|
|
145
165
|
def build_formals(self) -> None:
|
|
146
166
|
scope, summary = self.scope, self.summary
|
|
147
167
|
params = list(scope.params)
|
|
@@ -168,14 +188,8 @@ class _FunctionAssembler:
|
|
|
168
188
|
for e in self.ddg:
|
|
169
189
|
if e.source != entry:
|
|
170
190
|
continue
|
|
171
|
-
|
|
172
|
-
if
|
|
173
|
-
fid = self.formal_in[b]
|
|
174
|
-
elif CAPTURE_PREFIX + b in self.formal_in:
|
|
175
|
-
fid = self.formal_in[CAPTURE_PREFIX + b]
|
|
176
|
-
elif "::" in b and GLOBAL_PREFIX + b in self.formal_in:
|
|
177
|
-
fid = self.formal_in[GLOBAL_PREFIX + b]
|
|
178
|
-
else:
|
|
191
|
+
fid = self.formal_for(e.var)
|
|
192
|
+
if fid is None:
|
|
179
193
|
continue
|
|
180
194
|
self.extra.append(PDGEdge(source=fid, target=e.target, type="DDG", var=e.var))
|
|
181
195
|
|
|
@@ -268,6 +282,8 @@ class _FunctionAssembler:
|
|
|
268
282
|
for src, var in self._defs_reaching_call_matching(
|
|
269
283
|
cs.node_id, path
|
|
270
284
|
):
|
|
285
|
+
if src == self.cfg.entry_id:
|
|
286
|
+
src = self.formal_for(var) or src
|
|
271
287
|
self.extra.append(
|
|
272
288
|
PDGEdge(source=src, target=aid, type="DDG", var=var)
|
|
273
289
|
)
|
|
@@ -296,6 +312,8 @@ class _FunctionAssembler:
|
|
|
296
312
|
for src, var in self._defs_reaching_call_matching(
|
|
297
313
|
cs.node_id, g
|
|
298
314
|
):
|
|
315
|
+
if src == self.cfg.entry_id:
|
|
316
|
+
src = self.formal_for(var) or src
|
|
299
317
|
self.extra.append(
|
|
300
318
|
PDGEdge(source=src, target=aid, type="DDG", var=var)
|
|
301
319
|
)
|
|
@@ -104,8 +104,12 @@ def _methods_of(dec, spec: Optional[Dict[str, Any]], qualified: Optional[str] =
|
|
|
104
104
|
return []
|
|
105
105
|
source = spec.get("from")
|
|
106
106
|
if source == "match_suffix":
|
|
107
|
+
# Only a real verb: `heuristic.http-verb` also matches `.websocket`, and a
|
|
108
|
+
# rule may accept any suffix, but `http_methods` is what a consumer filters
|
|
109
|
+
# on to enumerate methods -- a value that is not one is worse there than an
|
|
110
|
+
# empty list (#213). The dispatch path below already filters the same way.
|
|
107
111
|
verb = (qualified or dec.qualified_name or "").rsplit(".", 1)[-1]
|
|
108
|
-
return [verb.upper()]
|
|
112
|
+
return [verb.upper()] if verb.lower() in _HTTP_VERBS else []
|
|
109
113
|
if source == "keyword":
|
|
110
114
|
raw = (dec.keyword_arguments or {}).get(spec.get("name", ""))
|
|
111
115
|
value = _literal(raw)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: codeanalyzer-python
|
|
3
|
-
Version: 1.5.
|
|
3
|
+
Version: 1.5.4
|
|
4
4
|
Summary: Static analysis for Python — canonical schema v2 (symbol table, call graph, and native CFG/PDG/SDG dataflow) as analysis.json or a Neo4j property graph.
|
|
5
5
|
Author-email: Rahul Krishna <i.m.ralk@gmail.com>
|
|
6
6
|
License-File: LICENSE
|
|
@@ -21,7 +21,7 @@ codeanalyzer/dataflow/identity.py,sha256=6aAz3iPSOpoS7l_moC7XGr2RS_GqJp_FlsWGglM
|
|
|
21
21
|
codeanalyzer/dataflow/pdg.py,sha256=1Bm7AnoRqXBryZulII2idPw0feV8eZQ1VqqprQ8PW-g,3731
|
|
22
22
|
codeanalyzer/dataflow/scalpel_oracle.py,sha256=FxRadKrTWar0VKHyQJM40n3cq25sld3Sj4lMdOm5NFk,11494
|
|
23
23
|
codeanalyzer/dataflow/scc.py,sha256=Doa_0-5f3agCu_5UmeEDlCUErg34TtniKIv8Uqd7Jiw,3493
|
|
24
|
-
codeanalyzer/dataflow/sdg.py,sha256=
|
|
24
|
+
codeanalyzer/dataflow/sdg.py,sha256=_dcR6nNc0ZTETaLHbmliEMeTG-AcQU0x-7DiB1cvoPs,19445
|
|
25
25
|
codeanalyzer/dataflow/slicing.py,sha256=lWZ7jHhlR8m7rECWJQXvwfs5GNZeJY55Cud3Ji5UbNU,3654
|
|
26
26
|
codeanalyzer/dataflow/summaries.py,sha256=TLtc5h4bLBC4lViuMhMlEp5rp_nBpDPOl4_wfBuRUY4,9210
|
|
27
27
|
codeanalyzer/dataflow/syntactic.py,sha256=AbHyXjKX_1xkGgKH48BpXYCWBauActGUwSMF_OD-uys,1124
|
|
@@ -38,7 +38,7 @@ codeanalyzer/dataflow/scalpel/core/func_call_visitor.py,sha256=ps0snjTchBXilhor3
|
|
|
38
38
|
codeanalyzer/dataflow/scalpel/core/vars_visitor.py,sha256=gE5fNyJS6jslD6vsMRbFLoy3n1xTwH-b54mBcNYO72M,5660
|
|
39
39
|
codeanalyzer/entrypoints/__init__.py,sha256=VaMd4mSEPLuPlRxxAve_nTJ9ZH62stXZGTPNwU_BQ50,99
|
|
40
40
|
codeanalyzer/entrypoints/detect.py,sha256=fsWRQz1njvB9d3LIJEHxsNFE1GrB7q52KCvozw_UIUQ,4594
|
|
41
|
-
codeanalyzer/entrypoints/matching.py,sha256=
|
|
41
|
+
codeanalyzer/entrypoints/matching.py,sha256=fppta04o1_HWBEHe6boV_7T964cdLuZlOoQHAW4yt0Q,8321
|
|
42
42
|
codeanalyzer/entrypoints/pipeline.py,sha256=vVSdttMfSAWour2fsC3LomMtwFLzRqmJHixJS82VY1I,7828
|
|
43
43
|
codeanalyzer/entrypoints/rules.py,sha256=yG772JHmNc2L10jIpxfg1xTh-QouJa6lNU9ubo3EZYg,6003
|
|
44
44
|
codeanalyzer/entrypoints/rules.yml,sha256=sguICRfDDNGjJPfZz-JSwkI_hzbTJaau1liHV_y4rTA,4637
|
|
@@ -70,9 +70,9 @@ codeanalyzer/syntactic_analysis/symbol_table_builder.py,sha256=tKed-VCSd_albMeZf
|
|
|
70
70
|
codeanalyzer/utils/__init__.py,sha256=hC6VWdR5rerSqBxzu9KQHTASWqwrrYJv-CMDwrTlzkc,137
|
|
71
71
|
codeanalyzer/utils/logging.py,sha256=Fw0tattPAOMs3o0JMjjXhRVLIF64f-SCcygUXF9jqeg,904
|
|
72
72
|
codeanalyzer/utils/progress_bar.py,sha256=C9JtzVdd10lIxTv-KA6PebqjKWueC_vMGwVzAtHuHIw,2818
|
|
73
|
-
codeanalyzer_python-1.5.
|
|
74
|
-
codeanalyzer_python-1.5.
|
|
75
|
-
codeanalyzer_python-1.5.
|
|
76
|
-
codeanalyzer_python-1.5.
|
|
77
|
-
codeanalyzer_python-1.5.
|
|
78
|
-
codeanalyzer_python-1.5.
|
|
73
|
+
codeanalyzer_python-1.5.4.dist-info/METADATA,sha256=pky-NFu9SoPYS5JNaPnJF4J-9yTTp02bDGA0qxkorpA,44845
|
|
74
|
+
codeanalyzer_python-1.5.4.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
75
|
+
codeanalyzer_python-1.5.4.dist-info/entry_points.txt,sha256=v4Vux0Nnx7sOntVk_CH7W9RX6SkIkvR1FQYq73oVlCQ,105
|
|
76
|
+
codeanalyzer_python-1.5.4.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
77
|
+
codeanalyzer_python-1.5.4.dist-info/licenses/NOTICE,sha256=MdVkNYqHJ20on2FmWvgD4WpMsX5mir33xdyPvTXd0A0,1223
|
|
78
|
+
codeanalyzer_python-1.5.4.dist-info/RECORD,,
|
|
File without changes
|
{codeanalyzer_python-1.5.3.dist-info → codeanalyzer_python-1.5.4.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{codeanalyzer_python-1.5.3.dist-info → codeanalyzer_python-1.5.4.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
|
File without changes
|