16 lines
2.1 KiB
Python
16 lines
2.1 KiB
Python
"""Adversarial mutations of the exact extracted bodies, never historical inputs."""
|
|
import pathlib,subprocess,shutil,json,resource,argparse
|
|
p=argparse.ArgumentParser();p.add_argument('lab',type=pathlib.Path);L=p.parse_args().lab.resolve();N=L/'negative';N.mkdir(exist_ok=True);records=[]
|
|
pkg=subprocess.check_output(['pkg-config','--cflags','--libs','wayland-server','pixman-1'],text=True).split()
|
|
mutants=[('B','popup.inc','desired && admitted','desired',''),('A','setter.inc','abort();','return;','1'),('B','setter.inc','wlr_scene_node_set_enabled(&tree->node, false);','/* mutant: false without admission mask */','1'),('B','setter.inc','\treturn true;\n}\n\nbool wlr_scene_tree_get_clip','\twlr_scene_node_set_enabled(&tree->node, true);\n\treturn true;\n}\n\nbool wlr_scene_tree_get_clip','1'),('C','create.inc','struct scene_tree_clip *entry = calloc(1, sizeof(*entry));','scene_tree_init(tree, parent);\n\tstruct scene_tree_clip *entry = calloc(1, sizeof(*entry));','2'),('C','setter.inc','entry->active = clip != NULL;','entry->active = false;','')]
|
|
for i,(mode,file,old,new,arg) in enumerate(mutants):
|
|
d=N/str(i);shutil.copytree(L/mode,d,ignore=shutil.ignore_patterns('A-*','B-*','C-*'),dirs_exist_ok=True)
|
|
f=d/file;s=f.read_text();assert old in s;f.write_text(s.replace(old,new,1));args=['cc','-std=c17','-O1','-DMODE_'+mode,'harness-scene.c','options.c',*pkg,'-o',str(d/'mutant')]
|
|
c=subprocess.run(args,cwd=d,capture_output=True);assert c.returncode==0,c.stderr
|
|
def limit():resource.setrlimit(resource.RLIMIT_CORE,(0,0))
|
|
argv=[str(d/'mutant')]+([arg] if arg else []);r=subprocess.run(argv,cwd=d,capture_output=True,preexec_fn=limit)
|
|
(d/'stdout').write_bytes(r.stdout);(d/'stderr').write_bytes(r.stderr)
|
|
# A must return 99 rather than expected SIGABRT; others must trip assertions.
|
|
rejected=r.returncode==99 if mode=='A' else r.returncode==-6
|
|
records.append(dict(mode=mode,file=file,mutation=old+' => '+new,argv=argv,returncode=r.returncode,rejected=rejected))
|
|
(N/'results.json').write_text(json.dumps(records,indent=2)+'\n');print(json.dumps(records,indent=2));raise SystemExit(not all(r['rejected'] for r in records))
|