]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Callgrind: Fix potential buffer overruns with user provided strings
authorJosef Weidendorfer <Josef.Weidendorfer@gmx.de>
Mon, 26 Feb 2007 00:16:09 +0000 (00:16 +0000)
committerJosef Weidendorfer <Josef.Weidendorfer@gmx.de>
Mon, 26 Feb 2007 00:16:09 +0000 (00:16 +0000)
This introduces some macros to shorten the code for output of
strings to a file descriptor. I could use this a lot,
but this commit limits itself to the potential buffer overruns
(to ease backporting - provided we want to do this)

Heavy use of the macros probably blows up the code. Perhaps
it would be better to provide e.g. a VG_(write_str3) function
in the tool API.

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

callgrind/command.c
callgrind/global.h

index bc4ae5521825022c51e9d28e72ca59eb0bb9a2d2..67fcab9f28ab50205dc468361a506005adfc7b1c 100644 (file)
@@ -128,41 +128,26 @@ static void setup_control(void)
   if (fd>=0) {
     Char buf[512];
     Int i;
-    
-    VG_(sprintf)(buf, 
-                "# This file is generated by Callgrind-" VERSION ".\n"
-                "# It is used to enable controlling the supervision of\n"
-                "#  '%s'\n"
-                "# by external tools.\n\n",
-                VG_(args_the_exename)
-       );
-    VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
+
+    WRITE_STR3(fd,
+              "# This file is generated by Callgrind-" VERSION ".\n"
+              "# It is used to enable controlling the supervision of\n"
+              "#  '", VG_(args_the_exename), "'\n"
+              "# by external tools.\n\n");
     
     VG_(sprintf)(buf, "version: " COMMAND_VERSION "\n");
     VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
     
-    VG_(sprintf)(buf, "base: %s\n", dir);
-    VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
-    
-    VG_(sprintf)(buf, "dumps: %s\n", dump_filename);
-    VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
-    
-    VG_(sprintf)(buf, "control: %s\n", command_file);
-    VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
-    
-    VG_(sprintf)(buf, "result: %s\n", result_file);
-    VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
-    
-    VG_(strcpy)(buf, "cmd:");
-    VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
-    VG_(sprintf)(buf, " %s", VG_(args_the_exename));
-    VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
+    WRITE_STR3(fd, "base: ", dir, "\n");
+    WRITE_STR3(fd, "dumps: ", dump_filename, "\n");
+    WRITE_STR3(fd, "control: ", command_file, "\n");
+    WRITE_STR3(fd, "result: ", result_file, "\n");
+
+    WRITE_STR2(fd, "cmd: ", VG_(args_the_exename));    
     for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
         HChar* arg = * (HChar**)VG_(indexXA)( VG_(args_for_client), i );
        if (!arg) continue;
-        tl_assert( VG_(strlen)(arg) < 512-4 ); /* see [512] above */
-       VG_(sprintf)(buf, " %s", arg);
-       VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
+       WRITE_STR2(fd, " ", arg);
     }
     VG_(write)(fd, "\n", 1);
     VG_(close)(fd);
@@ -224,19 +209,14 @@ static Int dump_info(Int fd)
     VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
     
     /* "base:" line */
-    VG_(sprintf)(buf, "base: %s\n", dump_base);
-    VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
+    WRITE_STR3(fd, "base: ", dump_base, "\n");
     
     /* "cmd:" line */
-    VG_(strcpy)(buf, "cmd:");
-    VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
-    VG_(sprintf)(buf, " %s", VG_(args_the_exename));
-    VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
+    WRITE_STR2(fd, "cmd: ", VG_(args_the_exename));
     for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
         HChar* arg = * (HChar**)VG_(indexXA)( VG_(args_for_client), i );
        if (!arg) continue;
-       VG_(sprintf)(buf, " %s", arg);
-       VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
+       WRITE_STR2(fd, " ", arg);
     }
     VG_(write)(fd, "\n", 1);
 
index bb85bc6760ca6bec97cb45cccc8b9d85e442be16..82b1d11629e47c7e8fdbed28d538abbb1d1c30dc 100644 (file)
@@ -121,6 +121,43 @@ struct _CommandLineOptions {
 #define LINE_BUF_LEN                     64
 
 
+/* Convenience macros */
+
+/* Use this only when size of sprintf args are known to fit into
+ * given buffer; for strings of unknown length, use WRITE_STR below
+ */
+#define WRITE_SPRINTF(fd, zz_buf, fmt, args...) \
+   do { Int len = VG_(sprintf)(zz_buf, fmt, ## args); \
+        VG_(write)(fd, (void*)zz_buf, len); \
+   } while (0)
+
+#define WRITE_STR(fd, str) \
+   do { if (str) { Int len = VG_(strlen)(str); \
+        VG_(write)(fd, (void*)str, len); } \
+        else VG_(write)(fd, "(null)", 6); \
+   } while (0)
+
+#define WRITE_STR2(fd, str1, str2) \
+   do { if (str1) { Int len = VG_(strlen)(str1); \
+        VG_(write)(fd, (void*)str1, len); } \
+        else VG_(write)(fd, "(null)", 6); \
+       if (str2) { Int len = VG_(strlen)(str2); \
+        VG_(write)(fd, (void*)str2, len); } \
+        else VG_(write)(fd, "(null)", 6); \
+   } while (0)
+
+#define WRITE_STR3(fd, str1, str2, str3) \
+   do { if (str1) { Int len = VG_(strlen)(str1); \
+        VG_(write)(fd, (void*)str1, len); } \
+        else VG_(write)(fd, "(null)", 6); \
+        if (str2) { Int len = VG_(strlen)(str2); \
+        VG_(write)(fd, (void*)str2, len); } \
+        else VG_(write)(fd, "(null)", 6); \
+        if (str3) { Int len = VG_(strlen)(str3); \
+        VG_(write)(fd, (void*)str3, len); } \
+        else VG_(write)(fd, "(null)", 6); \
+   } while (0)
+
 
 /*------------------------------------------------------------*/
 /*--- Statistics                                           ---*/