MarshalerUtil.sizeThing(...) and Serializer.serializeThing(...) methods operate in pairs, such that the former can be used to predict the number of bytes used by the latter.
However, the MarshalerUtil.sizeRepeatedString(...) method is inconsistent with output.serializeRepeatedString(...) in the case where an array containing a zero length string is encoded.
The encoding of a zero length String as a single element is zero length (i.e. elided), but when encoded as an element of an array (i.e. 'repeated bytes' protobuf field) it's non-zero length, as space on the wire must still be used for the tag to denote the unoccupied location in the array, otherwise subsequent element's array indexes become offset when decoded.
As a result of this, the actual payload to be transmitted will be larger than estimated, which breaks grpc http transport transmissions because the http content-length header uses the estimate rather than the (streamed, so not available at header write time) actual encoded size.
MarshalerUtil.sizeThing(...) and Serializer.serializeThing(...) methods operate in pairs, such that the former can be used to predict the number of bytes used by the latter.
However, the MarshalerUtil.sizeRepeatedString(...) method is inconsistent with output.serializeRepeatedString(...) in the case where an array containing a zero length string is encoded.
The encoding of a zero length String as a single element is zero length (i.e. elided), but when encoded as an element of an array (i.e. 'repeated bytes' protobuf field) it's non-zero length, as space on the wire must still be used for the tag to denote the unoccupied location in the array, otherwise subsequent element's array indexes become offset when decoded.
As a result of this, the actual payload to be transmitted will be larger than estimated, which breaks grpc http transport transmissions because the http content-length header uses the estimate rather than the (streamed, so not available at header write time) actual encoded size.