forked from MultiTagging/MultiTagging
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMain.py
More file actions
258 lines (242 loc) · 13 KB
/
Copy pathMain.py
File metadata and controls
258 lines (242 loc) · 13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
from Scripts.tagger import generateTags
from Scripts.evaluator import eval
from Scripts.plotting import plot_result
from Scripts.toolOverlap import getOverlap
from Scripts.election import electLabel
from Scripts.toolOverlap_perVuln import getOverlapPerV
from Scripts.ToolEfficiency import get_toolEfficiency
from Scripts.createPerformanceOutFiles import createPerformanceOutFiles
from IPython.display import display
import os
from pathlib import Path
import json
import pandas as pd
import warnings as w
w.simplefilter(action='ignore',category=FutureWarning)
Tools = ['MAIAN','Mythril','Semgrep','Slither','Solhint','VeriSmart']
#-------------------------------------------
#Get the correct path to the configuration file
#-------------------------------------------
config_file_name = 'Scripts/config.json'
self_dir = Path(__file__).resolve().parent
config_file_path = self_dir / config_file_name
#-------------------------------------------
configFile = open(config_file_path)
config_File = json.load(configFile)
configFile.close()
def main():
print("MultiTagging Framework")
flag = True
while flag:
print('.'*50 + '\n')
print('Enter the number of the selected function:\n 1: Get the labeled data for the tool reports.\n 2: Get vote-based labeled data. \n 3: Get the evaluation report.\n 4: Get the evaluation chart.\n 5: Get tools overlap degree.\n 6: Get tool efficiency scores \n 7: Exit')
print('.'*50 + '\n')
option = int(input('Your choice: '))
match option:
case 1:
try:
tool = input("Enter the tool name: ")
tool = validation(tool,'tool')
if tool is False :
print('Wrong input or MultiTagging does not support this tool')
else:
source = int(input("Enter 1 if you used SmartBugs to run the tool, otherwise enter 0: "))
if source not in [0,1]:
print('Wrong input; The source must be either 0 or 1')
else:
labeledDS =generateTags(tool,source)
display(labeledDS)
except:
print('Unexpected error')
case 2:
try:
toolList = getToolsList()
if len(toolList) >1 or 'All' in toolList:
baseFlieName = input("Enter the base data file name, e.g., SBcurated: ")
baseFlieName = validation(baseFlieName,'BaseDataFile')
if baseFlieName is False:
print('Wrong input, The base data file does not found')
else:
Fair = bool(strtobool(input("To perform a Fair assessment, which includes just the common samples that all tools were able to analyze, enter '1' or 'True'; otherwise, enter '0' or 'False'.")))
if Fair not in [True, False]:
print('Wrong Input!')
else:
#tools performance + overlap..
if Fair:
EvaluationsOutDir = './Results/Evaluations_Fair/'
overlapFileName = 'OverlapDegree_PerVuln_Fair.csv'
else:
EvaluationsOutDir = './Results/Evaluations/'
overlapFileName = 'OverlapDegree_PerVuln.csv'
baseDir = EvaluationsOutDir + baseFlieName + '/'
OverlapDir = './Results/Overlap/'
if not baseFlieName in [f.name for f in os.scandir(EvaluationsOutDir) if f.is_dir()]:
print('Tools evaluation results folder not found. \n Perform option #3 to get tools evaluation results.')
elif len([f.name for f in os.scandir(baseDir) if f.is_file() and '.csv' in f.name ]) <= 1:
print('Tools evaluation results not found. \n Perform option #3 to get tools evaluation results.')
elif not overlapFileName in [f.name for f in os.scandir(OverlapDir) if f.is_file()]:
print('Overlap degrees per vulnerability class csv file not found. \n Perform option #5 to generate Overlap degree csv file.')
else:
print('The data is being processed now, wait a moment...\n')
voteBasedLabeledData = electLabel(baseFlieName,toolList,Fair)
print('Vote Based-Labeled Data: \n')
display(voteBasedLabeledData)
else:
print('You must pass at least two tool names')
except:
print('Unexpected error')
case 3:
try:
dataFileName = input("Enter the labeled data file name (it is the same as the tool name), e.g., Slither: ")
dataFileName = validation(dataFileName,'tool')
if dataFileName is False :
print('Wrong input, The labeled data file does not found')
else:
baseFlieName = input("Enter the base data file name, e.g., SBcurated.csv: ")
baseFlieName = validation(baseFlieName,'BaseDataFile')
if baseFlieName is False:
print('Wrong input, The base data file does not found')
else:
Fair = bool(strtobool(input("To perform a Fair assessment, which includes just the common samples that all tools were able to analyze, enter '1' or 'True'; otherwise, enter '0' or 'False'.")))
if Fair not in [True, False]:
print('Wrong Input!')
else:
#create avgAnalysisTimeAndFailureRate files if not exit
files = os.listdir('./Results/Performance/')
if not 'avgAnalysisTimeAndFailureRate.csv' in files or not 'avgAnalysisTimeAndFailureRate_Fair.csv' in files:
Bases = baseFlieName.split('.')[0]
createPerformanceOutFiles(Tools,Bases)
evaluationResult = eval(dataFileName,baseFlieName +'.csv',Fair)
print('The evaluation result of',dataFileName,'using the base',baseFlieName,'is')
display(evaluationResult)
except:
print('Unexpected error')
case 4:
try:
toolList = getToolsList()
if len(toolList) > 0 :
baseList = getBasesList()
if len(baseList) > 0:
Fair = bool(strtobool(input("To perform a Fair assessment, which includes just the common samples that all tools were able to analyze, enter '1' or 'True'; otherwise, enter '0' or 'False'.")))
if Fair not in [True, False]:
print('Wrong Input!')
else:
Eval_Results = plot_result(toolList,baseList,Fair)
#Eval_Results.to_csv('./Results/Charts/AllResult.csv',index=False)
print('Evaluation Data:\n')
display(Eval_Results)
else:
print('Wrong input')
else:
print('Wrong input')
except:
print('Unexpected error')
case 5:
try:
toolList = getToolsList()
if len(toolList) >1 or 'All' in toolList:
Fair = bool(strtobool(input("To perform a Fair assessment, which includes just the common samples that all tools were able to analyze, enter '1' or 'True'; otherwise, enter '0' or 'False'.")))
if Fair not in [True, False]:
print('Wrong Input!')
else:
overlapPerClass = bool(strtobool(input('To measure the overlap degree per vulnerability class, enter "True" or "1" otherwise enter "False" or "0"')))
if overlapPerClass not in [True, False]:
print('Wrong Input!')
else:
print('The data is being processed now, wait a moment...\n\n')
if overlapPerClass:
overlapDF = getOverlapPerV(toolList,Fair)
print('Tools Overlap Degrees For Each Vulnerability Class: \n')
else:
overlapDF = getOverlap(toolList,Fair)
print('Tools Overlap Degrees: \n')
display(overlapDF)
else:
print('You must pass at least two tool names')
except:
print('Unexpected error')
case 6:
Fair = bool(strtobool(input("To perform a Fair assessment, which includes just the common samples that all tools were able to analyze, enter '1' or 'True'; otherwise, enter '0' or 'False'.")))
if Fair not in [True, False]:
print('Wrong Input!')
else:
get_toolEfficiency(Fair)
case 7:
flag =False
def validation(input,type):
match type:
case 'tool':
ToolsLower = list(pd.Series(Tools).str.lower())
if input.lower() in ToolsLower:
#print(Tools[ToolsLower.index(input)])
return Tools[ToolsLower.index(input)]
else:
return False
case 'LabeledDataFile' | 'BaseDataFile':
if '.' in input:
input = input.split('.')[0]
match type:
case 'LabeledDataFile':
LabeledData_Dir = config_File['LabeledData'][0]['Path']
case 'BaseDataFile':
LabeledData_Dir = config_File['BaseDS'][0]['Path']
dataFiles = [f.name.split('.')[0] for f in os.scandir(LabeledData_Dir) if f.is_file() and '.csv' in f.name]
if input not in dataFiles:
return False
else:
return input
def getToolsList():
Tools =[]
AllTools = int(input("Enter 1 if you want to pass all tools, otherwise enter 0 to pass the tool names one by one: "))
if AllTools not in [0,1]:
print('Wrong input')
elif AllTools == 1:
Tools.append('All')
else:
print('Enter the name of the tool and press Enter (to Exit, press Enter directly): ')
while True:
tool = input()
if len(tool) == 0:
break
tool = validation(tool,'tool')
if tool is False :
print('Wrong input or MultiTagging does not support this tool')
else:
Tools.append(tool)
print('Enter the name of the next tool and press Enter (to Exit, press Enter directly): ')
return Tools
def getBasesList():
Bases =[]
AllBases = int(input("Enter 1 if you want to pass all bases, otherwise enter 0 to pass the base names one by one: "))
if AllBases not in [0,1]:
print('Wrong input')
elif AllBases == 1:
Bases.append('All')
else:
print('Enter the name of the base data and press Enter (to Exit, press Enter directly): ')
while True:
base = input()
if len(base) == 0:
break
base = validation(base,'LabeledDataFile')
if base is False :
print('Wrong input, Base file does not found')
else:
Bases.append(base)
print('Enter the name of the next base data and press Enter (to Exit, press Enter directly): ')
return Bases
def strtobool (val):
#Source: https://stackoverflow.com/questions/715417/converting-from-a-string-to-boolean-in-python
"""Convert a string representation of truth to true (1) or false (0).
True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values
are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if
'val' is anything else.
"""
val = val.lower()
if val in ('y', 'yes', 't', 'true', 'on', '1'):
return 1
elif val in ('n', 'no', 'f', 'false', 'off', '0'):
return 0
else:
raise ValueError("invalid truth value %r" % (val,))
main()