Skip to content

Commit 42d4f47

Browse files
jhumpdsnet
authored andcommitted
jsonpb: skip unexported or non-protobuf fields (#510)
As mentioned in #509, jsonpb panics when marshaling/unmarshaling a non-generated message that has an unexported pointer field. This change will restore dynamic messages to working with jsonpb (they work fine in master; just broken in this dev branch as of #472).
1 parent 9a84eb8 commit 42d4f47

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

jsonpb/jsonpb.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1134,6 +1134,12 @@ func checkRequiredFields(pb proto.Message) error {
11341134
for i := 0; i < v.NumField(); i++ {
11351135
field := v.Field(i)
11361136
sfield := v.Type().Field(i)
1137+
1138+
if sfield.PkgPath != "" {
1139+
// blank PkgPath means the field is exported; skip if not exported
1140+
continue
1141+
}
1142+
11371143
if strings.HasPrefix(sfield.Name, "XXX_") {
11381144
continue
11391145
}
@@ -1156,8 +1162,12 @@ func checkRequiredFields(pb proto.Message) error {
11561162
sfield = v.Type().Field(0)
11571163
}
11581164

1165+
protoTag := sfield.Tag.Get("protobuf")
1166+
if protoTag == "" {
1167+
continue
1168+
}
11591169
var prop proto.Properties
1160-
prop.Init(sfield.Type, sfield.Name, sfield.Tag.Get("protobuf"), &sfield)
1170+
prop.Init(sfield.Type, sfield.Name, protoTag, &sfield)
11611171

11621172
switch field.Kind() {
11631173
case reflect.Map:

jsonpb/jsonpb_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,19 @@ func TestMarshalAnyJSONPBMarshaler(t *testing.T) {
533533
}
534534
}
535535

536+
func TestMarshalWithCustomValidation(t *testing.T) {
537+
msg := dynamicMessage{rawJson: `{ "foo": "bar", "baz": [0, 1, 2, 3] }`, dummy: &dynamicMessage{}}
538+
539+
js, err := new(Marshaler).MarshalToString(&msg)
540+
if err != nil {
541+
t.Errorf("an unexpected error occurred when marshalling to json: %v", err)
542+
}
543+
err = Unmarshal(strings.NewReader(js), &msg)
544+
if err != nil {
545+
t.Errorf("an unexpected error occurred when unmarshalling from json: %v", err)
546+
}
547+
}
548+
536549
// Test marshaling message containing unset required fields should produce error.
537550
func TestMarshalUnsetRequiredFields(t *testing.T) {
538551
msgExt := &pb.Real{}
@@ -1004,6 +1017,10 @@ func (s *stringField) UnmarshalJSONPB(jum *Unmarshaler, js []byte) error {
10041017
// It provides implementations of JSONPBMarshaler and JSONPBUnmarshaler for JSON support.
10051018
type dynamicMessage struct {
10061019
rawJson string `protobuf:"bytes,1,opt,name=rawJson"`
1020+
1021+
// an unexported nested message is present just to ensure that it
1022+
// won't result in a panic (see issue #509)
1023+
dummy *dynamicMessage `protobuf:"bytes,2,opt,name=dummy"`
10071024
}
10081025

10091026
func (m *dynamicMessage) Reset() {

0 commit comments

Comments
 (0)