From 8447cee0e0de612703a2fe3c5de0a2345e9bd0c5 Mon Sep 17 00:00:00 2001 From: Di Xu Date: Thu, 20 Jul 2017 10:48:18 +0800 Subject: [PATCH] update json-patch to fix nil value issue when creating mergepatch --- Godeps/Godeps.json | 2 +- .../Godeps/Godeps.json | 2 +- .../k8s.io/apimachinery/Godeps/Godeps.json | 2 +- .../src/k8s.io/apiserver/Godeps/Godeps.json | 2 +- .../k8s.io/kube-aggregator/Godeps/Godeps.json | 2 +- .../sample-apiserver/Godeps/Godeps.json | 2 +- .../github.com/evanphx/json-patch/.travis.yml | 6 +- vendor/github.com/evanphx/json-patch/merge.go | 38 +++---------- vendor/github.com/evanphx/json-patch/patch.go | 56 +++++++++++++++++++ 9 files changed, 75 insertions(+), 37 deletions(-) diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 5b026bc5c73..3021ce4997d 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -1090,7 +1090,7 @@ }, { "ImportPath": "github.com/evanphx/json-patch", - "Rev": "ba18e35c5c1b36ef6334cad706eb681153d2d379" + "Rev": "944e07253867aacae43c04b2e6a239005443f33a" }, { "ImportPath": "github.com/exponent-io/jsonpath", diff --git a/staging/src/k8s.io/apiextensions-apiserver/Godeps/Godeps.json b/staging/src/k8s.io/apiextensions-apiserver/Godeps/Godeps.json index 06b8366c983..f3725a094cd 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/Godeps/Godeps.json +++ b/staging/src/k8s.io/apiextensions-apiserver/Godeps/Godeps.json @@ -104,7 +104,7 @@ }, { "ImportPath": "github.com/evanphx/json-patch", - "Rev": "ba18e35c5c1b36ef6334cad706eb681153d2d379" + "Rev": "944e07253867aacae43c04b2e6a239005443f33a" }, { "ImportPath": "github.com/ghodss/yaml", diff --git a/staging/src/k8s.io/apimachinery/Godeps/Godeps.json b/staging/src/k8s.io/apimachinery/Godeps/Godeps.json index 6dbab2d1074..8793842a07c 100644 --- a/staging/src/k8s.io/apimachinery/Godeps/Godeps.json +++ b/staging/src/k8s.io/apimachinery/Godeps/Godeps.json @@ -40,7 +40,7 @@ }, { "ImportPath": "github.com/evanphx/json-patch", - "Rev": "ba18e35c5c1b36ef6334cad706eb681153d2d379" + "Rev": "944e07253867aacae43c04b2e6a239005443f33a" }, { "ImportPath": "github.com/ghodss/yaml", diff --git a/staging/src/k8s.io/apiserver/Godeps/Godeps.json b/staging/src/k8s.io/apiserver/Godeps/Godeps.json index ba0f5d17c44..db0b3e1ff33 100644 --- a/staging/src/k8s.io/apiserver/Godeps/Godeps.json +++ b/staging/src/k8s.io/apiserver/Godeps/Godeps.json @@ -324,7 +324,7 @@ }, { "ImportPath": "github.com/evanphx/json-patch", - "Rev": "ba18e35c5c1b36ef6334cad706eb681153d2d379" + "Rev": "944e07253867aacae43c04b2e6a239005443f33a" }, { "ImportPath": "github.com/ghodss/yaml", diff --git a/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json b/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json index a71868c4f8c..3b5a883e056 100644 --- a/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json +++ b/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json @@ -112,7 +112,7 @@ }, { "ImportPath": "github.com/evanphx/json-patch", - "Rev": "ba18e35c5c1b36ef6334cad706eb681153d2d379" + "Rev": "944e07253867aacae43c04b2e6a239005443f33a" }, { "ImportPath": "github.com/ghodss/yaml", diff --git a/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json b/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json index f5cc546f2b7..296086dbd60 100644 --- a/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json +++ b/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json @@ -104,7 +104,7 @@ }, { "ImportPath": "github.com/evanphx/json-patch", - "Rev": "ba18e35c5c1b36ef6334cad706eb681153d2d379" + "Rev": "944e07253867aacae43c04b2e6a239005443f33a" }, { "ImportPath": "github.com/ghodss/yaml", diff --git a/vendor/github.com/evanphx/json-patch/.travis.yml b/vendor/github.com/evanphx/json-patch/.travis.yml index ed5cb244c82..2092c72c46b 100644 --- a/vendor/github.com/evanphx/json-patch/.travis.yml +++ b/vendor/github.com/evanphx/json-patch/.travis.yml @@ -1,13 +1,15 @@ language: go go: - - 1.4 - - 1.3 + - 1.8 + - 1.7 install: - if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi + - go get github.com/jessevdk/go-flags script: + - go get - go test -cover ./... notifications: diff --git a/vendor/github.com/evanphx/json-patch/merge.go b/vendor/github.com/evanphx/json-patch/merge.go index 84e00b14895..b9af252fec3 100644 --- a/vendor/github.com/evanphx/json-patch/merge.go +++ b/vendor/github.com/evanphx/json-patch/merge.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "reflect" - "strings" ) func merge(cur, patch *lazyNode, mergeMerge bool) *lazyNode { @@ -28,7 +27,6 @@ func merge(cur, patch *lazyNode, mergeMerge bool) *lazyNode { func mergeDocs(doc, patch *partialDoc, mergeMerge bool) { for k, v := range *patch { - k := decodePatchKey(k) if v == nil { if mergeMerge { (*doc)[k] = nil @@ -226,6 +224,9 @@ func matchesValue(av, bv interface{}) bool { if bt == at { return true } + case nil: + // Both nil, fine. + return true case map[string]interface{}: bt := bv.(map[string]interface{}) for key := range at { @@ -250,16 +251,15 @@ func matchesValue(av, bv interface{}) bool { func getDiff(a, b map[string]interface{}) (map[string]interface{}, error) { into := map[string]interface{}{} for key, bv := range b { - escapedKey := encodePatchKey(key) av, ok := a[key] // value was added if !ok { - into[escapedKey] = bv + into[key] = bv continue } // If types have changed, replace completely if reflect.TypeOf(av) != reflect.TypeOf(bv) { - into[escapedKey] = bv + into[key] = bv continue } // Types are the same, compare values @@ -272,23 +272,23 @@ func getDiff(a, b map[string]interface{}) (map[string]interface{}, error) { return nil, err } if len(dst) > 0 { - into[escapedKey] = dst + into[key] = dst } case string, float64, bool: if !matchesValue(av, bv) { - into[escapedKey] = bv + into[key] = bv } case []interface{}: bt := bv.([]interface{}) if !matchesArray(at, bt) { - into[escapedKey] = bv + into[key] = bv } case nil: switch bv.(type) { case nil: // Both nil, fine. default: - into[escapedKey] = bv + into[key] = bv } default: panic(fmt.Sprintf("Unknown type:%T in key %s", av, key)) @@ -303,23 +303,3 @@ func getDiff(a, b map[string]interface{}) (map[string]interface{}, error) { } return into, nil } - -// From http://tools.ietf.org/html/rfc6901#section-4 : -// -// Evaluation of each reference token begins by decoding any escaped -// character sequence. This is performed by first transforming any -// occurrence of the sequence '~1' to '/', and then transforming any -// occurrence of the sequence '~0' to '~'. - -var ( - rfc6901Encoder = strings.NewReplacer("~", "~0", "/", "~1") - rfc6901Decoder = strings.NewReplacer("~1", "/", "~0", "~") -) - -func decodePatchKey(k string) string { - return rfc6901Decoder.Replace(k) -} - -func encodePatchKey(k string) string { - return rfc6901Encoder.Replace(k) -} diff --git a/vendor/github.com/evanphx/json-patch/patch.go b/vendor/github.com/evanphx/json-patch/patch.go index 3b33010538d..de70dbca78e 100644 --- a/vendor/github.com/evanphx/json-patch/patch.go +++ b/vendor/github.com/evanphx/json-patch/patch.go @@ -369,6 +369,15 @@ func (d *partialArray) add(key string, val *lazyNode) error { cur := *d + if idx < 0 { + idx *= -1 + + if idx > len(ary) { + return fmt.Errorf("Unable to access invalid index: %d", idx) + } + idx = len(ary) - idx + } + copy(ary[0:idx], cur[0:idx]) ary[idx] = val copy(ary[idx+1:], cur[idx:]) @@ -446,6 +455,11 @@ func (p Patch) replace(doc *container, op operation) error { return fmt.Errorf("jsonpatch replace operation does not apply: doc is missing path: %s", path) } + val, ok := con.get(key) + if val == nil || ok != nil { + return fmt.Errorf("jsonpatch replace operation does not apply: doc is missing key: %s", path) + } + return con.set(key, op.value()) } @@ -508,6 +522,31 @@ func (p Patch) test(doc *container, op operation) error { return fmt.Errorf("Testing value %s failed", path) } +func (p Patch) copy(doc *container, op operation) error { + from := op.from() + + con, key := findObject(doc, from) + + if con == nil { + return fmt.Errorf("jsonpatch copy operation does not apply: doc is missing from path: %s", from) + } + + val, err := con.get(key) + if err != nil { + return err + } + + path := op.path() + + con, key = findObject(doc, path) + + if con == nil { + return fmt.Errorf("jsonpatch copy operation does not apply: doc is missing destination path: %s", path) + } + + return con.set(key, val) +} + // Equal indicates if 2 JSON documents have the same structural equality. func Equal(a, b []byte) bool { ra := make(json.RawMessage, len(a)) @@ -570,6 +609,8 @@ func (p Patch) ApplyIndent(doc []byte, indent string) ([]byte, error) { err = p.move(&pd, op) case "test": err = p.test(&pd, op) + case "copy": + err = p.copy(&pd, op) default: err = fmt.Errorf("Unexpected kind: %s", op.kind()) } @@ -585,3 +626,18 @@ func (p Patch) ApplyIndent(doc []byte, indent string) ([]byte, error) { return json.Marshal(pd) } + +// From http://tools.ietf.org/html/rfc6901#section-4 : +// +// Evaluation of each reference token begins by decoding any escaped +// character sequence. This is performed by first transforming any +// occurrence of the sequence '~1' to '/', and then transforming any +// occurrence of the sequence '~0' to '~'. + +var ( + rfc6901Decoder = strings.NewReplacer("~1", "/", "~0", "~") +) + +func decodePatchKey(k string) string { + return rfc6901Decoder.Replace(k) +}