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 6c6de44e2d7768e1ae6fff642bb781ba82ffc0f0..0979f8836a04563cce31c7c9df3f6799ad1f69f0 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 54f64efedeeed9996d39fdb3245d1b0734a8167a..e4bfe89b6b5bfc6ce7618f979f330886c0ffcae4 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());
+}