Skip to content

Commit f6bacf4

Browse files
committed
fix: use block comments in CR mutator to prevent compilation errors
Line comments (//) break compilation when code continues after the commented portion on the same line. Block comments (/* */) work in all cases. Also include trailing semicolon in comment when present, preventing orphaned semicolon syntax errors like `/* stmt */;`.
1 parent e24fe56 commit f6bacf4

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

slither/tools/mutator/mutators/CR.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,14 @@ def _mutate(self) -> Dict:
2727
stop = start + node.source_mapping.length
2828
old_str = node.source_mapping.content
2929
line_no = node.source_mapping.lines
30-
new_str = "//" + old_str
30+
31+
# Check if there's a trailing semicolon to include
32+
source_code = self.slither.source_code[self.in_file]
33+
if stop < len(source_code) and source_code[stop] == ";":
34+
stop += 1
35+
old_str += ";"
36+
37+
new_str = "/* " + old_str + " */"
3138
create_patch_with_line(
3239
result,
3340
self.in_file,

tests/tools/mutator/test_mutator.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import pytest
1111
from slither import Slither
1212
from slither.tools.mutator.__main__ import _get_mutators, main
13+
from slither.tools.mutator.mutators.CR import CR
1314
from slither.tools.mutator.utils.testing_generated_mutant import run_test_cmd
1415
from slither.tools.mutator.utils.file_handling import get_sol_file_list, backup_source_file
1516

@@ -131,3 +132,38 @@ def mock_run(*args, **kwargs):
131132
result = run_test_cmd("forge test", timeout=1)
132133
assert not result
133134
assert "Tests took too long" in caplog.messages[0]
135+
136+
137+
def test_cr_mutator_uses_block_comments(solc_binary_path):
138+
"""CR mutator should use block comments /* */ not line comments //"""
139+
solc_path = solc_binary_path("0.8.15")
140+
file_path = (TEST_DATA_DIR / "test_source_unit" / "src" / "Counter.sol").as_posix()
141+
sl = Slither(file_path, solc=solc_path)
142+
143+
for contract in sl.contracts:
144+
if contract.name == "Counter":
145+
with tempfile.TemporaryDirectory() as tmp_dir:
146+
mutator = CR(
147+
compilation_unit=contract.compilation_unit,
148+
timeout=10,
149+
testing_command="forge test",
150+
testing_directory=".",
151+
contract_instance=contract,
152+
solc_remappings=None,
153+
verbose=False,
154+
output_folder=Path(tmp_dir),
155+
dont_mutate_line=[],
156+
rate=100,
157+
)
158+
result = mutator._mutate()
159+
160+
# Verify mutations were generated
161+
assert "patches" in result, "CR mutator should generate patches"
162+
163+
# Verify all patches use block comments
164+
for patches in result["patches"].values():
165+
for patch in patches:
166+
new_str = patch["new_string"]
167+
assert new_str.startswith("/*"), f"Expected block comment, got: {new_str}"
168+
assert new_str.endswith("*/"), f"Expected block comment, got: {new_str}"
169+
assert "//" not in new_str, f"Should not use line comment: {new_str}"

0 commit comments

Comments
 (0)