Skip to content

Commit 706d19f

Browse files
authored
Merge pull request diffblue#241 from diffblue/feature/slicer_integration
SEC-41 : Integration of the 'full-slicer' into the pipe-line (tools-chain).
2 parents a7d9dad + 30eb25a commit 706d19f

8 files changed

+186
-16
lines changed

benchmarks/TRAINING/diffblue/taint_traces_01_evaluator.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
},
2626
"file": "Main.java",
2727
"function": "java::Main.bug:(I)V",
28-
"goto_binary_file": "program_slicing/instrumented_goto_program_0.gbf",
28+
"goto_binary_file": "program_slicing/sliced_goto_program_0.gbf",
2929
"line": 84
3030
}
3131
]

benchmarks/TRAINING/diffblue/taint_traces_04_evaluator.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
},
2424
"file": "Main.java",
2525
"function": "java::Main.baz0:()V",
26-
"goto_binary_file": "program_slicing/instrumented_goto_program_0.gbf",
26+
"goto_binary_file": "program_slicing/sliced_goto_program_0.gbf",
2727
"line": 19
2828
},
2929
{
@@ -35,7 +35,7 @@
3535
},
3636
"file": "Main.java",
3737
"function": "java::Main.baz1:()V",
38-
"goto_binary_file": "program_slicing/instrumented_goto_program_1.gbf",
38+
"goto_binary_file": "program_slicing/sliced_goto_program_1.gbf",
3939
"line": 26
4040
},
4141
{
@@ -47,7 +47,7 @@
4747
},
4848
"file": "Main.java",
4949
"function": "java::Main.baz2:(LOther;)V",
50-
"goto_binary_file": "program_slicing/instrumented_goto_program_2.gbf",
50+
"goto_binary_file": "program_slicing/sliced_goto_program_2.gbf",
5151
"line": 32
5252
}
5353
]

benchmarks/TRAINING/diffblue/taint_traces_05_evaluator.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
},
2424
"file": "DummyAssignmentSubmissionEdit.java",
2525
"function": "java::DummyAssignmentSubmissionEdit.setSubmittedText:(Ljava/lang/String;)V",
26-
"goto_binary_file": "program_slicing/instrumented_goto_program_0.gbf",
26+
"goto_binary_file": "program_slicing/sliced_goto_program_0.gbf",
2727
"line": 3
2828
}
2929
]

benchmarks/TRAINING/diffblue/taint_traces_06_evaluator.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
},
2424
"file": "taint_test/test.java",
2525
"function": "java::taint_test.test.doGet:(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V",
26-
"goto_binary_file": "program_slicing/instrumented_goto_program_0.gbf",
26+
"goto_binary_file": "program_slicing/sliced_goto_program_0.gbf",
2727
"line": 143
2828
},
2929
{
@@ -35,7 +35,7 @@
3535
},
3636
"file": "taint_test/test.java",
3737
"function": "java::taint_test.test.doGet:(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V",
38-
"goto_binary_file": "program_slicing/instrumented_goto_program_0.gbf",
38+
"goto_binary_file": "program_slicing/sliced_goto_program_0.gbf",
3939
"line": 165
4040
}
4141
]

benchmarks/TRAINING/diffblue/taint_traces_07_evaluator.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
},
2424
"file": "training07/test.java",
2525
"function": "java::training07.test.doGet:(Ltraining07/HttpServletRequest;Ltraining07/HttpServletResponse;)V",
26-
"goto_binary_file": "program_slicing/instrumented_goto_program_0.gbf",
26+
"goto_binary_file": "program_slicing/sliced_goto_program_0.gbf",
2727
"line": 109
2828
}
2929
]

driver/analyser.py

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import time
33
import json
44
import utility
5+
#import shutil
56

67

