From 74cd4cbf3cf89d81253ee3d1963cd146402d0089 Mon Sep 17 00:00:00 2001 From: martin-c Date: Sun, 12 Jul 2026 17:52:07 +0200 Subject: [PATCH] Fixes #25997 - nimsuggest SIGSEGV on ideType queries for void procs and module symbols (#25998) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #25997 `executeNoHooksV3`'s `ideType` handler dereferences the target symbol's type without nil checks, so nimsuggest (v3/v4) dies with SIGSEGV on a `type` query for any symbol without a usable type: - a **void proc** — `s.sym.typ[0]` (the return-type slot) is nil, e.g. "goto type definition" on the `add` in `s.add('x')`; - a **module symbol** — `s.sym.typ` is nil, e.g. a `type` query on the module name in an `import` statement. Both are one editor action away for any user whose client maps `textDocument/typeDefinition` to `type` (nimlangserver does), and the crash takes down the whole nimsuggest process. Root-caused from recurring nimlangserver crash reports by replaying a live session log; reproduced deterministically with a two-line file. The fix guards the derefs and returns an empty result for symbols with no type, matching the existing "bad type" behavior. Two regression cases are appended to `nimsuggest/tests/tv3_typeDefinition.nim` (appended at the end so the existing `$1`–`$4` line-number expectations are untouched); both crash with `SIGSEGV: Illegal storage access` before the fix and pass after. The existing `$3` generic case covers the guarded `elif` branch. --- nimsuggest/nimsuggest.nim | 7 ++++--- nimsuggest/tests/tv3_typeDefinition.nim | 9 +++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/nimsuggest/nimsuggest.nim b/nimsuggest/nimsuggest.nim index 0d8921905c..e772ef171a 100644 --- a/nimsuggest/nimsuggest.nim +++ b/nimsuggest/nimsuggest.nim @@ -1156,13 +1156,14 @@ proc executeNoHooksV3(cmd: IdeCmd, file: AbsoluteFile, dirtyfile: AbsoluteFile, graph.suggestResult(s.sym, s.sym.info) of ideType: let s = graph.findSymData(file, line, col) - if not s.isNil: + if not s.isNil and s.sym.typ != nil: let typeSym = s.sym.typ.sym if typeSym != nil: graph.suggestResult(typeSym, typeSym.info, ideType) - elif s.sym.typ.len != 0: + elif s.sym.typ.len != 0 and s.sym.typ[0] != nil: let genericType = s.sym.typ[0].sym - graph.suggestResult(genericType, genericType.info, ideType) + if genericType != nil: + graph.suggestResult(genericType, genericType.info, ideType) of ideUse, ideDus: let symbol = graph.findSymData(file, line, col) if not symbol.isNil: diff --git a/nimsuggest/tests/tv3_typeDefinition.nim b/nimsuggest/tests/tv3_typeDefinition.nim index f86d12cc67..2da86d060c 100644 --- a/nimsuggest/tests/tv3_typeDefinition.nim +++ b/nimsuggest/tests/tv3_typeDefinition.nim @@ -20,6 +20,13 @@ echo fo#[!]#oGeneric.bar # bad type echo unde#[!]#fined +# type of a void proc: typ[0] (return type) is nil, must not crash +var s = "" +s.a#[!]#dd('x') + +# type of a module symbol: typ is nil, must not crash +import std/str#[!]#utils + discard """ $nimsuggest --v3 --tester $file >type $1 @@ -29,4 +36,6 @@ type skType tv3_typeDefinition.Foo2 Foo2 $file 11 2 "" 100 >type $3 type skType tv3_typeDefinition.FooGeneric FooGeneric $file 14 2 "" 100 >type $4 +>type $5 +>type $6 """