diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_format.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_format.inc --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_format.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_format.inc @@ -539,24 +539,26 @@ continue; } else if (size == FSS_STRLEN) { if (void *argp = va_arg(aq, void *)) { + uptr len; if (dir.starredPrecision) { // FIXME: properly support starred precision for strings. - size = 0; + len = 0; } else if (dir.fieldPrecision > 0) { // Won't read more than "precision" symbols. - size = internal_strnlen((const char *)argp, dir.fieldPrecision); - if (size < dir.fieldPrecision) size++; + len = internal_strnlen((const char *)argp, dir.fieldPrecision); + if (len < (uptr)dir.fieldPrecision) + len++; } else { // Whole string will be accessed. - size = internal_strlen((const char *)argp) + 1; + len = internal_strlen((const char *)argp) + 1; } - COMMON_INTERCEPTOR_READ_RANGE(ctx, argp, size); + COMMON_INTERCEPTOR_READ_RANGE(ctx, argp, len); } } else if (size == FSS_WCSLEN) { if (void *argp = va_arg(aq, void *)) { // FIXME: Properly support wide-character strings (via wcsrtombs). - size = 0; - COMMON_INTERCEPTOR_READ_RANGE(ctx, argp, size); + uptr len = 0; + COMMON_INTERCEPTOR_READ_RANGE(ctx, argp, len); } } else { // Skip non-pointer args diff --git a/compiler-rt/test/asan/TestCases/vsnprintf.cpp b/compiler-rt/test/asan/TestCases/vsnprintf.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/vsnprintf.cpp @@ -0,0 +1,24 @@ +// RUN: %clangxx_asan -O2 %s -o %t +// RUN: %env_asan_opts=check_printf=1 %run %t 2>&1 + +// FIXME: printf is not intercepted on Windows yet. +// XFAIL: target={{.*windows.*}} + +#include +#include +#include + +void write(char *buf, int buf_size, const char *fmt, ...) { + va_list args; + va_start(args, fmt); + vsnprintf(buf, buf_size, fmt, args); + va_end(args); +} + +int main() { + char buffer[100]; + std::string str(2147483648, '='); + write(buffer, 100, "%s\n", str.c_str()); + printf("%s", buffer); + return 0; +}