78
def __get_my_dir(): return os.path.dirname(os.path.realpath(__file__))
@@ -122,7 +123,8 @@ def run_program_slicing(
122123
json_cfg_fname,
123124
results_dir,
124125
timeout,
125-
verbosity
126+
verbosity,
127+
dump_html_slice
126128
):
127129
prof = {"calling_slicer": []}
128130
prof_start_time = time.time()
@@ -135,30 +137,53 @@ def run_program_slicing(
135137
src_plain_fname = os.path.splitext(os.path.basename(cfg["goto_binary_file"]))[0]
136138
src_idx_name = int(src_plain_fname[src_plain_fname.rfind("_")+1:])
137139
dst_goto_program_fname = os.path.join(results_dir, "sliced_goto_program_" + str(src_idx_name) + ".gbf")
140+
dst_goto_stats_fname = os.path.join(results_dir, "sliced_goto_program_" + str(src_idx_name) + ".stats.json")
138141

139142
command = (
140143
get_goto_instrument_pathname() + " " +
141144
"--full-slice " +
142145
"--verbosity " + str(1) + " " +
143146
cfg["goto_binary_file"] + " " +
144-
"-o " + dst_goto_program_fname
147+
dst_goto_program_fname + " " +
148+
"--full-slice " +
149+
"--verbosity " + str(verbosity) + " " +
150+
"--save-code-statistics " + dst_goto_stats_fname
145151
)
146152
prof_calling_goto_instrument_start_time = time.time()
147153
print("Invoking 'goto-instrument' ...")
148154
with utility.PushCwd(results_dir) as cwd:
149155
if verbosity >= 9:
150156
print("CWD: " + cwd.get())
151157
print("CMD: " + command)
152-
# TODO: Uncomment the next line when the slicer is functional!
153-
# os.system(command)
158+
os.system(command)
159+
#shutil.copy(cfg["goto_binary_file"], dst_goto_program_fname)
160+
154161
prof["calling_slicer"].append({
155162
"gbf_idx": src_idx_name,
156163
"duration": time.time() - prof_calling_goto_instrument_start_time
157164
})
158165

159166
result.append(cfg.copy())
160-
# TODO: Uncomment the next line when the slicer is functional!
161-
# result[-1]["goto_binary_file"] = dst_goto_program_fname
167+
result[-1]["goto_binary_file"] = dst_goto_program_fname
168+
169+
if dump_html_slice:
170+
command = (
171+
get_security_analyser_pathname() + " " +
172+
dst_goto_program_fname + " " +
173+
"--dump-html-program " +
174+
"'" +
175+
os.path.join(
176+
results_dir,
177+
"HTML_dump_of_sliced_GOTO_programs",
178+
os.path.splitext(os.path.basename(dst_goto_program_fname))[0]
179+
) +
180+
"'"
181+
)
182+
with utility.PushCwd(results_dir) as cwd:
183+
if verbosity >= 9:
184+
print("CWD: " + cwd.get())
185+
print("CMD: " + command)
186+
os.system(command)
162187

163188
with open(os.path.join(results_dir, "sliced_goto_programs.json"), "w") as results_json:
164189
results_json.write(json.dumps(result, sort_keys=False, indent=4))

driver/presentation.py

Lines changed: 145 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,146 @@ def build_HTML_interface_to_slicing_tasks(root_dir,sub_dir,ofile):
349349
return len(instrumented_goto_programs)
350350

351351

352+
def build_HTML_interface_to_the_slicer(root_dir,sub_dir,ofile):
353+
full_sub_dir=os.path.join(root_dir, sub_dir)
354+
if not os.path.exists(full_sub_dir):
355+
os.makedirs(full_sub_dir)
356+
with open(os.path.join(full_sub_dir, "instrumented_goto_programs.json")) as json_file:
357+
cfgs = json.load(json_file)
358+
if cfgs is None:
359+
ofile.write("<p>ERROR: Reading of the JSON file '" +
360+
escape_text_to_HTML(os.path.join(full_sub_dir, "instrumented_goto_programs.json")) +
361+
"' has failed.</p>")
362+
return
363+
for cfg in cfgs:
364+
src_plain_fname = os.path.splitext(os.path.basename(cfg["goto_binary_file"]))[0]
365+
src_idx_name = int(src_plain_fname[src_plain_fname.rfind("_")+1:])
366+
dst_goto_program_fname = os.path.join(os.path.dirname(cfg["goto_binary_file"]),
367+
"sliced_goto_program_" + str(src_idx_name) + ".gbf")
368+
src_goto_stats_fname = os.path.splitext(cfg["goto_binary_file"])[0] + ".stats.json"
369+
dst_goto_stats_fname = os.path.join(os.path.dirname(cfg["goto_binary_file"]),
370+
"sliced_goto_program_" + str(src_idx_name) + ".stats.json")
371+
ofile.write("<table>\n"
372+
"<caption>Result #" + str(src_idx_name) + ".</caption>\n"
373+
" <tr>\n"
374+
" <th>Property</th>\n"
375+
" <th>value</th>\n"
376+
" </tr>\n")
377+
ofile.write(" <tr>\n")
378+
ofile.write(" <td>Original GOTO binary</td>\n")
379+
ofile.write(" <td>" + cfg["goto_binary_file"] + "</td>\n")
380+
ofile.write(" </tr>\n")
381+
ofile.write(" <tr>\n")
382+
ofile.write(" <td>Sliced GOTO binary</td>\n")
383+
ofile.write(" <td>" + escape_text_to_HTML(dst_goto_program_fname) + "</td>\n")
384+
ofile.write(" </tr>\n")
385+
sliced_program_html_dump = os.path.join(
386+
full_sub_dir,
387+
"HTML_dump_of_sliced_GOTO_programs",
388+
"sliced_goto_program_" + str(src_idx_name),
389+
"index.html"
390+
)
391+
if os.path.isfile(sliced_program_html_dump):
392+
ofile.write(" <tr>\n")
393+
ofile.write(" <td>Sliced GOTO program listing</td>\n")
394+
ofile.write(" <td><a href=\"./" +
395+
os.path.relpath(sliced_program_html_dump, root_dir) +
396+
"\">here</a></td>\n")
397+
ofile.write(" </tr>\n")
398+
399+
def load_stats(pathname):
400+
if not os.path.isfile(pathname):
401+
return None
402+
with open(pathname, "r") as ifile:
403+
return json.load(ifile)
404+
405+
def make_reduction_string(orig_value, reduced_value, add_percentage=True):
406+
result = str(orig_value - reduced_value) + " (from " + str(orig_value)
407+
if add_percentage:
408+
percentage = 100 * (orig_value - reduced_value) / orig_value if orig_value != 0 else 0
409+
result += "; " + "{:.1f}".format(percentage) + "%"
410+
return result + ")"
411+
412+
src_stats = load_stats(src_goto_stats_fname)
413+
dst_stats = load_stats(dst_goto_stats_fname)
414+
stats_available = src_stats is not None and dst_stats is not None
415+
416+
ofile.write(" <tr>\n")
417+
ofile.write(" <td>Reduced GOTO binary size [bytes]</td>\n")
418+
ofile.write(" <td>" + (
419+
make_reduction_string(
420+
os.stat(cfg["goto_binary_file"]).st_size,
421+
os.stat(dst_goto_program_fname).st_size
422+
)
423+
if stats_available else "NOT AVAILABLE"
424+
) + "</td>\n")
425+
ofile.write(" </tr>\n")
426+
427+
ofile.write(" <tr>\n")
428+
ofile.write(" <td>Removed functions</td>\n")
429+
ofile.write(" <td>" + (
430+
make_reduction_string(src_stats["num_functions"], dst_stats["num_functions"])
431+
if stats_available else "NOT AVAILABLE"
432+
) + "</td>\n")
433+
ofile.write(" </tr>\n")
434+
ofile.write(" <tr>\n")
435+
ofile.write(" <td>Removed function calls</td>\n")
436+
ofile.write(" <td>" + (
437+
make_reduction_string(src_stats["num_function_calls"], dst_stats["num_function_calls"])
438+
if stats_available else "NOT AVAILABLE"
439+
) + "</td>\n")
440+
ofile.write(" </tr>\n")
441+
ofile.write(" <tr>\n")
442+
ofile.write(" <td>Removed user variables</td>\n")
443+
ofile.write(" <td>" + (
444+
make_reduction_string(src_stats["num_user_variables"], dst_stats["num_user_variables"])
445+
if stats_available else "NOT AVAILABLE"
446+
) + "</td>\n")
447+
ofile.write(" </tr>\n")
448+
ofile.write(" <tr>\n")
449+
ofile.write(" <td>Removed auxiliary variables</td>\n")
450+
ofile.write(" <td>" + (
451+
make_reduction_string(src_stats["num_auxiliary_variables"], dst_stats["num_auxiliary_variables"])
452+
if stats_available else "NOT AVAILABLE"
453+
) + "</td>\n")
454+
ofile.write(" </tr>\n")
455+
ofile.write(" <tr>\n")
456+
ofile.write(" <td>Removed instructions</td>\n")
457+
ofile.write(" <td>" + (
458+
make_reduction_string(src_stats["num_instructions"], dst_stats["num_instructions"])
459+
if stats_available else "NOT AVAILABLE"
460+
) + "</td>\n")
461+
ofile.write(" </tr>\n")
462+
ofile.write(" <tr>\n")
463+
ofile.write(" <td>Removed conditional jumps</td>\n")
464+
ofile.write(" <td>" + (
465+
make_reduction_string(src_stats["num_conditional_gotos"], dst_stats["num_conditional_gotos"])
466+
if stats_available else "NOT AVAILABLE"
467+
) + "</td>\n")
468+
ofile.write(" </tr>\n")
469+
ofile.write(" <tr>\n")
470+
ofile.write(" <td>Removed unconditional jumps</td>\n")
471+
ofile.write(" <td>" + (
472+
make_reduction_string(src_stats["num_unconditional_gotos"], dst_stats["num_unconditional_gotos"])
473+
if stats_available else "NOT AVAILABLE"
474+
) + "</td>\n")
475+
ofile.write(" </tr>\n")
476+
ofile.write(" <tr>\n")
477+
ofile.write(" <td>Removed loops</td>\n")
478+
ofile.write(" <td>" + (
479+
make_reduction_string(src_stats["num_loops"], dst_stats["num_loops"])
480+
if stats_available else "NOT AVAILABLE"
481+
) + "</td>\n")
482+
ofile.write(" </tr>\n")
483+
ofile.write(" <tr>\n")
484+
ofile.write(" <td>Statistics in JSON</td>\n")
485+
ofile.write(" <td><a href=\"./" +
486+
os.path.relpath(dst_goto_stats_fname, root_dir) +
487+
"\">here</a></td>\n")
488+
ofile.write(" </tr>\n")
489+
ofile.write("</table>\n")
490+
491+
352492
def build_HTML_interface_to_group_of_error_traces(traces,tool_name,tgt_file,tgt_line,ofile):
353493
ofile.write(get_html_prefix("Error traces " + tool_name))
354494

@@ -698,7 +838,11 @@ def build_HTML_interface_to_results_and_statistics(
698838
if num_slicing_tasks == 0:
699839
ofile.write("<p>There was no slicing task generated.</p>\n")
700840
else:
701-
ofile.write("<p>The slicer removes no code from now. We are waiting for Lucas'es PRs fixing the slicer.</p>\n")
841+
build_HTML_interface_to_the_slicer(
842+
cmdline.results_dir,
843+
"program_slicing",
844+
ofile
845+
)
702846

703847

704848
#######################################################################################################

driver/run.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@ def evaluate(cmdline):
128128
os.path.abspath(os.path.join(cmdline.results_dir,"program_slicing","instrumented_goto_programs.json")),
129129
os.path.abspath(os.path.join(cmdline.results_dir,"program_slicing")),
130130
cmdline.timeout,
131-
cmdline.verbosity
131+
cmdline.verbosity,
132+
cmdline.dump_html_slice
132133
)
133134

134135
print("Starting the search for error traces.")

0 commit comments

Comments
 (0)