Repository: crytic/slither

Issue:
[Bug]: Infinite loop in RTLO detector
### What happened?

Slither hangs on this code indefinitely

### Can you share code with us to reproduce this bug?

https://github.com/ethereum/solidity/blob/develop/test/libsolidity/syntaxTests/comments/multiline_unicode_direction_override_5.sol

### Version

0.8.2

### Relevant log output

_No response_


Discussion:

Resolving patch:
diff --git a/slither/detectors/source/rtlo.py b/slither/detectors/source/rtlo.py
--- a/slither/detectors/source/rtlo.py
+++ b/slither/detectors/source/rtlo.py
@@ -88,6 +88,6 @@ def _detect(self):
                 results.append(res)
 
                 # Advance the start index for the next iteration
-                start_index = result_index + 1
+                start_index = idx + 1
 
         return results


Test patch:
diff --git a/tests/detectors/rtlo/0.8.0/unicode_direction_override.sol b/tests/detectors/rtlo/0.8.0/unicode_direction_override.sol
new file mode 100644
--- /dev/null
+++ b/tests/detectors/rtlo/0.8.0/unicode_direction_override.sol
@@ -0,0 +1,11 @@
+pragma solidity ^0.8.0;
+contract my_contract {
+    function empty_func() external pure
+    {
+        // The string below contains 3 RLO and 3 PDF unicode characters
+        // RLO is U+202E and changes the print direction to right-to-left
+        // PDF is U+202C and restores the print direction to what it was before RLO
+        /*ok ‮aaa‮bbb‮ccc‬ddd‬eee‬*/
+    }
+}
+// ----
\ No newline at end of file
diff --git a/tests/detectors/rtlo/0.8.0/unicode_direction_override.sol.0.8.0.RightToLeftOverride.json b/tests/detectors/rtlo/0.8.0/unicode_direction_override.sol.0.8.0.RightToLeftOverride.json
new file mode 100644
--- /dev/null
+++ b/tests/detectors/rtlo/0.8.0/unicode_direction_override.sol.0.8.0.RightToLeftOverride.json
@@ -0,0 +1,91 @@
+[
+    [
+        {
+            "elements": [
+                {
+                    "type": "other",
+                    "name": "rtlo-character",
+                    "source_mapping": {
+                        "start": 336,
+                        "length": 3,
+                        "filename_used": "/GENERIC_PATH",
+                        "filename_relative": "tests/detectors/rtlo/0.8.0/unicode_direction_override.sol",
+                        "filename_absolute": "/GENERIC_PATH",
+                        "filename_short": "tests/detectors/rtlo/0.8.0/unicode_direction_override.sol",
+                        "is_dependency": false,
+                        "lines": [
+                            8
+                        ],
+                        "starting_column": 14,
+                        "ending_column": 17
+                    }
+                }
+            ],
+            "description": "tests/detectors/rtlo/0.8.0/unicode_direction_override.sol contains a unicode right-to-left-override character at byte offset 336:\n\t- b'        /*ok \\xe2\\x80\\xaeaaa\\xe2\\x80\\xaebbb\\xe2\\x80\\xaeccc\\xe2\\x80\\xacddd\\xe2\\x80\\xaceee\\xe2\\x80\\xac*/'\n",
+            "markdown": "tests/detectors/rtlo/0.8.0/unicode_direction_override.sol contains a unicode right-to-left-override character at byte offset 336:\n\t- b'        /*ok \\xe2\\x80\\xaeaaa\\xe2\\x80\\xaebbb\\xe2\\x80\\xaeccc\\xe2\\x80\\xacddd\\xe2\\x80\\xaceee\\xe2\\x80\\xac*/'\n",
+            "first_markdown_element": "",
+            "id": "2407672dea557be27d0c488ba9c714e6a7f21dd3f7759058e718c1984e142f95",
+            "check": "rtlo",
+            "impact": "High",
+            "confidence": "High"
+        },
+        {
+            "elements": [
+                {
+                    "type": "other",
+                    "name": "rtlo-character",
+                    "source_mapping": {
+                        "start": 348,
+                        "length": 3,
+                        "filename_used": "/GENERIC_PATH",
+                        "filename_relative": "tests/detectors/rtlo/0.8.0/unicode_direction_override.sol",
+                        "filename_absolute": "/GENERIC_PATH",
+                        "filename_short": "tests/detectors/rtlo/0.8.0/unicode_direction_override.sol",
+                        "is_dependency": false,
+                        "lines": [
+                            8
+                        ],
+                        "starting_column": 26,
+                        "ending_column": 29
+                    }
+                }
+            ],
+            "description": "tests/detectors/rtlo/0.8.0/unicode_direction_override.sol contains a unicode right-to-left-override character at byte offset 348:\n\t- b'\\x80\\xaebbb\\xe2\\x80\\xaeccc\\xe2\\x80\\xacddd\\xe2\\x80\\xaceee\\xe2\\x80\\xac*/'\n",
+            "markdown": "tests/detectors/rtlo/0.8.0/unicode_direction_override.sol contains a unicode right-to-left-override character at byte offset 348:\n\t- b'\\x80\\xaebbb\\xe2\\x80\\xaeccc\\xe2\\x80\\xacddd\\xe2\\x80\\xaceee\\xe2\\x80\\xac*/'\n",
+            "first_markdown_element": "",
+            "id": "477e54031d4d30d485b9cdc2d7ef3e9ae3de52640364505df8eb9619c2bcde6b",
+            "check": "rtlo",
+            "impact": "High",
+            "confidence": "High"
+        },
+        {
+            "elements": [
+                {
+                    "type": "other",
+                    "name": "rtlo-character",
+                    "source_mapping": {
+                        "start": 342,
+                        "length": 3,
+                        "filename_used": "/GENERIC_PATH",
+                        "filename_relative": "tests/detectors/rtlo/0.8.0/unicode_direction_override.sol",
+                        "filename_absolute": "/GENERIC_PATH",
+                        "filename_short": "tests/detectors/rtlo/0.8.0/unicode_direction_override.sol",
+                        "is_dependency": false,
+                        "lines": [
+                            8
+                        ],
+                        "starting_column": 20,
+                        "ending_column": 23
+                    }
+                }
+            ],
+            "description": "tests/detectors/rtlo/0.8.0/unicode_direction_override.sol contains a unicode right-to-left-override character at byte offset 342:\n\t- b'\\x80\\xaeaaa\\xe2\\x80\\xaebbb\\xe2\\x80\\xaeccc\\xe2\\x80\\xacddd\\xe2\\x80\\xaceee\\xe2\\x80\\xac*/'\n",
+            "markdown": "tests/detectors/rtlo/0.8.0/unicode_direction_override.sol contains a unicode right-to-left-override character at byte offset 342:\n\t- b'\\x80\\xaeaaa\\xe2\\x80\\xaebbb\\xe2\\x80\\xaeccc\\xe2\\x80\\xacddd\\xe2\\x80\\xaceee\\xe2\\x80\\xac*/'\n",
+            "first_markdown_element": "",
+            "id": "9dd23585bb0ff1f244f749281b27f62978e0bb5b0ae58c8c9cb6d3f9c7e82253",
+            "check": "rtlo",
+            "impact": "High",
+            "confidence": "High"
+        }
+    ]
+]
\ No newline at end of file
diff --git a/tests/test_detectors.py b/tests/test_detectors.py
--- a/tests/test_detectors.py
+++ b/tests/test_detectors.py
@@ -724,6 +724,11 @@ def id_test(test_item: Test):
         "right_to_left_override.sol",
         "0.6.11",
     ),
+    Test(
+        all_detectors.RightToLeftOverride,
+        "unicode_direction_override.sol",
+        "0.8.0",
+    ),
     Test(all_detectors.VoidConstructor, "void-cst.sol", "0.4.25"),
     Test(all_detectors.VoidConstructor, "void-cst.sol", "0.5.16"),
     Test(all_detectors.VoidConstructor, "void-cst.sol", "0.6.11"),