#686623 sprintf(3): description of *printf functions is misleading

Package:
manpages-dev
Source:
manpages
Submitter:
Vincent Lefevre
Date:
2022-01-27 20:03:06 UTC
Severity:
minor
Tags:
#686623#5
Date:
2012-09-04 00:27:17 UTC
From:
To:
The sprintf(3) man page says about sprintf():

  sprintf(), snprintf(), vsprintf() and vsnprintf() write to the
  character string str.

but it does not say that a terminating null byte is written (this
is said only for snprintf() and vsnprintf() later). Of course,
since the above sentence uses the term "character string", one
could guess that a terminating null byte is written, but actually
this is an incorrect deduction. As I interpret the above sentence,
I would think that sprintf() writes a character string (i.e. a
sequence of non-null characters terminated by a null character),
but this is not how this function behaves: it can write several
null characters (thus, not just a character string). Here's an
example:

#include <stdio.h>
int main (void)
{
  char s[200];
  int c = 0;
  sprintf (s, "%c%100s", c, "foo");
  return 0;
}

Characters are written after the initial \0 (so that if s[200] is
replaced by s[1], one has an undefined behavior).

The C99 standard is much more clear than the man page. It says:

  The sprintf function is equivalent to fprintf, except that the
  output is written into an array (specified by the argument s)
  rather than to a stream. A null character is written at the end
  of the characters written; it is not counted as part of the
  returned value. If copying takes place between objects that
  overlap, the behavior is undefined.

The man page could say:

  sprintf(), snprintf(), vsprintf() and vsnprintf() write a
  sequence of characters to the array str; a null character
  is written [or added] at the end of this sequence.

#686623#14
Date:
2022-01-27 19:59:49 UTC
From:
To:
FWIW, the man page already states in RETURN VALUE

| Upon successful return, these functions return the number of characters
| printed (excluding the null byte used to end output to strings).

providing some further hint at the terminating null byte.

Still, in light of your counterexample (which I had omitted here) I feel
this point might indeed need more stressing ...

Cheers,
Flo