sflkit 0.2.3__tar.gz → 0.2.5__tar.gz
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.
- {sflkit-0.2.3/src/SFLKit.egg-info → sflkit-0.2.5}/PKG-INFO +1 -1
- {sflkit-0.2.3 → sflkit-0.2.5}/pyproject.toml +1 -1
- {sflkit-0.2.3 → sflkit-0.2.5/src/SFLKit.egg-info}/PKG-INFO +1 -1
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/__init__.py +1 -1
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/analysis/analysis_type.py +14 -2
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/analysis/predicate.py +60 -1
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/analysis/spectra.py +25 -1
- {sflkit-0.2.3 → sflkit-0.2.5}/LICENSE +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/README.md +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/setup.cfg +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/setup.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/SFLKit.egg-info/SOURCES.txt +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/SFLKit.egg-info/dependency_links.txt +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/SFLKit.egg-info/entry_points.txt +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/SFLKit.egg-info/requires.txt +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/SFLKit.egg-info/top_level.txt +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/analysis/__init__.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/analysis/analyzer.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/analysis/factory.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/analysis/mapping.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/analysis/similarity.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/analysis/suggestion.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/cli.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/color.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/config.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/instrumentation/__init__.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/instrumentation/dir_instrumentation.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/instrumentation/file_instrumentation.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/language/__init__.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/language/extract.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/language/finder.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/language/language.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/language/meta.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/language/python/__init__.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/language/python/extract.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/language/python/factory.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/language/python/finder.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/language/python/visitor.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/language/visitor.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/model/__init__.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/model/event_file.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/model/model.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/model/scope.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/runners/__init__.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/src/sflkit/runners/run.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/tests/test_analysis_objects.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/tests/test_cli.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/tests/test_color.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/tests/test_config.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/tests/test_events.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/tests/test_execution.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/tests/test_instrumentation.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/tests/test_language.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/tests/test_predicates.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/tests/test_runner.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/tests/test_scope.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/tests/test_spectra.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/tests/test_suggestions.py +0 -0
- {sflkit-0.2.3 → sflkit-0.2.5}/tests/test_visitors.py +0 -0
|
@@ -6,7 +6,7 @@ from sflkit.analysis.predicate import Predicate
|
|
|
6
6
|
from sflkit.config import Config, parse_config
|
|
7
7
|
from sflkit.instrumentation.dir_instrumentation import DirInstrumentation
|
|
8
8
|
|
|
9
|
-
__version__ = "0.2.
|
|
9
|
+
__version__ = "0.2.5"
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
def instrument_config(conf: Config, event_dump: str = None):
|
|
@@ -5,6 +5,12 @@ from typing import List, Type
|
|
|
5
5
|
from sflkit.model.scope import Scope
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
class EvaluationResult(enum.Enum):
|
|
9
|
+
TRUE = 1
|
|
10
|
+
FALSE = 0
|
|
11
|
+
UNOBSERVED = -1
|
|
12
|
+
|
|
13
|
+
|
|
8
14
|
class AnalysisType(enum.Enum):
|
|
9
15
|
LINE = 0
|
|
10
16
|
BRANCH = 1
|
|
@@ -22,6 +28,12 @@ class AnalysisType(enum.Enum):
|
|
|
22
28
|
SPECIAL_STRING = 13
|
|
23
29
|
EMPTY_BYTES = 14
|
|
24
30
|
|
|
31
|
+
def __str__(self):
|
|
32
|
+
return self.name
|
|
33
|
+
|
|
34
|
+
def __repr__(self):
|
|
35
|
+
return self.name
|
|
36
|
+
|
|
25
37
|
|
|
26
38
|
"""
|
|
27
39
|
If you want to add new spectra or predicates, please register them here and in sflkit/language/.py
|
|
@@ -29,7 +41,6 @@ If you want to add new spectra or predicates, please register them here and in s
|
|
|
29
41
|
|
|
30
42
|
|
|
31
43
|
class AnalysisObject(object):
|
|
32
|
-
|
|
33
44
|
function_finder = None
|
|
34
45
|
loop_finder = None
|
|
35
46
|
branch_finder = None
|
|
@@ -43,12 +54,13 @@ class AnalysisObject(object):
|
|
|
43
54
|
# noinspection PyUnusedLocal
|
|
44
55
|
def __init__(self, event):
|
|
45
56
|
self.suspiciousness: float = 0
|
|
57
|
+
self.last_evaluation: EvaluationResult = EvaluationResult.UNOBSERVED
|
|
46
58
|
|
|
47
59
|
def __repr__(self):
|
|
48
60
|
return f"{self.analysis_type()}:{self.suspiciousness}"
|
|
49
61
|
|
|
50
62
|
def __str__(self):
|
|
51
|
-
return
|
|
63
|
+
return f"{self.analysis_type()}"
|
|
52
64
|
|
|
53
65
|
@staticmethod
|
|
54
66
|
@abstractmethod
|
|
@@ -5,7 +5,7 @@ from typing import Tuple, Callable, Optional
|
|
|
5
5
|
from sflkitlib.events import EventType
|
|
6
6
|
from sflkitlib.events.event import BranchEvent, FunctionExitEvent, DefEvent
|
|
7
7
|
|
|
8
|
-
from sflkit.analysis.analysis_type import AnalysisType
|
|
8
|
+
from sflkit.analysis.analysis_type import AnalysisType, EvaluationResult
|
|
9
9
|
from sflkit.analysis.spectra import Spectrum
|
|
10
10
|
from sflkit.analysis.suggestion import Suggestion, Location
|
|
11
11
|
from sflkit.model import scope
|
|
@@ -24,6 +24,17 @@ class Predicate(Spectrum, ABC):
|
|
|
24
24
|
self.increase_true = 0
|
|
25
25
|
self.increase_false = 0
|
|
26
26
|
self.true_hits = dict()
|
|
27
|
+
self.last_evaluation = EvaluationResult.UNOBSERVED
|
|
28
|
+
|
|
29
|
+
@staticmethod
|
|
30
|
+
def default_evaluation() -> EvaluationResult:
|
|
31
|
+
return EvaluationResult.UNOBSERVED
|
|
32
|
+
|
|
33
|
+
def get_last_evaluation(self, id_: int) -> EvaluationResult:
|
|
34
|
+
if id_ not in self.true_hits:
|
|
35
|
+
return self.default_evaluation()
|
|
36
|
+
else:
|
|
37
|
+
return self.last_evaluation
|
|
27
38
|
|
|
28
39
|
def finalize(self, passed: list, failed: list):
|
|
29
40
|
super().finalize(passed, failed)
|
|
@@ -46,6 +57,9 @@ class Predicate(Spectrum, ABC):
|
|
|
46
57
|
self.true_hits[id_] = 0
|
|
47
58
|
if self._evaluate_predicate(scope_):
|
|
48
59
|
self.true_hits[id_] += 1
|
|
60
|
+
self.last_evaluation = EvaluationResult.TRUE
|
|
61
|
+
else:
|
|
62
|
+
self.last_evaluation = EvaluationResult.FALSE
|
|
49
63
|
|
|
50
64
|
def get_metric(self, metric: Callable = None):
|
|
51
65
|
if metric is None:
|
|
@@ -131,6 +145,9 @@ class Branch(Predicate):
|
|
|
131
145
|
if event.then_id == self.then_id:
|
|
132
146
|
super(Predicate, self).hit(id_, event, scope_)
|
|
133
147
|
self.true_hits[id_] += 1
|
|
148
|
+
self.last_evaluation = EvaluationResult.TRUE
|
|
149
|
+
else:
|
|
150
|
+
self.last_evaluation = EvaluationResult.FALSE
|
|
134
151
|
|
|
135
152
|
def get_suggestion(self, metric: Callable = None, base_dir: str = ""):
|
|
136
153
|
if metric == Predicate.IncreaseFalse:
|
|
@@ -142,6 +159,9 @@ class Branch(Predicate):
|
|
|
142
159
|
self.get_metric(metric),
|
|
143
160
|
)
|
|
144
161
|
|
|
162
|
+
def __str__(self):
|
|
163
|
+
return f"{self.analysis_type()}:{self.file}:{self.line}:{'then' if self.then else 'else'}:{self.then_id}"
|
|
164
|
+
|
|
145
165
|
|
|
146
166
|
class Comp(enum.Enum):
|
|
147
167
|
LT = 0
|
|
@@ -165,6 +185,12 @@ class Comp(enum.Enum):
|
|
|
165
185
|
elif self == Comp.NE:
|
|
166
186
|
return x != y
|
|
167
187
|
|
|
188
|
+
def __repr__(self):
|
|
189
|
+
return self.name
|
|
190
|
+
|
|
191
|
+
def __str__(self):
|
|
192
|
+
return self.name
|
|
193
|
+
|
|
168
194
|
|
|
169
195
|
class Comparison(Predicate, ABC):
|
|
170
196
|
def __init__(self, file, line, op: Comp):
|
|
@@ -209,6 +235,9 @@ class ScalarPair(Comparison):
|
|
|
209
235
|
def _get_second(self, scope_: scope.Scope):
|
|
210
236
|
return scope_.value(self.var2)
|
|
211
237
|
|
|
238
|
+
def __str__(self):
|
|
239
|
+
return f"{self.analysis_type()}:{self.file}:{self.line}:{self.var1}{self.op}{self.var2}"
|
|
240
|
+
|
|
212
241
|
|
|
213
242
|
class VariablePredicate(Comparison):
|
|
214
243
|
def __init__(self, event, op: Comp):
|
|
@@ -228,6 +257,9 @@ class VariablePredicate(Comparison):
|
|
|
228
257
|
def _get_first(self, scope_: scope.Scope):
|
|
229
258
|
return scope_.value(self.var)
|
|
230
259
|
|
|
260
|
+
def __str__(self):
|
|
261
|
+
return f"{self.analysis_type()}:{self.file}:{self.line}:{self.var}{self.op}0"
|
|
262
|
+
|
|
231
263
|
|
|
232
264
|
class NonePredicate(Comparison):
|
|
233
265
|
def __init__(self, event: DefEvent):
|
|
@@ -250,6 +282,9 @@ class NonePredicate(Comparison):
|
|
|
250
282
|
def _get_second(self, scope_: scope.Scope):
|
|
251
283
|
return None
|
|
252
284
|
|
|
285
|
+
def __str__(self):
|
|
286
|
+
return f"{self.analysis_type()}:{self.file}:{self.line}:{self.var}"
|
|
287
|
+
|
|
253
288
|
|
|
254
289
|
class ReturnPredicate(Comparison):
|
|
255
290
|
def __init__(self, event: FunctionExitEvent, op: Comp, value: Optional[int] = 0):
|
|
@@ -275,6 +310,9 @@ class ReturnPredicate(Comparison):
|
|
|
275
310
|
def _get_second(self, scope_: scope.Scope):
|
|
276
311
|
return self.value
|
|
277
312
|
|
|
313
|
+
def __str__(self):
|
|
314
|
+
return f"{self.analysis_type()}:{self.file}:{self.line}:{self.function}{self.op}{self.value}"
|
|
315
|
+
|
|
278
316
|
|
|
279
317
|
class EmptyStringPredicate(Comparison):
|
|
280
318
|
def __init__(self, event: DefEvent):
|
|
@@ -297,6 +335,9 @@ class EmptyStringPredicate(Comparison):
|
|
|
297
335
|
def _get_second(self, scope_: scope.Scope):
|
|
298
336
|
return ""
|
|
299
337
|
|
|
338
|
+
def __str__(self):
|
|
339
|
+
return f"{self.analysis_type()}:{self.file}:{self.line}:{self.var}"
|
|
340
|
+
|
|
300
341
|
|
|
301
342
|
class EmptyBytesPredicate(Comparison):
|
|
302
343
|
def __init__(self, event: DefEvent):
|
|
@@ -319,6 +360,9 @@ class EmptyBytesPredicate(Comparison):
|
|
|
319
360
|
def _get_second(self, scope_: scope.Scope):
|
|
320
361
|
return b""
|
|
321
362
|
|
|
363
|
+
def __str__(self):
|
|
364
|
+
return f"{self.analysis_type()}:{self.file}:{self.line}:{self.var}"
|
|
365
|
+
|
|
322
366
|
|
|
323
367
|
class FunctionPredicate(Predicate, ABC):
|
|
324
368
|
def __init__(self, file, line, var: str, predicate: callable):
|
|
@@ -345,6 +389,9 @@ class IsAsciiPredicate(FunctionPredicate):
|
|
|
345
389
|
def analysis_type():
|
|
346
390
|
return AnalysisType.ASCII_STRING
|
|
347
391
|
|
|
392
|
+
def __str__(self):
|
|
393
|
+
return f"{self.analysis_type()}:{self.file}:{self.line}:{self.var}"
|
|
394
|
+
|
|
348
395
|
|
|
349
396
|
class ContainsDigitPredicate(FunctionPredicate):
|
|
350
397
|
def __init__(self, event: DefEvent):
|
|
@@ -358,6 +405,9 @@ class ContainsDigitPredicate(FunctionPredicate):
|
|
|
358
405
|
def analysis_type():
|
|
359
406
|
return AnalysisType.DIGIT_STRING
|
|
360
407
|
|
|
408
|
+
def __str__(self):
|
|
409
|
+
return f"{self.analysis_type()}:{self.file}:{self.line}:{self.var}"
|
|
410
|
+
|
|
361
411
|
|
|
362
412
|
class ContainsSpecialPredicate(FunctionPredicate):
|
|
363
413
|
def __init__(self, event: DefEvent):
|
|
@@ -371,6 +421,9 @@ class ContainsSpecialPredicate(FunctionPredicate):
|
|
|
371
421
|
def analysis_type():
|
|
372
422
|
return AnalysisType.SPECIAL_STRING
|
|
373
423
|
|
|
424
|
+
def __str__(self):
|
|
425
|
+
return f"{self.analysis_type()}:{self.file}:{self.line}:{self.var}"
|
|
426
|
+
|
|
374
427
|
|
|
375
428
|
class Condition(Predicate):
|
|
376
429
|
def __init__(self, file: str, line: int, condition: str):
|
|
@@ -391,3 +444,9 @@ class Condition(Predicate):
|
|
|
391
444
|
self.true_hits[id_] = 0
|
|
392
445
|
if event.value:
|
|
393
446
|
self.true_hits[id_] += 1
|
|
447
|
+
self.last_evaluation = EvaluationResult.TRUE
|
|
448
|
+
else:
|
|
449
|
+
self.last_evaluation = EvaluationResult.FALSE
|
|
450
|
+
|
|
451
|
+
def __str__(self):
|
|
452
|
+
return f"{self.analysis_type()}:{self.file}:{self.line}:{self.condition}"
|
|
@@ -14,7 +14,7 @@ from sflkitlib.events.event import (
|
|
|
14
14
|
UseEvent,
|
|
15
15
|
)
|
|
16
16
|
|
|
17
|
-
from sflkit.analysis.analysis_type import AnalysisObject, AnalysisType
|
|
17
|
+
from sflkit.analysis.analysis_type import AnalysisObject, AnalysisType, EvaluationResult
|
|
18
18
|
from sflkit.analysis.suggestion import Suggestion, Location
|
|
19
19
|
from sflkit.model.scope import Scope
|
|
20
20
|
|
|
@@ -39,6 +39,20 @@ class Spectrum(AnalysisObject, ABC):
|
|
|
39
39
|
self.failed_observed = failed_observed
|
|
40
40
|
self.failed_not_observed = failed_not_observed
|
|
41
41
|
self.hits = dict()
|
|
42
|
+
self.last_evaluation: EvaluationResult = EvaluationResult.FALSE
|
|
43
|
+
|
|
44
|
+
def __str__(self):
|
|
45
|
+
return f"{self.analysis_type()}:{self.file}:{self.line}"
|
|
46
|
+
|
|
47
|
+
@staticmethod
|
|
48
|
+
def default_evaluation() -> EvaluationResult:
|
|
49
|
+
return EvaluationResult.FALSE
|
|
50
|
+
|
|
51
|
+
def get_last_evaluation(self, id_: int) -> EvaluationResult:
|
|
52
|
+
if id_ not in self.hits:
|
|
53
|
+
return self.default_evaluation()
|
|
54
|
+
else:
|
|
55
|
+
return self.last_evaluation
|
|
42
56
|
|
|
43
57
|
def get_metric(self, metric: Callable = None):
|
|
44
58
|
if metric is None:
|
|
@@ -59,6 +73,7 @@ class Spectrum(AnalysisObject, ABC):
|
|
|
59
73
|
self.suspiciousness = self.get_metric(metric)
|
|
60
74
|
|
|
61
75
|
def hit(self, id_, event, scope_: Scope = None):
|
|
76
|
+
self.last_evaluation = True
|
|
62
77
|
if id_ not in self.hits:
|
|
63
78
|
self.hits[id_] = 1
|
|
64
79
|
else:
|
|
@@ -483,6 +498,9 @@ class Function(Spectrum):
|
|
|
483
498
|
self.get_metric(metric),
|
|
484
499
|
)
|
|
485
500
|
|
|
501
|
+
def __str__(self):
|
|
502
|
+
return f"{self.analysis_type()}:{self.file}:{self.function}:{self.line}"
|
|
503
|
+
|
|
486
504
|
|
|
487
505
|
class DefUse(Spectrum):
|
|
488
506
|
def __init__(self, def_event: DefEvent, use_event: UseEvent):
|
|
@@ -505,6 +523,9 @@ class DefUse(Spectrum):
|
|
|
505
523
|
self.get_metric(metric),
|
|
506
524
|
)
|
|
507
525
|
|
|
526
|
+
def __str__(self):
|
|
527
|
+
return f"{self.analysis_type()}:{self.file}:{self.line}:{self.use_file}:{self.use_line}:{self.var}"
|
|
528
|
+
|
|
508
529
|
|
|
509
530
|
class Loop(Spectrum):
|
|
510
531
|
def __init__(
|
|
@@ -569,3 +590,6 @@ class Loop(Spectrum):
|
|
|
569
590
|
[Location(self.file, line) for line in finder.get_locations(base_dir)],
|
|
570
591
|
self.get_metric(metric),
|
|
571
592
|
)
|
|
593
|
+
|
|
594
|
+
def __str__(self):
|
|
595
|
+
return f"{self.analysis_type()}:{self.file}:{self.line}"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|