From: Paul Floyd Date: Sat, 9 Dec 2023 19:54:53 +0000 (+0100) Subject: Add a redir for memccpy X-Git-Tag: VALGRIND_3_23_0~228 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8a4b233e1da5991893de1cbe072dee40cf793c39;p=thirdparty%2Fvalgrind.git Add a redir for memccpy --- diff --git a/.gitignore b/.gitignore index 70c436fbae..f250b39c95 100644 --- a/.gitignore +++ b/.gitignore @@ -935,6 +935,8 @@ /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 diff --git a/NEWS b/NEWS index 5ee9b61d9b..2c50a2639c 100644 --- a/NEWS +++ b/NEWS @@ -47,6 +47,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 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 diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am index e49888be81..1caca9e59b 100644 --- a/memcheck/tests/Makefile.am +++ b/memcheck/tests/Makefile.am @@ -262,6 +262,8 @@ EXTRA_DIST = \ 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 \ @@ -497,6 +499,7 @@ check_PROGRAMS = \ match-overrun \ memalign_test memcmptest mempool mempool2 mmaptest \ memalign_args \ + memccpy1 memccpy2 \ memmem \ mismatches new_override metadata \ nanoleak_supp nanoleak2 new_nothrow \ diff --git a/memcheck/tests/memccpy1.c b/memcheck/tests/memccpy1.c new file mode 100644 index 0000000000..9d7ef64821 --- /dev/null +++ b/memcheck/tests/memccpy1.c @@ -0,0 +1,53 @@ +#include +#include +#include + +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."); +} + diff --git a/memcheck/tests/memccpy1.stderr.exp b/memcheck/tests/memccpy1.stderr.exp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/memcheck/tests/memccpy1.stdout.exp b/memcheck/tests/memccpy1.stdout.exp new file mode 100644 index 0000000000..68e8354229 --- /dev/null +++ b/memcheck/tests/memccpy1.stdout.exp @@ -0,0 +1,8 @@ +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 diff --git a/memcheck/tests/memccpy1.vgtest b/memcheck/tests/memccpy1.vgtest new file mode 100644 index 0000000000..160a498f4c --- /dev/null +++ b/memcheck/tests/memccpy1.vgtest @@ -0,0 +1,2 @@ +prog: memccpy1 +vgopts: -q diff --git a/memcheck/tests/memccpy2.c b/memcheck/tests/memccpy2.c new file mode 100644 index 0000000000..a5a1dfc9f0 --- /dev/null +++ b/memcheck/tests/memccpy2.c @@ -0,0 +1,13 @@ +#include +#include +#include + +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); +} + diff --git a/memcheck/tests/memccpy2.stderr.exp b/memcheck/tests/memccpy2.stderr.exp new file mode 100644 index 0000000000..0132ef06c5 --- /dev/null +++ b/memcheck/tests/memccpy2.stderr.exp @@ -0,0 +1,8 @@ +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) + diff --git a/memcheck/tests/memccpy2.vgtest b/memcheck/tests/memccpy2.vgtest new file mode 100644 index 0000000000..29039f1537 --- /dev/null +++ b/memcheck/tests/memccpy2.vgtest @@ -0,0 +1,2 @@ +prog: memccpy2 +vgopts: -q diff --git a/shared/vg_replace_strmem.c b/shared/vg_replace_strmem.c index 16c1bd2f9b..623a8b7b4a 100644 --- a/shared/vg_replace_strmem.c +++ b/shared/vg_replace_strmem.c @@ -106,6 +106,7 @@ 20460 MEMMEM 20470 WMEMCMP 20480 WCSNCPY + 20490 MEMCCPY */ #if defined(VGO_solaris) @@ -152,7 +153,7 @@ Bool is_overlap ( void* dst, const void* src, SizeT dstlen, SizeT srclen ) } } - +#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__)) @@ -170,7 +171,7 @@ static inline void my_exit ( int x ) _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. @@ -2346,6 +2347,41 @@ static inline void my_exit ( int x ) 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 ---*/ /*------------------------------------------------------------*/