Merge pull request #702 from crytic/dev-get_line_from_offset

Use get_line_from_offset from crytic_compile in source mapping
pull/704/head
Feist Josselin 4 years ago committed by GitHub
commit a30802f66e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 66
      slither/core/source_mapping/source_mapping.py

@ -1,5 +1,5 @@
import re
from typing import Dict, Union, Optional
from typing import Dict, Union, Optional, List, Tuple
from slither.core.context.context import Context
@ -9,56 +9,36 @@ class SourceMapping(Context):
super().__init__()
# TODO create a namedtuple for the source mapping rather than a dict
self._source_mapping: Optional[Dict] = None
# self._start: Optional[int] = None
# self._length: Optional[int] = None
# self._filename_used: Optional[str] = None
# self._filename_relative: Optional[str] = None
# self._filename_absolute: Optional[str] = None
# self._filename_short: Optional[str] = None
# self._is_dependency: Optional[bool] = None
# self._lines: Optional[List[int]] = None
# self._starting_column: Optional[int] = None
# self._ending_column: Optional[int] = None
@property
def source_mapping(self) -> Optional[Dict]:
return self._source_mapping
@staticmethod
def _compute_line(source_code, start, length):
def _compute_line(slither, filename, start: int, length: int) -> Tuple[List[int], int, int]:
"""
Compute line(s) numbers and starting/ending columns
from a start/end offset. All numbers start from 1.
Not done in an efficient way
"""
source_code = source_code.encode("utf-8")
total_length = len(source_code)
source_code = source_code.splitlines(True)
counter = 0
i = 0
lines = []
starting_column = None
ending_column = None
while counter < total_length:
# Determine the length of the line, and advance the line number
line_content = source_code[i]
line_length = len(line_content)
i = i + 1
# Determine our column numbers.
if starting_column is None and counter + line_length > start:
starting_column = (start - counter) + 1
if (
starting_column is not None
and ending_column is None
and counter + line_length > start + length
):
ending_column = ((start + length) - counter) + 1
# Advance the current position counter, and determine line numbers.
counter += line_length
if counter > start:
lines.append(i)
# If our advanced position for the next line is out of range, stop.
if counter > start + length:
break
start_line, starting_column = slither.crytic_compile.get_line_from_offset(filename, start)
end_line, ending_column = slither.crytic_compile.get_line_from_offset(
filename, start + length
)
return list(range(start_line, end_line + 1)), starting_column, ending_column
return lines, starting_column, ending_column
@staticmethod
def _convert_source_mapping(offset: str, slither): # pylint: disable=too-many-locals
def _convert_source_mapping(self, offset: str, slither): # pylint: disable=too-many-locals
"""
Convert a text offset to a real offset
see https://solidity.readthedocs.io/en/develop/miscellaneous.html#source-mappings
@ -85,8 +65,6 @@ class SourceMapping(Context):
is_dependency = False
lines = []
# If possible, convert the filename to its absolute/relative version
if slither.crytic_compile:
filenames = slither.crytic_compile.filename_lookup(filename_used)
@ -110,12 +88,8 @@ class SourceMapping(Context):
else:
filename = filename_used
if slither.crytic_compile and filename in slither.crytic_compile.src_content:
source_code = slither.crytic_compile.src_content[filename]
(lines, starting_column, ending_column) = SourceMapping._compute_line(source_code, s, l)
elif filename in slither.source_code:
source_code = slither.source_code[filename]
(lines, starting_column, ending_column) = SourceMapping._compute_line(source_code, s, l)
if slither.crytic_compile:
(lines, starting_column, ending_column) = self._compute_line(slither, filename, s, l)
else:
(lines, starting_column, ending_column) = ([], None, None)

Loading…
Cancel
Save