Commit 9722033f authored by Chip Turner's avatar Chip Turner Committed by facebook-github-bot-1

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
parent be90fbfb
...@@ -55,21 +55,6 @@ extern "C" int cplus_demangle_v3_callback( ...@@ -55,21 +55,6 @@ extern "C" int cplus_demangle_v3_callback(
#endif #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 { namespace folly {
#if FOLLY_HAVE_CPLUS_DEMANGLE_V3_CALLBACK #if FOLLY_HAVE_CPLUS_DEMANGLE_V3_CALLBACK
...@@ -106,6 +91,16 @@ void demangleCallback(const char* str, size_t size, void* p) { ...@@ -106,6 +91,16 @@ void demangleCallback(const char* str, size_t size, void* p) {
} // namespace } // 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) { size_t demangle(const char* name, char* out, size_t outSize) {
DemangleBuf dbuf; DemangleBuf dbuf;
dbuf.dest = out; dbuf.dest = out;
...@@ -119,7 +114,7 @@ size_t demangle(const char* name, char* out, size_t outSize) { ...@@ -119,7 +114,7 @@ size_t demangle(const char* name, char* out, size_t outSize) {
demangleCallback, demangleCallback,
&dbuf); &dbuf);
if (status == 0) { // failed, return original if (status == 0) { // failed, return original
return my_strlcpy(out, name, outSize); return folly::strlcpy(out, name, outSize);
} }
if (outSize != 0) { if (outSize != 0) {
*dbuf.dest = '\0'; *dbuf.dest = '\0';
...@@ -134,7 +129,7 @@ fbstring demangle(const char* name) { ...@@ -134,7 +129,7 @@ fbstring demangle(const char* name) {
} }
size_t demangle(const char* name, char* out, size_t outSize) { size_t demangle(const char* name, char* out, size_t outSize) {
return my_strlcpy(out, name, outSize); return folly::strlcpy(out, name, outSize);
} }
#endif #endif
......
...@@ -59,4 +59,7 @@ inline size_t demangle(const std::type_info& type, char* buf, size_t bufSize) { ...@@ -59,4 +59,7 @@ inline size_t demangle(const std::type_info& type, char* buf, size_t bufSize) {
return demangle(type.name(), buf, bufSize); return demangle(type.name(), buf, bufSize);
} }
// glibc doesn't have strlcpy
size_t strlcpy(char* dest, const char* const src, size_t size);
} }
...@@ -48,6 +48,28 @@ TEST(Demangle, demangle) { ...@@ -48,6 +48,28 @@ TEST(Demangle, demangle) {
} }
#endif #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[]) { int main(int argc, char *argv[]) {
testing::InitGoogleTest(&argc, argv); testing::InitGoogleTest(&argc, argv);
gflags::ParseCommandLineFlags(&argc, &argv, true); gflags::ParseCommandLineFlags(&argc, &argv, true);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment