Skip to content

gopls/internal/template: fix panic in completion when cursor is between opening braces#636

Open
YLChen-007 wants to merge 1 commit intogolang:masterfrom
YLChen-007:fix/template-completion-panic
Open

gopls/internal/template: fix panic in completion when cursor is between opening braces#636
YLChen-007 wants to merge 1 commit intogolang:masterfrom
YLChen-007:fix/template-completion-panic

Conversation

@YLChen-007
Copy link
Copy Markdown

Summary

Fix a Denial of Service (DoS) vulnerability in gopls where the language server crashes with panic: slice bounds out of range [8:7] when code completion is requested at a cursor position between the two { characters of a template action delimiter {{.

Root Cause

In completer.complete(), the expression c.p.buf[c.offset:start] panics when c.offset > start. This occurs when:

  • A .tmpl file contains a template action like hello {{ }}
  • The cursor is placed between the first { and second { (e.g., at byte offset 7)
  • c.offset is computed as tk.Start + len("{{") = 8
  • start (cursor position) = 7
  • Resulting slice buf[8:7] triggers panic: runtime error: slice bounds out of range [8:7]

Since there is no recovery mechanism, this crashes the entire gopls process, degrading the user's IDE workspace.

Fix

Added a bounds check before the slice operation in completer.complete():

if c.offset > start {
    return ans, nil
}

This returns an empty completion list when the cursor is inside the delimiter characters, which is the correct behavior — there is no meaningful text to complete at that position.

Testing

  • Added TestCompleteBoundsCheck regression test that directly constructs the problematic state (offset=8, cursor=7) and verifies complete() returns gracefully without panicking
  • All existing tests continue to pass (21 TestParsed subtests + TestSymbols + TestWordAt + TestQuotes)

Reproduction

  1. Open a workspace with gopls and configure templateExtensions: ["tmpl"]
  2. Create hi.tmpl with content: hello {{ }}
  3. Place cursor between the two { characters (byte offset 7)
  4. Trigger code completion → gopls crashes

Impact

Denial of Service. An attacker can craft a malicious Go project containing a .tmpl file that crashes gopls when the victim opens it and the cursor enters the trigger position.

@google-cla
Copy link
Copy Markdown

google-cla Bot commented Apr 12, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

…en opening braces

Add a bounds check in completer.complete() to prevent a slice bounds
out of range panic when the cursor is positioned between the two '{'
characters of a template action delimiter '{{'.

When an LSP client requests code completion at such a position,
c.offset (computed as tk.Start + len("{{")) can exceed the cursor
position (start), causing c.p.buf[c.offset:start] to panic with
'slice bounds out of range [8:7]'. This crashes the entire gopls
process, resulting in a Denial of Service for the IDE user.

The fix returns an empty completion list when c.offset > start,
which is the correct behavior since there is no meaningful text
to complete at a position inside the delimiter characters.

Includes a regression test that directly constructs the problematic
state and verifies complete() returns gracefully without panicking.
@YLChen-007 YLChen-007 force-pushed the fix/template-completion-panic branch from 8948a89 to bc699b3 Compare April 12, 2026 05:08
@gopherbot
Copy link
Copy Markdown
Contributor

This PR (HEAD: bc699b3) has been imported to Gerrit for code review.

Please visit Gerrit at https://go-review.googlesource.com/c/tools/+/765760.

Important tips:

  • Don't comment on this PR. All discussion takes place in Gerrit.
  • You need a Gmail or other Google account to log in to Gerrit.
  • To change your code in response to feedback:
    • Push a new commit to the branch used by your GitHub PR.
    • A new "patch set" will then appear in Gerrit.
    • Respond to each comment by marking as Done in Gerrit if implemented as suggested. You can alternatively write a reply.
    • Critical: you must click the blue Reply button near the top to publish your Gerrit responses.
    • Multiple commits in the PR will be squashed by GerritBot.
  • The title and description of the GitHub PR are used to construct the final commit message.
    • Edit these as needed via the GitHub web interface (not via Gerrit or git).
    • You should word wrap the PR description at ~76 characters unless you need longer lines (e.g., for tables or URLs).
  • See the Sending a change via GitHub and Reviews sections of the Contribution Guide as well as the FAQ for details.

@gopherbot
Copy link
Copy Markdown
Contributor

Message from Gopher Robot:

Patch Set 1:

(1 comment)


Please don’t reply on this GitHub thread. Visit golang.org/cl/765760.
After addressing review feedback, remember to publish your drafts!

@gopherbot
Copy link
Copy Markdown
Contributor

Message from Gopher Robot:

Patch Set 1:

Congratulations on opening your first change. Thank you for your contribution!

Next steps:
A maintainer will review your change and provide feedback. See
https://go.dev/doc/contribute#review for more info and tips to get your
patch through code review.

Most changes in the Go project go through a few rounds of revision. This can be
surprising to people new to the project. The careful, iterative review process
is our way of helping mentor contributors and ensuring that their contributions
have a lasting impact.


Please don’t reply on this GitHub thread. Visit golang.org/cl/765760.
After addressing review feedback, remember to publish your drafts!

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.

2 participants