Skip to content

Commit f984d17

Browse files
akoclaude
andcommitted
fix: add nil guards to REST client visitor to prevent panic on parse errors
The visitor crashed with a nil interface conversion at visitor_rest.go:26 when the parser produced error nodes (e.g., when old BEGIN...END syntax was used with the new {} grammar). Added defensive nil checks on all type assertions in ExitCreateRestClientStatement and its helpers so malformed input produces a clean parse error instead of a panic. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 8798071 commit f984d17

1 file changed

Lines changed: 24 additions & 5 deletions

File tree

mdl/visitor/visitor_rest.go

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,15 @@ func (b *Builder) ExitCreateRestClientStatement(ctx *parser.CreateRestClientStat
2222

2323
// Parse service-level properties (BaseUrl, Authentication, Folder)
2424
for _, propCtx := range ctx.AllRestClientProperty() {
25-
pc := propCtx.(*parser.RestClientPropertyContext)
26-
key := strings.ToLower(identifierOrKeywordText(pc.IdentifierOrKeyword().(*parser.IdentifierOrKeywordContext)))
25+
pc, ok := propCtx.(*parser.RestClientPropertyContext)
26+
if !ok || pc == nil {
27+
continue
28+
}
29+
iok := pc.IdentifierOrKeyword()
30+
if iok == nil {
31+
continue
32+
}
33+
key := strings.ToLower(identifierOrKeywordText(iok.(*parser.IdentifierOrKeywordContext)))
2734
switch key {
2835
case "baseurl":
2936
if sl := pc.STRING_LITERAL(); sl != nil {
@@ -37,7 +44,10 @@ func (b *Builder) ExitCreateRestClientStatement(ctx *parser.CreateRestClientStat
3744
if pc.BASIC() != nil {
3845
authDef := &ast.RestAuthDef{Scheme: "BASIC"}
3946
for _, subProp := range pc.AllRestClientProperty() {
40-
sp := subProp.(*parser.RestClientPropertyContext)
47+
sp, spOk := subProp.(*parser.RestClientPropertyContext)
48+
if !spOk || sp == nil || sp.IdentifierOrKeyword() == nil {
49+
continue
50+
}
4151
subKey := strings.ToLower(identifierOrKeywordText(sp.IdentifierOrKeyword().(*parser.IdentifierOrKeywordContext)))
4252
if sl := sp.STRING_LITERAL(); sl != nil {
4353
switch subKey {
@@ -56,7 +66,10 @@ func (b *Builder) ExitCreateRestClientStatement(ctx *parser.CreateRestClientStat
5666

5767
// Parse operations
5868
for _, opCtx := range ctx.AllRestClientOperation() {
59-
oc := opCtx.(*parser.RestClientOperationContext)
69+
oc, ok := opCtx.(*parser.RestClientOperationContext)
70+
if !ok || oc == nil {
71+
continue
72+
}
6073
opDef := parseRestClientOperation(oc)
6174
stmt.Operations = append(stmt.Operations, opDef)
6275
}
@@ -91,7 +104,10 @@ func parseRestClientOperation(ctx *parser.RestClientOperationContext) *ast.RestO
91104

92105
// Parse properties
93106
for _, propCtx := range ctx.AllRestClientOpProp() {
94-
pc := propCtx.(*parser.RestClientOpPropContext)
107+
pc, ok := propCtx.(*parser.RestClientOpPropContext)
108+
if !ok || pc == nil {
109+
continue
110+
}
95111
parseRestClientOpProp(pc, op)
96112
}
97113

@@ -100,6 +116,9 @@ func parseRestClientOperation(ctx *parser.RestClientOperationContext) *ast.RestO
100116

101117
// parseRestClientOpProp dispatches a single operation property to the right handler.
102118
func parseRestClientOpProp(ctx *parser.RestClientOpPropContext, op *ast.RestOperationDef) {
119+
if ctx == nil {
120+
return
121+
}
103122
// Determine key name from the identifierOrKeyword
104123
iokCtx := ctx.IdentifierOrKeyword()
105124
if iokCtx == nil {

0 commit comments

Comments
 (0)