[OpenAFS-devel] Re: sprintf -> snprintf...
R. Lindsay Todd
toddr@rpi.edu
Fri, 27 Jun 2003 12:33:34 -0400
[Coming late to this discussion, since I'm not on -info]
As other have pointed out, there is an snprintf.c implementation in
src/util. This defines afs_vsnprintf and afs_snprintf, as well as
vsnprintf and snprintf for systems that do not already have these. This
is a "fairly complete" implementation -- it doesn't support the i18n
feature of specifying positional parameters, some of the newer ISO
descriptions, or correct return count if the buffer is too small. But
it does support features not found in every sprintf, such as %llu and
%lld formats for 64-bit integers.
In trying to add LFS to the fileserver, I've needed to be able to
display integers that might be either 32- or 64-bit, depending on
compilation options. Having to choose formats based on compilation
options becomes messy. The cleanest solution I've found, and what I've
implemented, is to make cast these values to afs_intmax_t or
afs_uintmax_t, which are guaranteed to be correctly formatted using %lld
or %llu, respectively, whether or not the AFS_64BIT_ENV is set. But the
best way to guarantee this is to control the implementation of
afs_vsnprintf, especially since we will need something like this on some
architectures anyway.
A number of changes to CVS lately have converted uses of sprintf to
afs_snprintf in the fileserver and volserver. It turns out that some of
the uses of sprintf are problematic: There are cases of %Ld being used
-- I believe that is a GNU extension. I found one buffer overrun
involving deleting volumes... Who knows what else lurks? So it seems
to me that moving to snprintf and similar is necessary to ensure safety.
The question at hand is then, to attempt to use a system snprintf, or
always use our own afs_snprintf? I think that most of the time, when
snprintf is used, it is to generate a string that will be used next to
log a message, or as a file name for a file system operation. The
system snprintf might, maybe, be a little more efficient, but I'm not
sure it matters in this context. Meanwhile, we have to maintain our own
snprintf implementation for systems that don't have it, and we have to
maintain a test program to verify that the system snprintf is robust
enough, and to get correct types of afs_intmax_t. That seems like a lot
of overhead for (maybe) marginal gain.
So it seems to me that we should always use our own afs_snprintf. The
only question I have: Is the version we have in src/util robust enough
to replace sprintf throughout the codebase? It seems to be for src/vol,
src/volser, and src/viced, but I haven't gone through other parts of the
code.
/Lindsay
Russ Allbery wrote:
>Switching to devel (should have done that before when I started attaching
>code).
>
>
--
R. Lindsay Todd email: toddr@rpi.edu
Senior Systems Programmer phone: 518-276-2605
Rensselaer Polytechnic Institute fax: 518-276-2809
Troy, NY 12180-3590 WWW: http://www.rpi.edu/~toddr