Repository: crytic/slither

Issue:
Line/column number calculation regression
Recent adoption of `crytic-compile` in slither have required some code paths to be changed. A regression can be observed in source mapping line/column calculations due to CR, LF, and CRLF line endings, as described in #194 .

The problematic code can be found here:
https://github.com/crytic/slither/blob/04c147f7e50223c6af458ca430befae747ccd259/slither/slither.py#L68

The same solution described in the previous PR should be taken for all source file reading operations: retain format and line endings.

This issue currently will cause incorrect line/column number calculations in files with CRLF line endings.
Line/column number calculation regression
Recent adoption of `crytic-compile` in slither have required some code paths to be changed. A regression can be observed in source mapping line/column calculations due to CR, LF, and CRLF line endings, as described in #194 .

The problematic code can be found here:
https://github.com/crytic/slither/blob/04c147f7e50223c6af458ca430befae747ccd259/slither/slither.py#L68

The same solution described in the previous PR should be taken for all source file reading operations: retain format and line endings.

This issue currently will cause incorrect line/column number calculations in files with CRLF line endings.


Discussion:

Resolving patch:
diff --git a/slither/core/slither_core.py b/slither/core/slither_core.py
--- a/slither/core/slither_core.py
+++ b/slither/core/slither_core.py
@@ -56,6 +56,14 @@ def filename(self):
         """str: Filename."""
         return self._filename
 
+    def _add_source_code(self, path):
+        """
+        :param path:
+        :return:
+        """
+        with open(path, encoding='utf8', newline='') as f:
+            self.source_code[path] = f.read()
+
     # endregion
     ###################################################################################
     ###################################################################################
diff --git a/slither/slither.py b/slither/slither.py
--- a/slither/slither.py
+++ b/slither/slither.py
@@ -65,8 +65,7 @@ def __init__(self, contract, **kwargs):
             for path, ast in cryticCompile.asts.items():
 
                 self._parse_contracts_from_loaded_json(ast, path)
-                with open(path) as f:
-                    self.source_code[path] = f.read()
+                self._add_source_code(path)
 
         self._detectors = []
         self._printers = []
diff --git a/slither/solc_parsing/slitherSolc.py b/slither/solc_parsing/slitherSolc.py
--- a/slither/solc_parsing/slitherSolc.py
+++ b/slither/solc_parsing/slitherSolc.py
@@ -89,9 +89,7 @@ def _parse_contracts_from_loaded_json(self, data_loaded, filename):
         if 'sourcePaths' in data_loaded:
             for sourcePath in data_loaded['sourcePaths']:
                 if os.path.isfile(sourcePath):
-                    with open(sourcePath, encoding='utf8', newline='') as f:
-                        source_code = f.read()
-                    self.source_code[sourcePath] = source_code
+                    self._add_source_code(sourcePath)
 
         if data_loaded[self.get_key()] == 'root':
             self._solc_version = '0.3'
@@ -152,15 +150,11 @@ def _parse_source_unit(self, data, filename):
 
         self._source_units[sourceUnit] = name
         if os.path.isfile(name) and not name in self.source_code:
-            with open(name, encoding='utf8', newline='') as f:
-                source_code = f.read()
-            self.source_code[name] = source_code
+            self._add_source_code(name)
         else:
             lib_name = os.path.join('node_modules', name)
             if os.path.isfile(lib_name) and not name in self.source_code:
-                with open(lib_name, encoding='utf8', newline='') as f:
-                    source_code = f.read()
-                self.source_code[name] = source_code
+                self._add_source_code(lib_name)
 
     # endregion
     ###################################################################################


Test patch: