Bladeren bron

Fix encoding and sizing of empty byte slices in proto3 maps.

Empty byte slices were being skipped, since that's the correct
behaviour when it is a standalone bytes field, but it's the
wrong behaviour when it is the value of a map field,
which should always have its key and value encoded.

Fixes #20.
David Symonds 11 jaren geleden
bovenliggende
commit
889ae49d31
3 gewijzigde bestanden met toevoegingen van 12 en 1 verwijderingen
  1. 6 1
      proto/properties.go
  2. 4 0
      proto/proto3_proto/proto3.proto
  3. 2 0
      proto/size_test.go

+ 6 - 1
proto/properties.go

@@ -440,7 +440,12 @@ func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lock
 			p.enc = (*Buffer).enc_slice_byte
 			p.dec = (*Buffer).dec_slice_byte
 			p.size = size_slice_byte
-			if p.proto3 {
+			// This is a []byte, which is either a bytes field,
+			// or the value of a map field. In the latter case,
+			// we always encode an empty []byte, so we should not
+			// use the proto3 enc/size funcs.
+			// f == nil iff this is the key/value of a map field.
+			if p.proto3 && f != nil {
 				p.enc = (*Buffer).enc_proto3_slice_byte
 				p.size = size_proto3_slice_byte
 			}

+ 4 - 0
proto/proto3_proto/proto3.proto

@@ -62,3 +62,7 @@ message Message {
 message Nested {
   string bunny = 1;
 }
+
+message MessageWithMap {
+  map<bool, bytes> byte_mapping = 1;
+}

+ 2 - 0
proto/size_test.go

@@ -113,10 +113,12 @@ var SizeTests = []struct {
 	{"proto3 bytes", &proto3pb.Message{Data: []byte("wowsa")}},
 	{"proto3 bytes, empty", &proto3pb.Message{Data: []byte{}}},
 	{"proto3 enum", &proto3pb.Message{Hilarity: proto3pb.Message_PUNS}},
+	{"proto3 map field with empty bytes", &proto3pb.MessageWithMap{ByteMapping: map[bool][]byte{false: []byte{}}}},
 
 	{"map field", &pb.MessageWithMap{NameMapping: map[int32]string{1: "Rob", 7: "Andrew"}}},
 	{"map field with message", &pb.MessageWithMap{MsgMapping: map[int64]*pb.FloatingPoint{0x7001: &pb.FloatingPoint{F: Float64(2.0)}}}},
 	{"map field with bytes", &pb.MessageWithMap{ByteMapping: map[bool][]byte{true: []byte("this time for sure")}}},
+	{"map field with empty bytes", &pb.MessageWithMap{ByteMapping: map[bool][]byte{true: []byte{}}}},
 }
 
 func TestSize(t *testing.T) {