folly: fbvector: ubsan: avoid memset(nullptr, 0, 0)
authorNathan Bronson <ngbronson@fb.com>
Wed, 16 Nov 2016 22:01:49 +0000 (14:01 -0800)
committerFacebook Github Bot <facebook-github-bot-bot@fb.com>
Wed, 16 Nov 2016 22:08:48 +0000 (14:08 -0800)
Summary:
Constructing an empty FBVector by length results in a call to
memset with a null destination, which is undefined behavior.  This diff
fixes it.

Reviewed By: luciang, meyering, Gownta

Differential Revision: D4191612

fbshipit-source-id: 3dcc091396fc33ac2230bd2d90906325131b0a3b

folly/FBVector.h
folly/test/FBVectorTest.cpp

index 6c6de44..0979f88 100644 (file)
@@ -430,7 +430,9 @@ private:
   // optimized
   static void S_uninitialized_fill_n(T* dest, size_type n) {
     if (folly::IsZeroInitializable<T>::value) {
-      std::memset(dest, 0, sizeof(T) * n);
+      if (LIKELY(n != 0)) {
+        std::memset(dest, 0, sizeof(T) * n);
+      }
     } else {
       auto b = dest;
       auto e = dest + n;
index 54f64ef..e4bfe89 100644 (file)
@@ -268,3 +268,17 @@ TEST(FBVector, shrink_to_fit_after_clear) {
   EXPECT_EQ(fb1.size(), 0);
   EXPECT_EQ(fb1.capacity(), 0);
 }
+
+TEST(FBVector, zero_len) {
+  fbvector<int> fb1(0);
+  fbvector<int> fb2(0, 10);
+  fbvector<int> fb3(std::move(fb1));
+  fbvector<int> fb4;
+  fb4 = std::move(fb2);
+  fbvector<int> fb5 = fb3;
+  fbvector<int> fb6;
+  fb6 = fb4;
+  std::initializer_list<int> il = {};
+  fb6 = il;
+  fbvector<int> fb7(fb6.begin(), fb6.end());
+}