[OPEN-ILS-DEV] Re: PATCH: bzero is deprecated and unnecessary

Scott McKellar mck9 at swbell.net
Sun Sep 30 10:44:53 EDT 2007


--- Dan Scott <denials at gmail.com> wrote:

<snip -- about nul-filling buffers>

I think the best rationale for pre-filling buffers is that, if you're
going to have problems with a buffer -- such as a wild pointer
pointing into the unused portion -- you want the code to fail in a 
consistent and reproducible way.  Miker hinted at this notion
at one point, in a posting from July 13, referring to "the principle
of least surprise."

While I can appreciate the principle, I think there are better ways
to apply it.

First, I wouldn't initialize the buffer with nuls.  I'd initialize it
with (for example) exclamation points, with perhaps a nul at the end.  
That way if a wayward pointer gives us a string of exclamation points,
we'll have a better chance of recognizing the problem.  A string of
nuls is neither distinctive nor informative.

Secondly, I would confine the buffer-filling to test builds, so that
we don't incur the overhead in production builds.  For example
(uncompiled and untested):

#ifdef NDEBUG
#define osrf_prefill( s, n )
#else
#define osrf_prefill( s, n ) \
do { \
    void * temp_s = (s); \
    size_t temp_n = (n); \
    memset( temp_s, '!', temp_n ); \
    temp_s[ temp_n - 1 ] = '\0'; \
} while( 0 )
#endif

(I use temp_s and temp_n to avoid evaluating the arguments more than
once.)  

This approach may require some non-trivial rearrangement of the 
Makefiles so that we could readily use or not use the debugging
versions of things.  I am not the one to judge whether it would be
worth the trouble.

Of course none of the above applies to the use of memset in
safe_malloc.  In that case the client code relies on the 
initialization with zeros.

I am tempted to create a safe_calloc, identical to the present
safe_malloc except in name.  Then anywhere we really need the zeros
we can switch to safe_calloc.  In the fullness of time we could 
remove the memset from safe_malloc.

(Of course for consistency we should probably have a safe_strdup
and maybe a safe_realloc.  As it stands now, we lock the front door
but leave the back door wide open.)

<snip>

> Actually, if I'm reading it correctly, C99 does guarantee the
> null-terminating behaviour:

<snip -- quotes from the Standard>

> (Spec is at
> http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf)

I stand corrected.  I had relied on various man files, all of which
were more than a little vague on this point.  I have the C89 Standard
within reach but I didn't have the C99 Standard.  Now I do.  Thanks
for contributing to my education.

Nevertheless, it might be prudent to add a nul manually at the end
of the receiving buffer after calling snprintf, in the rare cases
where you want to use the truncated string.  Despite what the 
Standard says, not all snprintfs are created equal.  In particular
some of them treat the return code differently, and may vary in
other ways for all I know.

Scott McKellar
http://home.swbell.net/mck9/ct/



More information about the Open-ils-dev mailing list