Skip to content

Commit

Permalink
Improve message error for when Crytic throws a KeyError. (#2418)
Browse files Browse the repository at this point in the history
* Improve message error for when Crytic throws a KeyError.

* Remove unneeded logger usage and fix typo
  • Loading branch information
DarkaMaul authored Jun 5, 2024
1 parent b9a3ea6 commit 4d09e59
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 3 deletions.
18 changes: 15 additions & 3 deletions slither/core/source_mapping/source_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from Crypto.Hash import SHA1
from crytic_compile.utils.naming import Filename
from slither.core.context.context import Context
from slither.exceptions import SlitherException

if TYPE_CHECKING:
from slither.core.compilation_unit import SlitherCompilationUnit
Expand Down Expand Up @@ -136,9 +137,20 @@ def _compute_line(
start_line, starting_column = compilation_unit.core.crytic_compile.get_line_from_offset(
filename, start
)
end_line, ending_column = compilation_unit.core.crytic_compile.get_line_from_offset(
filename, start + length
)
try:
end_line, ending_column = compilation_unit.core.crytic_compile.get_line_from_offset(
filename, start + length
)
except KeyError:
# This error may occur when the build is not synchronised with the source code on disk.
# See the GitHub issue https://github.com/crytic/slither/issues/2296
msg = f"""The source code appears to be out of sync with the build artifacts on disk.
This discrepancy can occur after recent modifications to {filename.short}. To resolve this
issue, consider executing the clean command of the build system (e.g. forge clean).
"""
# We still re-raise the exception as a SlitherException here
raise SlitherException(msg) from None

return list(range(start_line, end_line + 1)), starting_column, ending_column


Expand Down
3 changes: 3 additions & 0 deletions tests/e2e/compilation/test_data/test_change/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Foundry

To init this test case, run `forge install --no-commit --no-git foundry-rs/forge-std`
6 changes: 6 additions & 0 deletions tests/e2e/compilation/test_data/test_change/foundry.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[profile.default]
src = "src"
out = "out"
libs = ["lib"]

# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
16 changes: 16 additions & 0 deletions tests/e2e/compilation/test_data/test_change/src/Counter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

contract Counter {
uint256 public number;

function setNumber(uint256 newNumber) public {
number = newNumber;
}

//START
function increment() public {
number++;
}
//END
}
40 changes: 40 additions & 0 deletions tests/e2e/compilation/test_diagnostic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from pathlib import Path
import shutil
import re

import pytest

from slither import Slither
from slither.exceptions import SlitherException


TEST_DATA_DIR = Path(__file__).resolve().parent / "test_data"

foundry_available = shutil.which("forge") is not None
project_ready = Path(TEST_DATA_DIR, "test_change/lib/forge-std").exists()


@pytest.mark.skipif(
not foundry_available or not project_ready, reason="requires Foundry and project setup"
)
def test_diagnostic():

test_file_directory = TEST_DATA_DIR / "test_change"

sl = Slither(test_file_directory.as_posix())
assert len(sl.compilation_units) == 1

counter_file = test_file_directory / "src" / "Counter.sol"
shutil.copy(counter_file, counter_file.with_suffix(".bak"))

with counter_file.open("r") as file:
content = file.read()

with counter_file.open("w") as file:
file.write(re.sub(r"//START.*?//END\n?", "", content, flags=re.DOTALL))

with pytest.raises(SlitherException):
Slither(test_file_directory.as_posix(), ignore_compile=True)

# Restore the original counter so the test is idempotent
Path(counter_file.with_suffix(".bak")).rename(counter_file)

0 comments on commit 4d09e59

Please sign in to comment.