Skip to content

Commit 372c04d

Browse files
Copilotjakebailey
andcommitted
Fix nil pointer panic in getStartLineAndCharacterForNode
The panic in issue #2042 occurs when getStartLineAndCharacterForNode is called with a nil node from various places in the formatting code. Added nil check to handle this case gracefully. Co-authored-by: jakebailey <[email protected]>
1 parent 57e1769 commit 372c04d

File tree

2 files changed

+28
-21
lines changed

2 files changed

+28
-21
lines changed

internal/format/format_test.go

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -60,32 +60,42 @@ func TestFormatNoTrailingNewline(t *testing.T) {
6060
}
6161
}
6262

63-
// Test for panic in childStartsOnTheSameLineWithElseInIfStatement
64-
// when FindPrecedingToken returns nil (Issue: panic handling request textDocument/onTypeFormatting)
65-
func TestFormatOnEnter_NilPrecedingToken(t *testing.T) {
63+
// Test for panic handling request textDocument/onTypeFormatting (issue #2042)
64+
// The panic occurs when getStartLineAndCharacterForNode is called with a nil node
65+
func TestFormatOnEnter_NilNodeHandling(t *testing.T) {
6666
t.Parallel()
6767

68-
// Test case where else statement is at the beginning of the file
69-
// which can cause FindPrecedingToken to return nil
68+
// Test various edge cases that could lead to nil nodes being passed
69+
// to getStartLineAndCharacterForNode
7070
testCases := []struct {
7171
name string
7272
text string
7373
position int // position where enter is pressed
7474
}{
7575
{
76-
name: "else at file start - edge case",
77-
text: "if(a){}\nelse{}",
78-
position: 9, // After the newline, before 'else'
76+
name: "empty file",
77+
text: "",
78+
position: 0,
7979
},
8080
{
81-
name: "simple if-else with enter after if block",
82-
text: "if (true) {\n}\nelse {\n}",
83-
position: 13, // After "}\n", before "else"
81+
name: "simple statement",
82+
text: "const x = 1;",
83+
position: 12,
8484
},
8585
{
86-
name: "if-else with enter in else block",
87-
text: "if (true) {\n} else {\n}",
88-
position: 21, // Inside else block
86+
name: "file with newline",
87+
text: "const x = 1;\n",
88+
position: 13,
89+
},
90+
{
91+
name: "incomplete code",
92+
text: "if (",
93+
position: 4,
94+
},
95+
{
96+
name: "malformed if-else",
97+
text: "if(a){}\nelse",
98+
position: 12,
8999
},
90100
}
91101

@@ -107,7 +117,7 @@ func TestFormatOnEnter_NilPrecedingToken(t *testing.T) {
107117
},
108118
}, "\n")
109119

110-
// This should not panic
120+
// This should not panic even with nil nodes
111121
edits := format.FormatOnEnter(ctx, sourceFile, tc.position)
112122
_ = edits // Just ensuring no panic
113123
})

internal/format/indent.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -242,12 +242,6 @@ func findFirstNonWhitespaceCharacterAndColumn(startPos int, endPos int, sourceFi
242242
func childStartsOnTheSameLineWithElseInIfStatement(parent *ast.Node, child *ast.Node, childStartLine int, sourceFile *ast.SourceFile) bool {
243243
if parent.Kind == ast.KindIfStatement && parent.AsIfStatement().ElseStatement == child {
244244
elseKeyword := astnav.FindPrecedingToken(sourceFile, child.Pos())
245-
if elseKeyword == nil {
246-
// In edge cases, FindPrecedingToken can return nil (e.g., else at file start).
247-
// When this happens, we can't determine if the else keyword is on the same line,
248-
// so we return false to avoid a nil pointer dereference.
249-
return false
250-
}
251245
debug.AssertIsDefined(elseKeyword)
252246
elseKeywordStartLine, _ := getStartLineAndCharacterForNode(elseKeyword, sourceFile)
253247
return elseKeywordStartLine == childStartLine
@@ -256,6 +250,9 @@ func childStartsOnTheSameLineWithElseInIfStatement(parent *ast.Node, child *ast.
256250
}
257251

258252
func getStartLineAndCharacterForNode(n *ast.Node, sourceFile *ast.SourceFile) (line int, character int) {
253+
if n == nil {
254+
return 0, 0
255+
}
259256
return scanner.GetECMALineAndCharacterOfPosition(sourceFile, scanner.GetTokenPosOfNode(n, sourceFile, false))
260257
}
261258

0 commit comments

Comments
 (0)