diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -2546,7 +2546,7 @@ // TODO: add read check if __dn_comp intercept added int res = REAL(DN_EXPAND_INTERCEPTOR_NAME)(base, end, src, dest, space); if (res >= 0) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, internal_strlen(dest) + 1); return res; } # define INIT___DN_EXPAND \ diff --git a/compiler-rt/test/msan/Linux/dn_expand.cpp b/compiler-rt/test/msan/Linux/dn_expand.cpp --- a/compiler-rt/test/msan/Linux/dn_expand.cpp +++ b/compiler-rt/test/msan/Linux/dn_expand.cpp @@ -34,12 +34,52 @@ assert(res >= 0); assert(strlen(output) == 0); __msan_check_mem_is_initialized(output, strlen(output) + 1); - __msan_check_mem_is_initialized(output, res); +} + +void testComp() { + char unsigned msg[1024]; + char unsigned *mb = msg; + char unsigned *me = msg + sizeof(msg); + char unsigned **pb = (char unsigned **)mb; + pb[0] = msg; + pb[1] = nullptr; + mb += 64; + char unsigned **pe = (char unsigned **)mb; + + char unsigned *n1 = mb; + int res = dn_comp("llvm.org", mb, me - mb, pb, pe); + assert(res == 10); + mb += res; + + char unsigned *n2 = mb; + res = dn_comp("lab.llvm.org", mb, me - mb, pb, pe); + assert(res == 6); + mb += res; + + { + char output[1024]; + res = dn_expand(msg, msg + sizeof(msg), n1, output, sizeof(output)); + + fprintf(stderr, "%d\n", res); + assert(res == 10); + assert(strlen(output) == 8); + __msan_check_mem_is_initialized(output, strlen(output) + 1); + } + + { + char output[1024]; + res = dn_expand(msg, msg + sizeof(msg), n2, output, sizeof(output)); + + assert(res == 6); + assert(strlen(output) == 12); + __msan_check_mem_is_initialized(output, strlen(output) + 1); + } } int main(int iArgc, const char *szArgv[]) { testWrite(); testWriteZeroLength(); + testComp(); return 0; } diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/dn_expand.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/dn_expand.cpp --- a/compiler-rt/test/sanitizer_common/TestCases/Linux/dn_expand.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/dn_expand.cpp @@ -34,9 +34,48 @@ assert(strcmp(output, "") == 0); } +void testComp() { + char unsigned msg[1024]; + char unsigned *mb = msg; + char unsigned *me = msg + sizeof(msg); + char unsigned **pb = (char unsigned **)mb; + pb[0] = msg; + pb[1] = nullptr; + mb += 64; + char unsigned **pe = (char unsigned **)mb; + + char unsigned *n1 = mb; + int res = dn_comp("llvm.org", mb, me - mb, pb, pe); + assert(res == 10); + mb += res; + + char unsigned *n2 = mb; + res = dn_comp("lab.llvm.org", mb, me - mb, pb, pe); + assert(res == 6); + mb += res; + + { + char output[1024]; + res = dn_expand(msg, msg + sizeof(msg), n1, output, sizeof(output)); + + fprintf(stderr, "%d\n", res); + assert(res == 10); + assert(strcmp(output, "llvm.org") == 0); + } + + { + char output[1024]; + res = dn_expand(msg, msg + sizeof(msg), n2, output, sizeof(output)); + + assert(res == 6); + assert(strcmp(output, "lab.llvm.org") == 0); + } +} + int main(int iArgc, const char *szArgv[]) { testWrite(); testWriteZeroLength(); + testComp(); return 0; }