internal/impl: introduce instability to protoreflect.Message.Range order

Change-Id: I6f53aaf4071b4cbf596f3438a83cf3e5c93f1712
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/240017
Reviewed-by: Herbie Ong <herbie@google.com>
This commit is contained in:
Joe Tsai 2020-06-25 10:40:16 -07:00
parent a9513ebdb8
commit 1726b83dc4
2 changed files with 15 additions and 0 deletions

View File

@ -26,6 +26,14 @@ func Bool() bool {
return randSeed%2 == 1
}
// Intn returns a deterministically random integer between 0 and n-1, inclusive.
func Intn(n int) int {
if n <= 0 {
panic("must be positive")
}
return int(randSeed % uint64(n))
}
// randSeed is a best-effort at an approximate hash of the Go binary.
var randSeed = binaryHash()

View File

@ -8,6 +8,7 @@ import (
"fmt"
"reflect"
"google.golang.org/protobuf/internal/detrand"
"google.golang.org/protobuf/internal/pragma"
pref "google.golang.org/protobuf/reflect/protoreflect"
)
@ -92,6 +93,12 @@ func (mi *MessageInfo) makeKnownFieldsFunc(si structInfo) {
i++
}
}
// Introduce instability to iteration order, but keep it deterministic.
if len(mi.rangeInfos) > 1 && detrand.Bool() {
i := detrand.Intn(len(mi.rangeInfos) - 1)
mi.rangeInfos[i], mi.rangeInfos[i+1] = mi.rangeInfos[i+1], mi.rangeInfos[i]
}
}
func (mi *MessageInfo) makeUnknownFieldsFunc(t reflect.Type, si structInfo) {