@@ -58,13 +58,20 @@ namespace __asan {
5858
5959static inline uptr MaybeRealStrnlen (const char *s, uptr maxlen) {
6060#if SANITIZER_INTERCEPT_STRNLEN
61- if (REAL (strnlen)) {
61+ if (REAL (strnlen))
6262 return REAL (strnlen)(s, maxlen);
63- }
64- #endif
63+ # endif
6564 return internal_strnlen (s, maxlen);
6665}
6766
67+ static inline uptr MaybeRealWcsnlen (const wchar_t * s, uptr maxlen) {
68+ # if SANITIZER_INTERCEPT_WCSNLEN
69+ if (REAL (wcsnlen))
70+ return REAL (wcsnlen)(s, maxlen);
71+ # endif
72+ return internal_wcsnlen (s, maxlen);
73+ }
74+
6875void SetThreadName (const char *name) {
6976 AsanThread *t = GetCurrentThread ();
7077 if (t)
@@ -570,6 +577,20 @@ INTERCEPTOR(char *, strcpy, char *to, const char *from) {
570577 return REAL (strcpy)(to, from);
571578}
572579
580+ INTERCEPTOR (wchar_t *, wcscpy, wchar_t * to, const wchar_t * from) {
581+ void * ctx;
582+ ASAN_INTERCEPTOR_ENTER (ctx, wcscpy);
583+ if (!TryAsanInitFromRtl ())
584+ return REAL (wcscpy)(to, from);
585+ if (flags ()->replace_str ) {
586+ uptr size = (internal_wcslen (from) + 1 ) * sizeof (wchar_t );
587+ CHECK_RANGES_OVERLAP (" wcscpy" , to, size, from, size);
588+ ASAN_READ_RANGE (ctx, from, size);
589+ ASAN_WRITE_RANGE (ctx, to, size);
590+ }
591+ return REAL (wcscpy)(to, from);
592+ }
593+
573594// Windows doesn't always define the strdup identifier,
574595// and when it does it's a macro defined to either _strdup
575596// or _strdup_dbg, _strdup_dbg ends up calling _strdup, so
@@ -633,6 +654,20 @@ INTERCEPTOR(char*, strncpy, char *to, const char *from, usize size) {
633654 return REAL (strncpy)(to, from, size);
634655}
635656
657+ INTERCEPTOR (wchar_t *, wcsncpy, wchar_t * to, const wchar_t * from, uptr size) {
658+ void * ctx;
659+ ASAN_INTERCEPTOR_ENTER (ctx, wcsncpy);
660+ AsanInitFromRtl ();
661+ if (flags ()->replace_str ) {
662+ uptr from_size =
663+ Min (size, MaybeRealWcsnlen (from, size) + 1 ) * sizeof (wchar_t );
664+ CHECK_RANGES_OVERLAP (" wcsncpy" , to, from_size, from, from_size);
665+ ASAN_READ_RANGE (ctx, from, from_size);
666+ ASAN_WRITE_RANGE (ctx, to, size * sizeof (wchar_t ));
667+ }
668+ return REAL (wcsncpy)(to, from, size);
669+ }
670+
636671template <typename Fn>
637672static ALWAYS_INLINE auto StrtolImpl (void *ctx, Fn real, const char *nptr,
638673 char **endptr, int base)
@@ -809,6 +844,11 @@ void InitializeAsanInterceptors() {
809844 ASAN_INTERCEPT_FUNC (strncat);
810845 ASAN_INTERCEPT_FUNC (strncpy);
811846 ASAN_INTERCEPT_FUNC (strdup);
847+
848+ // Intercept wcs* functions.
849+ ASAN_INTERCEPT_FUNC (wcscpy);
850+ ASAN_INTERCEPT_FUNC (wcsncpy);
851+
812852# if ASAN_INTERCEPT___STRDUP
813853 ASAN_INTERCEPT_FUNC (__strdup);
814854#endif
0 commit comments