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
#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
} // 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;
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';
}
size_t demangle(const char* name, char* out, size_t outSize) {
- return my_strlcpy(out, name, outSize);
+ return folly::strlcpy(out, name, outSize);
}
#endif
return demangle(type.name(), buf, bufSize);
}
+// glibc doesn't have strlcpy
+size_t strlcpy(char* dest, const char* const src, size_t size);
+
}
}
#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);