Forráskód Böngészése

internal/encoding/wire: increase maximum field number

The protobuf documentation explicitly specifies (1<<29)-1 as the maximum
field number, but the C++ implementation itself has a special-case where it
allows field numbers up to MaxInt32 for MessageSet fields, but continues
to apply the former limit in all non-MessageSet cases.

To avoid complicated branching logic, we use the larger limit for all cases
if MessageSet is supported, otherwise, we impose the documented limit.

Change-Id: I710a2a21aa3beba161c3e6ca2f2ed9a266920a5a
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/175817
Reviewed-by: Damien Neil <dneil@google.com>
Joe Tsai 6 éve
szülő
commit
972d873b59
2 módosított fájl, 14 hozzáadás és 6 törlés
  1. 12 4
      internal/encoding/wire/wire.go
  2. 2 2
      internal/encoding/wire/wire_test.go

+ 12 - 4
internal/encoding/wire/wire.go

@@ -9,9 +9,11 @@ package wire
 
 import (
 	"io"
+	"math"
 	"math/bits"
 
 	"github.com/golang/protobuf/v2/internal/errors"
+	"github.com/golang/protobuf/v2/internal/flags"
 )
 
 // Number represents the field number.
@@ -479,11 +481,17 @@ func SizeGroup(num Number, n int) int {
 // The Number is -1 if the decoded field number overflows.
 // Other than overflow, this does not check for field number validity.
 func DecodeTag(x uint64) (Number, Type) {
-	num := Number(x >> 3)
-	if num > MaxValidNumber {
-		num = -1
+	// NOTE: MessageSet allows for larger field numbers than normal.
+	if flags.Proto1Legacy {
+		if x>>3 > uint64(math.MaxInt32) {
+			return -1, 0
+		}
+	} else {
+		if x>>3 > uint64(MaxValidNumber) {
+			return -1, 0
+		}
 	}
-	return num, Type(x & 7)
+	return Number(x >> 3), Type(x & 7)
 }
 
 // EncodeTag encodes the field Number and wire Type into its unified form.

+ 2 - 2
internal/encoding/wire/wire_test.go

@@ -136,8 +136,8 @@ func TestTag(t *testing.T) {
 		wantRaw:    dhex("f8ffffff0f"),
 		consumeOps: ops{consumeTag{wantNum: MaxValidNumber, wantType: VarintType, wantCnt: 5}},
 	}, {
-		appendOps:  ops{appendTag{inNum: MaxValidNumber + 1, inType: VarintType}},
-		wantRaw:    dhex("8080808010"),
+		appendOps:  ops{appendVarint{inVal: ((math.MaxInt32+1)<<3 | uint64(VarintType))}},
+		wantRaw:    dhex("8080808040"),
 		consumeOps: ops{consumeTag{wantErr: errFieldNumber}},
 	}})
 }