mirror of
https://github.com/protocolbuffers/protobuf-go.git
synced 2025-02-01 00:32:37 +00:00
internal/impl: check for required fields in missing map value
If a map value is a message with required fields, the validator should note that it is uninitialized if a map item contains no value. In this case, the value is an empty message which obviously does not have the required field set. Change-Id: I7698e60765e3c95478f293e121bba3ad7fc88e27 Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/213900 Reviewed-by: Joe Tsai <joetsai@google.com>
This commit is contained in:
parent
b02b6d1da5
commit
54a0a0476a
@ -266,6 +266,7 @@ State:
|
|||||||
case 2:
|
case 2:
|
||||||
vi.typ = st.valType
|
vi.typ = st.valType
|
||||||
vi.mi = st.mi
|
vi.mi = st.mi
|
||||||
|
vi.requiredIndex = 1
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
var f *coderFieldInfo
|
var f *coderFieldInfo
|
||||||
@ -436,15 +437,23 @@ State:
|
|||||||
}
|
}
|
||||||
b = st.tail
|
b = st.tail
|
||||||
PopState:
|
PopState:
|
||||||
|
numRequiredFields := 0
|
||||||
switch st.typ {
|
switch st.typ {
|
||||||
case validationTypeMessage, validationTypeGroup:
|
case validationTypeMessage, validationTypeGroup:
|
||||||
// If there are more than 64 required fields, this check will
|
numRequiredFields = int(st.mi.numRequiredFields)
|
||||||
// always fail and we will report that the message is potentially
|
case validationTypeMap:
|
||||||
// uninitialized.
|
// If this is a map field with a message value that contains
|
||||||
if st.mi.numRequiredFields > 0 && bits.OnesCount64(st.requiredMask) != int(st.mi.numRequiredFields) {
|
// required fields, require that the value be present.
|
||||||
initialized = false
|
if st.mi != nil && st.mi.numRequiredFields > 0 {
|
||||||
|
numRequiredFields = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// If there are more than 64 required fields, this check will
|
||||||
|
// always fail and we will report that the message is potentially
|
||||||
|
// uninitialized.
|
||||||
|
if numRequiredFields > 0 && bits.OnesCount64(st.requiredMask) != numRequiredFields {
|
||||||
|
initialized = false
|
||||||
|
}
|
||||||
states = states[:len(states)-1]
|
states = states[:len(states)-1]
|
||||||
}
|
}
|
||||||
if !initialized {
|
if !initialized {
|
||||||
|
@ -1270,6 +1270,20 @@ var testValidMessages = []testProto{
|
|||||||
}),
|
}),
|
||||||
}.Marshal(),
|
}.Marshal(),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
desc: "required field in absent map message value",
|
||||||
|
partial: true,
|
||||||
|
decodeTo: []proto.Message{&testpb.TestRequiredForeign{
|
||||||
|
MapMessage: map[int32]*testpb.TestRequired{
|
||||||
|
2: {},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
wire: pack.Message{
|
||||||
|
pack.Tag{3, pack.BytesType}, pack.LengthPrefix(pack.Message{
|
||||||
|
pack.Tag{1, pack.VarintType}, pack.Varint(2),
|
||||||
|
}),
|
||||||
|
}.Marshal(),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
desc: "required field in map message set",
|
desc: "required field in map message set",
|
||||||
decodeTo: []proto.Message{&testpb.TestRequiredForeign{
|
decodeTo: []proto.Message{&testpb.TestRequiredForeign{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user