--- valgrind/memcheck/mc_replace_strmem.c +++ valgrind/memcheck/mc_replace_strmem.c @@ -101,6 +101,7 @@ 20390 WCSCPY 20400 WCSCHR 20410 WCSRCHR + 20420 STPNCPY */ @@ -983,6 +984,34 @@ static inline void my_exit ( int x ) #endif +/*---------------------- stpncpy ----------------------*/ + +#define STPNCPY(soname, fnname) \ + char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \ + ( char* dst, const char* src, SizeT n ); \ + char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \ + ( char* dst, const char* src, SizeT n ) \ + { \ + const Char* src_orig = src; \ + Char* dst_str = dst; \ + SizeT m = 0; \ + \ + while (m < n && *src) { m++; *dst++ = *src++; } \ + /* Check for overlap after copying; all n bytes of dst are relevant, */ \ + /* but only m+1 bytes of src if terminator was found */ \ + if (is_overlap(dst_str, src_orig, n, (m < n) ? m+1 : n)) \ + RECORD_OVERLAP_ERROR("stpncpy", dst, src, n); \ + dst_str = dst; \ + while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \ + \ + return dst_str; \ + } + +#if defined(VGO_linux) + STPNCPY(VG_Z_LIBC_SONAME, stpncpy) +#endif + + /*---------------------- memset ----------------------*/ /* Why are we bothering to intercept this? It seems entirely --- valgrind/memcheck/tests/Makefile.am +++ valgrind/memcheck/tests/Makefile.am @@ -190,6 +190,7 @@ EXTRA_DIST = \ signal2.stderr.exp signal2.stdout.exp signal2.vgtest \ sigprocmask.stderr.exp sigprocmask.stderr.exp2 sigprocmask.vgtest \ static_malloc.stderr.exp static_malloc.vgtest \ + stpncpy.vgtest stpncpy.stderr.exp \ strchr.stderr.exp strchr.stderr.exp2 strchr.stderr.exp-darwin \ strchr.stderr.exp3 strchr.vgtest \ str_tester.stderr.exp str_tester.vgtest \ @@ -286,6 +287,7 @@ check_PROGRAMS = \ sbfragment \ sh-mem sh-mem-random \ sigaltstack signal2 sigprocmask static_malloc sigkill \ + stpncpy \ strchr \ str_tester \ supp_unknown supp1 supp2 suppfree \ --- /dev/null +++ valgrind/memcheck/tests/stpncpy.c @@ -0,0 +1,37 @@ +#include +#include +#include + +int main(int argc, char **argv) +{ + char a[] = "The spazzy orange tiger jumped over the tawny jaguar."; + char *b, *c; + char *d, *e; + + size_t l = strlen (a); + fprintf (stderr, "strlen: %zd\n", l); // strlen: 53 + + b = (char *) malloc((l + 3)); // Extra space for some zeros. + b[l] = 'X'; + b[l + 1] = 'X'; + b[l + 2] = 'X'; + c = stpncpy (b, a, l + 3); + + fprintf (stderr, "equal: %d\n", strcmp (a, b)); // equal: 0 + fprintf (stderr, "retlen: %zd\n", c - b); // retlen: 53 + fprintf (stderr, "last: '%c'\n", *(c - 1)); // last: '.' + fprintf (stderr, "zero0: %d\n", *c); // zero0: 0 + fprintf (stderr, "zero1: %d\n", *(c + 1)); // zero1: 0 + fprintf (stderr, "zero2: %d\n", *(c + 2)); // zero2: 0 + + d = (char *) malloc (l - 1); // No room for zero termination or dot. + e = stpncpy (d, b, l - 1); + + fprintf (stderr, "equal: %d\n", strncmp (b, d, l - 1)); // equal: 0 + fprintf (stderr, "retlen: %zd\n", e - d); // retlen: 52 + fprintf (stderr, "last: '%c'\n", *(e - 1)); // last: 'r' + + free (b); + free (d); + return 0; +} --- /dev/null +++ valgrind/memcheck/tests/stpncpy.stderr.exp @@ -0,0 +1,10 @@ +strlen: 53 +equal: 0 +retlen: 53 +last: '.' +zero0: 0 +zero1: 0 +zero2: 0 +equal: 0 +retlen: 52 +last: 'r' --- /dev/null +++ valgrind/memcheck/tests/stpncpy.vgtest @@ -0,0 +1,2 @@ +prog: stpncpy +vgopts: -q --- valgrind/memcheck/tests/Makefile.in.orig 2012-11-04 21:02:22.477642451 +0100 +++ valgrind/memcheck/tests/Makefile.in 2012-11-04 21:04:10.077182544 +0100 @@ -108,16 +108,17 @@ realloc3$(EXEEXT) sbfragment$(EXEEXT) sh-mem$(EXEEXT) \ sh-mem-random$(EXEEXT) sigaltstack$(EXEEXT) signal2$(EXEEXT) \ sigprocmask$(EXEEXT) static_malloc$(EXEEXT) sigkill$(EXEEXT) \ - strchr$(EXEEXT) str_tester$(EXEEXT) supp_unknown$(EXEEXT) \ - supp1$(EXEEXT) supp2$(EXEEXT) suppfree$(EXEEXT) \ - test-plo$(EXEEXT) trivialleak$(EXEEXT) unit_libcbase$(EXEEXT) \ - unit_oset$(EXEEXT) varinfo1$(EXEEXT) varinfo2$(EXEEXT) \ - varinfo3$(EXEEXT) varinfo4$(EXEEXT) varinfo5$(EXEEXT) \ - varinfo5so.so$(EXEEXT) varinfo6$(EXEEXT) vcpu_fbench$(EXEEXT) \ - vcpu_fnfns$(EXEEXT) wcs$(EXEEXT) xml1$(EXEEXT) wrap1$(EXEEXT) \ - wrap2$(EXEEXT) wrap3$(EXEEXT) wrap4$(EXEEXT) wrap5$(EXEEXT) \ - wrap6$(EXEEXT) wrap7$(EXEEXT) wrap7so.so$(EXEEXT) \ - wrap8$(EXEEXT) writev1$(EXEEXT) $(am__EXEEXT_1) + stpncpy$(EXEEXT) strchr$(EXEEXT) str_tester$(EXEEXT) \ + supp_unknown$(EXEEXT) supp1$(EXEEXT) supp2$(EXEEXT) \ + suppfree$(EXEEXT) test-plo$(EXEEXT) trivialleak$(EXEEXT) \ + unit_libcbase$(EXEEXT) unit_oset$(EXEEXT) varinfo1$(EXEEXT) \ + varinfo2$(EXEEXT) varinfo3$(EXEEXT) varinfo4$(EXEEXT) \ + varinfo5$(EXEEXT) varinfo5so.so$(EXEEXT) varinfo6$(EXEEXT) \ + vcpu_fbench$(EXEEXT) vcpu_fnfns$(EXEEXT) wcs$(EXEEXT) \ + xml1$(EXEEXT) wrap1$(EXEEXT) wrap2$(EXEEXT) wrap3$(EXEEXT) \ + wrap4$(EXEEXT) wrap5$(EXEEXT) wrap6$(EXEEXT) wrap7$(EXEEXT) \ + wrap7so.so$(EXEEXT) wrap8$(EXEEXT) writev1$(EXEEXT) \ + $(am__EXEEXT_1) @DWARF4_TRUE@am__append_12 = dw4 subdir = memcheck/tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -454,6 +455,9 @@ static_malloc_SOURCES = static_malloc.c static_malloc_OBJECTS = static_malloc.$(OBJEXT) static_malloc_LDADD = $(LDADD) +stpncpy_SOURCES = stpncpy.c +stpncpy_OBJECTS = stpncpy.$(OBJEXT) +stpncpy_LDADD = $(LDADD) str_tester_SOURCES = str_tester.c str_tester_OBJECTS = str_tester-str_tester.$(OBJEXT) str_tester_LDADD = $(LDADD) @@ -608,7 +612,7 @@ pdb-realloc2.c pipe.c pointer-trace.c post-syscall.c \ realloc1.c realloc2.c realloc3.c sbfragment.c sh-mem.c \ sh-mem-random.c sigaltstack.c sigkill.c signal2.c \ - sigprocmask.c static_malloc.c str_tester.c strchr.c \ + sigprocmask.c static_malloc.c stpncpy.c str_tester.c strchr.c \ $(supp1_SOURCES) $(supp2_SOURCES) $(supp_unknown_SOURCES) \ suppfree.c test-plo.c trivialleak.c unit_libcbase.c \ unit_oset.c varinfo1.c varinfo2.c varinfo3.c varinfo4.c \ @@ -639,7 +643,7 @@ pdb-realloc2.c pipe.c pointer-trace.c post-syscall.c \ realloc1.c realloc2.c realloc3.c sbfragment.c sh-mem.c \ sh-mem-random.c sigaltstack.c sigkill.c signal2.c \ - sigprocmask.c static_malloc.c str_tester.c strchr.c \ + sigprocmask.c static_malloc.c stpncpy.c str_tester.c strchr.c \ $(supp1_SOURCES) $(supp2_SOURCES) $(supp_unknown_SOURCES) \ suppfree.c test-plo.c trivialleak.c unit_libcbase.c \ unit_oset.c varinfo1.c varinfo2.c varinfo3.c varinfo4.c \ @@ -1117,6 +1121,7 @@ signal2.stderr.exp signal2.stdout.exp signal2.vgtest \ sigprocmask.stderr.exp sigprocmask.stderr.exp2 sigprocmask.vgtest \ static_malloc.stderr.exp static_malloc.vgtest \ + stpncpy.vgtest stpncpy.stderr.exp \ strchr.stderr.exp strchr.stderr.exp2 strchr.stderr.exp-darwin \ strchr.stderr.exp3 strchr.vgtest \ str_tester.stderr.exp str_tester.vgtest \ @@ -1576,6 +1581,9 @@ static_malloc$(EXEEXT): $(static_malloc_OBJECTS) $(static_malloc_DEPENDENCIES) @rm -f static_malloc$(EXEEXT) $(LINK) $(static_malloc_OBJECTS) $(static_malloc_LDADD) $(LIBS) +stpncpy$(EXEEXT): $(stpncpy_OBJECTS) $(stpncpy_DEPENDENCIES) + @rm -f stpncpy$(EXEEXT) + $(LINK) $(stpncpy_OBJECTS) $(stpncpy_LDADD) $(LIBS) str_tester$(EXEEXT): $(str_tester_OBJECTS) $(str_tester_DEPENDENCIES) @rm -f str_tester$(EXEEXT) $(str_tester_LINK) $(str_tester_OBJECTS) $(str_tester_LDADD) $(LIBS) @@ -1774,6 +1782,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signal2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sigprocmask.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/static_malloc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stpncpy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_tester-str_tester.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strchr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/supp.Po@am__quote@