Repository: go-kratos/kratos
Pull request #2492 (2022-11-07 18:04:26)

build(deps): bump github.com/aliyun/aliyun-log-go-sdk from 0.1.39 to 0.1.40 in /contrib/log/aliyun
Bumps [github.com/aliyun/aliyun-log-go-sdk](https://github.com/aliyun/aliyun-log-go-sdk) from 0.1.39 to 0.1.40.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/aliyun/aliyun-log-go-sdk/releases">github.com/aliyun/aliyun-log-go-sdk's releases</a>.</em></p>
<blockquote>
<h2>v0.1.40</h2>
<h1>feature</h1>
<ol>
<li>add more index params <a href="https://github-redirect.dependabot.com/aliyun/aliyun-log-go-sdk/issues/185">#185</a></li>
</ol>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/aliyun/aliyun-log-go-sdk/commit/a9c91db6063bb4951aed521613f90866b055ec10"><code>a9c91db</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/aliyun/aliyun-log-go-sdk/issues/185">#185</a> from EvanLjp/supply-index-paramter</li>
<li><a href="https://github.com/aliyun/aliyun-log-go-sdk/commit/085d14f3b7aacbfbd60732280e45b91da499bc34"><code>085d14f</code></a> polish codes</li>
<li><a href="https://github.com/aliyun/aliyun-log-go-sdk/commit/2900cb71431974a5cf04133c91180a0dc40a649b"><code>2900cb7</code></a> supply index paramter</li>
<li>See full diff in <a href="https://github.com/aliyun/aliyun-log-go-sdk/compare/v0.1.39...v0.1.40">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/aliyun/aliyun-log-go-sdk&package-manager=go_modules&previous-version=0.1.39&new-version=0.1.40)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Patch:
diff --git a/contrib/log/aliyun/go.mod b/contrib/log/aliyun/go.mod
index 1c7b5fa8..54abe05f 100644
--- a/contrib/log/aliyun/go.mod
+++ b/contrib/log/aliyun/go.mod
@@ -3,7 +3,7 @@ module github.com/go-kratos/kratos/contrib/log/aliyun/v2
 go 1.16
 
 require (
-	github.com/aliyun/aliyun-log-go-sdk v0.1.39
+	github.com/aliyun/aliyun-log-go-sdk v0.1.40
 	github.com/go-kratos/kratos/v2 v2.5.2
 	google.golang.org/protobuf v1.28.1
 )
diff --git a/contrib/log/aliyun/go.sum b/contrib/log/aliyun/go.sum
index ab2ac488..0b42927b 100644
--- a/contrib/log/aliyun/go.sum
+++ b/contrib/log/aliyun/go.sum
@@ -12,8 +12,8 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
 github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
-github.com/aliyun/aliyun-log-go-sdk v0.1.39 h1:oVLVcRbtOhE4a1D4HhO3OYPR6wMADl3ldcbVeFrRL8Y=
-github.com/aliyun/aliyun-log-go-sdk v0.1.39/go.mod h1:1QQ59pEJiVVXqKgbHcU6FWIgxT5RKBt+CT8AiQ2bEts=
+github.com/aliyun/aliyun-log-go-sdk v0.1.40 h1:GNlRoTe9Fi7dfhIMHAnb+b5837/fIw8lqs1DRqaU1CM=
+github.com/aliyun/aliyun-log-go-sdk v0.1.40/go.mod h1:1QQ59pEJiVVXqKgbHcU6FWIgxT5RKBt+CT8AiQ2bEts=
 github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
 github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
 github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
diff --git a/contrib/registry/etcd/go.mod b/contrib/registry/etcd/go.mod
index c4c072ec..f6ae3437 100644
--- a/contrib/registry/etcd/go.mod
+++ b/contrib/registry/etcd/go.mod
@@ -5,7 +5,7 @@ go 1.16
 require (
 	github.com/go-kratos/kratos/v2 v2.5.2
 	go.etcd.io/etcd/client/v3 v3.5.4
-	google.golang.org/grpc v1.46.2
+	google.golang.org/grpc v1.50.1
 )
 
 replace github.com/go-kratos/kratos/v2 => ../../../
