From: Stella Lau Date: Thu, 17 Aug 2017 23:34:56 +0000 (-0700) Subject: Fix undefined behavior when decoding varint X-Git-Tag: v2017.08.21.00~5 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=322158b3359d2147aa81d914f31907712ec38973;p=folly.git Fix undefined behavior when decoding varint Summary: Left shifting `0x7f` by `63` is undefined behavior (i.e. when decoding `0xFFFF...`) Reviewed By: yfeldblum, terrelln Differential Revision: D5653353 fbshipit-source-id: c74c9f43a9bc82d15a2223df853dc533cea1478b --- diff --git a/folly/Varint.h b/folly/Varint.h index cd44d267..2f53dcf1 100644 --- a/folly/Varint.h +++ b/folly/Varint.h @@ -145,7 +145,7 @@ inline Expected tryDecodeVarint(Range& data) { b = *p++; val |= (b & 0x7f) << 42; if (b >= 0) break; b = *p++; val |= (b & 0x7f) << 49; if (b >= 0) break; b = *p++; val |= (b & 0x7f) << 56; if (b >= 0) break; - b = *p++; val |= (b & 0x7f) << 63; if (b >= 0) break; + b = *p++; val |= (b & 0x01) << 63; if (b >= 0) break; return makeUnexpected(DecodeVarintError::TooManyBytes); } while (false); } else { diff --git a/folly/test/VarintTest.cpp b/folly/test/VarintTest.cpp index 6f2b1bd0..b8799cd2 100644 --- a/folly/test/VarintTest.cpp +++ b/folly/test/VarintTest.cpp @@ -98,6 +98,17 @@ TEST(Varint, Simple) { {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01}); } +void testVarintFail(std::initializer_list bytes) { + size_t n = bytes.size(); + ByteRange data(&*bytes.begin(), n); + auto ret = tryDecodeVarint(data); + EXPECT_FALSE(ret.hasValue()); +} + +TEST(Varint, Fail) { + testVarintFail({0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}); +} + TEST(ZigZag, Simple) { EXPECT_EQ(0, encodeZigZag(0)); EXPECT_EQ(1, encodeZigZag(-1));