Improve message error for when Crytic throws a KeyError. (#2418)

* Improve message error for when Crytic throws a KeyError.

* Remove unneeded logger usage and fix typo
pull/2473/head
dm 6 months ago committed by GitHub
parent b9a3ea6189
commit 4d09e59915
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 18
      slither/core/source_mapping/source_mapping.py
  2. 3
      tests/e2e/compilation/test_data/test_change/README.md
  3. 6
      tests/e2e/compilation/test_data/test_change/foundry.toml
  4. 16
      tests/e2e/compilation/test_data/test_change/src/Counter.sol
  5. 40
      tests/e2e/compilation/test_diagnostic.py

@ -4,6 +4,7 @@ from typing import Dict, Union, List, Tuple, TYPE_CHECKING, Optional, Any
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
@ -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

@ -0,0 +1,3 @@
# Foundry
To init this test case, run `forge install --no-commit --no-git foundry-rs/forge-std`

@ -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

@ -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
}

@ -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)
Loading…
Cancel
Save