File size: 1,591 Bytes
b19c92c |
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 |
import ast, javalang, re
class BugDetector:
def detect_none_deref_python(self,code):
issues=[];
try:
t=ast.parse(code)
for n in ast.walk(t):
if isinstance(n,ast.Attribute) and isinstance(n.value,ast.Name):
issues.append({'line':n.lineno,'msg':f"Possible None dereference: {n.value.id}"})
except: pass
return issues
def detect_unused_vars_python(self,code):
issues=[]
try:
t=ast.parse(code);assigned=set();used=set()
for n in ast.walk(t):
if isinstance(n,ast.Assign):
for t2 in n.targets:
if isinstance(t2,ast.Name): assigned.add(t2.id)
if isinstance(n,ast.Name) and isinstance(n.ctx,ast.Load): used.add(n.id)
for v in assigned-used: issues.append({'msg':f"Unused variable {v}"})
except: pass
return issues
def detect_null_checks_java(self,code):
issues=[]
try:
for m in re.finditer(r"(\w+)\.\w+\(",code):
v=m.group(1);ctx=code[max(0,m.start()-200):m.end()+200]
if not re.search(rf"if *\( *{v} *!= *null",ctx):
issues.append({'msg':f"Possible null dereference: {v}"})
except: pass
return issues
def analyze(self,code,lang):
lang=lang.lower()
if lang=='python': return self.detect_none_deref_python(code)+self.detect_unused_vars_python(code)
if lang=='java': return self.detect_null_checks_java(code)
return []
|