fix bug in FBString::find
authorPhilip Pronin <philipp@fb.com>
Wed, 10 Aug 2016 22:03:37 +0000 (15:03 -0700)
committerFacebook Github Bot 5 <facebook-github-bot-5-bot@fb.com>
Wed, 10 Aug 2016 22:08:37 +0000 (15:08 -0700)
Summary:
Standard (21.4.7.2 / 1):

> Determines the lowest position xpos, if possible, such that both of the following conditions obtain:
- pos <= xpos and xpos + str.size() <= size();
- traits::eq(at(xpos+I), str.at(I)) for all elements I of the string controlled
by str.

The existing logic violates the first requirement for `str.size() == 0` by
unconditionally returning `pos`.

Reviewed By: ot, Gownta

Differential Revision: D3698862

fbshipit-source-id: 9622f1b99b259d2d81ae83795dff9cd94619c725

folly/FBString.h
folly/test/FBStringTest.cpp

index b3ec8f43eff94d90987e1fefd3dc4e810dca4fd4..077d1be934c533c499585705c3a7bb5528afa979 100644 (file)
@@ -1768,11 +1768,12 @@ public:
 
   size_type find(const value_type* needle, const size_type pos,
                  const size_type nsize) const {
-    if (!nsize) return pos;
     auto const size = this->size();
     // nsize + pos can overflow (eg pos == npos), guard against that by checking
     // that nsize + pos does not wrap around.
     if (nsize + pos > size || nsize + pos < pos) return npos;
+
+    if (nsize == 0) return pos;
     // Don't use std::search, use a Boyer-Moore-like trick by comparing
     // the last characters first
     auto const haystack = data();
index 56b6ef0cb88f296620f5d323f214d3cd1b21abf2..c6945a1f2ee0656636bca1e10c9b96584b17df10 100644 (file)
@@ -1267,6 +1267,9 @@ TEST(FBString, testFixedBugs) {
     auto test2 = "a" + std::move(s2);
     EXPECT_EQ(2, test2.size());
   }
+  { // D3698862
+    EXPECT_EQ(fbstring().find(fbstring(), 4), fbstring::npos);
+  }
 }
 
 TEST(FBString, findWithNpos) {