diff options
Diffstat (limited to 'src/google/protobuf/wire_format_lite.h')
-rw-r--r-- | src/google/protobuf/wire_format_lite.h | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/src/google/protobuf/wire_format_lite.h b/src/google/protobuf/wire_format_lite.h index 8a1540b7..cf614c02 100644 --- a/src/google/protobuf/wire_format_lite.h +++ b/src/google/protobuf/wire_format_lite.h @@ -336,7 +336,6 @@ class LIBPROTOBUF_EXPORT WireFormatLite { static bool ReadBytes(io::CodedInputStream* input, string* value); static bool ReadBytes(io::CodedInputStream* input, string** p); - enum Operation { PARSE = 0, SERIALIZE = 1, @@ -855,20 +854,24 @@ inline double WireFormatLite::DecodeDouble(uint64 value) { inline uint32 WireFormatLite::ZigZagEncode32(int32 n) { // Note: the right-shift must be arithmetic - return static_cast<uint32>((n << 1) ^ (n >> 31)); + // Note: left shift must be unsigned because of overflow + return (static_cast<uint32>(n) << 1) ^ static_cast<uint32>(n >> 31); } inline int32 WireFormatLite::ZigZagDecode32(uint32 n) { - return static_cast<int32>(n >> 1) ^ -static_cast<int32>(n & 1); + // Note: Using unsigned types prevent undefined behavior + return static_cast<int32>((n >> 1) ^ -(n & 1)); } inline uint64 WireFormatLite::ZigZagEncode64(int64 n) { // Note: the right-shift must be arithmetic - return static_cast<uint64>((n << 1) ^ (n >> 63)); + // Note: left shift must be unsigned because of overflow + return (static_cast<uint64>(n) << 1) ^ static_cast<uint64>(n >> 63); } inline int64 WireFormatLite::ZigZagDecode64(uint64 n) { - return static_cast<int64>(n >> 1) ^ -static_cast<int64>(n & 1); + // Note: Using unsigned types prevent undefined behavior + return static_cast<int64>((n >> 1) ^ -(n & 1)); } // String is for UTF-8 text only, but, even so, ReadString() can simply |