#3638: Compilation errors for 1.6
-----------------------+----------------------
  Reporter:  grarpamp  |      Owner:  mutt-dev
      Type:  defect    |     Status:  new
  Priority:  major     |  Milestone:  1.6
 Component:  mutt      |    Version:  1.5.21
Resolution:            |   Keywords:
-----------------------+----------------------

Comment (by invalid@…):

 {{{
 On Thu, Apr 18, 2013 at 10:36:10AM -0000, Mutt wrote:

 It's not that mkstemp() isn't safe if you need to add a suffix (e.g. a
 file extension); it's that it won't do that.  You have to take the
 filename you get back and add the suffix yourself, and THEN open the
 file properly, expecting that it could fail.   It's not a question of
 safety of mkstemp(); it's a question of the standard library routines
 lacking imagination in how people might want their temporary files
 named[1].  Oh, and then, you need to remember to close the file that
 mkstemp() opened for you, that you didn't actually want.

 The bottom line is that without implementing a very complicated
 mutt-specific temp file routine which generates its own random
 filenames of somewhat arbitrary construction, the way Mutt uses
 mktemp() is about as optimal as one can expect to get in their temp
 file maker thingy.

 [END RELEVANT COMMENT]

 -=-=-=-=-=-

 [BEGIN RELATED DIATRIBE]

 [1] This isn't so unreasonable, though it turns out to be non-ideal.
 Temp files are meant to be transient, and as such their names should
 usually not be interesting.  However in the case of, for example, MIME
 file attachments whose readers insist that the files they read be
 named a particular way, despite the file being perfectly valid input
 for that reader regardless of its name, it's a bit more complicated
 than that, and the library routines provided by the standard do not
 suffice.

 This is where mkstemps() and its friends come in... only there are two
 problems with it (IMO).  The first is that it is not part of the
 standard, so your system may not have it.  That makes it a tough sell
 in portable code.  The second is, IMO, that the interface is
 brain-dead.  The variable part of the template is always the string
 "XXXXXX" and no other, so this should be assumed.  The interface can
 then become:

   int mkstemps(const char *prefix, const char *suffix, char *filename);

 This obviates the need to count the characters in the suffix (or in
 any part of the file name), eliminating an opportunity for a silly
 programming error.  And it lets you pass in string constants (or
 macros that expand to string contsants); often the prefix and suffix
 would be constant, e.g. something like "mutt_attachment" and ".html".

 By contrast, with the current implementation of mkstemps(), you have
 to do all of the following:

  - assemble the prefix, "XXXXXX", and the suffix into a char array
  - count the suffix characters (perhaps by calling strlen())
  - make sure the array you're putting this all in was the right size
    and make sure your code that assembles the string does not overrun
    the array

 The last one could be done a couple ways, depending on whether the
 suffix and prefix are known string constants.  You might count the
 characters manually.  You might call strlen() a couple of times.  You
 might pre-allocate a string array of the correct size, if they are
 both constant.  You may dynamically allocate the space, if they are
 not both constant (especially if memory pressure is an issue).  Or you
 might allocate an array thought to be sufficiently large, and then
 make sure it's not overrun.

 This is a lot to get wrong, and it's completely pointless:  The
 library function can do all of this for you.  Then, all you have to do
 is to remember to call free().  Granted that's a common programming
 error, but it's just one, and chances are that with the current
 interface, you were going to do that anyway...

 The point is, even if your system has mkstemps(), you're probably
 better off using mktemp() the way Mutt uses it instead.  You just have
 to make sure that the file does not already exist when you go to
 create it, and that you create the file 0600 so that evildoers can't
 write their exploit over your data... and Mutt does that.  With older
 versions of glibc, mk*tmp*() opened the file with 0666, so you had to
 also remember to set your umask to prevent people from executing an
 exploit on your tempfile.
 }}}

-- 
Ticket URL: </ticket/3638#comment:7>
Mutt <http://www.mutt.org/>
The Mutt mail user agent

Reply via email to