str_format: always return length of written string

Quoting the man page of vsnprintf:

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

  The functions snprintf() and vsnprintf() do not write more than size bytes (including
  the terminating null byte ('\0')).  If the output was truncated due  to  this  limit,
  then  the  return  value  is the number of characters (excluding the terminating null
  byte) which would have been written to the final string  if  enough  space  had  been
  available.  Thus, a return value of size or more means that the output was truncated.
  (See also below under NOTES.)

  If an output error is encountered, a negative value is returned.

[...]

  The glibc implementation of the functions snprintf() and vsnprintf() conforms to  the
  C99  standard,  that  is, behaves as described above, since glibc version 2.1.  Until
  glibc 2.0.6, they would return -1 when the output was truncated.
This commit is contained in:
def 2019-03-20 19:09:23 +01:00 committed by Dennis Felsing
parent 664a425b9d
commit d9804f5142
3 changed files with 25 additions and 2 deletions

View file

@ -2336,14 +2336,26 @@ int str_format(char *buffer, int buffer_size, const char *format, ...)
va_start(ap, format);
ret = _vsnprintf(buffer, buffer_size, format, ap);
va_end(ap);
buffer[buffer_size-1] = 0; /* assure null termination */
/* _vsnprintf is documented to return negative values on truncation, but
* in practice we didn't see that. let's handle it anyway just in case. */
if(ret < 0)
ret = buffer_size - 1;
#else
va_list ap;
va_start(ap, format);
ret = vsnprintf(buffer, buffer_size, format, ap);
va_end(ap);
/* null termination is assured by definition of vsnprintf */
#endif
buffer[buffer_size-1] = 0; /* assure null termination */
/* a return value of buffer_size or more indicates truncated output */
if(ret >= buffer_size)
ret = buffer_size - 1;
return ret;
}

View file

@ -1019,7 +1019,7 @@ int str_length(const char *str);
... - Parameters for the formatting.
Returns:
Length of written string
Length of written string, even if it has been truncated
Remarks:
- See the C manual for syntax for the printf formatting string.

View file

@ -166,3 +166,14 @@ TEST(Str, InList)
EXPECT_FALSE(str_in_list("", ",", ""));
EXPECT_FALSE(str_in_list("", ",", "xyz"));
}
TEST(Str, StrFormat)
{
char aBuf[4];
EXPECT_EQ(str_format(aBuf, 4, "%d:", 9), 2);
EXPECT_STREQ(aBuf, "9:");
EXPECT_EQ(str_format(aBuf, 4, "%d: ", 9), 3);
EXPECT_STREQ(aBuf, "9: ");
EXPECT_EQ(str_format(aBuf, 4, "%d: ", 99), 3);
EXPECT_STREQ(aBuf, "99:");
}