Revert all changes to strutil.{h,cc} from this PR
diff --git a/src/google/protobuf/stubs/strutil.cc b/src/google/protobuf/stubs/strutil.cc
index fe2b07b..594c8ea 100644
--- a/src/google/protobuf/stubs/strutil.cc
+++ b/src/google/protobuf/stubs/strutil.cc
@@ -43,8 +43,6 @@
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/stl_util.h>
 
-#undef StringReplace
-
 #ifdef _WIN32
 // MSVC has only _snprintf, not snprintf.
 //
@@ -131,15 +129,11 @@
 //    it only replaces the first instance of "old."
 // ----------------------------------------------------------------------
 
-#define DONOTCHECKIN_GOOGLE_DCHECK_NO_OVERLAP(dest, src) \
-    GOOGLE_DCHECK_GT(uintptr_t((src).data() - (dest).data()), \
-                     uintptr_t((dest).size()))
-
-void StringReplace(StringPiece s, StringPiece oldsub, StringPiece newsub,
-                   bool replace_all, std::string *res, const char *filename, int linenum) {
+void StringReplace(const std::string &s, const std::string &oldsub,
+                   const std::string &newsub, bool replace_all,
+                   std::string *res) {
   if (oldsub.empty()) {
-    DONOTCHECKIN_GOOGLE_DCHECK_NO_OVERLAP(*res, s);
-    StrAppend(res, s);  // if empty, append the given string.
+    res->append(s);  // if empty, append the given string.
     return;
   }
 
@@ -150,15 +144,11 @@
     if (pos == std::string::npos) {
       break;
     }
-    DONOTCHECKIN_GOOGLE_DCHECK_NO_OVERLAP(*res, s);
-    StrAppend(res, s.substr(start_pos, pos - start_pos));
-    DONOTCHECKIN_GOOGLE_DCHECK_NO_OVERLAP(*res, newsub);
-    StrAppend(res, newsub);
+    res->append(s, start_pos, pos - start_pos);
+    res->append(newsub);
     start_pos = pos + oldsub.size();  // start searching again after the "old"
   } while (replace_all);
-  DONOTCHECKIN_GOOGLE_DCHECK_NO_OVERLAP(*res, s)
-      << " file=" << (filename ? filename : "") << " line=" << linenum;
-  StrAppend(res, s.substr(start_pos, s.length() - start_pos));
+  res->append(s, start_pos, s.length() - start_pos);
 }
 
 // ----------------------------------------------------------------------
@@ -170,10 +160,10 @@
 //    happened or not.
 // ----------------------------------------------------------------------
 
-std::string StringReplaceImpl(StringPiece s, StringPiece oldsub, StringPiece newsub,
-                          bool replace_all, const char *filename, int linenum) {
+std::string StringReplace(const std::string &s, const std::string &oldsub,
+                          const std::string &newsub, bool replace_all) {
   std::string ret;
-  StringReplace(s, oldsub, newsub, replace_all, &ret, filename, linenum);
+  StringReplace(s, oldsub, newsub, replace_all, &ret);
   return ret;
 }
 
@@ -455,24 +445,22 @@
 //    In the first and second calls, the length of dest is returned. In the
 //    the third call, the new string is returned.
 // ----------------------------------------------------------------------
-int UnescapeCEscapeString(StringPiece src, std::string *dest) {
+int UnescapeCEscapeString(const std::string &src, std::string *dest) {
   return UnescapeCEscapeString(src, dest, nullptr);
 }
 
-int UnescapeCEscapeString(StringPiece src, std::string *dest,
+int UnescapeCEscapeString(const std::string &src, std::string *dest,
                           std::vector<std::string> *errors) {
   std::unique_ptr<char[]> unescaped(new char[src.size() + 1]);
-  int len = UnescapeCEscapeSequences(std::string(src).c_str(), unescaped.get(),
-                                     errors);
+  int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), errors);
   GOOGLE_CHECK(dest);
   dest->assign(unescaped.get(), len);
   return len;
 }
 
-std::string UnescapeCEscapeString(StringPiece src) {
+std::string UnescapeCEscapeString(const std::string &src) {
   std::unique_ptr<char[]> unescaped(new char[src.size() + 1]);
-  int len = UnescapeCEscapeSequences(std::string(src).c_str(), unescaped.get(),
-                                     nullptr);
+  int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), nullptr);
   return std::string(unescaped.get(), len);
 }
 
