summaryrefslogtreecommitdiff
path: root/lib/sanitizer_common/sanitizer_common_interceptors.inc
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-07-10 14:01:51 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-07-10 14:01:51 +0000
commit9b21ba6f661a6b14e3e81bb4f06ffb769be028c4 (patch)
tree6976dae904c15b2f3e6351bde7e912aeeda40f5b /lib/sanitizer_common/sanitizer_common_interceptors.inc
parentd26cb23c22c1330e1cce383180818f4c3dcc7d18 (diff)
downloadcompiler-rt-9b21ba6f661a6b14e3e81bb4f06ffb769be028c4.tar.gz
compiler-rt-9b21ba6f661a6b14e3e81bb4f06ffb769be028c4.tar.bz2
compiler-rt-9b21ba6f661a6b14e3e81bb4f06ffb769be028c4.tar.xz
[sanitizer] Fix handling of edge cases in mbstowcs-like interceptors.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@186002 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common/sanitizer_common_interceptors.inc')
-rw-r--r--lib/sanitizer_common/sanitizer_common_interceptors.inc38
1 files changed, 26 insertions, 12 deletions
diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 67864c53..78992040 100644
--- a/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -1542,8 +1542,10 @@ INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len);
SIZE_T res = REAL(mbstowcs)(dest, src, len);
- if (res != (SIZE_T) - 1 && dest)
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, (res + 1) * sizeof(wchar_t));
+ if (res != (SIZE_T) - 1 && dest) {
+ SIZE_T write_cnt = res + (res < len);
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
+ }
return res;
}
@@ -1555,8 +1557,12 @@ INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len,
COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
}
SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);
- if (res != (SIZE_T) - 1 && dest)
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, (res + 1) * sizeof(wchar_t));
+ if (res != (SIZE_T)(-1) && dest && src) {
+ // This function, and several others, may or may not write the terminating
+ // \0 character. They write it iff they clear *src.
+ SIZE_T write_cnt = res + !*src;
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
+ }
return res;
}
@@ -1577,8 +1583,10 @@ INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms,
if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
}
SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);
- if (res != (SIZE_T) - 1 && dest)
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, (res + 1) * sizeof(wchar_t));
+ if (res != (SIZE_T)(-1) && dest && src) {
+ SIZE_T write_cnt = res + !*src;
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
+ }
return res;
}
@@ -1592,8 +1600,10 @@ INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len);
SIZE_T res = REAL(wcstombs)(dest, src, len);
- if (res != (SIZE_T) - 1 && dest)
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res + 1);
+ if (res != (SIZE_T) - 1 && dest) {
+ SIZE_T write_cnt = res + (res < len);
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
+ }
return res;
}
@@ -1605,8 +1615,10 @@ INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len,
COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
}
SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);
- if (res != (SIZE_T) - 1 && dest)
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res + 1);
+ if (res != (SIZE_T) - 1 && dest && src) {
+ SIZE_T write_cnt = res + !*src;
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
+ }
return res;
}
@@ -1627,8 +1639,10 @@ INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms,
if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
}
SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);
- if (res != (SIZE_T) - 1 && dest)
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res + 1);
+ if (res != (SIZE_T) - 1 && dest && src) {
+ SIZE_T write_cnt = res + !*src;
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
+ }
return res;
}