Skip to content

Commit cc7baf7

Browse files
authored
Attempt to fix #185 - Set overrides items (#186)
If you try to set an unknown key, simple object within a nested array, passing in the index, the parser will override the object and does not take into account the given index [1]. With current parser version, given this json as input: ```json { "test": { "key": [ { "innerKey": "innerKeyValue", "innerKey2": "innerKeyValue2" } ] } } ``` and following path to set an unknown key: `"test", "key", "[1]", "newInnerKey"` with data `"new object"`, the output would be: ```json { "test": { "key": [ { "newInnerKey": "new object" } ] } } ``` which I think it is wrong, since it overrides what index [0] had but the above path wanted to insert the object in index [1] instead. With the changes done in this PR, given the same json input, path and data, the output would be: ```json { "test": { "key": [ { "innerKey": "innerKeyValue", "innerKey2": "innerKeyValue2" }, { "newInnerKey": "new object" } ] } } ``` the above result would be correct since we are setting a new object within the existing array in a different index [1], keeping what the array already had in previous index [0]. Added also a test to cover this scenario. All tests pass. This appears to fix #185 and includes a test for it. **Description**: What this PR does **Benchmark before change**: Benchmarks are broken.
1 parent 11fa7e4 commit cc7baf7

File tree

2 files changed

+18
-6
lines changed

2 files changed

+18
-6
lines changed

parser.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -599,15 +599,17 @@ func createInsertComponent(keys []string, setValue []byte, comma, object bool) [
599599
if comma {
600600
buffer.WriteString(",")
601601
}
602-
if isIndex {
602+
if isIndex && !comma {
603603
buffer.WriteString("[")
604604
} else {
605605
if object {
606606
buffer.WriteString("{")
607607
}
608-
buffer.WriteString("\"")
609-
buffer.WriteString(keys[0])
610-
buffer.WriteString("\":")
608+
if !isIndex {
609+
buffer.WriteString("\"")
610+
buffer.WriteString(keys[0])
611+
buffer.WriteString("\":")
612+
}
611613
}
612614

613615
for i := 1; i < len(keys); i++ {
@@ -627,7 +629,7 @@ func createInsertComponent(keys []string, setValue []byte, comma, object bool) [
627629
buffer.WriteString("}")
628630
}
629631
}
630-
if isIndex {
632+
if isIndex && !comma {
631633
buffer.WriteString("]")
632634
}
633635
if object && !isIndex {
@@ -776,7 +778,9 @@ func Set(data []byte, setValue []byte, keys ...string) (value []byte, err error)
776778
depthOffset := endOffset
777779
if depth != 0 {
778780
// if subpath is a non-empty object, add to it
779-
if data[startOffset] == '{' && data[startOffset+1+nextToken(data[startOffset+1:])] != '}' {
781+
// or if subpath is a non-empty array, add to it
782+
if (data[startOffset] == '{' && data[startOffset+1+nextToken(data[startOffset+1:])] != '}') ||
783+
(data[startOffset] == '[' && data[startOffset+1+nextToken(data[startOffset+1:])] == '{') && keys[depth:][0][0] == 91 {
780784
depthOffset--
781785
startOffset = depthOffset
782786
// otherwise, over-write it with a new object

parser_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,14 @@ var setTests = []SetTest{
392392
isFound: true,
393393
data: `{"top":["one", "two", "value"]}`,
394394
},
395+
{
396+
desc: "set unknown key (simple object within nested array)",
397+
json: `{"test":{"key":[{"innerKey":"innerKeyValue", "innerKey2":"innerKeyValue2"}]}}`,
398+
isFound: true,
399+
path: []string{"test", "key", "[1]", "newInnerKey"},
400+
setData: `"new object"`,
401+
data: `{"test":{"key":[{"innerKey":"innerKeyValue", "innerKey2":"innerKeyValue2"},{"newInnerKey":"new object"}]}}`,
402+
},
395403
}
396404

397405
var getTests = []GetTest{

0 commit comments

Comments
 (0)