]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Add an intercept for stpncpy. Fixes #309427.
authorJulian Seward <jseward@acm.org>
Thu, 6 Dec 2012 17:54:33 +0000 (17:54 +0000)
committerJulian Seward <jseward@acm.org>
Thu, 6 Dec 2012 17:54:33 +0000 (17:54 +0000)
(Mark Wielaard, mjw@redhat.com)

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13163

memcheck/mc_replace_strmem.c
memcheck/tests/Makefile.am
memcheck/tests/stpncpy.c [new file with mode: 0644]
memcheck/tests/stpncpy.stderr.exp [new file with mode: 0644]
memcheck/tests/stpncpy.stdout.exp [new file with mode: 0644]
memcheck/tests/stpncpy.vgtest [new file with mode: 0644]

index 1e4328c80357b6131716db5c5fc1e7aab7a1f397..84cc40d3dc6575e48d03232d0bfa910d8af29344 100644 (file)
    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 HChar* src_orig = src; \
+            HChar* 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
index 39dba569532f2d1fed6322f4973a9ae02bcb8d1a..8e5d9cdae6242995603d4508f7f5e3db778ac73f 100644 (file)
@@ -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 stpncpy.stdout.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 \
diff --git a/memcheck/tests/stpncpy.c b/memcheck/tests/stpncpy.c
new file mode 100644 (file)
index 0000000..4c83419
--- /dev/null
@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+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;
+}
diff --git a/memcheck/tests/stpncpy.stderr.exp b/memcheck/tests/stpncpy.stderr.exp
new file mode 100644 (file)
index 0000000..7aa24b8
--- /dev/null
@@ -0,0 +1,10 @@
+strlen: 53
+equal: 0
+retlen: 53
+last: '.'
+zero0: 0
+zero1: 0
+zero2: 0
+equal: 0
+retlen: 52
+last: 'r'
diff --git a/memcheck/tests/stpncpy.stdout.exp b/memcheck/tests/stpncpy.stdout.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/memcheck/tests/stpncpy.vgtest b/memcheck/tests/stpncpy.vgtest
new file mode 100644 (file)
index 0000000..fbfcaa7
--- /dev/null
@@ -0,0 +1,2 @@
+prog: stpncpy
+vgopts: -q