Skip to content

Conversation

@stevennevins
Copy link
Contributor

@stevennevins stevennevins commented Dec 5, 2025

Summary

CR mutator now uses block comments (/* */) instead of line comments (//).

Problem

Line comment // comments out everything after it on the line. This breaks compilation when code continues:

// Original
function test() public onlyOwner {

// With // - BROKEN
function test() public // onlyOwner {

// With /* */ - WORKS  
function test() public /* onlyOwner */ {

Solution

new_str = "/* " + old_str + " */"

Scenarios Improved

Function modifier same line as brace:

// Original
function foo() onlyOwner {

// Before (broken)
function foo() // onlyOwner {

// After (works)
function foo() /* onlyOwner */ {

Single-line functions:

// Original
function getX() view returns (uint) { return x; }

// Before (broken) - commenting return statement
function getX() view returns (uint) { // return x; }

// After (works)
function getX() view returns (uint) { /* return x; */ }

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 */;`.
@stevennevins stevennevins force-pushed the fix/cr-mutator-block-comments-v2 branch from c7ae8ab to f6bacf4 Compare December 5, 2025 15:10
@stevennevins stevennevins marked this pull request as ready for review December 11, 2025 21:39
Resolves merge conflict in tests/tools/mutator/test_mutator.py by keeping both:
- CR mutator block comments test (from this branch)
- Target selector parsing tests (from upstream/dev)
@stevennevins stevennevins force-pushed the fix/cr-mutator-block-comments-v2 branch from 0ccdbb6 to f1d994e Compare January 9, 2026 18:08
@dguido dguido changed the base branch from dev to master January 15, 2026 19:05
@dguido
Copy link
Member

dguido commented Jan 15, 2026

Code review

Found 1 issue:

  1. Byte offset used as character index - The new semicolon-checking code uses stop (a byte offset from Solidity's source mapping) as a character index into source_code (a Python string). This is incorrect for files containing multi-byte UTF-8 characters (e.g., unicode in comments or string literals). The codebase explicitly documents this limitation in source_mapping.py:content: "Use this property instead of eg source_code[start:end] Above will return incorrect content if source_code contains any unicode because self.start and self.end are byte offsets, not char offsets"

# Check if there's a trailing semicolon to include
source_code = self.slither.source_code[self.in_file]
if stop < len(source_code) and source_code[stop] == ";":
stop += 1
old_str += ";"

The fix should encode the source code to UTF-8 bytes before indexing, similar to how abstract_mutator.py does it:

source_bytes = self.slither.source_code[self.in_file].encode("utf8")
if stop < len(source_bytes) and source_bytes[stop:stop+1] == b";":

Reference:

def content(self) -> str:
"""
Return the txt content of the Source
Use this property instead of eg source_code[start:end]
Above will return incorrect content if source_code contains any unicode
because self.start and self.end are byte offsets, not char offsets
Returns: str
"""
# If the compilation unit was not initialized, it means that the set_offset was never called
# on the corresponding object, which should not happen
assert self.compilation_unit
return (
self.compilation_unit.core.source_code[self.filename.absolute]
.encode("utf8")[self.start : self.end]
.decode("utf8")
)

🤖 Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants