parent
25ecfcf00c
commit
9c1f8323ae
|
@ -0,0 +1,48 @@
|
|||
// RUN: %clangxx_msan -m64 -O0 -g %s -o %t && %t
|
||||
// RUN: %clangxx_msan -m64 -O0 -g -DPOSITIVE %s -o %t && not %t |& FileCheck %s
|
||||
|
||||
#include <assert.h>
|
||||
#include <iconv.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
int main(void) {
|
||||
iconv_t cd = iconv_open("ASCII", "ASCII");
|
||||
assert(cd != (iconv_t)-1);
|
||||
|
||||
char inbuf_[100];
|
||||
strcpy(inbuf_, "sample text");
|
||||
char outbuf_[100];
|
||||
char *inbuf = inbuf_;
|
||||
char *outbuf = outbuf_;
|
||||
size_t inbytesleft = strlen(inbuf_);
|
||||
size_t outbytesleft = sizeof(outbuf_);
|
||||
|
||||
#ifdef POSITIVE
|
||||
{
|
||||
char u;
|
||||
char *volatile p = &u;
|
||||
inbuf_[5] = *p;
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t res;
|
||||
res = iconv(cd, 0, 0, 0, 0);
|
||||
assert(res != (size_t)-1);
|
||||
|
||||
res = iconv(cd, 0, 0, &outbuf, &outbytesleft);
|
||||
assert(res != (size_t)-1);
|
||||
|
||||
res = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
|
||||
// CHECK: MemorySanitizer: use-of-uninitialized-value
|
||||
// CHECK: #0 {{.*}} in main {{.*}}iconv.cc:[[@LINE-2]]
|
||||
assert(res != (size_t)-1);
|
||||
assert(inbytesleft == 0);
|
||||
|
||||
assert(memcmp(inbuf_, outbuf_, strlen(inbuf_)) == 0);
|
||||
|
||||
iconv_close(cd);
|
||||
return 0;
|
||||
}
|
|
@ -2853,6 +2853,31 @@ INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim,
|
|||
#define INIT_GETLINE
|
||||
#endif
|
||||
|
||||
#if SANITIZER_INTERCEPT_ICONV
|
||||
INTERCEPTOR(SIZE_T, iconv, void *cd, char **inbuf, SIZE_T *inbytesleft,
|
||||
char **outbuf, SIZE_T *outbytesleft) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, iconv, cd, inbuf, inbytesleft, outbuf,
|
||||
outbytesleft);
|
||||
if (inbytesleft)
|
||||
COMMON_INTERCEPTOR_READ_RANGE(ctx, inbytesleft, sizeof(*inbytesleft));
|
||||
if (inbuf && inbytesleft)
|
||||
COMMON_INTERCEPTOR_READ_RANGE(ctx, *inbuf, *inbytesleft);
|
||||
if (outbytesleft)
|
||||
COMMON_INTERCEPTOR_READ_RANGE(ctx, outbytesleft, sizeof(*outbytesleft));
|
||||
void *outbuf_orig = outbuf ? *outbuf : 0;
|
||||
SIZE_T res = REAL(iconv)(cd, inbuf, inbytesleft, outbuf, outbytesleft);
|
||||
if (res != (SIZE_T) - 1 && outbuf && *outbuf > outbuf_orig) {
|
||||
SIZE_T sz = (char *)*outbuf - (char *)outbuf_orig;
|
||||
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, outbuf_orig, sz);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
#define INIT_ICONV COMMON_INTERCEPT_FUNCTION(iconv);
|
||||
#else
|
||||
#define INIT_ICONV
|
||||
#endif
|
||||
|
||||
#define SANITIZER_COMMON_INTERCEPTORS_INIT \
|
||||
INIT_STRCMP; \
|
||||
INIT_STRNCMP; \
|
||||
|
@ -2963,4 +2988,5 @@ INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim,
|
|||
INIT_LGAMMA_R; \
|
||||
INIT_DRAND48_R; \
|
||||
INIT_GETLINE; \
|
||||
INIT_ICONV; \
|
||||
/**/
|
||||
|
|
|
@ -158,6 +158,7 @@
|
|||
# define SANITIZER_INTERCEPT_LGAMMA SI_NOT_WINDOWS
|
||||
# define SANITIZER_INTERCEPT_LGAMMA_R SI_LINUX
|
||||
# define SANITIZER_INTERCEPT_DRAND48_R SI_LINUX_NOT_ANDROID
|
||||
# define SANITIZER_INTERCEPT_ICONV SI_MAC || SI_LINUX_NOT_ANDROID
|
||||
|
||||
// FIXME: getline seems to be available on OSX 10.7
|
||||
# define SANITIZER_INTERCEPT_GETLINE SI_LINUX_NOT_ANDROID
|
||||
|
|
|
@ -416,6 +416,7 @@ void StatOutput(u64 *stat) {
|
|||
name[StatInt_lrand48_r] = " lrand48_r ";
|
||||
name[StatInt_getline] = " getline ";
|
||||
name[StatInt_getdelim] = " getdelim ";
|
||||
name[StatInt_iconv] = " iconv ";
|
||||
|
||||
name[StatInt_pthread_attr_getdetachstate] = " pthread_addr_getdetachstate "; // NOLINT
|
||||
name[StatInt_pthread_attr_getguardsize] = " pthread_addr_getguardsize "; // NOLINT
|
||||
|
|
|
@ -411,6 +411,7 @@ enum StatType {
|
|||
StatInt_lrand48_r,
|
||||
StatInt_getline,
|
||||
StatInt_getdelim,
|
||||
StatInt_iconv,
|
||||
|
||||
StatInt_pthread_attr_getdetachstate,
|
||||
StatInt_pthread_attr_getguardsize,
|
||||
|
|
Loading…
Reference in New Issue