Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 33 additions & 4 deletions universalmutator/genmutants.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ def main():
print("USAGE: mutate <sourcefile> [<language>] [<rule1> <rule2>...]",
"[--noCheck] [--cmd <command string>] [--mutantDir <dir>]",
"[--lines <coverfile> [--tstl]] [--mutateTestCode] [--mutateBoth]",
"[--ignore <file>] [--compile <file>] [--noFastCheck] [--swap]",
"[--redundantOK] [--showRules] [--only <rule>]")
"[mutateChange <file>][--ignore <file>] [--compile <file>] [--noFastCheck]",
"[--swap][--redundantOK] [--showRules] [--only <rule>]")
print()
print(" --noCheck: skips compilation/comparison and just generates mutant files")
print(" --cmd executes command string, replacing MUTANT with the mutant name, and uses return code")
Expand All @@ -132,6 +132,7 @@ def main():
print(" --mutateInStrings: mutate inside strings (not just turn to empty string)")
print(" --mutateTestCode: mutate only test code")
print(" --mutateBoth: mutate both test and normal code")
print(" --mutateChange: only mutates the lines that have changed from the source file, to other file.")
print(" --ignore <file>: ignore lines matching patterns in <file>")
print(" --compile <file>: compile <file> instead of source (solidity handler only)")
print(" --comby: use comby as the method of mutating code")
Expand Down Expand Up @@ -259,6 +260,17 @@ def main():
args.remove(mdir)
if mdir[-1] != "/":
mdir += "/"

changeFile = None
try:
changepos = args.index("--mutateChange")
except ValueError:
changepos = -1

if changepos != -1:
changeFile = args[changepos + 1]
args.remove("--mutateChange")
args.remove(changeFile)

ignoreFile = None
try:
Expand Down Expand Up @@ -381,15 +393,32 @@ def main():
# remove non-ascii characters (comby issue)
line_processed = line.encode('ascii', 'ignore').decode()
source.append(line_processed)
skippedLines = []
if changeFile is not None:
print("ONLY MUTATING LINES CHANGED IN", changeFile)
change = []

with open(changeFile, 'r') as file:
for line in file:
# remove non-ascii characters (comby issue)
line_processed = line.encode('ascii', 'ignore').decode()
change.append(line_processed)

with open(changeFile, 'r') as changef, open(sourceFile, 'r') as sourcef:
for i in range (min(len(change),len(source))):

if change[i] == source[i]:

skippedLines.append(change[i])

mutants = []

if comby:
mutants = mutator.mutants_comby(source, ruleFiles=rules, mutateTestCode=mutateTestCode, mutateBoth=mutateBoth,
ignorePatterns=ignorePatterns, ignoreStringOnly=not mutateInStrings, fuzzing=fuzz, language=ending)
ignorePatterns=ignorePatterns, ignoreStringOnly=not mutateInStrings, fuzzing=fuzz, language=ending,skipLines=skippedLines)
else:
mutants = mutator.mutants_regexp(source, ruleFiles=rules, mutateTestCode=mutateTestCode, mutateBoth=mutateBoth,
ignorePatterns=ignorePatterns, ignoreStringOnly=not mutateInStrings, fuzzing=fuzz)
ignorePatterns=ignorePatterns, ignoreStringOnly=not mutateInStrings, fuzzing=fuzz, skipLines=skippedLines)
if fuzz:
if len(mutants) == 0:
sys.exit(255)
Expand Down
9 changes: 7 additions & 2 deletions universalmutator/mutator.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ def parseRules(ruleFiles, comby=False):


def mutants_comby(source, ruleFiles=None, mutateTestCode=False, mutateBoth=False,
ignorePatterns=None, ignoreStringOnly=False, fuzzing=False, language=".generic"):
ignorePatterns=None, ignoreStringOnly=False, fuzzing=False, language=".generic", skipLines=None):

if ruleFiles is None:
ruleFiles = ["universal.rules"]
comby = Comby()
Expand Down Expand Up @@ -128,7 +129,7 @@ def mutants_comby(source, ruleFiles=None, mutateTestCode=False, mutateBoth=False
return mutants

def mutants_regexp(source, ruleFiles=None, mutateTestCode=False, mutateBoth=False,
ignorePatterns=None, ignoreStringOnly=False, fuzzing=False):
ignorePatterns=None, ignoreStringOnly=False, fuzzing=False,skipLines = None):
if ruleFiles is None:
ruleFiles = ["universal.rules"]
print("MUTATING WITH RULES:", ", ".join(ruleFiles))
Expand Down Expand Up @@ -172,6 +173,10 @@ def mutants_regexp(source, ruleFiles=None, mutateTestCode=False, mutateBoth=Fals
if mutateTestCode and (not mutateBoth):
continue
skipLine = False

if skipLines and l in skipLines:
skipLine = True

for lhs in ignoreRules:
if lhs.search(l):
skipLine = True
Expand Down