Make strlcpy available in folly, second attempt
authorChip Turner <chip@fb.com>
Mon, 21 Sep 2015 20:42:50 +0000 (13:42 -0700)
committerfacebook-github-bot-1 <folly-bot@fb.com>
Mon, 21 Sep 2015 21:20:18 +0000 (14:20 -0700)
Summary: strncpy is bad.  strlcpy is somewhat less bad.  We already had
this function, but let's move it somewhere more reasonable.

This would make sense to live in String.h, but then we have circular
dependencies.  Since String.h includes Demangle.h, though, you get
strlcpy by including it, so this should be okay enough.

Reviewed By: @lbrandy

Differential Revision: D2097590

folly/Demangle.cpp
folly/Demangle.h
folly/test/DemangleTest.cpp

index ee587268fd8996c10bbbf91d215d9ffc19344244..54b46d277218529936f6d5a5c71e829cb0ab73f0 100644 (file)
@@ -55,21 +55,6 @@ extern "C" int cplus_demangle_v3_callback(
 
 #endif
 
-namespace {
-
-// glibc doesn't have strlcpy
-size_t my_strlcpy(char* dest, const char* src, size_t size) {
-  size_t len = strlen(src);
-  if (size != 0) {
-    size_t n = std::min(len, size - 1);  // always null terminate!
-    memcpy(dest, src, n);
-    dest[n] = '\0';
-  }
-  return len;
-}
-
-}  // namespace
-
 namespace folly {
 
 #if FOLLY_HAVE_CPLUS_DEMANGLE_V3_CALLBACK
@@ -106,6 +91,16 @@ void demangleCallback(const char* str, size_t size, void* p) {
 
 }  // namespace
 
+size_t strlcpy(char* dest, const char* const src, size_t size) {
+  size_t len = strlen(src);
+  if (size != 0) {
+    size_t n = std::min(len, size - 1);  // always null terminate!
+    memcpy(dest, src, n);
+    dest[n] = '\0';
+  }
+  return len;
+}
+
 size_t demangle(const char* name, char* out, size_t outSize) {
   DemangleBuf dbuf;
   dbuf.dest = out;
@@ -119,7 +114,7 @@ size_t demangle(const char* name, char* out, size_t outSize) {
       demangleCallback,
       &dbuf);
   if (status == 0) {  // failed, return original
-    return my_strlcpy(out, name, outSize);
+    return folly::strlcpy(out, name, outSize);
   }
   if (outSize != 0) {
     *dbuf.dest = '\0';
@@ -134,7 +129,7 @@ fbstring demangle(const char* name) {
 }
 
 size_t demangle(const char* name, char* out, size_t outSize) {
-  return my_strlcpy(out, name, outSize);
+  return folly::strlcpy(out, name, outSize);
 }
 
 #endif
index 1422e81799297c13f19379f5276a4349be6873c7..4b8b7001da2e8ce322577f52a5bcc430966732b5 100644 (file)
@@ -59,4 +59,7 @@ inline size_t demangle(const std::type_info& type, char* buf, size_t bufSize) {
   return demangle(type.name(), buf, bufSize);
 }
 
+// glibc doesn't have strlcpy
+size_t strlcpy(char* dest, const char* const src, size_t size);
+
 }
index eab9cff7cbbe6f0a37a20abde2fb341670ea1a67..0f235c887959c7923a4b2f6a1acfddfc4caf63ff 100644 (file)
@@ -48,6 +48,28 @@ TEST(Demangle, demangle) {
 }
 #endif
 
+TEST(Demangle, strlcpy) {
+  char buf[6];
+
+  EXPECT_EQ(3, folly::strlcpy(buf, "abc", 6));
+  EXPECT_EQ('\0', buf[3]);
+  EXPECT_EQ("abc", std::string(buf));
+
+  EXPECT_EQ(7, folly::strlcpy(buf, "abcdefg", 3));
+  EXPECT_EQ('\0', buf[2]);
+  EXPECT_EQ("ab", std::string(buf));
+
+  const char* big_string = "abcdefghijklmnop";
+
+  EXPECT_EQ(strlen(big_string), folly::strlcpy(buf, big_string, sizeof(buf)));
+  EXPECT_EQ('\0', buf[5]);
+  EXPECT_EQ("abcde", std::string(buf));
+
+  buf[0] = 'z';
+  EXPECT_EQ(strlen(big_string), folly::strlcpy(buf, big_string, 0));
+  EXPECT_EQ('z', buf[0]);  // unchanged, size = 0
+}
+
 int main(int argc, char *argv[]) {
   testing::InitGoogleTest(&argc, argv);
   gflags::ParseCommandLineFlags(&argc, &argv, true);