diff --git a/contrib/registry/etcd/go.sum b/contrib/registry/etcd/go.sum
index e847ccab..36c78cdc 100644
--- a/contrib/registry/etcd/go.sum
+++ b/contrib/registry/etcd/go.sum
@@ -268,8 +268,9 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp
 google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
 google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
 google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
-google.golang.org/grpc v1.46.2 h1:u+MLGgVf7vRdjEYZ8wDFhAVNmhkbJ5hmrA1LMWK1CAQ=
 google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
+google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY=
+google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
 google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
diff --git a/encoding/form/form.go b/encoding/form/form.go
index 823aeb8f..ba0447e4 100644
--- a/encoding/form/form.go
+++ b/encoding/form/form.go
@@ -4,10 +4,10 @@ import (
 	"net/url"
 	"reflect"
 
-	"github.com/go-kratos/kratos/v2/encoding"
-
 	"github.com/go-playground/form/v4"
 	"google.golang.org/protobuf/proto"
+
+	"github.com/go-kratos/kratos/v2/encoding"
 )
 
 const (
@@ -70,7 +70,8 @@ func (c codec) Unmarshal(data []byte, v interface{}) error {
 	}
 	if m, ok := v.(proto.Message); ok {
 		return DecodeValues(m, vs)
-	} else if m, ok := reflect.Indirect(reflect.ValueOf(v)).Interface().(proto.Message); ok {
+	}
+	if m, ok := rv.Interface().(proto.Message); ok {
 		return DecodeValues(m, vs)
 	}
 
diff --git a/encoding/form/proto_decode.go b/encoding/form/proto_decode.go
index fcf46d46..1620162b 100644
--- a/encoding/form/proto_decode.go
+++ b/encoding/form/proto_decode.go
@@ -10,13 +10,12 @@ import (
 	"time"
 
 	"google.golang.org/protobuf/encoding/protojson"
-	"google.golang.org/protobuf/types/known/structpb"
-
 	"google.golang.org/protobuf/proto"
 	"google.golang.org/protobuf/reflect/protoreflect"
 	"google.golang.org/protobuf/reflect/protoregistry"
 	"google.golang.org/protobuf/types/known/durationpb"
 	"google.golang.org/protobuf/types/known/fieldmaskpb"
+	"google.golang.org/protobuf/types/known/structpb"
 	"google.golang.org/protobuf/types/known/timestamppb"
 	"google.golang.org/protobuf/types/known/wrapperspb"
 )
@@ -122,15 +121,13 @@ func populateRepeatedField(fd protoreflect.FieldDescriptor, list protoreflect.Li
 }
 
 func populateMapField(fd protoreflect.FieldDescriptor, mp protoreflect.Map, fieldPath []string, values []string) error {
-	flen := len(fieldPath)
-	vlen := len(values)
 	// post sub key.
-	nkey := flen - 1
+	nkey := len(fieldPath) - 1
 	key, err := parseField(fd.MapKey(), fieldPath[nkey])
 	if err != nil {
 		return fmt.Errorf("parsing map key %q: %w", fd.FullName().Name(), err)
 	}
-	vkey := vlen - 1
+	vkey := len(values) - 1
 	value, err := parseField(fd.MapValue(), values[vkey])
 	if err != nil {
 		return fmt.Errorf("parsing map value %q: %w", fd.FullName().Name(), err)


Test patch:
diff --git a/encoding/form/form_test.go b/encoding/form/form_test.go
index ddd053cd..647d1edc 100644
--- a/encoding/form/form_test.go
+++ b/encoding/form/form_test.go
@@ -26,14 +26,12 @@ type TestModel struct {
 	Name string `json:"name"`
 }
 
-const contentType = "x-www-form-urlencoded"
-
 func TestFormCodecMarshal(t *testing.T) {
 	req := &LoginRequest{
 		Username: "kratos",
 		Password: "kratos_pwd",
 	}
-	content, err := encoding.GetCodec(contentType).Marshal(req)
+	content, err := encoding.GetCodec(Name).Marshal(req)
 	if err != nil {
 		t.Errorf("marshal error: %v", err)
 	}
@@ -45,7 +43,7 @@ func TestFormCodecMarshal(t *testing.T) {
 		Username: "kratos",
 		Password: "",
 	}
-	content, err = encoding.GetCodec(contentType).Marshal(req)
+	content, err = encoding.GetCodec(Name).Marshal(req)
 	if err != nil {
 		t.Errorf("expect %v, got %v", nil, err)
 	}
@@ -57,7 +55,7 @@ func TestFormCodecMarshal(t *testing.T) {
 		ID:   1,
 		Name: "kratos",
 	}
-	content, err = encoding.GetCodec(contentType).Marshal(m)
+	content, err = encoding.GetCodec(Name).Marshal(m)
 	t.Log(string(content))
 	if err != nil {
 		t.Errorf("expect %v, got %v", nil, err)
@@ -72,13 +70,13 @@ func TestFormCodecUnmarshal(t *testing.T) {
 		Username: "kratos",
 		Password: "kratos_pwd",
 	}
-	content, err := encoding.GetCodec(contentType).Marshal(req)
+	content, err := encoding.GetCodec(Name).Marshal(req)
 	if err != nil {
 		t.Errorf("expect %v, got %v", nil, err)
 	}
 
 	bindReq := new(LoginRequest)
-	err = encoding.GetCodec(contentType).Unmarshal(content, bindReq)
+	err = encoding.GetCodec(Name).Unmarshal(content, bindReq)
 	if err != nil {
 		t.Errorf("expect %v, got %v", nil, err)
 	}
@@ -119,7 +117,7 @@ func TestProtoEncodeDecode(t *testing.T) {
 		String_:   &wrapperspb.StringValue{Value: "go-kratos"},
 		Bytes:     &wrapperspb.BytesValue{Value: []byte("123")},
 	}
-	content, err := encoding.GetCodec(contentType).Marshal(in)
+	content, err := encoding.GetCodec(Name).Marshal(in)
 	if err != nil {
 		t.Errorf("expect %v, got %v", nil, err)
 	}
@@ -130,7 +128,7 @@ func TestProtoEncodeDecode(t *testing.T) {
 		t.Errorf("rawpath is not equal to %v", string(content))
 	}
 	in2 := &complex.Complex{}
-	err = encoding.GetCodec(contentType).Unmarshal(content, in2)
+	err = encoding.GetCodec(Name).Unmarshal(content, in2)
 	if err != nil {
 		t.Errorf("expect %v, got %v", nil, err)
 	}
@@ -163,7 +161,7 @@ func TestProtoEncodeDecode(t *testing.T) {
 func TestDecodeStructPb(t *testing.T) {
 	req := new(ectest.StructPb)
 	query := `data={"name":"kratos"}&data_list={"name1": "kratos"}&data_list={"name2": "go-kratos"}`
-	if err := encoding.GetCodec(contentType).Unmarshal([]byte(query), req); err != nil {
+	if err := encoding.GetCodec(Name).Unmarshal([]byte(query), req); err != nil {
 		t.Errorf("expect %v, got %v", nil, err)
 	}
 	if !reflect.DeepEqual("kratos", req.Data.GetFields()["name"].GetStringValue()) {
@@ -186,7 +184,7 @@ func TestDecodeBytesValuePb(t *testing.T) {
 	val := base64.URLEncoding.EncodeToString([]byte(url))
 	content := "bytes=" + val
 	in2 := &complex.Complex{}
-	if err := encoding.GetCodec(contentType).Unmarshal([]byte(content), in2); err != nil {
+	if err := encoding.GetCodec(Name).Unmarshal([]byte(content), in2); err != nil {
 		t.Errorf("expect %v, got %v", nil, err)
 	}
 	if !reflect.DeepEqual(url, string(in2.Bytes.Value)) {
diff --git a/encoding/form/proto_decode_test.go b/encoding/form/proto_decode_test.go
new file mode 100644
index 00000000..fbe23433
--- /dev/null
+++ b/encoding/form/proto_decode_test.go
@@ -0,0 +1,217 @@
+package form
+
+import (
+	"fmt"
+	"net/url"
+	"reflect"
+	"strconv"
+	"testing"
+
+	"google.golang.org/protobuf/reflect/protoreflect"
+
+	"github.com/go-kratos/kratos/v2/internal/testdata/complex"
+)
+
+func TestDecodeValues(t *testing.T) {
+	form, err := url.ParseQuery("a=19&age=18&b=true&bool=false&byte=MTIz&bytes=MTIz&count=3&d=22.22&double=12.33&duration=" +
+		"2m0.000000022s&field=1%2C2&float=12.34&id=2233&int32=32&int64=64&numberOne=2233&price=11.23&sex=woman&simples=3344&" +
+		"simples=5566&string=go-kratos&timestamp=1970-01-01T00%3A00%3A20.000000002Z&uint32=32&uint64=64&very_simple.component=5566")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	comp := &complex.Complex{}
+	err = DecodeValues(comp, form)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if comp.Id != int64(2233) {
+		t.Errorf("want %v, got %v", int64(2233), comp.Id)
+	}
+	if comp.NoOne != "2233" {
+		t.Errorf("want %v, got %v", "2233", comp.NoOne)
+	}
+	if comp.Simple == nil {
+		t.Fatalf("want %v, got %v", nil, comp.Simple)
+	}
+	if comp.Simple.Component != "5566" {
+		t.Errorf("want %v, got %v", "5566", comp.Simple.Component)
+	}
+	if len(comp.Simples) != 2 {
+		t.Fatalf("want %v, got %v", 2, len(comp.Simples))
+	}
+	if comp.Simples[0] != "3344" {
+		t.Errorf("want %v, got %v", "3344", comp.Simples[0])
+	}
+	if comp.Simples[1] != "5566" {
+		t.Errorf("want %v, got %v", "5566", comp.Simples[1])
+	}
+}
+
+func TestGetFieldDescriptor(t *testing.T) {
+	comp := &complex.Complex{}
+
+	field := getFieldDescriptor(comp.ProtoReflect(), "id")
+	if field.Kind() != protoreflect.Int64Kind {
+		t.Errorf("want: %d, got: %d", protoreflect.Int64Kind, field.Kind())
+	}
+
+	field = getFieldDescriptor(comp.ProtoReflect(), "simples")
+	if field.Kind() != protoreflect.StringKind {
+		t.Errorf("want: %d, got: %d", protoreflect.StringKind, field.Kind())
+	}
+}
+
+func TestPopulateRepeatedField(t *testing.T) {
+	query, err := url.ParseQuery("simples=3344&simples=5566")
+	if err != nil {
+		t.Fatal(err)
+	}
+	comp := &complex.Complex{}
+	field := getFieldDescriptor(comp.ProtoReflect(), "simples")
+
+	err = populateRepeatedField(field, comp.ProtoReflect().Mutable(field).List(), query["simples"])
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !reflect.DeepEqual([]string{"3344", "5566"}, comp.GetSimples()) {
+		t.Errorf("want: %v, got: %v", []string{"3344", "5566"}, comp.GetSimples())
+	}
+}
+
+func TestPopulateMapField(t *testing.T) {
+	query, err := url.ParseQuery("map%5Bkratos%5D=https://go-kratos.dev/")
+	if err != nil {
+		t.Fatal(err)
+	}
+	comp := &complex.Complex{}
+	field := getFieldDescriptor(comp.ProtoReflect(), "map")
+	// Fill the comp map field with the url query values
+	err = populateMapField(field, comp.ProtoReflect().Mutable(field).Map(), []string{"kratos"}, query["map[kratos]"])
+	if err != nil {
+		t.Fatal(err)
+	}
+	// Get the comp map field value
+	if query["map[kratos]"][0] != comp.Map["kratos"] {
+		t.Errorf("want: %s, got: %s", query["map[kratos]"], comp.Map["kratos"])
+	}
+}
+
+func TestParseField(t *testing.T) {
+	tests := []struct {
+		name                    string
+		fieldName               string
+		protoReflectKind        protoreflect.Kind
+		value                   string
+		targetProtoReflectValue protoreflect.Value
+		targetErr               error
+	}{
+		{
+			name:                    "BoolKind",
+			fieldName:               "b",
+			protoReflectKind:        protoreflect.BoolKind,
+			value:                   "true",
+			targetProtoReflectValue: protoreflect.ValueOfBool(true),
+			targetErr:               nil,
+		},
+		{
+			name:                    "BoolKind",
+			fieldName:               "b",
+			protoReflectKind:        protoreflect.BoolKind,
+			value:                   "a",
+			targetProtoReflectValue: protoreflect.Value{},
+			targetErr:               &strconv.NumError{Func: "ParseBool", Num: "a", Err: strconv.ErrSyntax},
+		},
+		{
+			name:                    "EnumKind",
+			fieldName:               "sex",
+			protoReflectKind:        protoreflect.EnumKind,
+			value:                   "1",
+			targetProtoReflectValue: protoreflect.ValueOfEnum(1),
+			targetErr:               nil,
+		},
+		{
+			name:                    "EnumKind",
+			fieldName:               "sex",
+			protoReflectKind:        protoreflect.EnumKind,
+			value:                   "2",
+			targetProtoReflectValue: protoreflect.Value{},
+			targetErr:               fmt.Errorf("%q is not a valid value", "2"),
+		},
+	}
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			comp := &complex.Complex{}
+			field := getFieldDescriptor(comp.ProtoReflect(), test.fieldName)
+			if test.protoReflectKind != field.Kind() {
+				t.Fatalf("want: %d, got: %d", test.protoReflectKind, field.Kind())
+			}
+			val, err := parseField(field, test.value)
+			if !reflect.DeepEqual(test.targetErr, err) {
+				t.Fatalf("want: %s, got: %s", test.targetErr, err)
+			}
+			if !reflect.DeepEqual(test.targetProtoReflectValue, val) {
+				t.Errorf("want: %s, got: %s", test.targetProtoReflectValue, val)
+			}
+		})
+	}
+}
+
+func TestJsonSnakeCase(t *testing.T) {
+	tests := []struct {
+		camelCase string
+		snakeCase string
+	}{
+		{
+			"userId", "user_id",
+		},
+		{
+			"user", "user",
+		},
+		{
+			"userIdAndUsername", "user_id_and_username",
+		},
+		{
+			"", "",
+		},
+	}
+	for _, test := range tests {
+		t.Run(test.camelCase, func(t *testing.T) {
+			snake := jsonSnakeCase(test.camelCase)
+			if snake != test.snakeCase {
+				t.Errorf("want: %s, got: %s", test.snakeCase, snake)
+			}
+		})
+	}
+}
+
+func TestIsASCIIUpper(t *testing.T) {
+	tests := []struct {
+		b     byte
+		upper bool
+	}{
+		{
+			'A', true,
+		},
+		{
+			'a', false,
+		},
+		{
+			',', false,
+		},
+		{
+			'1', false,
+		},
+		{
+			' ', false,
+		},
+	}
+	for _, test := range tests {
+		t.Run(string(test.b), func(t *testing.T) {
+			upper := isASCIIUpper(test.b)
+			if test.upper != upper {
+				t.Errorf("'%s' is not ascii upper", string(test.b))
+			}
+		})
+	}
+}