Repository: goccy/go-yaml
Pull request #584 (2024-12-10 01:33:07)

Fix node-anchor-not-indented
Add validation for invalid usage of anchor and tag in map or sequence

codecov-commenter: :warning: Please install the !['codecov app svg image'](https://github.com/codecov/engineering-team/assets/152432831/e90313f4-9d3a-4b63-8b54-cfe14e7ec20d) to ensure uploads and comments are reliably processed by Codecov.

## [Codecov](https://app.codecov.io/gh/goccy/go-yaml/pull/584?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Masaaki+Goshima) Report
Attention: Patch coverage is `70.45455%` with `13 lines` in your changes missing coverage. Please review.
> Project coverage is 77.35%. Comparing base [(`1aa3b7d`)](https://app.codecov.io/gh/goccy/go-yaml/commit/1aa3b7d87ad690c4eb816dcd4fef14ac23a5db8a?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Masaaki+Goshima) to head [(`3989c51`)](https://app.codecov.io/gh/goccy/go-yaml/commit/3989c513a5e5ccb50da2ea8a842480b6f348edc6?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Masaaki+Goshima).

:exclamation: Your organization needs to install the [Codecov GitHub app](https://github.com/apps/codecov/installations/select_target) to enable full functionality.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master     #584      +/-   ##
==========================================
- Coverage   77.39%   77.35%   -0.04%     
==========================================
  Files          21       21              
  Lines        7666     7710      +44     
==========================================
+ Hits         5933     5964      +31     
- Misses       1325     1335      +10     
- Partials      408      411       +3     
```

</details>

Patch:
diff --git a/parser/parser.go b/parser/parser.go
index 08f9dfe..7e2370b 100644
--- a/parser/parser.go
+++ b/parser/parser.go
@@ -754,6 +754,11 @@ func (p *parser) parseMapValue(ctx *context, key ast.MapKeyNode, colonTk *Token)
 		// &anchor
 		return nil, errors.ErrSyntax("anchor is not allowed in this context", tk.RawToken())
 	}
+	if tk.Column() <= keyCol && tk.Type() == token.TagType {
+		// key: <value does not defined>
+		// !!tag
+		return nil, errors.ErrSyntax("tag is not allowed in this context", tk.RawToken())
+	}
 
 	if tk.Column() < keyCol {
 		// in this case,
@@ -785,9 +790,43 @@ func (p *parser) parseMapValue(ctx *context, key ast.MapKeyNode, colonTk *Token)
 	if err != nil {
 		return nil, err
 	}
+	if err := p.validateAnchorValueInMapOrSeq(value, keyCol); err != nil {
+		return nil, err
+	}
 	return value, nil
 }
 
+func (p *parser) validateAnchorValueInMapOrSeq(value ast.Node, col int) error {
+	anchor, ok := value.(*ast.AnchorNode)
+	if !ok {
+		return nil
+	}
+	tag, ok := anchor.Value.(*ast.TagNode)
+	if !ok {
+		return nil
+	}
+	anchorTk := anchor.GetToken()
+	tagTk := tag.GetToken()
+
+	if anchorTk.Position.Line == tagTk.Position.Line {
+		// key:
+		//   &anchor !!tag
+		//
+		// - &anchor !!tag
+		return nil
+	}
+
+	if tagTk.Position.Column <= col {
+		// key: &anchor
+		// !!tag
+		//
+		// - &anchor
+		// !!tag
+		return errors.ErrSyntax("tag is not allowed in this context", tagTk)
+	}
+	return nil
+}
+
 func (p *parser) parseAnchor(ctx *context, g *TokenGroup) (*ast.AnchorNode, error) {
 	anchorNameGroup := g.First().Group
 	anchor, err := p.parseAnchorName(ctx.withGroup(anchorNameGroup))
@@ -1089,6 +1128,11 @@ func (p *parser) parseSequenceValue(ctx *context, seqTk *Token) (ast.Node, error
 		// &anchor
 		return nil, errors.ErrSyntax("anchor is not allowed in this sequence context", tk.RawToken())
 	}
+	if tk.Column() <= seqCol && tk.Type() == token.TagType {
+		// - <value does not defined>
+		// !!tag
+		return nil, errors.ErrSyntax("tag is not allowed in this sequence context", tk.RawToken())
+	}
 
 	if tk.Column() < seqCol {
 		// in this case,
@@ -1120,6 +1164,9 @@ func (p *parser) parseSequenceValue(ctx *context, seqTk *Token) (ast.Node, error
 	if err != nil {
 		return nil, err
 	}
+	if err := p.validateAnchorValueInMapOrSeq(value, seqCol); err != nil {
+		return nil, err
+	}
 	return value, nil
 }
 


Test patch:
diff --git a/yaml_test_suite_test.go b/yaml_test_suite_test.go
index edfe3f1..346ecc9 100644
--- a/yaml_test_suite_test.go
+++ b/yaml_test_suite_test.go
@@ -45,7 +45,6 @@ var failureTestNames = []string{
 	"multiline-scalar-at-top-level",                  // pass yamlv3.
 	"multiline-scalar-at-top-level-1-3",              // pass yamlv3.
 	"nested-implicit-complex-keys",                   // no json.
-	"node-anchor-not-indented",                       // pass yamlv3.
 	"plain-dashes-in-flow-sequence",
 	"question-mark-edge-cases/00",                           // no json.
 	"question-mark-edge-cases/01",                           // no json.