Merge pull request #65034 from caesarxuchao/json-case-sensitive

Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

Make kubernetes json serializer case sensitive

This PR imported the latest jsoniterator library so that case sensitivity during unmarhsaling is optional. The PR also set Kubernetes json serializer to be case sensitive.

Kubernetes json serializer had been case sensitive for 1.1-1.7 as we were using ugorji. This PR restores the behavior.

Fix #64612.

```release-notes
Kubernetes json deserializer is now case-sensitive as it was before 1.8.
If your config files contains fields with wrong case, the config files will be now invalid.
```

Kubernetes-commit: a2de1398f829ef38d645579160bdd6bfec8384d3
This commit is contained in:
Kubernetes Publisher 2018-06-14 15:41:26 -07:00
commit 8d6e3480fc
7 changed files with 136 additions and 117 deletions

162
Godeps/Godeps.json generated
View File

@ -156,7 +156,7 @@
},
{
"ImportPath": "github.com/json-iterator/go",
"Rev": "2ddf6d758266fcb080a4f9e054b9f292c85e6798"
"Rev": "f2b4162afba35581b6d4a50d3b8f34e33c144682"
},
{
"ImportPath": "github.com/modern-go/concurrent",
@ -268,323 +268,323 @@
},
{
"ImportPath": "k8s.io/api/admissionregistration/v1alpha1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/admissionregistration/v1beta1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/apps/v1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/apps/v1beta1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/apps/v1beta2",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/authentication/v1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/authentication/v1beta1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/authorization/v1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/authorization/v1beta1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/autoscaling/v1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/autoscaling/v2beta1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/batch/v1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/batch/v1beta1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/batch/v2alpha1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/certificates/v1beta1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/core/v1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/events/v1beta1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/extensions/v1beta1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/imagepolicy/v1alpha1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/networking/v1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/policy/v1beta1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/rbac/v1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/rbac/v1alpha1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/rbac/v1beta1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/scheduling/v1alpha1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/scheduling/v1beta1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/settings/v1alpha1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/storage/v1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/storage/v1alpha1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/api/storage/v1beta1",
"Rev": "72d6e4405f8143815cbd454ab04b38210a9f32fc"
"Rev": "783dfbe86ff74ef4a6e1243688e1585ac243f8e7"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/equality",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/errors",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/meta",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/resource",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/testing",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/testing/fuzzer",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/testing/roundtrip",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/fuzzer",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/internalversion",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1beta1",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/conversion",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/fields",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/labels",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/schema",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/json",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/protobuf",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/recognizer",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/streaming",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/versioning",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/selection",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/types",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/cache",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/clock",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/diff",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/errors",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/framer",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/httpstream",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/httpstream/spdy",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/intstr",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/json",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/mergepatch",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/net",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/remotecommand",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/runtime",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/sets",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/strategicpatch",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/validation",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/validation/field",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/wait",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/yaml",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/version",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/watch",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/json",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/netutil",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect",
"Rev": "521145febf93d5639dce48a49ee8dc080863b034"
"Rev": "5a8013207d0d28c7fe98193e5b6cdbf92e98a000"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto",

View File

@ -1,6 +1,12 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
name = "github.com/json-iterator/go"
packages = ["."]
revision = "ca39e5af3ece67bbcda3d0f4f56a8e24d9f2dad4"
version = "1.1.3"
[[projects]]
name = "github.com/modern-go/concurrent"
packages = ["."]
@ -16,6 +22,6 @@
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "ac7003b5a981716353a43055ab7d4c5357403cb30a60de2dbdeb446c1544beaa"
inputs-digest = "56a0b9e9e61d2bc8af5e1b68537401b7f4d60805eda3d107058f3171aa5cf793"
solver-name = "gps-cdcl"
solver-version = 1

View File

@ -2,12 +2,13 @@ package jsoniter
import (
"encoding/json"
"github.com/modern-go/concurrent"
"github.com/modern-go/reflect2"
"io"
"reflect"
"sync"
"unsafe"
"github.com/modern-go/concurrent"
"github.com/modern-go/reflect2"
)
// Config customize how the API should behave.
@ -23,6 +24,7 @@ type Config struct {
OnlyTaggedField bool
ValidateJsonRawMessage bool
ObjectFieldMustBeSimpleString bool
CaseSensitive bool
}
// API the public interface of this package.
@ -75,6 +77,7 @@ type frozenConfig struct {
extensions []Extension
streamPool *sync.Pool
iteratorPool *sync.Pool
caseSensitive bool
}
func (cfg *frozenConfig) initCache() {
@ -128,6 +131,7 @@ func (cfg Config) Froze() API {
objectFieldMustBeSimpleString: cfg.ObjectFieldMustBeSimpleString,
onlyTaggedField: cfg.OnlyTaggedField,
disallowUnknownFields: cfg.DisallowUnknownFields,
caseSensitive: cfg.CaseSensitive,
}
api.streamPool = &sync.Pool{
New: func() interface{} {

View File

@ -60,7 +60,7 @@ func (iter *Iterator) readFieldHash() int64 {
if b == '\\' {
iter.head = i
for _, b := range iter.readStringSlowPath() {
if 'A' <= b && b <= 'Z' {
if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive {
b += 'a' - 'A'
}
hash ^= int64(b)
@ -82,7 +82,7 @@ func (iter *Iterator) readFieldHash() int64 {
}
return hash
}
if 'A' <= b && b <= 'Z' {
if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive {
b += 'a' - 'A'
}
hash ^= int64(b)
@ -95,10 +95,14 @@ func (iter *Iterator) readFieldHash() int64 {
}
}
func calcHash(str string) int64 {
func calcHash(str string, caseSensitive bool) int64 {
hash := int64(0x811c9dc5)
for _, b := range str {
if caseSensitive {
hash ^= int64(b)
} else {
hash ^= int64(unicode.ToLower(b))
}
hash *= 0x1000193
}
return int64(hash)

View File

@ -2,9 +2,10 @@ package jsoniter
import (
"fmt"
"github.com/modern-go/reflect2"
"reflect"
"unsafe"
"github.com/modern-go/reflect2"
)
// ValDecoder is an internal type registered to cache as needed.
@ -40,6 +41,14 @@ type ctx struct {
decoders map[reflect2.Type]ValDecoder
}
func (b *ctx) caseSensitive() bool {
if b.frozenConfig == nil {
// default is case-insensitive
return false
}
return b.frozenConfig.caseSensitive
}
func (b *ctx) append(prefix string) *ctx {
return &ctx{
frozenConfig: b.frozenConfig,

View File

@ -1,7 +1,6 @@
package jsoniter
import (
"bytes"
"encoding/base64"
"reflect"
"strconv"
@ -418,20 +417,11 @@ func (codec *base64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
}
switch iter.WhatIsNext() {
case StringValue:
encoding := base64.StdEncoding
src := iter.SkipAndReturnBytes()
// New line characters (\r and \n) are ignored.
// Refer to https://golang.org/pkg/encoding/base64/#Encoding.Decode
src = bytes.Replace(src, []byte(`\r`), []byte{}, -1)
src = bytes.Replace(src, []byte(`\n`), []byte{}, -1)
src = src[1 : len(src)-1]
decodedLen := encoding.DecodedLen(len(src))
dst := make([]byte, decodedLen)
len, err := encoding.Decode(dst, src)
src := iter.ReadString()
dst, err := base64.StdEncoding.DecodeString(src)
if err != nil {
iter.ReportError("decode base64", err.Error())
} else {
dst = dst[:len]
codec.sliceType.UnsafeSet(ptr, unsafe.Pointer(&dst))
}
case ArrayValue:

View File

@ -2,10 +2,11 @@ package jsoniter
import (
"fmt"
"github.com/modern-go/reflect2"
"io"
"strings"
"unsafe"
"github.com/modern-go/reflect2"
)
func decoderOfStruct(ctx *ctx, typ reflect2.Type) ValDecoder {
@ -31,11 +32,15 @@ func decoderOfStruct(ctx *ctx, typ reflect2.Type) ValDecoder {
for k, binding := range bindings {
fields[k] = binding.Decoder.(*structFieldDecoder)
}
if !ctx.caseSensitive() {
for k, binding := range bindings {
if _, found := fields[strings.ToLower(k)]; !found {
fields[strings.ToLower(k)] = binding.Decoder.(*structFieldDecoder)
}
}
}
return createStructDecoder(ctx, typ, fields)
}
@ -46,12 +51,13 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
knownHash := map[int64]struct{}{
0: {},
}
switch len(fields) {
case 0:
return &skipObjectDecoder{typ}
case 1:
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields, false}
@ -65,7 +71,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
var fieldDecoder1 *structFieldDecoder
var fieldDecoder2 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields, false}
@ -88,7 +94,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
var fieldDecoder2 *structFieldDecoder
var fieldDecoder3 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields, false}
@ -119,7 +125,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
var fieldDecoder3 *structFieldDecoder
var fieldDecoder4 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields, false}
@ -156,7 +162,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
var fieldDecoder4 *structFieldDecoder
var fieldDecoder5 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields, false}
@ -199,7 +205,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
var fieldDecoder5 *structFieldDecoder
var fieldDecoder6 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields, false}
@ -248,7 +254,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
var fieldDecoder6 *structFieldDecoder
var fieldDecoder7 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields, false}
@ -303,7 +309,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
var fieldDecoder7 *structFieldDecoder
var fieldDecoder8 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields, false}
@ -364,7 +370,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
var fieldDecoder8 *structFieldDecoder
var fieldDecoder9 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields, false}
@ -431,7 +437,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
var fieldDecoder9 *structFieldDecoder
var fieldDecoder10 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields, false}
@ -513,13 +519,13 @@ func (decoder *generalStructDecoder) decodeOneField(ptr unsafe.Pointer, iter *It
fieldBytes := iter.ReadStringAsSlice()
field = *(*string)(unsafe.Pointer(&fieldBytes))
fieldDecoder = decoder.fields[field]
if fieldDecoder == nil {
if fieldDecoder == nil && !iter.cfg.caseSensitive {
fieldDecoder = decoder.fields[strings.ToLower(field)]
}
} else {
field = iter.ReadString()
fieldDecoder = decoder.fields[field]
if fieldDecoder == nil {
if fieldDecoder == nil && !iter.cfg.caseSensitive {
fieldDecoder = decoder.fields[strings.ToLower(field)]
}
}