|
| 1 | +package publiccode |
| 2 | + |
| 3 | +import ( |
| 4 | + "testing" |
| 5 | + |
| 6 | + "github.com/goccy/go-yaml/ast" |
| 7 | + "github.com/goccy/go-yaml/token" |
| 8 | +) |
| 9 | + |
| 10 | +// TestFindKeyPosNilToken verifies that findKeyPos does not panic when a |
| 11 | +// MappingNode key has a nil token (GetToken() == nil). |
| 12 | +// |
| 13 | +// Before the fix at parser.go:469, the direct dereference |
| 14 | +// |
| 15 | +// keyVal := mv.Key.GetToken().Value |
| 16 | +// |
| 17 | +// would panic with a nil pointer dereference in this case. |
| 18 | +func TestFindKeyPosNilToken(t *testing.T) { |
| 19 | + // First entry: NullNode key with Token == nil → GetToken() returns nil. |
| 20 | + nilKeyEntry := &ast.MappingValueNode{ |
| 21 | + BaseNode: &ast.BaseNode{}, |
| 22 | + Key: &ast.NullNode{BaseNode: &ast.BaseNode{}}, |
| 23 | + Value: &ast.StringNode{BaseNode: &ast.BaseNode{}, Value: "v"}, |
| 24 | + } |
| 25 | + |
| 26 | + // Second entry: a real StringNode key so the traversal has something to match. |
| 27 | + realTok := &token.Token{Type: token.StringType, Value: "target"} |
| 28 | + realKeyEntry := &ast.MappingValueNode{ |
| 29 | + BaseNode: &ast.BaseNode{}, |
| 30 | + Key: &ast.StringNode{BaseNode: &ast.BaseNode{}, Token: realTok, Value: "target"}, |
| 31 | + Value: &ast.StringNode{BaseNode: &ast.BaseNode{}, Value: "v2"}, |
| 32 | + } |
| 33 | + |
| 34 | + node := &ast.MappingNode{ |
| 35 | + BaseNode: &ast.BaseNode{}, |
| 36 | + Values: []*ast.MappingValueNode{nilKeyEntry, realKeyEntry}, |
| 37 | + } |
| 38 | + |
| 39 | + // Search for a key that does not exist: exercises the nil-token skip |
| 40 | + // without entering the "found" branch that would need a real Position. |
| 41 | + // Must not panic — that is the primary assertion. |
| 42 | + line, col := findKeyPos(node, []string{"nonexistent"}) |
| 43 | + if line != 0 || col != 0 { |
| 44 | + t.Errorf("expected (0,0) for missing key, got (%d,%d)", line, col) |
| 45 | + } |
| 46 | +} |
0 commit comments