[compiler-rt] r253690 - [compiler-rt] Add internal implementations for strlcat and strlcpy
Anna Zaks via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 20 10:42:05 PST 2015
Author: zaks
Date: Fri Nov 20 12:42:05 2015
New Revision: 253690
URL: http://llvm.org/viewvc/llvm-project?rev=253690&view=rev
Log:
[compiler-rt] Add internal implementations for strlcat and strlcpy
The compiler-rt should make use of strlcpy() rather than strncpy(). Using internal_strncpy() may be fine with appropriate bounds checking or enforcement of nul-termination elsewhere, but it's just good practice these days to avoid using strncpy() in new code.
A patch by Jeremy Sequoia!
Differential Revision: http://reviews.llvm.org/D14714
Modified:
compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.h
compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_libc_test.cc
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.cc?rev=253690&r1=253689&r2=253690&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.cc Fri Nov 20 12:42:05 2015
@@ -175,6 +175,19 @@ uptr internal_strlen(const char *s) {
return i;
}
+uptr internal_strlcat(char *dst, const char *src, uptr maxlen) {
+ const uptr srclen = internal_strlen(src);
+ const uptr dstlen = internal_strnlen(dst, maxlen);
+ if (dstlen == maxlen) return maxlen + srclen;
+ if (srclen < maxlen - dstlen) {
+ internal_memmove(dst + dstlen, src, srclen + 1);
+ } else {
+ internal_memmove(dst + dstlen, src, maxlen - dstlen - 1);
+ dst[maxlen - 1] = '\0';
+ }
+ return dstlen + srclen;
+}
+
char *internal_strncat(char *dst, const char *src, uptr n) {
uptr len = internal_strlen(dst);
uptr i;
@@ -184,6 +197,17 @@ char *internal_strncat(char *dst, const
return dst;
}
+uptr internal_strlcpy(char *dst, const char *src, uptr maxlen) {
+ const uptr srclen = internal_strlen(src);
+ if (srclen < maxlen) {
+ internal_memmove(dst, src, srclen + 1);
+ } else if (maxlen != 0) {
+ internal_memmove(dst, src, maxlen - 1);
+ dst[maxlen - 1] = '\0';
+ }
+ return srclen;
+}
+
char *internal_strncpy(char *dst, const char *src, uptr n) {
uptr i;
for (i = 0; i < n && src[i]; i++)
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.h?rev=253690&r1=253689&r2=253690&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.h Fri Nov 20 12:42:05 2015
@@ -43,8 +43,10 @@ uptr internal_strcspn(const char *s, con
char *internal_strdup(const char *s);
char *internal_strndup(const char *s, uptr n);
uptr internal_strlen(const char *s);
+uptr internal_strlcat(char *dst, const char *src, uptr maxlen);
char *internal_strncat(char *dst, const char *src, uptr n);
int internal_strncmp(const char *s1, const char *s2, uptr n);
+uptr internal_strlcpy(char *dst, const char *src, uptr maxlen);
char *internal_strncpy(char *dst, const char *src, uptr n);
uptr internal_strnlen(const char *s, uptr maxlen);
char *internal_strrchr(const char *s, int c);
Modified: compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_libc_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_libc_test.cc?rev=253690&r1=253689&r2=253690&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_libc_test.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_libc_test.cc Fri Nov 20 12:42:05 2015
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
// Tests for sanitizer_libc.h.
//===----------------------------------------------------------------------===//
+#include <algorithm>
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_libc.h"
@@ -145,12 +146,65 @@ TEST(SanitizerCommon, FileOps) {
#endif
}
+static const size_t kStrlcpyBufSize = 8;
+void test_internal_strlcpy(char *dbuf, const char *sbuf) {
+ uptr retval = 0;
+ retval = internal_strlcpy(dbuf, sbuf, kStrlcpyBufSize);
+ EXPECT_EQ(internal_strncmp(dbuf, sbuf, kStrlcpyBufSize - 1), 0);
+ EXPECT_EQ(internal_strlen(dbuf),
+ std::min(internal_strlen(sbuf), (uptr)(kStrlcpyBufSize - 1)));
+ EXPECT_EQ(retval, internal_strlen(sbuf));
+
+ // Test with shorter maxlen.
+ uptr maxlen = 2;
+ if (internal_strlen(sbuf) > maxlen) {
+ retval = internal_strlcpy(dbuf, sbuf, maxlen);
+ EXPECT_EQ(internal_strncmp(dbuf, sbuf, maxlen - 1), 0);
+ EXPECT_EQ(internal_strlen(dbuf), maxlen - 1);
+ }
+}
+
TEST(SanitizerCommon, InternalStrFunctions) {
const char *haystack = "haystack";
EXPECT_EQ(haystack + 2, internal_strchr(haystack, 'y'));
EXPECT_EQ(haystack + 2, internal_strchrnul(haystack, 'y'));
EXPECT_EQ(0, internal_strchr(haystack, 'z'));
EXPECT_EQ(haystack + 8, internal_strchrnul(haystack, 'z'));
+
+ char dbuf[kStrlcpyBufSize] = {};
+ const char *samesizestr = "1234567";
+ const char *shortstr = "123";
+ const char *longerstr = "123456789";
+
+ // Test internal_strlcpy.
+ internal_strlcpy(dbuf, shortstr, 0);
+ EXPECT_EQ(dbuf[0], 0);
+ EXPECT_EQ(dbuf[0], 0);
+ test_internal_strlcpy(dbuf, samesizestr);
+ test_internal_strlcpy(dbuf, shortstr);
+ test_internal_strlcpy(dbuf, longerstr);
+
+ // Test internal_strlcat.
+ char dcatbuf[kStrlcpyBufSize] = {};
+ uptr retval = 0;
+ retval = internal_strlcat(dcatbuf, "aaa", 0);
+ EXPECT_EQ(internal_strlen(dcatbuf), (uptr)0);
+ EXPECT_EQ(retval, (uptr)3);
+
+ retval = internal_strlcat(dcatbuf, "123", kStrlcpyBufSize);
+ EXPECT_EQ(internal_strcmp(dcatbuf, "123"), 0);
+ EXPECT_EQ(internal_strlen(dcatbuf), (uptr)3);
+ EXPECT_EQ(retval, (uptr)3);
+
+ retval = internal_strlcat(dcatbuf, "123", kStrlcpyBufSize);
+ EXPECT_EQ(internal_strcmp(dcatbuf, "123123"), 0);
+ EXPECT_EQ(internal_strlen(dcatbuf), (uptr)6);
+ EXPECT_EQ(retval, (uptr)6);
+
+ retval = internal_strlcat(dcatbuf, "123", kStrlcpyBufSize);
+ EXPECT_EQ(internal_strcmp(dcatbuf, "1231231"), 0);
+ EXPECT_EQ(internal_strlen(dcatbuf), (uptr)7);
+ EXPECT_EQ(retval, (uptr)9);
}
// FIXME: File manipulations are not yet supported on Windows
More information about the llvm-commits
mailing list