forked from OSchip/llvm-project
[compiler-rt] change internal internal libc invariants
llvm-libc is expected to be built with sanitizers and not use interceptors in the long run. For now though, we have a hybrid process, where functions implemented in llvm-libc are instrumented, and glibc fills and sanitizer interceptors fill in the rest. Current sanitizers have an invariant that the REAL(...) function called from inside of an interceptor is uninstrumented. A lot of interceptors call strlen() in order to figure out the size of the region to check/poison. Switch these callsites over to the internal, unsanitized implementation. Reviewed By: hctim, vitalybuka Differential Revision: https://reviews.llvm.org/D108316
This commit is contained in:
parent
b232a88c6f
commit
40067b88c0
|
@ -49,8 +49,8 @@ namespace __asan {
|
|||
ASAN_READ_RANGE((ctx), (s), \
|
||||
common_flags()->strict_string_checks ? (len) + 1 : (n))
|
||||
|
||||
#define ASAN_READ_STRING(ctx, s, n) \
|
||||
ASAN_READ_STRING_OF_LEN((ctx), (s), REAL(strlen)(s), (n))
|
||||
# define ASAN_READ_STRING(ctx, s, n) \
|
||||
ASAN_READ_STRING_OF_LEN((ctx), (s), internal_strlen(s), (n))
|
||||
|
||||
static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) {
|
||||
#if SANITIZER_INTERCEPT_STRNLEN
|
||||
|
@ -370,9 +370,9 @@ DEFINE_REAL(char*, index, const char *string, int c)
|
|||
ASAN_INTERCEPTOR_ENTER(ctx, strcat);
|
||||
ENSURE_ASAN_INITED();
|
||||
if (flags()->replace_str) {
|
||||
uptr from_length = REAL(strlen)(from);
|
||||
uptr from_length = internal_strlen(from);
|
||||
ASAN_READ_RANGE(ctx, from, from_length + 1);
|
||||
uptr to_length = REAL(strlen)(to);
|
||||
uptr to_length = internal_strlen(to);
|
||||
ASAN_READ_STRING_OF_LEN(ctx, to, to_length, to_length);
|
||||
ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1);
|
||||
// If the copying actually happens, the |from| string should not overlap
|
||||
|
@ -394,7 +394,7 @@ INTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) {
|
|||
uptr from_length = MaybeRealStrnlen(from, size);
|
||||
uptr copy_length = Min(size, from_length + 1);
|
||||
ASAN_READ_RANGE(ctx, from, copy_length);
|
||||
uptr to_length = REAL(strlen)(to);
|
||||
uptr to_length = internal_strlen(to);
|
||||
ASAN_READ_STRING_OF_LEN(ctx, to, to_length, to_length);
|
||||
ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1);
|
||||
if (from_length > 0) {
|
||||
|
@ -419,7 +419,7 @@ INTERCEPTOR(char *, strcpy, char *to, const char *from) {
|
|||
}
|
||||
ENSURE_ASAN_INITED();
|
||||
if (flags()->replace_str) {
|
||||
uptr from_size = REAL(strlen)(from) + 1;
|
||||
uptr from_size = internal_strlen(from) + 1;
|
||||
CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size);
|
||||
ASAN_READ_RANGE(ctx, from, from_size);
|
||||
ASAN_WRITE_RANGE(ctx, to, from_size);
|
||||
|
@ -432,7 +432,7 @@ INTERCEPTOR(char*, strdup, const char *s) {
|
|||
ASAN_INTERCEPTOR_ENTER(ctx, strdup);
|
||||
if (UNLIKELY(!asan_inited)) return internal_strdup(s);
|
||||
ENSURE_ASAN_INITED();
|
||||
uptr length = REAL(strlen)(s);
|
||||
uptr length = internal_strlen(s);
|
||||
if (flags()->replace_str) {
|
||||
ASAN_READ_RANGE(ctx, s, length + 1);
|
||||
}
|
||||
|
@ -448,7 +448,7 @@ INTERCEPTOR(char*, __strdup, const char *s) {
|
|||
ASAN_INTERCEPTOR_ENTER(ctx, strdup);
|
||||
if (UNLIKELY(!asan_inited)) return internal_strdup(s);
|
||||
ENSURE_ASAN_INITED();
|
||||
uptr length = REAL(strlen)(s);
|
||||
uptr length = internal_strlen(s);
|
||||
if (flags()->replace_str) {
|
||||
ASAN_READ_RANGE(ctx, s, length + 1);
|
||||
}
|
||||
|
|
|
@ -204,9 +204,9 @@ INTERCEPTOR(char *, strcat, char *to, const char *from) {
|
|||
void *ctx;
|
||||
MEMPROF_INTERCEPTOR_ENTER(ctx, strcat);
|
||||
ENSURE_MEMPROF_INITED();
|
||||
uptr from_length = REAL(strlen)(from);
|
||||
uptr from_length = internal_strlen(from);
|
||||
MEMPROF_READ_RANGE(from, from_length + 1);
|
||||
uptr to_length = REAL(strlen)(to);
|
||||
uptr to_length = internal_strlen(to);
|
||||
MEMPROF_READ_STRING(to, to_length);
|
||||
MEMPROF_WRITE_RANGE(to + to_length, from_length + 1);
|
||||
return REAL(strcat)(to, from);
|
||||
|
@ -219,7 +219,7 @@ INTERCEPTOR(char *, strncat, char *to, const char *from, uptr size) {
|
|||
uptr from_length = MaybeRealStrnlen(from, size);
|
||||
uptr copy_length = Min(size, from_length + 1);
|
||||
MEMPROF_READ_RANGE(from, copy_length);
|
||||
uptr to_length = REAL(strlen)(to);
|
||||
uptr to_length = internal_strlen(to);
|
||||
MEMPROF_READ_STRING(to, to_length);
|
||||
MEMPROF_WRITE_RANGE(to + to_length, from_length + 1);
|
||||
return REAL(strncat)(to, from, size);
|
||||
|
@ -232,7 +232,7 @@ INTERCEPTOR(char *, strcpy, char *to, const char *from) {
|
|||
return REAL(strcpy)(to, from);
|
||||
}
|
||||
ENSURE_MEMPROF_INITED();
|
||||
uptr from_size = REAL(strlen)(from) + 1;
|
||||
uptr from_size = internal_strlen(from) + 1;
|
||||
MEMPROF_READ_RANGE(from, from_size);
|
||||
MEMPROF_WRITE_RANGE(to, from_size);
|
||||
return REAL(strcpy)(to, from);
|
||||
|
@ -244,7 +244,7 @@ INTERCEPTOR(char *, strdup, const char *s) {
|
|||
if (UNLIKELY(!memprof_inited))
|
||||
return internal_strdup(s);
|
||||
ENSURE_MEMPROF_INITED();
|
||||
uptr length = REAL(strlen)(s);
|
||||
uptr length = internal_strlen(s);
|
||||
MEMPROF_READ_RANGE(s, length + 1);
|
||||
GET_STACK_TRACE_MALLOC;
|
||||
void *new_mem = memprof_malloc(length + 1, &stack);
|
||||
|
@ -258,7 +258,7 @@ INTERCEPTOR(char *, __strdup, const char *s) {
|
|||
if (UNLIKELY(!memprof_inited))
|
||||
return internal_strdup(s);
|
||||
ENSURE_MEMPROF_INITED();
|
||||
uptr length = REAL(strlen)(s);
|
||||
uptr length = internal_strlen(s);
|
||||
MEMPROF_READ_RANGE(s, length + 1);
|
||||
GET_STACK_TRACE_MALLOC;
|
||||
void *new_mem = memprof_malloc(length + 1, &stack);
|
||||
|
|
|
@ -286,7 +286,7 @@ INTERCEPTOR(void, malloc_stats, void) {
|
|||
INTERCEPTOR(char *, strcpy, char *dest, const char *src) {
|
||||
ENSURE_MSAN_INITED();
|
||||
GET_STORE_STACK_TRACE;
|
||||
SIZE_T n = REAL(strlen)(src);
|
||||
SIZE_T n = internal_strlen(src);
|
||||
CHECK_UNPOISONED_STRING(src + n, 0);
|
||||
char *res = REAL(strcpy)(dest, src);
|
||||
CopyShadowAndOrigin(dest, src, n + 1, &stack);
|
||||
|
@ -296,7 +296,7 @@ INTERCEPTOR(char *, strcpy, char *dest, const char *src) {
|
|||
INTERCEPTOR(char *, strncpy, char *dest, const char *src, SIZE_T n) {
|
||||
ENSURE_MSAN_INITED();
|
||||
GET_STORE_STACK_TRACE;
|
||||
SIZE_T copy_size = REAL(strnlen)(src, n);
|
||||
SIZE_T copy_size = internal_strnlen(src, n);
|
||||
if (copy_size < n)
|
||||
copy_size++; // trailing \0
|
||||
char *res = REAL(strncpy)(dest, src, n);
|
||||
|
@ -309,7 +309,7 @@ INTERCEPTOR(char *, strncpy, char *dest, const char *src, SIZE_T n) {
|
|||
INTERCEPTOR(char *, stpcpy, char *dest, const char *src) {
|
||||
ENSURE_MSAN_INITED();
|
||||
GET_STORE_STACK_TRACE;
|
||||
SIZE_T n = REAL(strlen)(src);
|
||||
SIZE_T n = internal_strlen(src);
|
||||
CHECK_UNPOISONED_STRING(src + n, 0);
|
||||
char *res = REAL(stpcpy)(dest, src);
|
||||
CopyShadowAndOrigin(dest, src, n + 1, &stack);
|
||||
|
@ -325,7 +325,7 @@ INTERCEPTOR(char *, strdup, char *src) {
|
|||
GET_STORE_STACK_TRACE;
|
||||
// On FreeBSD strdup() leverages strlen().
|
||||
InterceptorScope interceptor_scope;
|
||||
SIZE_T n = REAL(strlen)(src);
|
||||
SIZE_T n = internal_strlen(src);
|
||||
CHECK_UNPOISONED_STRING(src + n, 0);
|
||||
char *res = REAL(strdup)(src);
|
||||
CopyShadowAndOrigin(res, src, n + 1, &stack);
|
||||
|
@ -336,7 +336,7 @@ INTERCEPTOR(char *, strdup, char *src) {
|
|||
INTERCEPTOR(char *, __strdup, char *src) {
|
||||
ENSURE_MSAN_INITED();
|
||||
GET_STORE_STACK_TRACE;
|
||||
SIZE_T n = REAL(strlen)(src);
|
||||
SIZE_T n = internal_strlen(src);
|
||||
CHECK_UNPOISONED_STRING(src + n, 0);
|
||||
char *res = REAL(__strdup)(src);
|
||||
CopyShadowAndOrigin(res, src, n + 1, &stack);
|
||||
|
@ -351,7 +351,7 @@ INTERCEPTOR(char *, __strdup, char *src) {
|
|||
INTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) {
|
||||
ENSURE_MSAN_INITED();
|
||||
char *res = REAL(gcvt)(number, ndigit, buf);
|
||||
SIZE_T n = REAL(strlen)(buf);
|
||||
SIZE_T n = internal_strlen(buf);
|
||||
__msan_unpoison(buf, n + 1);
|
||||
return res;
|
||||
}
|
||||
|
@ -363,8 +363,8 @@ INTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) {
|
|||
INTERCEPTOR(char *, strcat, char *dest, const char *src) {
|
||||
ENSURE_MSAN_INITED();
|
||||
GET_STORE_STACK_TRACE;
|
||||
SIZE_T src_size = REAL(strlen)(src);
|
||||
SIZE_T dest_size = REAL(strlen)(dest);
|
||||
SIZE_T src_size = internal_strlen(src);
|
||||
SIZE_T dest_size = internal_strlen(dest);
|
||||
CHECK_UNPOISONED_STRING(src + src_size, 0);
|
||||
CHECK_UNPOISONED_STRING(dest + dest_size, 0);
|
||||
char *res = REAL(strcat)(dest, src);
|
||||
|
@ -375,8 +375,8 @@ INTERCEPTOR(char *, strcat, char *dest, const char *src) {
|
|||
INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) {
|
||||
ENSURE_MSAN_INITED();
|
||||
GET_STORE_STACK_TRACE;
|
||||
SIZE_T dest_size = REAL(strlen)(dest);
|
||||
SIZE_T copy_size = REAL(strnlen)(src, n);
|
||||
SIZE_T dest_size = internal_strlen(dest);
|
||||
SIZE_T copy_size = internal_strnlen(src, n);
|
||||
CHECK_UNPOISONED_STRING(dest + dest_size, 0);
|
||||
char *res = REAL(strncat)(dest, src, n);
|
||||
CopyShadowAndOrigin(dest + dest_size, src, copy_size, &stack);
|
||||
|
@ -612,7 +612,8 @@ INTERCEPTOR(char *, fcvt, double x, int a, int *b, int *c) {
|
|||
char *res = REAL(fcvt)(x, a, b, c);
|
||||
__msan_unpoison(b, sizeof(*b));
|
||||
__msan_unpoison(c, sizeof(*c));
|
||||
if (res) __msan_unpoison(res, REAL(strlen)(res) + 1);
|
||||
if (res)
|
||||
__msan_unpoison(res, internal_strlen(res) + 1);
|
||||
return res;
|
||||
}
|
||||
#define MSAN_MAYBE_INTERCEPT_FCVT INTERCEPT_FUNCTION(fcvt)
|
||||
|
@ -625,7 +626,8 @@ INTERCEPTOR(char *, getenv, char *name) {
|
|||
return REAL(getenv)(name);
|
||||
ENSURE_MSAN_INITED();
|
||||
char *res = REAL(getenv)(name);
|
||||
if (res) __msan_unpoison(res, REAL(strlen)(res) + 1);
|
||||
if (res)
|
||||
__msan_unpoison(res, internal_strlen(res) + 1);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -635,7 +637,7 @@ static void UnpoisonEnviron() {
|
|||
char **envp = environ;
|
||||
for (; *envp; ++envp) {
|
||||
__msan_unpoison(envp, sizeof(*envp));
|
||||
__msan_unpoison(*envp, REAL(strlen)(*envp) + 1);
|
||||
__msan_unpoison(*envp, internal_strlen(*envp) + 1);
|
||||
}
|
||||
// Trailing NULL pointer.
|
||||
__msan_unpoison(envp, sizeof(*envp));
|
||||
|
@ -758,7 +760,7 @@ INTERCEPTOR(char *, fgets_unlocked, char *s, int size, void *stream) {
|
|||
ENSURE_MSAN_INITED();
|
||||
char *res = REAL(fgets_unlocked)(s, size, stream);
|
||||
if (res)
|
||||
__msan_unpoison(s, REAL(strlen)(s) + 1);
|
||||
__msan_unpoison(s, internal_strlen(s) + 1);
|
||||
return res;
|
||||
}
|
||||
#define MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED INTERCEPT_FUNCTION(fgets_unlocked)
|
||||
|
@ -829,7 +831,7 @@ INTERCEPTOR(int, gethostname, char *name, SIZE_T len) {
|
|||
ENSURE_MSAN_INITED();
|
||||
int res = REAL(gethostname)(name, len);
|
||||
if (!res || (res == -1 && errno == errno_ENAMETOOLONG)) {
|
||||
SIZE_T real_len = REAL(strnlen)(name, len);
|
||||
SIZE_T real_len = internal_strnlen(name, len);
|
||||
if (real_len < len)
|
||||
++real_len;
|
||||
__msan_unpoison(name, real_len);
|
||||
|
@ -1080,9 +1082,9 @@ INTERCEPTOR(void, tzset, int fake) {
|
|||
InterceptorScope interceptor_scope;
|
||||
REAL(tzset)(fake);
|
||||
if (tzname[0])
|
||||
__msan_unpoison(tzname[0], REAL(strlen)(tzname[0]) + 1);
|
||||
__msan_unpoison(tzname[0], internal_strlen(tzname[0]) + 1);
|
||||
if (tzname[1])
|
||||
__msan_unpoison(tzname[1], REAL(strlen)(tzname[1]) + 1);
|
||||
__msan_unpoison(tzname[1], internal_strlen(tzname[1]) + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1455,9 +1457,9 @@ INTERCEPTOR(int, dladdr, void *addr, dlinfo *info) {
|
|||
if (res != 0) {
|
||||
__msan_unpoison(info, sizeof(*info));
|
||||
if (info->dli_fname)
|
||||
__msan_unpoison(info->dli_fname, REAL(strlen)(info->dli_fname) + 1);
|
||||
__msan_unpoison(info->dli_fname, internal_strlen(info->dli_fname) + 1);
|
||||
if (info->dli_sname)
|
||||
__msan_unpoison(info->dli_sname, REAL(strlen)(info->dli_sname) + 1);
|
||||
__msan_unpoison(info->dli_sname, internal_strlen(info->dli_sname) + 1);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -1466,7 +1468,8 @@ INTERCEPTOR(char *, dlerror, int fake) {
|
|||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, dlerror, fake);
|
||||
char *res = REAL(dlerror)(fake);
|
||||
if (res) __msan_unpoison(res, REAL(strlen)(res) + 1);
|
||||
if (res)
|
||||
__msan_unpoison(res, internal_strlen(res) + 1);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1484,7 +1487,7 @@ static int msan_dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size,
|
|||
if (info->dlpi_phdr && info->dlpi_phnum)
|
||||
__msan_unpoison(info->dlpi_phdr, struct_ElfW_Phdr_sz * info->dlpi_phnum);
|
||||
if (info->dlpi_name)
|
||||
__msan_unpoison(info->dlpi_name, REAL(strlen)(info->dlpi_name) + 1);
|
||||
__msan_unpoison(info->dlpi_name, internal_strlen(info->dlpi_name) + 1);
|
||||
}
|
||||
dl_iterate_phdr_data *cbdata = (dl_iterate_phdr_data *)data;
|
||||
UnpoisonParam(3);
|
||||
|
@ -1526,7 +1529,7 @@ INTERCEPTOR(wchar_t *, wcscpy, wchar_t *dest, const wchar_t *src) {
|
|||
ENSURE_MSAN_INITED();
|
||||
GET_STORE_STACK_TRACE;
|
||||
wchar_t *res = REAL(wcscpy)(dest, src);
|
||||
CopyShadowAndOrigin(dest, src, sizeof(wchar_t) * (REAL(wcslen)(src) + 1),
|
||||
CopyShadowAndOrigin(dest, src, sizeof(wchar_t) * (internal_wcslen(src) + 1),
|
||||
&stack);
|
||||
return res;
|
||||
}
|
||||
|
@ -1534,7 +1537,7 @@ INTERCEPTOR(wchar_t *, wcscpy, wchar_t *dest, const wchar_t *src) {
|
|||
INTERCEPTOR(wchar_t *, wcsncpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
|
||||
ENSURE_MSAN_INITED();
|
||||
GET_STORE_STACK_TRACE;
|
||||
SIZE_T copy_size = REAL(wcsnlen)(src, n);
|
||||
SIZE_T copy_size = internal_wcsnlen(src, n);
|
||||
if (copy_size < n) copy_size++; // trailing \0
|
||||
wchar_t *res = REAL(wcsncpy)(dest, src, n);
|
||||
CopyShadowAndOrigin(dest, src, copy_size * sizeof(wchar_t), &stack);
|
||||
|
@ -1598,7 +1601,7 @@ void *__msan_memmove(void *dest, const void *src, SIZE_T n) {
|
|||
|
||||
void __msan_unpoison_string(const char* s) {
|
||||
if (!MEM_IS_APP(s)) return;
|
||||
__msan_unpoison(s, REAL(strlen)(s) + 1);
|
||||
__msan_unpoison(s, internal_strlen(s) + 1);
|
||||
}
|
||||
|
||||
namespace __msan {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -33,7 +33,7 @@
|
|||
INTERCEPTOR(int, statvfs, char *path, void *buf) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf);
|
||||
if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
|
||||
if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
|
||||
// FIXME: under ASan the call below may write to freed memory and corrupt
|
||||
// its metadata. See
|
||||
// https://github.com/google/sanitizers/issues/321.
|
||||
|
@ -99,7 +99,7 @@ INTERCEPTOR(int, getvfsstat, void *buf, SIZE_T bufsize, int flags) {
|
|||
INTERCEPTOR(int, statvfs1, const char *path, void *buf, int flags) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, statvfs1, path, buf, flags);
|
||||
if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
|
||||
if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
|
||||
int res = REAL(statvfs1)(path, buf, flags);
|
||||
if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs90_sz);
|
||||
return res;
|
||||
|
|
|
@ -258,6 +258,18 @@ s64 internal_simple_strtoll(const char *nptr, const char **endptr, int base) {
|
|||
}
|
||||
}
|
||||
|
||||
uptr internal_wcslen(const wchar_t *s) {
|
||||
uptr i = 0;
|
||||
while (s[i]) i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
uptr internal_wcsnlen(const wchar_t *s, uptr maxlen) {
|
||||
uptr i = 0;
|
||||
while (i < maxlen && s[i]) i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
bool mem_is_zero(const char *beg, uptr size) {
|
||||
CHECK_LE(size, 1ULL << FIRST_32_SECOND_64(30, 40)); // Sanity check.
|
||||
const char *end = beg + size;
|
||||
|
|
|
@ -51,6 +51,8 @@ char *internal_strstr(const char *haystack, const char *needle);
|
|||
s64 internal_simple_strtoll(const char *nptr, const char **endptr, int base);
|
||||
int internal_snprintf(char *buffer, uptr length, const char *format, ...)
|
||||
FORMAT(3, 4);
|
||||
uptr internal_wcslen(const wchar_t *s);
|
||||
uptr internal_wcsnlen(const wchar_t *s, uptr maxlen);
|
||||
|
||||
// Return true if all bytes in [mem, mem+size) are zero.
|
||||
// Optimized for the case when the result is true.
|
||||
|
|
|
@ -279,6 +279,23 @@ TEST(SanitizerCommon, InternalStrFunctions) {
|
|||
EXPECT_EQ(retval, (uptr)9);
|
||||
}
|
||||
|
||||
TEST(SanitizerCommon, InternalWideStringFunctions) {
|
||||
const wchar_t *emptystr = L"";
|
||||
const wchar_t *samesizestr = L"1234567";
|
||||
const wchar_t *shortstr = L"123";
|
||||
const wchar_t *longerstr = L"123456789";
|
||||
|
||||
ASSERT_EQ(internal_wcslen(emptystr), 0ul);
|
||||
ASSERT_EQ(internal_wcslen(samesizestr), 7ul);
|
||||
ASSERT_EQ(internal_wcslen(shortstr), 3ul);
|
||||
ASSERT_EQ(internal_wcslen(longerstr), 9ul);
|
||||
|
||||
ASSERT_EQ(internal_wcsnlen(emptystr, 7), 0ul);
|
||||
ASSERT_EQ(internal_wcsnlen(samesizestr, 7), 7ul);
|
||||
ASSERT_EQ(internal_wcsnlen(shortstr, 7), 3ul);
|
||||
ASSERT_EQ(internal_wcsnlen(longerstr, 7), 7ul);
|
||||
}
|
||||
|
||||
// FIXME: File manipulations are not yet supported on Windows
|
||||
#if SANITIZER_POSIX && !SANITIZER_MAC
|
||||
TEST(SanitizerCommon, InternalMmapWithOffset) {
|
||||
|
|
Loading…
Reference in New Issue