Summary:
Avoid a clang-caught heap-buffer-overrun
and document that the ssse3 decoder requires at least 17 bytes
of readable memory starting at the source pointer.
* folly/GroupVarint.h (decode_simple): Comment out dead code.
(decode)[__SSSE3__]: Add a comment describing this limitation.
* folly/test/GroupVarintTest.cpp (testGroupVarint32):
Include <algorithm> for use of std::max.
Ensure that the buffer we use has length at least 17.
Test Plan:
Now, all tests succeed with clang/asan
Reviewed By: simpkins@fb.com
Subscribers: trunkagent, mathieubaudet, njormrod
FB internal diff:
D1579109
Tasks:
5241437
p += k2+1;
size_t k3 = b3key(k);
*d = loadUnaligned<uint32_t>(p) & kMask[k3];
- p += k3+1;
+ // p += k3+1;
return end;
}
}
#ifdef __SSSE3__
+ /**
+ * Just like the non-SSSE3 decode below, but with the additional constraint
+ * that we must be able to read at least 17 bytes from the input pointer, p.
+ */
static const char* decode(const char* p, uint32_t* dest) {
uint8_t key = p[0];
__m128i val = _mm_loadu_si128((const __m128i*)(p+1));
return p + detail::groupVarintLengths[key];
}
+ /**
+ * Just like decode_simple, but with the additional constraint that
+ * we must be able to read at least 17 bytes from the input pointer, p.
+ */
static const char* decode(const char* p, uint32_t* a, uint32_t* b,
uint32_t* c, uint32_t* d) {
uint8_t key = p[0];
*/
#include <stdarg.h>
+#include <algorithm>
#include <folly/GroupVarint.h>
// On platforms where it's not supported, GroupVarint will be compiled out.
EXPECT_EQ(expectedBytes.size(), size);
std::vector<char> foundBytes;
- foundBytes.resize(size + 4);
+
+ // ssse3 decoding requires that the source buffer have length >= 17,
+ // so that it can read 128 bits from &start[1] via _mm_loadu_si128.
+ foundBytes.resize(std::max(size + 4, 17UL));
char* start = &(foundBytes.front());
char* p = GroupVarint32::encode(start, a, b, c, d);
EXPECT_EQ((void*)(start + size), (void*)p);