On Tue, May 01, 2018 at 11:15:51AM -0700, Kevin J. McCarthy wrote:
[re: strncpy vs. snprintf...]
> > Sorry, this was badly worded.  Checking the return value is required
> > to ensure that snprintf() wrote all the data (rc < size, NOT <= size),
> > assuming you want that.  If you actually want it to silently truncate,
> > which you may if for example you're formatting the index, then you can
> > ignore it.  That may or may not cause an error if compiled with -Wall
> > -Werror flags... the glibc folks have been doing a lot of that lately.
> 
> Hi Derek,
> 
> I haven't forgotten or ignored your past emails, and this is still on my
> list.  I've been thinking about a couple ways to deal with this, that
> I'll try after this release.  The nice thing about the static buffers is
> the speed, but I've been thinking of allocating a pool of BUFFER of
> various sizes and using that for the critical parts of the code.

Great.  That seems like a reasonable approach, though unless you're
doing a lot of these in a loop, I expect in most cases the UI I/O (and
human perception) will be the bottleneck, not the memory allocation,
and using malloc()/realloc() directly should be fine/imperceptible.
Note that since snprintf returns the exact size needed (with a modern
libc), you need at most one realloc() in all cases.  If you want to be
sure it works with older libc's then the code is slightly more
complicated, requiring realloc() in a loop.

I imagine what you really want is something like a mutt_snprintf()
wrapper that allocs/reallocs the space dynamically as needed.  The man
page actually has example code that does exactly that (using
vsnprintf), which could be used as a template.  You'd have a few
implementation options:

 - have an additional parameter which indicates whether or not
   truncation is desired, and skip the realloc() when true.  

 - Or you could always realloc() when needed, and skip specifying the
   size.  Or both--when truncate is false the size can be ignored.  
   If truncate is not desired, the passed-in size could be used as a
   hint for the initial string allocation.

 - If you can safely assume a modern libc, you could initially use a
   local char (size 1) to try the snprintf, which should basically
   always fail but give you the size of the buffer you need to
   allocate for the message to fit.  
   
 - If you can not assume a modern libc then alternatively you'd want
   to use an initial size that's typical of the case, perhaps
   implicitly assumed (say 30-100 chars or whatever), or based on the
   size of the format string, or the passed-in size as above.
   
Lots of options... any of them should work.  Just depends on what sort
of interface you'd prefer.


-- 
Derek D. Martin    http://www.pizzashack.org/   GPG Key ID: 0xDFBEAD02
-=-=-=-=-
This message is posted from an invalid address.  Replying to it will result in
undeliverable mail due to spam prevention.  Sorry for the inconvenience.

Attachment: pgpxkXOemjOJY.pgp
Description: PGP signature

Reply via email to