Skip to content

Fix access violation in initialize when client omits optional clientInfo fields - #168

Open
dickbonnema wants to merge 1 commit into
genericptr:trunkfrom
dickbonnema:fix-head-av
Open

dickbonnema wants to merge 1 commit into
genericptr:trunkfrom
dickbonnema:fix-head-av

Conversation

@dickbonnema

Copy link
Copy Markdown

Problem

Commit 818f633 (#159) changed TClientInfo.version from string to TOptionalString, and TDiagnostic.code/source to TOptionalInteger/TOptionalString. These TOptional* types are classes that stay nil when the client omits the field from the JSON payload.

Two dereference sites were not nil-safe:

  1. TInitialize.ShowConfigStatus (src/serverprotocol/PasLS.General.pas): Params.clientInfo.version.HasValue raises an access violation during initialize when the client sends clientInfo without a version (or no clientInfo at all - both are optional per the LSP spec). The server responds with {"error":{"code":-32603,"message":"Access violation"}} and cannot be used.

  2. TDiagnostic.Assign (src/protocol/LSP.Basic.pas): Src.source.HasValue has the same issue when source was never set.

Reproduction

Send an initialize request with clientInfo present but without version:

{"jsonrpc":"2.0","id":1,"method":"initialize","params":{
  "processId": 1234,
  "clientInfo": {"name": "my-client"},
  "rootUri": "file:///tmp/x",
  "capabilities": {}
}}

? Server replies -32603 Access violation on trunk (818f633).

Fix

Guard both dereferences with Assigned() checks. No behaviour change for clients that do send the fields.

Verified end-to-end: with this patch, the full LSP handshake (initialize ? didOpen ? hover ? definition ? publishDiagnostics ? shutdown) completes successfully against a client that omits clientInfo.version.

TOptionalString/TOptionalInteger are classes that stay nil when the
client omits the field. Dereferencing them in ShowConfigStatus
(Params.clientInfo.version.HasValue) and TDiagnostic.Assign
(Src.source.HasValue) caused an access violation during initialize
for clients that send clientInfo without a version (or no clientInfo).

Guard both derefs with Assigned() checks. Verified end-to-end against
lazarus-mcp LSP smoke tests (5/5 passing with full capabilities).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant