/memcheck/tests/match-overrun
/memcheck/tests/memalign_args
/memcheck/tests/memalign_test
+/memcheck/tests/memccpy1
+/memcheck/tests/memccpy2
/memcheck/tests/memcmptest
/memcheck/tests/memmem
/memcheck/tests/mempool
477630 Include ucontext.h rather than sys/ucontext.h in Solaris sources
477719 vgdb incorrectly replies to qRcmd packet
478211 Redundant code for vgdb.c and Valgrind core tools
+n-i-bz Add redirect for memccpy
To see details of a given bug, visit
https://bugs.kde.org/show_bug.cgi?id=XXXXXX
memalign_args.stderr.exp-glibc \
memalign_args.stderr.exp-darwin \
memalign_args.stderr.exp-solaris \
+ memccpy1.stderr.exp memccpy1.stdout.exp memccpy1.vgtest \
+ memccpy2.stderr.exp memccpy2.vgtest \
memcmptest.stderr.exp memcmptest.stderr.exp2 \
memcmptest.stdout.exp memcmptest.vgtest \
memmem.stderr.exp memmem.vgtest \
match-overrun \
memalign_test memcmptest mempool mempool2 mmaptest \
memalign_args \
+ memccpy1 memccpy2 \
memmem \
mismatches new_override metadata \
nanoleak_supp nanoleak2 new_nothrow \
--- /dev/null
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+int main(void)
+{
+ const char src0[] = "Stars: Altair, Sun, Vega.";
+ const char* src = strdup(src0);
+ const char terminal[] = {':', ' ', ',', '.', '!'};
+ char dest[sizeof src0];
+ const char alt = '@';
+
+ for (size_t i = 0; i != sizeof terminal; ++i)
+ {
+ void* to = memccpy(dest, src, terminal[i], sizeof dest);
+
+ printf("Terminal '%c' (%s):\t\"", terminal[i], to ? "found" : "absent");
+
+ // if `terminal` character was not found - print the whole `dest`
+ to = to ? to : dest + sizeof dest;
+
+ for (char* from = dest; from != to; ++from)
+ putchar(isprint(*from) ? *from : alt);
+
+ puts("\"");
+ }
+
+
+ puts("\n" "Separate star names from distances (ly):");
+ const char *star_distance[] = {
+ "Arcturus : 37", "Vega : 25", "Capella : 43", "Rigel : 860", "Procyon : 11"
+ };
+ char names_only[64];
+ char *first = names_only;
+ char *last = names_only + sizeof names_only;
+
+ for (size_t t = 0; t != (sizeof star_distance) / (sizeof star_distance[0]); ++t)
+ {
+ if (first)
+ first = memccpy(first, star_distance[t], ' ', last - first);
+ else
+ break;
+ }
+
+ if (first)
+ {
+ *first = '\0';
+ puts(names_only);
+ }
+ else
+ puts("Buffer is too small.");
+}
+
--- /dev/null
+Terminal ':' (found): "Stars:"
+Terminal ' ' (found): "Stars: "
+Terminal ',' (found): "Stars: Altair,"
+Terminal '.' (found): "Stars: Altair, Sun, Vega."
+Terminal '!' (absent): "Stars: Altair, Sun, Vega.@"
+
+Separate star names from distances (ly):
+Arcturus Vega Capella Rigel Procyon
--- /dev/null
+prog: memccpy1
+vgopts: -q
--- /dev/null
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+int main(void)
+{
+ char* astring = strdup("this is a string # with something to seek");
+ size_t len = strlen(astring);
+ memccpy(astring+10, astring, '#', len-10);
+ sprintf(astring, "this is a string # with something to seek");
+ memccpy(astring, astring+10, '#', len);
+}
+
--- /dev/null
+Source and destination overlap in memccpy(0x........, 0x........, 31)
+ at 0x........: memccpy (vg_replace_strmem.c:...)
+ by 0x........: main (memccpy2.c:9)
+
+Source and destination overlap in memccpy(0x........, 0x........, 41)
+ at 0x........: memccpy (vg_replace_strmem.c:...)
+ by 0x........: main (memccpy2.c:11)
+
--- /dev/null
+prog: memccpy2
+vgopts: -q
20460 MEMMEM
20470 WMEMCMP
20480 WCSNCPY
+ 20490 MEMCCPY
*/
#if defined(VGO_solaris)
}
}
-
+#if defined(VGO_linux)
/* Call here to exit if we can't continue. On Android we can't call
_exit for some reason, so we have to blunt-instrument it. */
__attribute__ ((__noreturn__))
_exit(x);
# endif
}
-
+#endif
// This is a macro rather than a function because we don't want to have an
// extra function in the stack trace.
WCSNCPY(VG_Z_LIBC_SONAME, wcsncpy)
#endif
+ /*---------------------- memccpy ----------------------*/
+
+ /* memccpy */
+#define MEMCCPY(soname, fnname) \
+ void* VG_REPLACE_FUNCTION_EZU(20490,soname,fnname) \
+ ( void *dst, const void *src, Int c, SizeT len ); \
+ void* VG_REPLACE_FUNCTION_EZU(20490,soname,fnname) \
+ ( void *dst, const void *src, Int c, SizeT len ) \
+ { \
+ const char *s = src; \
+ char *d = dst; \
+ const char x = c; \
+ SizeT i = len; \
+ \
+ while (i-- > 0) \
+ if ((*d++ = *s++) == x) { \
+ SizeT srclen = (i < len) ? i : len; \
+ RECORD_COPY(srclen); \
+ if (is_overlap(dst, src, srclen, srclen)) \
+ RECORD_OVERLAP_ERROR("memccpy", dst, src, len); \
+ return d; \
+ } \
+ \
+ if (len) { \
+ RECORD_COPY(len); \
+ if (is_overlap(dst, src, len, len)) \
+ RECORD_OVERLAP_ERROR("memccpy", dst, src, len); \
+ } \
+ return NULL; \
+ }
+
+#if defined(VGO_linux) || defined(VGO_freebsd) || defined(VGO_darwin) || defined(VGO_solaris)
+ MEMCCPY(VG_Z_LIBC_SONAME, memccpy)
+#endif
+
/*------------------------------------------------------------*/
/*--- Improve definedness checking of process environment ---*/
/*------------------------------------------------------------*/