updated create patch

pull/2278/head
Vishnuram Rajkumar 10 months ago
parent 9db7167817
commit 6ad193abd9
  1. 30
      slither/tools/mutator/__main__.py
  2. 4
      slither/tools/mutator/mutators/AOR.py
  3. 4
      slither/tools/mutator/mutators/ASOR.py
  4. 4
      slither/tools/mutator/mutators/BOR.py
  5. 32
      slither/tools/mutator/mutators/CR.py
  6. 4
      slither/tools/mutator/mutators/FHR.py
  7. 6
      slither/tools/mutator/mutators/LIR.py
  8. 4
      slither/tools/mutator/mutators/LOR.py
  9. 6
      slither/tools/mutator/mutators/MIA.py
  10. 6
      slither/tools/mutator/mutators/MVIE.py
  11. 7
      slither/tools/mutator/mutators/MVIV.py
  12. 4
      slither/tools/mutator/mutators/MWA.py
  13. 4
      slither/tools/mutator/mutators/ROR.py
  14. 14
      slither/tools/mutator/mutators/RR.py
  15. 6
      slither/tools/mutator/mutators/SBR.py
  16. 10
      slither/tools/mutator/mutators/UOR.py
  17. 5
      slither/tools/mutator/mutators/all_mutators.py
  18. 2
      slither/tools/mutator/utils/file_handling.py
  19. 22
      slither/tools/mutator/utils/patch.py
  20. 2
      slither/tools/mutator/utils/testing_generated_mutant.py

@ -83,6 +83,20 @@ def parse_args() -> argparse.Namespace:
help="mutant generators to run",
)
# list of contract names you want to mutate
parser.add_argument(
"--contract-names",
help="list of contract names you want to mutate",
)
# flag to run full mutation based revert mutator output
parser.add_argument(
"--quick",
help="to stop full mutation if revert mutator passes",
action="store_true",
default=False,
)
# Initiate all the crytic config cli options
cryticparser.init(parser)
@ -118,6 +132,7 @@ class ListMutators(argparse.Action): # pylint: disable=too-few-public-methods
def main() -> None:
args = parse_args()
# arguments
test_command: str = args.test_cmd
test_directory: str = args.test_dir
@ -127,6 +142,8 @@ def main() -> None:
solc_remappings: str | None = args.solc_remaps
verbose: bool = args.verbose
mutators_to_run: List[str] | None = args.mutators_to_run
contract_names: List[str] | None = args.contract_names
quick_flag: bool = args.quick
print(magenta(f"Starting Mutation Campaign in '{args.codebase} \n"))
@ -150,6 +167,13 @@ def main() -> None:
if timeout == None:
timeout = 30
# setting RR mutator as first mutator
mutators_list = _get_mutators(mutators_to_run)
for M in mutators_list:
if M.NAME == "RR":
mutators_list.remove(M)
mutators_list.insert(0, M)
for filename in sol_file_list:
contract_name = os.path.split(filename)[1].split('.sol')[0]
# TODO: user provides contract name
@ -165,14 +189,16 @@ def main() -> None:
# mutation
try:
for compilation_unit_of_main_file in sl.compilation_units:
# TODO
for M in _get_mutators(mutators_to_run):
for M in mutators_list:
m = M(compilation_unit_of_main_file, int(timeout), test_command, test_directory, contract_name, solc_remappings, verbose, output_folder)
# check whether the contract instance exists or not
if m.get_exist_flag():
count_valid, count_invalid = m.mutate()
v_count += count_valid
total_count += count_valid + count_invalid
if quick_flag:
if str(m.NAME) == 'RR' and v_count > 0:
break
except Exception as e:
logger.error(e)

