Handle platforms where off_t is not convertible to size_t
[folly.git] / folly / FBString.h
index 541baa0ff9949f58b6b938420d80f05c0b442fe0..02e4d276464ffc3c68971e3fd7c3e3b5299105e5 100644 (file)
 #endif
 #endif
 
+#include <atomic>
+#include <limits>
+#include <type_traits>
+
+// libc++ doesn't provide this header
+#ifndef _LIBCPP_VERSION
 // This file appears in two locations: inside fbcode and in the
 // libstdc++ source code (when embedding fbstring as std::string).
 // To aid in this schizophrenic use, two macros are defined in
@@ -65,6 +71,7 @@
 //   _LIBSTDCXX_FBSTRING - Set inside libstdc++.  This is useful to
 //      gate use inside fbcode v. libstdc++
 #include <bits/c++config.h>
+#endif
 
 #ifdef _LIBSTDCXX_FBSTRING
 
 #define FBSTRING_LIKELY(x)   (__builtin_expect((x), 1))
 #define FBSTRING_UNLIKELY(x) (__builtin_expect((x), 0))
 
-#include <atomic>
-#include <limits>
-#include <type_traits>
-
 // Ignore shadowing warnings within this file, so includers can use -Wshadow.
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wshadow"
@@ -1794,7 +1797,9 @@ public:
                  const size_type nsize) const {
     if (!nsize) return pos;
     auto const size = this->size();
-    if (nsize + pos > size) return npos;
+    // 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;
     // Don't use std::search, use a Boyer-Moore-like trick by comparing
     // the last characters first
     auto const haystack = data();
@@ -2307,7 +2312,7 @@ operator<<(
   std::basic_ostream<typename basic_fbstring<E, T, A, S>::value_type,
   typename basic_fbstring<E, T, A, S>::traits_type>& os,
     const basic_fbstring<E, T, A, S>& str) {
-  os.write(str.data(), str.size());
+  std::__ostream_insert(os, str.data(), str.size());
   return os;
 }