@@ -19,7 +19,7 @@ def create_empty_database(lang, extension, database):
19
19
subprocess_run (["codeql" , "database" , "init" , "--language=" + lang ,
20
20
"--source-root=/tmp/empty" , "--allow-missing-source-root" , database ])
21
21
subprocess_run (["mkdir" , "-p" , database + "/src/tmp/empty" ])
22
- subprocess_run (["touch" , database + "/src/tmp/empty/empty. " + extension ])
22
+ subprocess_run (["touch" , database + "/src/tmp/empty/empty" + extension ])
23
23
subprocess_run (["codeql" , "database" , "finalize" ,
24
24
database , "--no-pre-finalize" ])
25
25
@@ -89,8 +89,9 @@ def add_package_stats_to_row(row, sorted_cwes, collect):
89
89
90
90
91
91
class LanguageConfig :
92
- def __init__ (self , lang , ext , ql_path ):
92
+ def __init__ (self , lang , capitalized_lang , ext , ql_path ):
93
93
self .lang = lang
94
+ self .capitalized_lang = capitalized_lang
94
95
self .ext = ext
95
96
self .ql_path = ql_path
96
97
@@ -108,151 +109,163 @@ def __init__(self, lang, ext, ql_path):
108
109
# Languages for which we want to generate coverage reports.
109
110
configs = [
110
111
LanguageConfig (
111
- "java" , "java" , prefix + "java/ql/src/meta/frameworks/Coverage.ql" )
112
+ "java" , "Java" , ". java" , prefix + "java/ql/src/meta/frameworks/Coverage.ql" )
112
113
]
113
114
114
- for config in configs :
115
- lang = config .lang
116
- ext = config .ext
117
- query_path = config .ql_path
118
- db = "empty-" + lang
119
- ql_output = "output-" + lang + ".csv"
120
- # create_empty_database(lang, ext, db)
121
- run_codeql_query (query_path , db , ql_output )
122
-
123
- packages = {}
124
- parts = set ()
125
- kinds = set ()
126
-
127
- # Read the generated CSV file, and collect package statistics.
128
- with open (ql_output ) as csvfile :
129
- reader = csv .reader (csvfile )
130
- for row in reader :
131
- package = row [0 ]
132
- if package not in packages :
133
- packages [package ] = {
134
- "count" : row [1 ],
135
- "part" : {},
136
- "kind" : {}
137
- }
138
- part = row [3 ]
139
- parts .add (part )
140
- if part not in packages [package ]["part" ]:
141
- packages [package ]["part" ][part ] = 0
142
- packages [package ]["part" ][part ] += int (row [4 ])
143
- kind = part + ":" + row [2 ]
144
- kinds .add (kind )
145
- if kind not in packages [package ]["kind" ]:
146
- packages [package ]["kind" ][kind ] = 0
147
- packages [package ]["kind" ][kind ] += int (row [4 ])
148
-
149
- # Write the denormalized package statistics to a CSV file.
150
- with open ("csv-flow-model-coverage-" + lang + ".csv" , 'w' , newline = '' ) as csvfile :
151
- csvwriter = csv .writer (csvfile )
152
-
153
- parts = sorted (parts )
154
- kinds = sorted (kinds )
155
-
156
- columns = ["package" ]
157
- columns .extend (parts )
158
- columns .extend (kinds )
159
-
160
- csvwriter .writerow (columns )
161
-
162
- for package in sorted (packages ):
163
- row = [package ]
164
- for part in parts :
165
- append_csv_dict_item (row , packages [package ]["part" ], part )
166
- for kind in kinds :
167
- append_csv_dict_item (row , packages [package ]["kind" ], kind )
168
- csvwriter .writerow (row )
169
-
170
- # Read the additional framework data, such as URL, friendly name
171
- frameworks = {}
172
-
173
- with open (prefix + "misc/scripts/frameworks-" + lang + ".csv" ) as csvfile :
174
- reader = csv .reader (csvfile )
175
- next (reader )
176
- for row in reader :
177
- framwork = row [0 ]
178
- if framwork not in frameworks :
179
- frameworks [framwork ] = {
180
- "package" : row [2 ],
181
- "url" : row [1 ]
182
- }
183
-
184
- # Read the additional CWE data
185
- cwes = {}
186
-
187
- with open (prefix + "misc/scripts/cwe-sink-" + lang + ".csv" ) as csvfile :
188
- reader = csv .reader (csvfile )
189
- next (reader )
190
- for row in reader :
191
- cwe = row [0 ]
192
- if cwe not in cwes :
193
- cwes [cwe ] = {
194
- "sink" : row [1 ],
195
- "label" : row [2 ]
196
- }
197
-
198
- with open ("rst-csv-flow-model-coverage-" + lang + ".csv" , 'w' , newline = '' ) as csvfile :
199
- csvwriter = csv .writer (csvfile )
200
-
201
- columns = ["Framework / library" , "package" ,
202
- "remote flow sources" , "taint & value steps" , "sinks (total)" ]
203
- for cwe in sorted (cwes ):
204
- columns .append ("`" + cwe + "` :sub:`" + cwes [cwe ]["label" ] + "`" )
205
- csvwriter .writerow (columns )
206
-
207
- processed_packages = set ()
208
-
209
- for framework in sorted (frameworks ):
210
- row = []
211
- # Add the framework name to the row
212
- if not frameworks [framework ]["url" ]:
213
- row .append (framework )
214
- else :
215
- row .append (
216
- "`" + framework + " <" + frameworks [framework ]["url" ] + ">`_" )
217
-
218
- # Add the package name to the row
219
- row .append (frameworks [framework ]["package" ])
220
-
221
- prefix = frameworks [framework ]["package" ]
222
-
223
- # Collect statistics on the current framework
224
- def collect_framework (): return collect_package_stats (
115
+ with open ("csv-flow-model-coverage.rst" , 'w' ) as rst_file :
116
+ for config in configs :
117
+ lang = config .lang
118
+ db = "empty-" + lang
119
+ ql_output = "output-" + lang + ".csv"
120
+ create_empty_database (lang , config .ext , db )
121
+ run_codeql_query (config .ql_path , db , ql_output )
122
+
123
+ packages = {}
124
+ parts = set ()
125
+ kinds = set ()
126
+
127
+ # Read the generated CSV file, and collect package statistics.
128
+ with open (ql_output ) as csvfile :
129
+ reader = csv .reader (csvfile )
130
+ for row in reader :
131
+ package = row [0 ]
132
+ if package not in packages :
133
+ packages [package ] = {
134
+ "count" : row [1 ],
135
+ "part" : {},
136
+ "kind" : {}
137
+ }
138
+ part = row [3 ]
139
+ parts .add (part )
140
+ if part not in packages [package ]["part" ]:
141
+ packages [package ]["part" ][part ] = 0
142
+ packages [package ]["part" ][part ] += int (row [4 ])
143
+ kind = part + ":" + row [2 ]
144
+ kinds .add (kind )
145
+ if kind not in packages [package ]["kind" ]:
146
+ packages [package ]["kind" ][kind ] = 0
147
+ packages [package ]["kind" ][kind ] += int (row [4 ])
148
+
149
+ # Write the denormalized package statistics to a CSV file.
150
+ with open ("csv-flow-model-coverage-" + lang + ".csv" , 'w' , newline = '' ) as csvfile :
151
+ csvwriter = csv .writer (csvfile )
152
+
153
+ parts = sorted (parts )
154
+ kinds = sorted (kinds )
155
+
156
+ columns = ["package" ]
157
+ columns .extend (parts )
158
+ columns .extend (kinds )
159
+
160
+ csvwriter .writerow (columns )
161
+
162
+ for package in sorted (packages ):
163
+ row = [package ]
164
+ for part in parts :
165
+ append_csv_dict_item (row , packages [package ]["part" ], part )
166
+ for kind in kinds :
167
+ append_csv_dict_item (row , packages [package ]["kind" ], kind )
168
+ csvwriter .writerow (row )
169
+
170
+ # Read the additional framework data, such as URL, friendly name
171
+ frameworks = {}
172
+
173
+ with open (prefix + "misc/scripts/frameworks-" + lang + ".csv" ) as csvfile :
174
+ reader = csv .reader (csvfile )
175
+ next (reader )
176
+ for row in reader :
177
+ framwork = row [0 ]
178
+ if framwork not in frameworks :
179
+ frameworks [framwork ] = {
180
+ "package" : row [2 ],
181
+ "url" : row [1 ]
182
+ }
183
+
184
+ # Read the additional CWE data
185
+ cwes = {}
186
+
187
+ with open (prefix + "misc/scripts/cwe-sink-" + lang + ".csv" ) as csvfile :
188
+ reader = csv .reader (csvfile )
189
+ next (reader )
190
+ for row in reader :
191
+ cwe = row [0 ]
192
+ if cwe not in cwes :
193
+ cwes [cwe ] = {
194
+ "sink" : row [1 ],
195
+ "label" : row [2 ]
196
+ }
197
+
198
+ file_name = "rst-csv-flow-model-coverage-" + lang + ".csv"
199
+
200
+ rst_file .write (
201
+ config .capitalized_lang + " framework & library support\n " )
202
+ rst_file .write ("================================\n \n " )
203
+ rst_file .write (".. csv-table:: \n " )
204
+ rst_file .write (" :file: " + file_name + "\n " )
205
+ rst_file .write (" :header-rows: 1\n " )
206
+ rst_file .write (" :class: fullWidthTable\n " )
207
+ rst_file .write (" :widths: auto\n \n " )
208
+
209
+ # Write CSV file with package statistics and framework data to be used in RST file.
210
+ with open (file_name , 'w' , newline = '' ) as csvfile :
211
+ csvwriter = csv .writer (csvfile )
212
+
213
+ columns = ["Framework / library" , "package" ,
214
+ "remote flow sources" , "taint & value steps" , "sinks (total)" ]
215
+ for cwe in sorted (cwes ):
216
+ columns .append ("`" + cwe + "` :sub:`" +
217
+ cwes [cwe ]["label" ] + "`" )
218
+ csvwriter .writerow (columns )
219
+
220
+ processed_packages = set ()
221
+
222
+ for framework in sorted (frameworks ):
223
+ row = []
224
+ # Add the framework name to the row
225
+ if not frameworks [framework ]["url" ]:
226
+ row .append (framework )
227
+ else :
228
+ row .append (
229
+ "`" + framework + " <" + frameworks [framework ]["url" ] + ">`_" )
230
+
231
+ # Add the package name to the row
232
+ row .append (frameworks [framework ]["package" ])
233
+
234
+ prefix = frameworks [framework ]["package" ]
235
+
236
+ # Collect statistics on the current framework
237
+ def collect_framework (): return collect_package_stats (
238
+ packages ,
239
+ lambda p : (prefix .endswith ("*" ) and p .startswith (prefix [:- 1 ])) or (not prefix .endswith ("*" ) and prefix == p ))
240
+
241
+ row , f_processed_packages = add_package_stats_to_row (
242
+ row , sorted (cwes ), collect_framework )
243
+
244
+ csvwriter .writerow (row )
245
+ processed_packages .update (f_processed_packages )
246
+
247
+ # Collect statistics on all packages that are not part of a framework
248
+ row = ["Others" , None ]
249
+
250
+ def collect_others (): return collect_package_stats (
225
251
packages ,
226
- lambda p : (prefix .endswith ("*" ) and p .startswith (prefix [:- 1 ])) or (not prefix .endswith ("*" ) and prefix == p ))
227
-
228
- row , f_processed_packages = add_package_stats_to_row (
229
- row , sorted (cwes ), collect_framework )
230
-
231
- csvwriter .writerow (row )
232
- processed_packages .update (f_processed_packages )
252
+ lambda p : p not in processed_packages )
233
253
234
- # Collect statistics on all packages that are not part of a framework
235
- row = [ "Others" , None ]
254
+ row , other_packages = add_package_stats_to_row (
255
+ row , sorted ( cwes ), collect_others )
236
256
237
- def collect_others (): return collect_package_stats (
238
- packages ,
239
- lambda p : p not in processed_packages )
257
+ row [1 ] = ", " .join (sorted (other_packages ))
240
258
241
- row , _ = add_package_stats_to_row (
242
- row , sorted (cwes ), collect_others )
243
-
244
- csvwriter .writerow (row )
245
-
246
- # Collect statistics on all packages
247
- row = ["Total" , None ]
259
+ csvwriter .writerow (row )
248
260
249
- def collect_total (): return collect_package_stats (
250
- packages ,
251
- lambda p : True )
261
+ # Collect statistics on all packages
262
+ row = ["Total" , None ]
252
263
253
- row , _ = add_package_stats_to_row (
254
- row , sorted (cwes ), collect_total )
264
+ def collect_total (): return collect_package_stats (
265
+ packages ,
266
+ lambda p : True )
255
267
256
- csvwriter .writerow (row )
268
+ row , _ = add_package_stats_to_row (
269
+ row , sorted (cwes ), collect_total )
257
270
258
- # todo: generate rst page referencing the csv files
271
+ csvwriter . writerow ( row )
0 commit comments