From 9722033f9009b184b4c669cdc53e85e7567c482a Mon Sep 17 00:00:00 2001 From: Chip Turner Date: Mon, 21 Sep 2015 13:42:50 -0700 Subject: [PATCH] Make strlcpy available in folly, second attempt 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 | 29 ++++++++++++----------------- folly/Demangle.h | 3 +++ folly/test/DemangleTest.cpp | 22 ++++++++++++++++++++++ 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/folly/Demangle.cpp b/folly/Demangle.cpp index ee587268..54b46d27 100644 --- a/folly/Demangle.cpp +++ b/folly/Demangle.cpp @@ -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 diff --git a/folly/Demangle.h b/folly/Demangle.h index 1422e817..4b8b7001 100644 --- a/folly/Demangle.h +++ b/folly/Demangle.h @@ -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); + } diff --git a/folly/test/DemangleTest.cpp b/folly/test/DemangleTest.cpp index eab9cff7..0f235c88 100644 --- a/folly/test/DemangleTest.cpp +++ b/folly/test/DemangleTest.cpp @@ -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); -- 2.34.1