@@ -513,11 +501,9 @@
         if ((!utf8_safe || static_cast<uint8_t>(*src) < 0x80) &&
             (!isprint(*src) ||
              (last_hex_escape && isxdigit(*src)))) {
-          // need space for 4 letter escape and the trailing '\0' to
-          // be written by snprintf.
-          if (dest_len - used < 5)
+          if (dest_len - used < 4) // need space for 4 letter escape
             return -1;
-          snprintf(dest + used, 5, (use_hex ? "\\x%02x" : "\\%03o"),
+          sprintf(dest + used, (use_hex ? "\\x%02x" : "\\%03o"),
                   static_cast<uint8_t>(*src));
           is_hex_escape = use_hex;
           used += 4;
@@ -606,7 +592,7 @@
   }
 }
 
-std::string CEscape(StringPiece src) {
+std::string CEscape(const std::string &src) {
   std::string dest;
   CEscapeAndAppend(src, &dest);
   return dest;
@@ -614,7 +600,7 @@
 
 namespace strings {
 
-std::string Utf8SafeCEscape(StringPiece src) {
+std::string Utf8SafeCEscape(const std::string &src) {
   const int dest_length = src.size() * 4 + 1; // Maximum possible expansion
   std::unique_ptr<char[]> dest(new char[dest_length]);
   const int len = CEscapeInternal(src.data(), src.size(),
@@ -623,7 +609,7 @@
   return std::string(dest.get(), len);
 }
 
-std::string CHexEscape(StringPiece src) {
+std::string CHexEscape(const std::string &src) {
   const int dest_length = src.size() * 4 + 1; // Maximum possible expansion
   std::unique_ptr<char[]> dest(new char[dest_length]);
   const int len = CEscapeInternal(src.data(), src.size(),
@@ -677,7 +663,7 @@
   return static_cast<uint32_t>(result);
 }
 
-inline bool safe_parse_sign(StringPiece *text /*inout*/,
+inline bool safe_parse_sign(std::string *text /*inout*/,
                             bool *negative_ptr /*output*/) {
   const char* start = text->data();
   const char* end = start + text->size();
@@ -706,7 +692,7 @@
 }
 
 template <typename IntType>
-bool safe_parse_positive_int(StringPiece text, IntType *value_p) {
+bool safe_parse_positive_int(std::string text, IntType *value_p) {
   int base = 10;
   IntType value = 0;
   const IntType vmax = std::numeric_limits<IntType>::max();
@@ -739,7 +725,7 @@
 }
 
 template <typename IntType>
-bool safe_parse_negative_int(StringPiece text, IntType *value_p) {
+bool safe_parse_negative_int(const std::string &text, IntType *value_p) {
   int base = 10;
   IntType value = 0;
   const IntType vmin = std::numeric_limits<IntType>::min();
@@ -779,7 +765,7 @@
 }
 
 template <typename IntType>
-bool safe_int_internal(StringPiece text, IntType *value_p) {
+bool safe_int_internal(std::string text, IntType *value_p) {
   *value_p = 0;
   bool negative;
   if (!safe_parse_sign(&text, &negative)) {
@@ -793,7 +779,7 @@
 }
 
 template <typename IntType>
-bool safe_uint_internal(StringPiece text, IntType *value_p) {
+bool safe_uint_internal(std::string text, IntType *value_p) {
   *value_p = 0;
   bool negative;
   if (!safe_parse_sign(&text, &negative) || negative) {
@@ -1355,19 +1341,19 @@
   return *str != '\0' && *endptr == '\0';
 }
 
-bool safe_strto32(StringPiece str, int32_t *value) {
+bool safe_strto32(const std::string &str, int32_t *value) {
   return safe_int_internal(str, value);
 }
 
-bool safe_strtou32(StringPiece str, uint32_t *value) {
+bool safe_strtou32(const std::string &str, uint32_t *value) {
   return safe_uint_internal(str, value);
 }
 
-bool safe_strto64(StringPiece str, int64_t *value) {
+bool safe_strto64(const std::string &str, int64_t *value) {
   return safe_int_internal(str, value);
 }
 
-bool safe_strtou64(StringPiece str, uint64_t *value) {
+bool safe_strtou64(const std::string &str, uint64_t *value) {
   return safe_uint_internal(str, value);
 }
 
@@ -1625,8 +1611,8 @@
   GOOGLE_DCHECK_EQ(out, begin + result->size());
 }
 
-int GlobalReplaceSubstring(StringPiece substring, StringPiece replacement,
-                           std::string *s) {
+int GlobalReplaceSubstring(const std::string &substring,
+                           const std::string &replacement, std::string *s) {
   GOOGLE_CHECK(s != nullptr);
   if (s->empty() || substring.empty())
     return 0;
@@ -2346,15 +2332,15 @@
 //       (1) determines the presence of LF (first one is ok)
 //       (2) if yes, removes any CR, else convert every CR to LF
 
-void CleanStringLineEndings(StringPiece src, std::string *dst,
+void CleanStringLineEndings(const std::string &src, std::string *dst,
                             bool auto_end_last_line) {
   if (dst->empty()) {
-    StrAppend(dst, src);
+    dst->append(src);
     CleanStringLineEndings(dst, auto_end_last_line);
   } else {
-    std::string tmp(src);
+    std::string tmp = src;
     CleanStringLineEndings(&tmp, auto_end_last_line);
-    StrAppend(dst, tmp);
+    dst->append(tmp);
   }
 }
 
diff --git a/src/google/protobuf/stubs/strutil.h b/src/google/protobuf/stubs/strutil.h
index 3eeb727..9658abf 100644
--- a/src/google/protobuf/stubs/strutil.h
+++ b/src/google/protobuf/stubs/strutil.h
@@ -118,11 +118,12 @@
          memcmp(str.data(), prefix.data(), prefix.size()) == 0;
 }
 
-inline std::string StripPrefixString(StringPiece str, StringPiece prefix) {
+inline std::string StripPrefixString(const std::string& str,
+                                     const std::string& prefix) {
   if (HasPrefixString(str, prefix)) {
-    return str.substr(prefix.size()).ToString();
+    return str.substr(prefix.size());
   } else {
-    return str.ToString();
+    return str;
   }
 }
 
@@ -140,11 +141,12 @@
                 suffix.size()) == 0;
 }
 
-inline std::string StripSuffixString(StringPiece str, StringPiece suffix) {
+inline std::string StripSuffixString(const std::string& str,
+                                     const std::string& suffix) {
   if (HasSuffixString(str, suffix)) {
-    return str.substr(0, str.size() - suffix.size()).ToString();
+    return str.substr(0, str.size() - suffix.size());
   } else {
-    return str.ToString();
+    return str;
   }
 }
 
@@ -190,8 +192,8 @@
 
 inline void ToUpper(std::string* s) { UpperString(s); }
 
-inline std::string ToUpper(StringPiece s) {
-  std::string out(s);
+inline std::string ToUpper(const std::string& s) {
+  std::string out = s;
   UpperString(&out);
   return out;
 }
@@ -204,9 +206,10 @@
 //    happened or not.
 // ----------------------------------------------------------------------
 
-PROTOBUF_EXPORT std::string StringReplaceImpl(StringPiece s, StringPiece oldsub,
-                                          StringPiece newsub, bool replace_all, const char *filename = nullptr, int linenum = 0);
-#define StringReplace(s,o,n,all) StringReplaceImpl(s,o,n,all,__FILE__, __LINE__)
+PROTOBUF_EXPORT std::string StringReplace(const std::string& s,
+                                          const std::string& oldsub,
+                                          const std::string& newsub,
+                                          bool replace_all);
 
 // ----------------------------------------------------------------------
 // SplitStringUsing()
@@ -311,10 +314,12 @@
 //    the third call, the new string is returned.
 // ----------------------------------------------------------------------
 
-PROTOBUF_EXPORT int UnescapeCEscapeString(StringPiece src, std::string* dest);
-PROTOBUF_EXPORT int UnescapeCEscapeString(StringPiece src, std::string* dest,
+PROTOBUF_EXPORT int UnescapeCEscapeString(const std::string& src,
+                                          std::string* dest);
+PROTOBUF_EXPORT int UnescapeCEscapeString(const std::string& src,
+                                          std::string* dest,
                                           std::vector<std::string>* errors);
-PROTOBUF_EXPORT std::string UnescapeCEscapeString(StringPiece src);
+PROTOBUF_EXPORT std::string UnescapeCEscapeString(const std::string& src);
 
 // ----------------------------------------------------------------------
 // CEscape()
@@ -323,7 +328,7 @@
 //
 //    Escaped chars: \n, \r, \t, ", ', \, and !isprint().
 // ----------------------------------------------------------------------
-PROTOBUF_EXPORT std::string CEscape(StringPiece src);
+PROTOBUF_EXPORT std::string CEscape(const std::string& src);
 
 // ----------------------------------------------------------------------
 // CEscapeAndAppend()
@@ -334,10 +339,10 @@
 
 namespace strings {
 // Like CEscape() but does not escape bytes with the upper bit set.
-PROTOBUF_EXPORT std::string Utf8SafeCEscape(StringPiece src);
+PROTOBUF_EXPORT std::string Utf8SafeCEscape(const std::string& src);
 
 // Like CEscape() but uses hex (\x) escapes instead of octals.
-PROTOBUF_EXPORT std::string CHexEscape(StringPiece src);
+PROTOBUF_EXPORT std::string CHexEscape(const std::string& src);
 }  // namespace strings
 
 // ----------------------------------------------------------------------
@@ -394,23 +399,35 @@
 // ----------------------------------------------------------------------
 PROTOBUF_EXPORT bool safe_strtob(StringPiece str, bool* value);
 
-PROTOBUF_EXPORT bool safe_strto32(StringPiece str, int32_t* value);
-PROTOBUF_EXPORT bool safe_strtou32(StringPiece str, uint32_t* value);
+PROTOBUF_EXPORT bool safe_strto32(const std::string& str, int32_t* value);
+PROTOBUF_EXPORT bool safe_strtou32(const std::string& str, uint32_t* value);
 inline bool safe_strto32(const char* str, int32_t* value) {
   return safe_strto32(std::string(str), value);
 }
+inline bool safe_strto32(StringPiece str, int32_t* value) {
+  return safe_strto32(str.ToString(), value);
+}
 inline bool safe_strtou32(const char* str, uint32_t* value) {
   return safe_strtou32(std::string(str), value);
 }
+inline bool safe_strtou32(StringPiece str, uint32_t* value) {
+  return safe_strtou32(str.ToString(), value);
+}
 
-PROTOBUF_EXPORT bool safe_strto64(StringPiece str, int64_t* value);
-PROTOBUF_EXPORT bool safe_strtou64(StringPiece str, uint64_t* value);
+PROTOBUF_EXPORT bool safe_strto64(const std::string& str, int64_t* value);
+PROTOBUF_EXPORT bool safe_strtou64(const std::string& str, uint64_t* value);
 inline bool safe_strto64(const char* str, int64_t* value) {
   return safe_strto64(std::string(str), value);
 }
+inline bool safe_strto64(StringPiece str, int64_t* value) {
+  return safe_strto64(str.ToString(), value);
+}
 inline bool safe_strtou64(const char* str, uint64_t* value) {
   return safe_strtou64(std::string(str), value);
 }
+inline bool safe_strtou64(StringPiece str, uint64_t* value) {
+  return safe_strtou64(str.ToString(), value);
+}
 
 PROTOBUF_EXPORT bool safe_strtof(const char* str, float* value);
 PROTOBUF_EXPORT bool safe_strtod(const char* str, double* value);
@@ -781,8 +798,8 @@
 //
 //    NOTE: The string pieces must not overlap s.
 // ----------------------------------------------------------------------
-PROTOBUF_EXPORT int GlobalReplaceSubstring(StringPiece substring,
-                                           StringPiece replacement,
+PROTOBUF_EXPORT int GlobalReplaceSubstring(const std::string& substring,
+                                           const std::string& replacement,
                                            std::string* s);
 
 // ----------------------------------------------------------------------
@@ -900,7 +917,8 @@
 //
 //       (1) determines the presence of LF (first one is ok)
 //       (2) if yes, removes any CR, else convert every CR to LF
-PROTOBUF_EXPORT void CleanStringLineEndings(StringPiece src, std::string* dst,
+PROTOBUF_EXPORT void CleanStringLineEndings(const std::string& src,
+                                            std::string* dst,
                                             bool auto_end_last_line);
 
 // Same as above, but transforms the argument in place.