{"action":"created","issue":{"url":"https://api.github.com/repos/tree-sitter/tree-sitter-haskell/issues/19","repository_url":"https://api.github.com/repos/tree-sitter/tree-sitter-haskell","labels_url":"https://api.github.com/repos/tree-sitter/tree-sitter-haskell/issues/19/labels{/name}","comments_url":"https://api.github.com/repos/tree-sitter/tree-sitter-haskell/issues/19/comments","events_url":"https://api.github.com/repos/tree-sitter/tree-sitter-haskell/issues/19/events","html_url":"https://github.com/tree-sitter/tree-sitter-haskell/issues/19","id":326251462,"number":19,"title":"Out-of-bound read in Scanner::scan","user":{"login":"philipturnbull","id":45588,"avatar_url":"https://avatars1.githubusercontent.com/u/45588?v=4","gravatar_id":"","url":"https://api.github.com/users/philipturnbull","html_url":"https://github.com/philipturnbull","followers_url":"https://api.github.com/users/philipturnbull/followers","following_url":"https://api.github.com/users/philipturnbull/following{/other_user}","gists_url":"https://api.github.com/users/philipturnbull/gists{/gist_id}","starred_url":"https://api.github.com/users/philipturnbull/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/philipturnbull/subscriptions","organizations_url":"https://api.github.com/users/philipturnbull/orgs","repos_url":"https://api.github.com/users/philipturnbull/repos","events_url":"https://api.github.com/users/philipturnbull/events{/privacy}","received_events_url":"https://api.github.com/users/philipturnbull/received_events","type":"User","site_admin":true},"labels":[{"id":328200347,"url":"https://api.github.com/repos/tree-sitter/tree-sitter-haskell/labels/bug","name":"bug","color":"fc2929","default":true}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-05-24T19:04:43Z","updated_at":"2018-05-24T21:36:56Z","closed_at":"2018-05-24T21:36:56Z","author_association":"MEMBER","body":"Fuzzing with AddressSanitizer triggers an oob-read:\r\n```\r\n==32493==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020002affee at pc 0x00000051a4dd bp 0x7ffee1c62390 sp 0x7ffee1c62388\r\nREAD of size 2 at 0x6020002affee thread T0\r\nSCARINESS: 24 (2-byte-read-heap-buffer-overflow-far-from-bounds)\r\n    @0 0x51a4dc in (anonymous namespace)::Scanner::scan(TSLexer*, bool const*) /src/octofuzz/tree-sitter/test/fixtures/grammars/haskell/src/scanner.cc:316:54\r\n    @1 0x76d2d1 in parser__lex /src/octofuzz/tree-sitter/src/runtime/parser.c:257:11\r\n    @2 0x767d97 in parser__get_lookahead /src/octofuzz/tree-sitter/src/runtime/parser.c:489:12\r\n    @3 0x76519a in parser__advance /src/octofuzz/tree-sitter/src/runtime/parser.c:1081:21\r\n    @4 0x7642c9 in parser_parse /src/octofuzz/tree-sitter/src/runtime/parser.c:1303:9\r\n    @5 0x75ccbf in ts_document_parse_with_options /src/octofuzz/tree-sitter/src/runtime/document.c:137:16\r\n```\r\n\r\nwhich corresponds to:\r\n\r\nhttps://github.com/tree-sitter/tree-sitter-haskell/blob/2be101d585b1d6cefc9cf132ed3b6c2fb078c6cb/src/scanner.cc#L314-L321\r\n\r\n`indent_length_stack.size() > 0` is not guaranteed to be true after the first iteration of the `while` loop. When `indent_length_stack.size() == 0` then `indent_length_stack.back()` on line 316 triggers an out-of-bound read.\r\n\r\nThree example inputs that trigger the issue (`hexdump`ed):\r\n```\r\n00000000  6d 0d 62 0a 6f                                    |m.b.o|\r\n00000005\r\n\r\n00000000  0d 4d 0a 3d                                       |.M.=|\r\n00000004\r\n\r\n00000000  6d 28 0a 71                                       |m(.q|\r\n00000004\r\n```\r\n\r\nI think the fix looks like:\r\n```diff\r\ndiff --git a/src/scanner.cc b/src/scanner.cc\r\nindex 7e6faa4..3ff7faa 100644\r\n--- a/src/scanner.cc\r\n+++ b/src/scanner.cc\r\n@@ -313,10 +313,8 @@ struct Scanner {\r\n\r\n       if (indent_length_stack.size() > 0) {\r\n         if (indent_length < indent_length_stack.back()) {\r\n-          while (indent_length < indent_length_stack.back()) {\r\n-            if (indent_length_stack.size() > 0) {\r\n-              indent_length_stack.pop_back();\r\n-            }\r\n+          while (indent_length_stack.size() > 0 && indent_length < indent_length_stack.back()) {\r\n+            indent_length_stack.pop_back();\r\n             queued_close_brace_count++;\r\n           }\r\n```\r\n\r\nbut I'm not 100% sure that gives the same behaviour 🤷‍♂️ \r\n"},"comment":{"url":"https://api.github.com/repos/tree-sitter/tree-sitter-haskell/issues/comments/391870929","html_url":"https://github.com/tree-sitter/tree-sitter-haskell/issues/19#issuecomment-391870929","issue_url":"https://api.github.com/repos/tree-sitter/tree-sitter-haskell/issues/19","id":391870929,"user":{"login":"rewinfrey","id":941226,"avatar_url":"https://avatars1.githubusercontent.com/u/941226?v=4","gravatar_id":"","url":"https://api.github.com/users/rewinfrey","html_url":"https://github.com/rewinfrey","followers_url":"https://api.github.com/users/rewinfrey/followers","following_url":"https://api.github.com/users/rewinfrey/following{/other_user}","gists_url":"https://api.github.com/users/rewinfrey/gists{/gist_id}","starred_url":"https://api.github.com/users/rewinfrey/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rewinfrey/subscriptions","organizations_url":"https://api.github.com/users/rewinfrey/orgs","repos_url":"https://api.github.com/users/rewinfrey/repos","events_url":"https://api.github.com/users/rewinfrey/events{/privacy}","received_events_url":"https://api.github.com/users/rewinfrey/received_events","type":"User","site_admin":true},"created_at":"2018-05-24T21:36:56Z","updated_at":"2018-05-24T21:36:56Z","author_association":"MEMBER","body":"@philipturnbull thank you for filing this! All tests still pass and current behavior is preserved, so for now this solution is 👍 . Fixed in https://github.com/tree-sitter/tree-sitter-haskell/commit/33f07f66ebc478b3e48187b91d335b6220394a33"}}
{"actor":{"display_login":"rewinfrey"}}