Forgot to sign-off...
(v)scnprintf says it should return 0 when size is 0, but doesn't do
so. Also size_t is unsigned, it can't be less then 0. Fix the code and
comments.
Signed-off-by: Vitaly Mayatskikh <[email protected]>
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 0fbd012..8e75c7e 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -947,7 +947,7 @@ EXPORT_SYMBOL(vsnprintf);
* @args: Arguments for the format string
*
* The return value is the number of characters which have been written into
- * the @buf not including the trailing '\0'. If @size is <= 0 the function
+ * the @buf not including the trailing '\0'. If @size is == 0 the function
* returns 0.
*
* Call this function if you are already dealing with a va_list.
@@ -958,7 +958,8 @@ EXPORT_SYMBOL(vsnprintf);
int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
{
int i;
-
+ if (!size)
+ return 0;
i=vsnprintf(buf,size,fmt,args);
return (i >= size) ? (size - 1) : i;
}
@@ -998,7 +999,7 @@ EXPORT_SYMBOL(snprintf);
* @...: Arguments for the format string
*
* The return value is the number of characters written into @buf not including
- * the trailing '\0'. If @size is <= 0 the function returns 0.
+ * the trailing '\0'. If @size is == 0 the function returns 0.
*/
int scnprintf(char * buf, size_t size, const char *fmt, ...)
@@ -1006,6 +1007,8 @@ int scnprintf(char * buf, size_t size, const char *fmt, ...)
va_list args;
int i;
+ if (!size)
+ return 0;
va_start(args, fmt);
i = vsnprintf(buf, size, fmt, args);
va_end(args);
--
wbr, Vitaly
On Wed, 11 Mar 2009, Vitaly Mayatskikh wrote:
>
> (v)scnprintf says it should return 0 when size is 0, but doesn't do
> so. Also size_t is unsigned, it can't be less then 0. Fix the code and
> comments.
That is bogus.
The code really does (od "did"? Maybe you removed it) check for _smaller_
than 0:
int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
{
...
/* Reject out-of-range values early. Large positive sizes are
used for unknown buffer sizes. */
if (unlikely((int) size < 0)) {
/* There can be only one.. */
static char warn = 1;
WARN_ON(warn);
warn = 0;
return 0;
}
...
because under/overflows have happened.
The kernel is _not_ a regular libc. We have different rules.
Linus
> On Wed, 11 Mar 2009, Vitaly Mayatskikh wrote:
> >
> > (v)scnprintf says it should return 0 when size is 0, but doesn't do
> > so. Also size_t is unsigned, it can't be less then 0. Fix the code and
> > comments.
>
> That is bogus.
>
> The code really does (od "did"? Maybe you removed it) check for _smaller_
> than 0:
Well, (v)scnprintf says it returns 0 for size <= 0, but really returns
-1 for size == 0. I think, this code can't return 0 for size == 0:
i=vsnprintf(buf,size,fmt,args);
return (i >= size) ? (size - 1) : i;
Systemtap's script:
function test:long()
%{
char tmp[256];
long err;
err = scnprintf(tmp, 0, "%lu", (long)128);
THIS->__retvalue = err;
%}
probe begin
{
printf("scnprintf returns %d\n", test());
}
stap -g scnprintf.stp
scnprintf returns -1
--
wbr, Vitaly