prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Incorrect source mappings because of certain (Unicode?) characters in comments
  Certain characters (or scripts) in Solidity comments appear to cause incorrect source mappings.
  
  For example, in `0x06012c8cf97bead5deae237070f9587f8e7a266d_KittyCore.sol`, the symbol that looks like underscore in "email_protected":
  ```
  /// @author Dieter Shirley <<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6004051405200118090f0d1a050e4e030f">[email_protected]</a>> (https://github.com/dete) 
  ```
  Similarly, the Asian characters in below comments from `0x5d0d76787d9d564061dd23f8209f804a3b8ad2f2_FoMo3Dlong.sol` also cause source mapping problems:
  
  ```
  struct Round {
          uint256 plyr;   // pID of player in lead， lead领导吗？                                                                
          uint256 team;   // tID of team in lead                                                                                 
          uint256 end;    // time ends/ended                                                                                     
          bool ended;     // has round end function been ran  这个开关值得研究下                                                 
  	uint256 strt;   // time round started                                                                                  
  	uint256 keys;   // keys                                                                                                
  	uint256 eth;    // total eth in                                                                                        
  	uint256 pot;    // eth to pot (during round) / final amount paid to winner (after round ends)                          
          uint256 mask;   // global mask                                                                                         
          uint256 ico;    // total eth sent in during ICO phase                                                                  
          uint256 icoGen; // total eth for gen during ICO phase                                                                  
          uint256 icoAvg; // average key price for ICO phase                                                                     
      }
  ```
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `slither/core/source_mapping/source_mapping.py`
  Content:
  ```
  1 import re
  2 import os
  3 from slither.core.context.context import Context
  4 
  5 class SourceMapping(Context):
  6 
  7     def __init__(self):
  8         super(SourceMapping, self).__init__()
  9         self._source_mapping = None
  10 
  11     @property
  12     def source_mapping(self):
  13         return self._source_mapping
  14 
  15     @staticmethod
  16     def _compute_line(source_code, start, length):
  17         """
  18             Compute line(s) numbers and starting/ending columns
  19             from a start/end offset. All numbers start from 1.
  20 
  21             Not done in an efficient way
  22         """
  23         total_length = len(source_code)
  24         source_code = source_code.splitlines(True)
  25         counter = 0
  26         i = 0
  27         lines = []
  28         starting_column = None
  29         ending_column = None
  30         while counter < total_length:
  31             # Determine the length of the line, and advance the line number
  32             lineLength = len(source_code[i])
  33             i = i + 1
  34 
  35             # Determine our column numbers.
  36             if starting_column is None and counter + lineLength > start:
  37                 starting_column = (start - counter) + 1
  38             if starting_column is not None and ending_column is None and counter + lineLength > start + length:
  39                 ending_column = ((start + length) - counter) + 1
  40 
  41             # Advance the current position counter, and determine line numbers.
  42             counter += lineLength
  43             if counter > start:
  44                 lines.append(i)
  45 
  46             # If our advanced position for the next line is out of range, stop.
  47             if counter > start + length:
  48                 break
  49 
  50         return (lines, starting_column, ending_column)
  51 
  52     @staticmethod
  53     def _convert_source_mapping(offset, slither):
  54         '''
  55         Convert a text offset to a real offset
  56         see https://solidity.readthedocs.io/en/develop/miscellaneous.html#source-mappings
  57         Returns:
  58             (dict): {'start':0, 'length':0, 'filename': 'file.sol'}
  59         '''
  60         sourceUnits = slither.source_units
  61 
  62         position = re.findall('([0-9]*):([0-9]*):([-]?[0-9]*)', offset)
  63         if len(position) != 1:
  64             return {}
  65 
  66         s, l, f = position[0]
  67         s = int(s)
  68         l = int(l)
  69         f = int(f)
  70 
  71         if f not in sourceUnits:
  72             return {'start':s, 'length':l}
  73         filename_used = sourceUnits[f]
  74         filename_absolute = None
  75         filename_relative = None
  76         filename_short = None
  77 
  78         lines = []
  79 
  80         # If possible, convert the filename to its absolute/relative version
  81         if slither.crytic_compile:
  82             filenames = slither.crytic_compile.filename_lookup(filename_used)
  83             filename_absolute = filenames.absolute
  84             filename_relative = filenames.relative
  85             filename_short = filenames.short
  86 
  87             if filename_absolute in slither.source_code:
  88                 filename = filename_absolute
  89             elif filename_relative in slither.source_code:
  90                 filename = filename_relative
  91             elif filename_short in slither.source_code:
  92                 filename = filename_short
  93             else:#
  94                 filename = filename_used.used
  95         else:
  96             filename = filename_used
  97 
  98         if filename in slither.source_code:
  99             source_code = slither.source_code[filename]
  100             (lines, starting_column, ending_column) = SourceMapping._compute_line(source_code,
  101                                                                                   s,
  102                                                                                   l)
  103         else:
  104             (lines, starting_column, ending_column) = ([], None, None)
  105 
  106 
  107         return {'start':s,
  108                 'length':l,
  109                 'filename_used': filename_used,
  110                 'filename_relative': filename_relative,
  111                 'filename_absolute': filename_absolute,
  112                 'filename_short': filename_short,
  113                 'lines' : lines,
  114                 'starting_column': starting_column,
  115                 'ending_column': ending_column
  116                 }
  117 
  118     def set_offset(self, offset, slither):
  119         if isinstance(offset, dict):
  120             self._source_mapping = offset
  121         else:
  122             self._source_mapping = self._convert_source_mapping(offset, slither)
  123 
  124 
  125     @property
  126     def source_mapping_str(self):
  127 
  128         lines = self.source_mapping.get('lines', None)
  129         if not lines:
  130             lines = ''
  131         elif len(lines) == 1:
  132             lines = '#{}'.format(lines[0])
  133         else:
  134             lines = '#{}-{}'.format(lines[0], lines[-1])
  135         return '{}{}'.format(self.source_mapping['filename_short'], lines)
  136 
  137
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/slither/core/source_mapping/source_mapping.py b/slither/core/source_mapping/source_mapping.py
  --- a/slither/core/source_mapping/source_mapping.py
  +++ b/slither/core/source_mapping/source_mapping.py
  @@ -20,6 +20,7 @@
   
               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
  @@ -29,17 +30,18 @@
           ending_column = None
           while counter < total_length:
               # Determine the length of the line, and advance the line number
  -            lineLength = len(source_code[i])
  +            line_content = source_code[i]
  +            line_length = len(line_content)
               i = i + 1
   
               # Determine our column numbers.
  -            if starting_column is None and counter + lineLength > start:
  +            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 + lineLength > start + length:
  +            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 += lineLength
  +            counter += line_length
               if counter > start:
                   lines.append(i)
  
verification_info: {"golden_diff": "diff --git a/slither/core/source_mapping/source_mapping.py b/slither/core/source_mapping/source_mapping.py\n--- a/slither/core/source_mapping/source_mapping.py\n+++ b/slither/core/source_mapping/source_mapping.py\n@@ -20,6 +20,7 @@\n \n             Not done in an efficient way\n         \"\"\"\n+        source_code = source_code.encode('utf-8')\n         total_length = len(source_code)\n         source_code = source_code.splitlines(True)\n         counter = 0\n@@ -29,17 +30,18 @@\n         ending_column = None\n         while counter < total_length:\n             # Determine the length of the line, and advance the line number\n-            lineLength = len(source_code[i])\n+            line_content = source_code[i]\n+            line_length = len(line_content)\n             i = i + 1\n \n             # Determine our column numbers.\n-            if starting_column is None and counter + lineLength > start:\n+            if starting_column is None and counter + line_length > start:\n                 starting_column = (start - counter) + 1\n-            if starting_column is not None and ending_column is None and counter + lineLength > start + length:\n+            if starting_column is not None and ending_column is None and counter + line_length > start + length:\n                 ending_column = ((start + length) - counter) + 1\n \n             # Advance the current position counter, and determine line numbers.\n-            counter += lineLength\n+            counter += line_length\n             if counter > start:\n                 lines.append(i)\n", "issue": "Incorrect source mappings because of certain (Unicode?) characters in comments\nCertain characters (or scripts) in Solidity comments appear to cause incorrect source mappings.\r\n\r\nFor example, in `0x06012c8cf97bead5deae237070f9587f8e7a266d_KittyCore.sol`, the symbol that looks like underscore in \"email_protected\":\r\n```\r\n/// @author Dieter Shirley <<a href=\"/cdn-cgi/l/email-protection\" class=\"__cf_email__\" data-cfemail=\"6004051405200118090f0d1a050e4e030f\">[email_protected]</a>> (https://github.com/dete) \r\n```\r\nSimilarly, the Asian characters in below comments from `0x5d0d76787d9d564061dd23f8209f804a3b8ad2f2_FoMo3Dlong.sol` also cause source mapping problems:\r\n\r\n```\r\nstruct Round {\r\n        uint256 plyr;   // pID of player in lead\uff0c lead\u9886\u5bfc\u5417\uff1f                                                                \r\n        uint256 team;   // tID of team in lead                                                                                 \r\n        uint256 end;    // time ends/ended                                                                                     \r\n        bool ended;     // has round end function been ran  \u8fd9\u4e2a\u5f00\u5173\u503c\u5f97\u7814\u7a76\u4e0b                                                 \r\n\tuint256 strt;   // time round started                                                                                  \r\n\tuint256 keys;   // keys                                                                                                \r\n\tuint256 eth;    // total eth in                                                                                        \r\n\tuint256 pot;    // eth to pot (during round) / final amount paid to winner (after round ends)                          \r\n        uint256 mask;   // global mask                                                                                         \r\n        uint256 ico;    // total eth sent in during ICO phase                                                                  \r\n        uint256 icoGen; // total eth for gen during ICO phase                                                                  \r\n        uint256 icoAvg; // average key price for ICO phase                                                                     \r\n    }\r\n```\n", "before_files": [{"content": "import re\nimport os\nfrom slither.core.context.context import Context\n\nclass SourceMapping(Context):\n\n    def __init__(self):\n        super(SourceMapping, self).__init__()\n        self._source_mapping = None\n\n    @property\n    def source_mapping(self):\n        return self._source_mapping\n\n    @staticmethod\n    def _compute_line(source_code, start, length):\n        \"\"\"\n            Compute line(s) numbers and starting/ending columns\n            from a start/end offset. All numbers start from 1.\n\n            Not done in an efficient way\n        \"\"\"\n        total_length = len(source_code)\n        source_code = source_code.splitlines(True)\n        counter = 0\n        i = 0\n        lines = []\n        starting_column = None\n        ending_column = None\n        while counter < total_length:\n            # Determine the length of the line, and advance the line number\n            lineLength = len(source_code[i])\n            i = i + 1\n\n            # Determine our column numbers.\n            if starting_column is None and counter + lineLength > start:\n                starting_column = (start - counter) + 1\n            if starting_column is not None and ending_column is None and counter + lineLength > start + length:\n                ending_column = ((start + length) - counter) + 1\n\n            # Advance the current position counter, and determine line numbers.\n            counter += lineLength\n            if counter > start:\n                lines.append(i)\n\n            # If our advanced position for the next line is out of range, stop.\n            if counter > start + length:\n                break\n\n        return (lines, starting_column, ending_column)\n\n    @staticmethod\n    def _convert_source_mapping(offset, slither):\n        '''\n        Convert a text offset to a real offset\n        see https://solidity.readthedocs.io/en/develop/miscellaneous.html#source-mappings\n        Returns:\n            (dict): {'start':0, 'length':0, 'filename': 'file.sol'}\n        '''\n        sourceUnits = slither.source_units\n\n        position = re.findall('([0-9]*):([0-9]*):([-]?[0-9]*)', offset)\n        if len(position) != 1:\n            return {}\n\n        s, l, f = position[0]\n        s = int(s)\n        l = int(l)\n        f = int(f)\n\n        if f not in sourceUnits:\n            return {'start':s, 'length':l}\n        filename_used = sourceUnits[f]\n        filename_absolute = None\n        filename_relative = None\n        filename_short = None\n\n        lines = []\n\n        # If possible, convert the filename to its absolute/relative version\n        if slither.crytic_compile:\n            filenames = slither.crytic_compile.filename_lookup(filename_used)\n            filename_absolute = filenames.absolute\n            filename_relative = filenames.relative\n            filename_short = filenames.short\n\n            if filename_absolute in slither.source_code:\n                filename = filename_absolute\n            elif filename_relative in slither.source_code:\n                filename = filename_relative\n            elif filename_short in slither.source_code:\n                filename = filename_short\n            else:#\n                filename = filename_used.used\n        else:\n            filename = filename_used\n\n        if filename in slither.source_code:\n            source_code = slither.source_code[filename]\n            (lines, starting_column, ending_column) = SourceMapping._compute_line(source_code,\n                                                                                  s,\n                                                                                  l)\n        else:\n            (lines, starting_column, ending_column) = ([], None, None)\n\n\n        return {'start':s,\n                'length':l,\n                'filename_used': filename_used,\n                'filename_relative': filename_relative,\n                'filename_absolute': filename_absolute,\n                'filename_short': filename_short,\n                'lines' : lines,\n                'starting_column': starting_column,\n                'ending_column': ending_column\n                }\n\n    def set_offset(self, offset, slither):\n        if isinstance(offset, dict):\n            self._source_mapping = offset\n        else:\n            self._source_mapping = self._convert_source_mapping(offset, slither)\n\n\n    @property\n    def source_mapping_str(self):\n\n        lines = self.source_mapping.get('lines', None)\n        if not lines:\n            lines = ''\n        elif len(lines) == 1:\n            lines = '#{}'.format(lines[0])\n        else:\n            lines = '#{}-{}'.format(lines[0], lines[-1])\n        return '{}{}'.format(self.source_mapping['filename_short'], lines)\n\n", "path": "slither/core/source_mapping/source_mapping.py"}], "after_files": [{"content": "import re\nimport os\nfrom slither.core.context.context import Context\n\nclass SourceMapping(Context):\n\n    def __init__(self):\n        super(SourceMapping, self).__init__()\n        self._source_mapping = None\n\n    @property\n    def source_mapping(self):\n        return self._source_mapping\n\n    @staticmethod\n    def _compute_line(source_code, start, length):\n        \"\"\"\n            Compute line(s) numbers and starting/ending columns\n            from a start/end offset. All numbers start from 1.\n\n            Not done in an efficient way\n        \"\"\"\n        source_code = source_code.encode('utf-8')\n        total_length = len(source_code)\n        source_code = source_code.splitlines(True)\n        counter = 0\n        i = 0\n        lines = []\n        starting_column = None\n        ending_column = None\n        while counter < total_length:\n            # Determine the length of the line, and advance the line number\n            line_content = source_code[i]\n            line_length = len(line_content)\n            i = i + 1\n\n            # Determine our column numbers.\n            if starting_column is None and counter + line_length > start:\n                starting_column = (start - counter) + 1\n            if starting_column is not None and ending_column is None and counter + line_length > start + length:\n                ending_column = ((start + length) - counter) + 1\n\n            # Advance the current position counter, and determine line numbers.\n            counter += line_length\n            if counter > start:\n                lines.append(i)\n\n            # If our advanced position for the next line is out of range, stop.\n            if counter > start + length:\n                break\n\n        return (lines, starting_column, ending_column)\n\n    @staticmethod\n    def _convert_source_mapping(offset, slither):\n        '''\n        Convert a text offset to a real offset\n        see https://solidity.readthedocs.io/en/develop/miscellaneous.html#source-mappings\n        Returns:\n            (dict): {'start':0, 'length':0, 'filename': 'file.sol'}\n        '''\n        sourceUnits = slither.source_units\n\n        position = re.findall('([0-9]*):([0-9]*):([-]?[0-9]*)', offset)\n        if len(position) != 1:\n            return {}\n\n        s, l, f = position[0]\n        s = int(s)\n        l = int(l)\n        f = int(f)\n\n        if f not in sourceUnits:\n            return {'start':s, 'length':l}\n        filename_used = sourceUnits[f]\n        filename_absolute = None\n        filename_relative = None\n        filename_short = None\n\n        lines = []\n\n        # If possible, convert the filename to its absolute/relative version\n        if slither.crytic_compile:\n            filenames = slither.crytic_compile.filename_lookup(filename_used)\n            filename_absolute = filenames.absolute\n            filename_relative = filenames.relative\n            filename_short = filenames.short\n\n            if filename_absolute in slither.source_code:\n                filename = filename_absolute\n            elif filename_relative in slither.source_code:\n                filename = filename_relative\n            elif filename_short in slither.source_code:\n                filename = filename_short\n            else:#\n                filename = filename_used.used\n        else:\n            filename = filename_used\n\n        if filename in slither.source_code:\n            source_code = slither.source_code[filename]\n            (lines, starting_column, ending_column) = SourceMapping._compute_line(source_code,\n                                                                                  s,\n                                                                                  l)\n        else:\n            (lines, starting_column, ending_column) = ([], None, None)\n\n\n        return {'start':s,\n                'length':l,\n                'filename_used': filename_used,\n                'filename_relative': filename_relative,\n                'filename_absolute': filename_absolute,\n                'filename_short': filename_short,\n                'lines' : lines,\n                'starting_column': starting_column,\n                'ending_column': ending_column\n                }\n\n    def set_offset(self, offset, slither):\n        if isinstance(offset, dict):\n            self._source_mapping = offset\n        else:\n            self._source_mapping = self._convert_source_mapping(offset, slither)\n\n\n    @property\n    def source_mapping_str(self):\n\n        lines = self.source_mapping.get('lines', None)\n        if not lines:\n            lines = ''\n        elif len(lines) == 1:\n            lines = '#{}'.format(lines[0])\n        else:\n            lines = '#{}-{}'.format(lines[0], lines[-1])\n        return '{}{}'.format(self.source_mapping['filename_short'], lines)\n\n", "path": "slither/core/source_mapping/source_mapping.py"}]}