From 3404b76db2b29dc7a27c1cefda0e557346055904 Mon Sep 17 00:00:00 2001 From: bohendo Date: Wed, 5 Feb 2025 15:18:03 -0500 Subject: [PATCH 1/2] remap offsets from bytes to chars during source map conversion --- slither/core/source_mapping/source_mapping.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/slither/core/source_mapping/source_mapping.py b/slither/core/source_mapping/source_mapping.py index 355aa5538..251d62995 100644 --- a/slither/core/source_mapping/source_mapping.py +++ b/slither/core/source_mapping/source_mapping.py @@ -165,16 +165,19 @@ def _convert_source_mapping( if len(position) != 1: return Source(compilation_unit) - s, l, f = position[0] - s = int(s) - l = int(l) + s_bytes, l_bytes, f = position[0] + s_bytes = int(s_bytes) + l_bytes = int(l_bytes) f = int(f) if f not in sourceUnits: + # TODO: figure out the filename so we can get the source code + # to remap bytes to chars.. When is this branch even used? new_source = Source(compilation_unit) - new_source.start = s - new_source.length = l + new_source.start = s_bytes + new_source.length = l_bytes return new_source + filename_used = sourceUnits[f] # If possible, convert the filename to its absolute/relative version @@ -183,6 +186,12 @@ def _convert_source_mapping( filename: Filename = compilation_unit.core.crytic_compile.filename_lookup(filename_used) is_dependency = compilation_unit.core.crytic_compile.is_dependency(filename.absolute) + # convert byte-offset indicies to char-offset + source_code = compilation_unit.core.source_code[filename.absolute] + s = int(len(source_code.encode("utf-8")[:s_bytes].decode("utf-8"))) + l = int(len(source_code.encode("utf-8")[s_bytes : s_bytes + l_bytes].decode("utf-8"))) + f = int(f) + (lines, starting_column, ending_column) = _compute_line(compilation_unit, filename, s, l) new_source = Source(compilation_unit) From ef3bab15de69aad2205c469aaa3af868e6816f62 Mon Sep 17 00:00:00 2001 From: bohendo Date: Wed, 5 Feb 2025 16:18:27 -0500 Subject: [PATCH 2/2] assume no unicode if no source code is available --- slither/core/source_mapping/source_mapping.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/slither/core/source_mapping/source_mapping.py b/slither/core/source_mapping/source_mapping.py index 251d62995..ca9436006 100644 --- a/slither/core/source_mapping/source_mapping.py +++ b/slither/core/source_mapping/source_mapping.py @@ -150,9 +150,10 @@ def _compute_line( return list(range(start_line, end_line + 1)), starting_column, ending_column +# pylint: disable=too-many-locals def _convert_source_mapping( offset: str, compilation_unit: "SlitherCompilationUnit" -) -> Source: # pylint: disable=too-many-locals +) -> Source: """ Convert a text offset to a real offset see https://solidity.readthedocs.io/en/develop/miscellaneous.html#source-mappings @@ -186,11 +187,15 @@ def _convert_source_mapping( filename: Filename = compilation_unit.core.crytic_compile.filename_lookup(filename_used) is_dependency = compilation_unit.core.crytic_compile.is_dependency(filename.absolute) - # convert byte-offset indicies to char-offset - source_code = compilation_unit.core.source_code[filename.absolute] - s = int(len(source_code.encode("utf-8")[:s_bytes].decode("utf-8"))) - l = int(len(source_code.encode("utf-8")[s_bytes : s_bytes + l_bytes].decode("utf-8"))) - f = int(f) + if filename.absolute in compilation_unit.core.source_code: + # convert byte-offset indicies to char-offset + source_code = compilation_unit.core.source_code[filename.absolute] + s = int(len(source_code.encode("utf-8")[:s_bytes].decode("utf-8"))) + l = int(len(source_code.encode("utf-8")[s_bytes : s_bytes + l_bytes].decode("utf-8"))) + else: + # no source code is available, hopefully the source code doesn't contain unicode + s = int(s_bytes) + l = int(l_bytes) (lines, starting_column, ending_column) = _compute_line(compilation_unit, filename, s, l)