@ -1,6 +1,6 @@
from typing import Dict
from slither.slithir.operations import Binary, BinaryType
from slither.formatters.utils.patches import create_patch
from slither.tools.mutator.utils.patch import create_patch_with_line
from slither.tools.mutator.mutators.abstract_mutator import AbstractMutator, FaultNature
from slither.core.expressions.unary_operation import UnaryOperation
@ -40,5 +40,5 @@ class AOR(AbstractMutator): # pylint: disable=too-few-public-methods
line_no = node.source_mapping.lines
# Replace the expression with true
new_str = f"{old_str.split(ir.type.value)[0]}{op.value}{old_str.split(ir.type.value)[1]}"
create_patch(result, self.in_file, start, stop, old_str, new_str, line_no[0])
create_patch_with_line(result, self.in_file, start, stop, old_str, new_str, line_no[0])
return result

@ -1,5 +1,5 @@
from typing import Dict
from slither.formatters.utils.patches import create_patch
from slither.tools.mutator.utils.patch import create_patch_with_line
from slither.tools.mutator.mutators.abstract_mutator import AbstractMutator, FaultNature
from slither.core.expressions.assignment_operation import AssignmentOperationType, AssignmentOperation
@ -44,5 +44,5 @@ class ASOR(AbstractMutator): # pylint: disable=too-few-public-methods
line_no = node.source_mapping.lines
# Replace the expression with true
new_str = f"{old_str.split(str(ir.expression.type))[0]}{op}{old_str.split(str(ir.expression.type))[1]}"
create_patch(result, self.in_file, start, stop, old_str, new_str, line_no[0])
create_patch_with_line(result, self.in_file, start, stop, old_str, new_str, line_no[0])
return result

