Okay, this patch is sure to raise some eyebrows, so please take a look
and provide feedback.

I finally took a closer look at the usage of mktemp() in mutt.  It's
inside mutt_adv_mktemp(), which provides the ability to specify a
preferred temp file name.  If that file already exists, it calls
mktemp() and preserves the prefix and suffix of the suggested temp file
name.  (The suffix is concatenated on after the call the mktemp.)

mutt_adv_mktemp() is called all of 4 times in mutt.

On the other hand, there is another function: mutt_mktemp().  This is
essentially mutt's own version of mktemp, combining the Hostname, uid,
pid, and a couple random integers to basically roll our own mktemp.
This is function is called 91 times in mutt.

Since we are already relying pretty heavily on our own mutt_mktemp(),
I don't see why we can't just use that instead of mktemp inside
mutt_adv_mktemp().

So that's what I've done: added a new macro mutt_mktemp_pfx_sfx() that
calls mutt_mktemp() with a prefix and suffix to use.  The old calls to
mutt_mktemp (which fortunately is a macro) now have "mutt" and NULL
passed in as the prefix and suffix, which should provide the exact same
behavior as before.

-- 
Kevin J. McCarthy
GPG Fingerprint: 8975 A9B3 3AA3 7910 385C  5308 ADEF 7684 8031 6BDA
http://www.8t8.us/configs/gpg-key-transition-statement.txt
# HG changeset patch
# User Kevin McCarthy <[email protected]>
# Date 1439603350 25200
#      Fri Aug 14 18:49:10 2015 -0700
# Node ID 5bfe33e41e8278cf696c0af5c335f1459e2982ef
# Parent  55ea6e829b4644476a68651dd1b4ef67dc6571e2
Change mutt_adv_mktemp to call mutt_mktemp instead of mktemp. (see #3638).

mutt_mktemp is currently called in 95% of the cases in mutt, and
is already our "own rolled" version of mktemp.  The "insecure mktemp
warning" discussion keeps coming up, so instead add prefix and suffix
functionality to mutt_mktemp() and call that.

All other uses of Tempdir in the mutt source did not call
mutt_expand_path() first, so remove that from mutt_adv_mktemp().

diff --git a/muttlib.c b/muttlib.c
--- a/muttlib.c
+++ b/muttlib.c
@@ -59,46 +59,38 @@
 /* Modified by blong to accept a "suggestion" for file name.  If
  * that file exists, then construct one with unique name but 
  * keep any extension.  This might fail, I guess.
  * Renamed to mutt_adv_mktemp so I only have to change where it's
  * called, and not all possible cases.
  */
 void mutt_adv_mktemp (char *s, size_t l)
 {
-  char buf[_POSIX_PATH_MAX];
-  char tmp[_POSIX_PATH_MAX];
-  char *period;
-  size_t sl;
+  char prefix[_POSIX_PATH_MAX];
+  char *suffix;
   struct stat sb;
-  
-  strfcpy (buf, NONULL (Tempdir), sizeof (buf));
-  mutt_expand_path (buf, sizeof (buf));
+
   if (s[0] == '\0')
   {
-    snprintf (s, l, "%s/muttXXXXXX", buf);
-    mktemp (s);
+    mutt_mktemp (s, l);
   }
   else
   {
-    strfcpy (tmp, s, sizeof (tmp));
-    mutt_sanitize_filename (tmp, 1);
-    snprintf (s, l, "%s/%s", buf, tmp);
+    strfcpy (prefix, s, sizeof (prefix));
+    mutt_sanitize_filename (prefix, 1);
+    snprintf (s, l, "%s/%s", NONULL (Tempdir), prefix);
     if (lstat (s, &sb) == -1 && errno == ENOENT)
       return;
-    if ((period = strrchr (tmp, '.')) != NULL)
-      *period = 0;
-    snprintf (s, l, "%s/%s.XXXXXX", buf, tmp);
-    mktemp (s);
-    if (period != NULL)
+
+    if ((suffix = strrchr (prefix, '.')) != NULL)
     {
-      *period = '.';
-      sl = mutt_strlen(s);
-      strfcpy(s + sl, period, l - sl);
+      *suffix = 0;
+      ++suffix;
     }
+    mutt_mktemp_pfx_sfx (s, l, prefix, suffix);
   }
 }
 
 /* create a send-mode duplicate from a receive-mode body */
 
 int mutt_copy_body (FILE *fp, BODY **tgt, BODY *src)
 {
   char tmp[_POSIX_PATH_MAX];
@@ -774,20 +766,23 @@
   mutt_free_list (&base->userhdrs);
   MOVE_ELEM(spam);
   MOVE_ELEM(userhdrs);
 #undef MOVE_ELEM
   
   mutt_free_envelope(extra);
 }
 
-void _mutt_mktemp (char *s, size_t slen, const char *src, int line)
+void _mutt_mktemp (char *s, size_t slen, const char *prefix, const char 
*suffix,
+                   const char *src, int line)
 {
-  size_t n = snprintf (s, slen, "%s/mutt-%s-%d-%d-%ld%ld", NONULL (Tempdir), 
NONULL (Hostname),
-      (int) getuid (), (int) getpid (), random (), random ());
+  size_t n = snprintf (s, slen, "%s/%s-%s-%d-%d-%ld%ld%s%s",
+      NONULL (Tempdir), NONULL (prefix), NONULL (Hostname),
+      (int) getuid (), (int) getpid (), random (), random (),
+      suffix ? "." : "", NONULL (suffix));
   if (n >= slen)
     dprint (1, (debugfile, "%s:%d: ERROR: insufficient buffer space to hold 
temporary filename! slen=%zu but need %zu\n",
            src, line, slen, n));
   dprint (3, (debugfile, "%s:%d: mutt_mktemp returns \"%s\".\n", src, line, 
s));
   if (unlink (s) && errno != ENOENT)
     dprint (1, (debugfile, "%s:%d: ERROR: unlink(\"%s\"): %s (errno %d)\n", 
src, line, s, strerror (errno), errno));
 }
 
diff --git a/protos.h b/protos.h
--- a/protos.h
+++ b/protos.h
@@ -213,18 +213,19 @@
 void mutt_check_lookup_list (BODY *, char *, int);
 void mutt_make_attribution (CONTEXT *ctx, HEADER *cur, FILE *out);
 void mutt_make_forward_subject (ENVELOPE *env, CONTEXT *ctx, HEADER *cur);
 void mutt_make_help (char *, size_t, const char *, int, int);
 void mutt_make_misc_reply_headers (ENVELOPE *env, CONTEXT *ctx, HEADER *cur, 
ENVELOPE *curenv);
 void mutt_make_post_indent (CONTEXT *ctx, HEADER *cur, FILE *out);
 void mutt_merge_envelopes(ENVELOPE* base, ENVELOPE** extra);
 void mutt_message_to_7bit (BODY *, FILE *);
-#define mutt_mktemp(a,b) _mutt_mktemp (a, b, __FILE__, __LINE__)
-void _mutt_mktemp (char *, size_t, const char *, int);
+#define mutt_mktemp(a,b) mutt_mktemp_pfx_sfx (a, b, "mutt", NULL)
+#define mutt_mktemp_pfx_sfx(a,b,c,d)  _mutt_mktemp (a, b, c, d, __FILE__, 
__LINE__)
+void _mutt_mktemp (char *, size_t, const char *, const char *, const char *, 
int);
 void mutt_normalize_time (struct tm *);
 void mutt_paddstr (int, const char *);
 void mutt_parse_mime_message (CONTEXT *ctx, HEADER *);
 void mutt_parse_part (FILE *, BODY *);
 void mutt_perror (const char *);
 void mutt_prepare_envelope (ENVELOPE *, int);
 void mutt_unprepare_envelope (ENVELOPE *);
 void mutt_pretty_mailbox (char *, size_t);
@@ -503,17 +504,16 @@
 extern char *asctime ();
 extern char *strpbrk ();
 extern int fflush ();
 extern long lrand48 ();
 extern void srand48 ();
 extern time_t mktime ();
 extern int vsprintf ();
 extern int ungetc ();
-extern char *mktemp ();
 extern int ftruncate ();
 extern void *memset ();
 extern int pclose ();
 extern int socket ();
 extern int connect ();
 extern size_t strftime ();
 extern int lstat ();
 extern void rewind ();

Attachment: signature.asc
Description: PGP signature

Reply via email to