Files
ast-project/part1/oracle.py
T
2026-06-24 13:47:14 +02:00

75 lines
1.7 KiB
Python

#!/usr/bin/env python3
import random
import subprocess
from runner import run_sql_parallel
from sqlite_static_helper import *
from stats import save_bug
def is_crash(rc: int, _stderr: str) -> bool:
# https://tldp.org/LDP/abs/html/exitcodes.html
if rc > 128 and rc != 130:
return True
return False
def is_unexpected_error(b_rc, _b_err, r_rc, _r_err, _sql):
if b_rc != 0 and r_rc == 0:
return True
return False
def is_valid_sql(r_rc: int, _r_err: str):
if r_rc != 0:
return False
return True
def check(buggy_bin: str,
ref_bin: str,
sql: str,
with_flag: bool = False,
save_bugs: bool = True) -> int:
"""
Returns:
- `-1`: The query was not successfully executed on the reference binary, probably due to syntax issues
- `0`: The query caused a logic bug, crash, or some other unexpected error.
- `1`: The query was successfully executed on both binaries.
"""
flag = '' if not with_flag else random.choice(FLAGS)
try:
b_out, b_err, b_rc, r_out, r_err, r_rc = run_sql_parallel(
buggy_bin, ref_bin, sql, flag)
except subprocess.TimeoutExpired:
return 0
except Exception:
return -1
if not is_valid_sql(r_rc, r_err):
return -1
# # Crash Detection
if is_crash(b_rc, b_err) and not is_crash(r_rc, r_err):
if save_bugs:
save_bug(sql, 'crash', b_out, b_err, flag=flag)
return 0
# # Unexpected Error Detection
elif is_unexpected_error(b_rc, b_err, r_rc, r_err, sql):
if save_bugs:
save_bug(sql, 'unexpected_error', b_out, b_err, flag=flag)
return 0
# # Logic Bug Detection
elif b_rc == 0 and r_rc == 0 and b_out != r_out:
if save_bugs:
save_bug(sql, 'logic', b_out, b_err, r_out, flag=flag)
return 0
return 1