| 53 | }; |
| 54 | |
| 55 | void SerializeMessage(const MessageLite& message, faststring* param_buf, |
| 56 | int additional_size, bool use_cached_size) { |
| 57 | DCHECK_GE(additional_size, 0); |
| 58 | size_t pb_size = use_cached_size ? message.GetCachedSize() : message.ByteSizeLong(); |
| 59 | DCHECK_EQ(message.ByteSizeLong(), pb_size); |
| 60 | // Use 8-byte integers to avoid overflowing when additional_size approaches INT_MAX. |
| 61 | int64_t recorded_size = static_cast<int64_t>(pb_size) + |
| 62 | static_cast<int64_t>(additional_size); |
| 63 | int64_t size_with_delim = static_cast<int64_t>(pb_size) + |
| 64 | static_cast<int64_t>(CodedOutputStream::VarintSize32(recorded_size)); |
| 65 | int64_t total_size = size_with_delim + static_cast<int64_t>(additional_size); |
| 66 | // The message format relies on an unsigned 32-bit integer to express the size, so |
| 67 | // the message must not exceed this size. Since additional_size is limited to INT_MAX, |
| 68 | // this is a safe limitation. |
| 69 | CHECK_LE(total_size, std::numeric_limits<uint32_t>::max()); |
| 70 | |
| 71 | if (PREDICT_FALSE(total_size > FLAGS_rpc_max_message_size)) { |
| 72 | LOG(WARNING) << Substitute("Serialized $0 ($1 bytes) is larger than the maximum configured " |
| 73 | "RPC message size ($2 bytes). " |
| 74 | "Sending anyway, but peer may reject the data.", |
| 75 | message.GetTypeName(), total_size, FLAGS_rpc_max_message_size); |
| 76 | } |
| 77 | |
| 78 | param_buf->resize(size_with_delim); |
| 79 | uint8_t* dst = param_buf->data(); |
| 80 | dst = CodedOutputStream::WriteVarint32ToArray(recorded_size, dst); |
| 81 | dst = message.SerializeWithCachedSizesToArray(dst); |
| 82 | CHECK_EQ(dst, param_buf->data() + size_with_delim); |
| 83 | } |
| 84 | |
| 85 | void SerializeHeader(const MessageLite& header, |
| 86 | size_t param_len, |
no test coverage detected