aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/wire_format_lite.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/google/protobuf/wire_format_lite.h')
-rw-r--r--src/google/protobuf/wire_format_lite.h13
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