@ -1,6 +1,6 @@
from typing import Dict
from slither.slithir.operations import Binary, BinaryType
from slither.formatters.utils.patches import create_patch
from slither.tools.mutator.utils.patch import create_patch_with_line
from slither.tools.mutator.mutators.abstract_mutator import AbstractMutator, FaultNature
bitwise_operators = [
@ -33,5 +33,5 @@ class BOR(AbstractMutator): # pylint: disable=too-few-public-methods
line_no = node.source_mapping.lines
# Replace the expression with true
new_str = f"{old_str.split(ir.type.value)[0]}{op.value}{old_str.split(ir.type.value)[1]}"
create_patch(result, self.in_file, start, stop, old_str, new_str, line_no[0])
create_patch_with_line(result, self.in_file, start, stop, old_str, new_str, line_no[0])
return result

@ -0,0 +1,32 @@
from typing import Dict
from slither.core.cfg.node import NodeType
from slither.tools.mutator.utils.patch import create_patch_with_line
from slither.tools.mutator.mutators.abstract_mutator import AbstractMutator, FaultNature
class CR(AbstractMutator): # pylint: disable=too-few-public-methods
NAME = "CR"
HELP = 'Comment Replacement'
FAULTNATURE = FaultNature.Missing
def _mutate(self) -> Dict:
result: Dict = {}
for function in self.contract.functions_and_modifiers_declared:
for node in function.nodes:
if node.type != NodeType.ENTRYPOINT and NodeType.ENDIF != node.type and NodeType.ENDLOOP != node.type:
# Get the string
start = node.source_mapping.start
stop = start + node.source_mapping.length
old_str = self.in_file_str[start:stop]
line_no = node.source_mapping.lines
new_str = "//" + old_str
create_patch_with_line(result, self.in_file, start, stop, old_str, new_str, line_no[0])
return result

@ -1,5 +1,5 @@
from typing import Dict
from slither.formatters.utils.patches import create_patch
from slither.tools.mutator.utils.patch import create_patch_with_line
from slither.tools.mutator.mutators.abstract_mutator import AbstractMutator, FaultNature
import re
@ -31,6 +31,6 @@ class FHR(AbstractMutator): # pylint: disable=too-few-public-methods
right_value = value.split(" ==> ")[1]
if re.search(re.compile(left_value), old_str) != None:
new_str = re.sub(re.compile(left_value), right_value, old_str)
create_patch(result, self.in_file, start, stop, old_str, new_str, line_no[0])
create_patch_with_line(result, self.in_file, start, stop, old_str, new_str, line_no[0])
return result

@ -2,7 +2,7 @@ from typing import Dict
from slither.core.expressions import Literal
from slither.core.variables.variable import Variable
from slither.tools.mutator.mutators.abstract_mutator import AbstractMutator, FaultNature
from slither.formatters.utils.patches import create_patch
from slither.tools.mutator.utils.patch import create_patch_with_line
from slither.core.solidity_types import ElementaryType
literal_replacements = []
@ -41,7 +41,7 @@ class LIR(AbstractMutator): # pylint: disable=too-few-public-methods
old_value = old_str[old_str.find("=")+1:].strip()
if old_value != value:
new_str = f"{old_str.split('=')[0]}= {value}"
create_patch(
create_patch_with_line(
result,
self.in_file,
start,
@ -69,7 +69,7 @@ class LIR(AbstractMutator): # pylint: disable=too-few-public-methods
old_value = old_str[old_str.find("=")+1:].strip()
if old_value != new_value:
new_str = f"{old_str.split('=')[0]}= {new_value}"
create_patch(
create_patch_with_line(
result,
self.in_file,
start,

@ -1,6 +1,6 @@
from typing import Dict
from slither.slithir.operations import Binary, BinaryType
from slither.formatters.utils.patches import create_patch
from slither.tools.mutator.utils.patch import create_patch_with_line
from slither.tools.mutator.mutators.abstract_mutator import AbstractMutator, FaultNature
logical_operators = [
@ -32,5 +32,5 @@ class LOR(AbstractMutator): # pylint: disable=too-few-public-methods
# Replace the expression with true
new_str = f"{old_str.split(ir.type.value)[0]} {op.value} {old_str.split(ir.type.value)[1]}"
create_patch(result, self.in_file, start, stop, old_str, new_str, line_no[0])
create_patch_with_line(result, self.in_file, start, stop, old_str, new_str, line_no[0])
return result

@ -1,6 +1,6 @@
from typing import Dict
from slither.core.cfg.node import NodeType
from slither.formatters.utils.patches import create_patch
from slither.tools.mutator.utils.patch import create_patch_with_line
from slither.tools.mutator.mutators.abstract_mutator import AbstractMutator, FaultNature
from slither.core.expressions.unary_operation import UnaryOperationType, UnaryOperation
@ -24,11 +24,11 @@ class MIA(AbstractMutator): # pylint: disable=too-few-public-methods
# Replace the expression with true and false
for value in ["true", "false"]:
new_str = value
create_patch(result, self.in_file, start, stop, old_str, new_str, line_no[0])
create_patch_with_line(result, self.in_file, start, stop, old_str, new_str, line_no[0])
if not isinstance(node.expression, UnaryOperation):
new_str = str(UnaryOperationType.BANG) + '(' + old_str + ')'
create_patch(result, self.in_file, start, stop, old_str, new_str, line_no[0])
create_patch_with_line(result, self.in_file, start, stop, old_str, new_str, line_no[0])
print(node.expression)

@ -2,7 +2,7 @@ from typing import Dict
from slither.core.expressions import Literal
from slither.core.variables.variable import Variable
from slither.tools.mutator.mutators.abstract_mutator import AbstractMutator, FaultNature
from slither.formatters.utils.patches import create_patch
from slither.tools.mutator.utils.patch import create_patch_with_line
class MVIE(AbstractMutator): # pylint: disable=too-few-public-methods
NAME = "MVIE"
@ -28,7 +28,7 @@ class MVIE(AbstractMutator): # pylint: disable=too-few-public-methods
new_str = old_str[: old_str.find("=")]
line_no = variable.node_initialization.source_mapping.lines
create_patch(
create_patch_with_line(
result,
self.in_file,
start,
@ -48,7 +48,7 @@ class MVIE(AbstractMutator): # pylint: disable=too-few-public-methods
new_str = old_str[: old_str.find("=")]
line_no = variable.source_mapping.lines
create_patch(
create_patch_with_line(
result,
self.in_file,
start,

@ -1,9 +1,8 @@
from typing import Dict
from slither.core.expressions import Literal
from slither.core.variables.variable import Variable
from slither.tools.mutator.mutators.abstract_mutator import AbstractMutator, FaultNature
from slither.formatters.utils.patches import create_patch
from slither.tools.mutator.utils.patch import create_patch_with_line
class MVIV(AbstractMutator): # pylint: disable=too-few-public-methods
NAME = "MVIV"
@ -28,7 +27,7 @@ class MVIV(AbstractMutator): # pylint: disable=too-few-public-methods
old_str = self.in_file_str[start:stop]
new_str = old_str[: old_str.find("=")]
line_no = variable.node_initialization.source_mapping.lines
create_patch(
create_patch_with_line(
result,
self.in_file,
start,
@ -46,7 +45,7 @@ class MVIV(AbstractMutator): # pylint: disable=too-few-public-methods
old_str = self.in_file_str[start:stop]
new_str = old_str[: old_str.find("=")]
line_no = variable.source_mapping.lines
create_patch(
create_patch_with_line(
result,
self.in_file,
start,

@ -1,6 +1,6 @@
from typing import Dict
from slither.core.cfg.node import NodeType
from slither.formatters.utils.patches import create_patch
from slither.tools.mutator.utils.patch import create_patch_with_line
from slither.tools.mutator.mutators.abstract_mutator import AbstractMutator, FaultNature
from slither.core.expressions.unary_operation import UnaryOperationType, UnaryOperation
@ -23,5 +23,5 @@ class MWA(AbstractMutator): # pylint: disable=too-few-public-methods
if not isinstance(node.expression, UnaryOperation):
new_str = str(UnaryOperationType.BANG) + '(' + old_str + ')'
create_patch(result, self.in_file, start, stop, old_str, new_str, line_no[0])
create_patch_with_line(result, self.in_file, start, stop, old_str, new_str, line_no[0])
return result

@ -1,6 +1,6 @@
from typing import Dict
from slither.slithir.operations import Binary, BinaryType
from slither.formatters.utils.patches import create_patch
from slither.tools.mutator.utils.patch import create_patch_with_line
from slither.tools.mutator.mutators.abstract_mutator import AbstractMutator, FaultNature
relational_operators = [
@ -36,6 +36,6 @@ class ROR(AbstractMutator): # pylint: disable=too-few-public-methods
# Replace the expression with true
new_str = f"{old_str.split(ir.type.value)[0]} {op.value} {old_str.split(ir.type.value)[1]}"
create_patch(result, self.in_file, start, stop, old_str, new_str, line_no[0])
create_patch_with_line(result, self.in_file, start, stop, old_str, new_str, line_no[0])
return result

@ -1,12 +1,12 @@
from typing import Dict
from slither.core.cfg.node import NodeType
from slither.formatters.utils.patches import create_patch
from slither.tools.mutator.utils.patch import create_patch_with_line
from slither.tools.mutator.mutators.abstract_mutator import AbstractMutator, FaultNature
class RCR(AbstractMutator): # pylint: disable=too-few-public-methods
NAME = "RCR"
HELP = 'Revert and Comment Replacement'
class RR(AbstractMutator): # pylint: disable=too-few-public-methods
NAME = "RR"
HELP = 'Revert Replacement'
FAULTNATURE = FaultNature.Missing
def _mutate(self) -> Dict:
@ -22,11 +22,7 @@ class RCR(AbstractMutator): # pylint: disable=too-few-public-methods
line_no = node.source_mapping.lines
if old_str != 'revert()':
new_str = 'revert()'
create_patch(result, self.in_file, start, stop, old_str, new_str, line_no[0])
new_str = "//" + old_str
create_patch(result, self.in_file, start, stop, old_str, new_str, line_no[0])
create_patch_with_line(result, self.in_file, start, stop, old_str, new_str, line_no[0])
return result

@ -1,6 +1,6 @@
from typing import Dict
from slither.core.cfg.node import NodeType
from slither.formatters.utils.patches import create_patch
from slither.tools.mutator.utils.patch import create_patch_with_line
from slither.tools.mutator.mutators.abstract_mutator import AbstractMutator, FaultNature
import re
from slither.core.variables.variable import Variable
@ -67,7 +67,7 @@ class SBR(AbstractMutator): # pylint: disable=too-few-public-methods
right_value = value.split(" ==> ")[1]
if re.search(re.compile(left_value), old_str) != None:
new_str = re.sub(re.compile(left_value), right_value, old_str)
create_patch(result, self.in_file, start, stop, old_str, new_str, line_no[0])
create_patch_with_line(result, self.in_file, start, stop, old_str, new_str, line_no[0])
for variable in self.contract.state_variables_declared:
node = variable.node_initialization
@ -81,7 +81,7 @@ class SBR(AbstractMutator): # pylint: disable=too-few-public-methods
right_value = value.split(" ==> ")[1]
if re.search(re.compile(left_value), old_str) != None:
new_str = re.sub(re.compile(left_value), right_value, old_str)
create_patch(result, self.in_file, start, stop, old_str, new_str, line_no[0])
create_patch_with_line(result, self.in_file, start, stop, old_str, new_str, line_no[0])
return result

@ -1,6 +1,6 @@
from typing import Dict
from slither.core.expressions.unary_operation import UnaryOperationType, UnaryOperation
from slither.formatters.utils.patches import create_patch
from slither.tools.mutator.utils.patch import create_patch_with_line
from slither.tools.mutator.mutators.abstract_mutator import AbstractMutator, FaultNature
unary_operators = [
@ -36,16 +36,16 @@ class UOR(AbstractMutator): # pylint: disable=too-few-public-methods
variable_read = node.variables_read[0]
new_str = str(variable_read) + str(op)
if new_str != old_str and str(op) != '-':
create_patch(result, self.in_file, start, stop, old_str, new_str, line_no[0])
create_patch_with_line(result, self.in_file, start, stop, old_str, new_str, line_no[0])
new_str = str(op) + str(variable_read)
create_patch(result, self.in_file, start, stop, old_str, new_str, line_no[0])
create_patch_with_line(result, self.in_file, start, stop, old_str, new_str, line_no[0])
else:
if node.expression.type != op:
variable_read = node.variables_read[0]
new_str = str(op) + str(variable_read)
if new_str != old_str and str(op) != '-':
create_patch(result, self.in_file, start, stop, old_str, new_str, line_no[0])
create_patch_with_line(result, self.in_file, start, stop, old_str, new_str, line_no[0])
new_str = str(variable_read) + str(op)
create_patch(result, self.in_file, start, stop, old_str, new_str, line_no[0])
create_patch_with_line(result, self.in_file, start, stop, old_str, new_str, line_no[0])
return result

@ -12,6 +12,5 @@ from slither.tools.mutator.mutators.LIR import LIR # severity medium
from slither.tools.mutator.mutators.FHR import FHR # severity medium
from slither.tools.mutator.mutators.MIA import MIA # severity medium
from slither.tools.mutator.mutators.ROR import ROR # severity medium
from slither.tools.mutator.mutators.RCR import RCR # severity high
from slither.tools.mutator.mutators.RR import RR # severity high
from slither.tools.mutator.mutators.CR import CR # severity high

@ -1,5 +1,5 @@
import os
from typing import Dict, Tuple, List
from typing import Dict, List
import logging
logger = logging.getLogger("Slither-Mutate")

@ -0,0 +1,22 @@
from typing import Dict, Union
from collections import defaultdict
# pylint: disable=too-many-arguments
def create_patch_with_line(
result: Dict,
file: str,
start: int,
end: int,
old_str: Union[str, bytes],
new_str: Union[str, bytes],
line_no: int
) -> None:
if isinstance(old_str, bytes):
old_str = old_str.decode("utf8")
if isinstance(new_str, bytes):
new_str = new_str.decode("utf8")
p = {"start": start, "end": end, "old_string": old_str, "new_string": new_str, "line_number": line_no}
if "patches" not in result:
result["patches"] = defaultdict(list)
if p not in result["patches"][file]:
result["patches"][file].append(p)

@ -4,7 +4,7 @@ import os
import logging
import time
import signal
from typing import List, Dict
from typing import Dict
from slither.tools.mutator.utils.file_handling import create_mutant_file, reset_file
from slither.utils.colors import green, red

Loading…
Cancel
Save