-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
go/parser: parser creates Stmt that causes token.File.Offset(stmt.End) to panic #57490
Comments
Change https://go.dev/cl/459735 mentions this issue: |
During parser error recovery, it may synthesize tokens such as RBRACE at EOF, causing the End position of the incomplete syntax nodes to be computed as Rbrace+len("}"), which is out of bounds, and would cause token.File.Offset to panic, or safetoken.Offset to return an error. This change is a workaround in gopls so that such End positions are considered valid, and are mapped to the end of the file. Also - a regression test. - remove safetoken.InRange, to avoid ambiguity. It was used in only one place (and dubiously even there). Fixes golang/go#57484 Updates golang/go#57490 Change-Id: I75bbe4f3b3c54aedf47a36649e8ee56bca205c8d Reviewed-on: https://go-review.googlesource.com/c/tools/+/459735 Run-TryBot: Alan Donovan <[email protected]> Reviewed-by: Robert Findley <[email protected]> TryBot-Result: Gopher Robot <[email protected]> gopls-CI: kokoro <[email protected]>
Change https://go.dev/cl/459736 mentions this issue: |
Panicking example: https://go.dev/play/p/JXREnQBsSPe (from #57484). |
This change expands the dominion of safetoken to include calls to token.File{,Set}.Position{,For}, since all need workarounds similar to that in Offset. As a side benefit, we now have a centralized place to implement the workaround for other bugs such as golang/go#41029, the newline at EOF problem). Unfortunately the former callers of FileSet.Position must stipulate whether the Pos is a start or an end, as the same value may denote the position 1 beyond the end of one file, or the start of the following file in the file set. Hence the two different functions, {Start,End}Position. The static check has been expanded, as have the tests. Of course, this approach is not foolproof: gopls has many dependencies that call methods of File and FileSet directly. Updates golang/go#41029 Updates golang/go#57484 Updates golang/go#57490 Change-Id: Ia727e3f55ca2703dd17ff2cac05e786793ca38eb Reviewed-on: https://go-review.googlesource.com/c/tools/+/459736 Run-TryBot: Alan Donovan <[email protected]> Reviewed-by: Robert Findley <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Auto-Submit: Alan Donovan <[email protected]> gopls-CI: kokoro <[email protected]>
@adonovan I looked into this:
I see several approaches here:
Approach 2) seems problematic because it changes a major invariant with unforeseeable consequences. 3) may be unsatisfactory because we don't know if we fixed all places already. I think 1) may be doable: removing the panics should not break existing code (parser.safePos notwithstanding), and if we have out-of-bounds positions, they will be automatically corrected. If we decide to do 1) we should do in early in cycle to catch problems ASAP. |
This issue is currently labeled as early-in-cycle for Go 1.22. |
I agree that (1) seems like the best we can do within the existing constraints. |
Work-arounds exist but we should eventually address this somehow. |
This issue is currently labeled as early-in-cycle for Go 1.23. |
Change https://go.dev/cl/559436 mentions this issue: |
Per the discussion on the issue, make methods that depend on incoming offsets or positions tolerant in the presence of out-of-bounds values by adjusting the values as needed. Add an internal flag debug that can be set to enable the old (not fault-tolerant) behavior. Fixes golang#57490. Change-Id: I8a7d422b9fd1d6f0980fd4e64da2f0489056d71e Reviewed-on: https://go-review.googlesource.com/c/go/+/559436 Reviewed-by: Alan Donovan <[email protected]> TryBot-Bypass: Robert Griesemer <[email protected]> Auto-Submit: Robert Griesemer <[email protected]> Reviewed-by: Robert Griesemer <[email protected]>
Given an input of
src
, the parser reserves a block of the token.Pos space of exactly len(src), even though it may synthesize virtual tokens (e.g. close brackets) at the EOF position during error recovery. The End position of the incomplete syntax node is then computed as Rparen + len(")"), which is out of bounds. See #57484 for a minimal example.The parser should reserve one extra byte in its call to FileSet.AddFile. Or use safePos in many more places.
@mdempsky @findleyr
The text was updated successfully, but these errors were encountered: