Skip to content

Commit be05df0

Browse files
committed
Fixing usage of quoted numeric keys #1247
1 parent c7c11ef commit be05df0

File tree

4 files changed

+26
-16
lines changed

4 files changed

+26
-16
lines changed

pkg/yqlib/lib.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,13 @@ func parseInt(numberString string) (int, error) {
352352
return int(parsed), err
353353
}
354354

355+
func createStringScalarNode(stringValue string) *yaml.Node {
356+
var node = &yaml.Node{Kind: yaml.ScalarNode}
357+
node.Value = stringValue
358+
node.Tag = "!!str"
359+
return node
360+
}
361+
355362
func createScalarNode(value interface{}, stringValue string) *yaml.Node {
356363
var node = &yaml.Node{Kind: yaml.ScalarNode}
357364
node.Value = stringValue

pkg/yqlib/operator_entries.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,20 +72,20 @@ func parseEntry(entry *yaml.Node, position int) (*yaml.Node, *yaml.Node, error)
7272
prefs := traversePreferences{DontAutoCreate: true}
7373
candidateNode := &CandidateNode{Node: entry}
7474

75-
keyResults, err := traverseMap(Context{}, candidateNode, "key", prefs, false)
75+
keyResults, err := traverseMap(Context{}, candidateNode, createStringScalarNode("key"), prefs, false)
7676

7777
if err != nil {
7878
return nil, nil, err
7979
} else if keyResults.Len() != 1 {
80-
return nil, nil, fmt.Errorf("Expected to find one 'key' entry but found %v in position %v", keyResults.Len(), position)
80+
return nil, nil, fmt.Errorf("expected to find one 'key' entry but found %v in position %v", keyResults.Len(), position)
8181
}
8282

83-
valueResults, err := traverseMap(Context{}, candidateNode, "value", prefs, false)
83+
valueResults, err := traverseMap(Context{}, candidateNode, createStringScalarNode("value"), prefs, false)
8484

8585
if err != nil {
8686
return nil, nil, err
8787
} else if valueResults.Len() != 1 {
88-
return nil, nil, fmt.Errorf("Expected to find one 'value' entry but found %v in position %v", valueResults.Len(), position)
88+
return nil, nil, fmt.Errorf("expected to find one 'value' entry but found %v in position %v", valueResults.Len(), position)
8989
}
9090

9191
return keyResults.Front().Value.(*CandidateNode).Node, valueResults.Front().Value.(*CandidateNode).Node, nil

pkg/yqlib/operator_traverse_path.go

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package yqlib
33
import (
44
"container/list"
55
"fmt"
6-
"strconv"
76

87
"github.com/elliotchance/orderedmap"
98
yaml "gopkg.in/yaml.v3"
@@ -57,7 +56,7 @@ func traverse(context Context, matchingNode *CandidateNode, operation *Operation
5756
switch value.Kind {
5857
case yaml.MappingNode:
5958
log.Debug("its a map with %v entries", len(value.Content)/2)
60-
return traverseMap(context, matchingNode, operation.StringValue, operation.Preferences.(traversePreferences), false)
59+
return traverseMap(context, matchingNode, createStringScalarNode(operation.StringValue), operation.Preferences.(traversePreferences), false)
6160

6261
case yaml.SequenceNode:
6362
log.Debug("its a sequence of %v things!", len(value.Content))
@@ -131,11 +130,8 @@ func traverseArrayIndices(context Context, matchingNode *CandidateNode, indicesT
131130
node.Tag = ""
132131
node.Kind = yaml.SequenceNode
133132
//check that the indices are numeric, if not, then we should create an object
134-
if len(indicesToTraverse) != 0 {
135-
_, err := strconv.ParseInt(indicesToTraverse[0].Value, 10, 64)
136-
if err != nil {
137-
node.Kind = yaml.MappingNode
138-
}
133+
if len(indicesToTraverse) != 0 && indicesToTraverse[0].Tag != "!!int" {
134+
node.Kind = yaml.MappingNode
139135
}
140136
}
141137

@@ -155,14 +151,14 @@ func traverseArrayIndices(context Context, matchingNode *CandidateNode, indicesT
155151

156152
func traverseMapWithIndices(context Context, candidate *CandidateNode, indices []*yaml.Node, prefs traversePreferences) (*list.List, error) {
157153
if len(indices) == 0 {
158-
return traverseMap(context, candidate, "", prefs, true)
154+
return traverseMap(context, candidate, createStringScalarNode(""), prefs, true)
159155
}
160156

161157
var matchingNodeMap = list.New()
162158

163159
for _, indexNode := range indices {
164160
log.Debug("traverseMapWithIndices: %v", indexNode.Value)
165-
newNodes, err := traverseMap(context, candidate, indexNode.Value, prefs, false)
161+
newNodes, err := traverseMap(context, candidate, indexNode, prefs, false)
166162
if err != nil {
167163
return nil, err
168164
}
@@ -224,9 +220,9 @@ func keyMatches(key *yaml.Node, wantedKey string) bool {
224220
return matchKey(key.Value, wantedKey)
225221
}
226222

227-
func traverseMap(context Context, matchingNode *CandidateNode, key string, prefs traversePreferences, splat bool) (*list.List, error) {
223+
func traverseMap(context Context, matchingNode *CandidateNode, keyNode *yaml.Node, prefs traversePreferences, splat bool) (*list.List, error) {
228224
var newMatches = orderedmap.NewOrderedMap()
229-
err := doTraverseMap(newMatches, matchingNode, key, prefs, splat)
225+
err := doTraverseMap(newMatches, matchingNode, keyNode.Value, prefs, splat)
230226

231227
if err != nil {
232228
return nil, err
@@ -235,7 +231,7 @@ func traverseMap(context Context, matchingNode *CandidateNode, key string, prefs
235231
if !prefs.DontAutoCreate && !context.DontAutoCreate && newMatches.Len() == 0 {
236232
//no matches, create one automagically
237233
valueNode := &yaml.Node{Tag: "!!null", Kind: yaml.ScalarNode, Value: "null"}
238-
keyNode := &yaml.Node{Kind: yaml.ScalarNode, Value: key}
234+
239235
node := matchingNode.Node
240236

241237
if len(node.Content) == 0 {

pkg/yqlib/operator_traverse_path_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ var traversePathOperatorScenarios = []expressionScenario{
4444
"D0, P[0 0], (!!int)::1\n",
4545
},
4646
},
47+
{
48+
skipDoc: true,
49+
expression: `.cat["12"] = "things"`,
50+
expected: []string{
51+
"D0, P[], ()::cat:\n \"12\": things\n",
52+
},
53+
},
4754
{
4855
skipDoc: true,
4956
document: `blah: {}`,

0 commit comments

Comments
 (0)