Unix Technical Forum

Re: more improvements for mg

This is a discussion on Re: more improvements for mg within the mailing.openbsd.tech forums, part of the OpenBSD category; --> Han Boetes wrote: > Theo de Raadt wrote: > > snprintf does not return size_t > > sizeof returns ...


Go Back   Unix Technical Forum > Unix Operating Systems > OpenBSD > mailing.openbsd.tech

Register FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 02-18-2008, 07:50 AM
Han Boetes
 
Posts: n/a
Default Re: more improvements for mg

Han Boetes wrote:
> Theo de Raadt wrote:
> > snprintf does not return size_t

>
> sizeof returns size_t



Alright... here is how I see it:

Lets asume for simplicity sake that an int has a range from -128
to 127 and size_t has a range from 0 to 255.

Now there are various ways to do this as I have seen:

size_t ret;
char foo[100];

...
ret = snprintf(foo, sizeof(foo), "%s", input);
if ((int)ret == -1 || ret >= sizeof(foo))
...

input size: what happens:
--------------------------------------------
illegal input snprintf returns -1, (int)ret == -1 works ok

0 - 99 none, cause everything is fine

100 - 127 ret >= sizeof(foo)

128 - 255 snprintf returns int, result will wrap in snprintf, compiler doesn't
warn against this.

255 - 383 wraps twice, and result will seem valid.



Or alternatively:

int ret;
char foo[100];

...
ret = snprintf(foo, sizeof(foo), "%s", input);
if (ret < 0 || ret >= sizeof(foo))
...

input size: what happens:
--------------------------------------------
illegal input snprintf returns -1, ret < 0 works ok

0 - 99 none, cause everything is fine

100 - 127 ret >= sizeof(foo)

128 - 255 snprintf returns int, result will wrap and returns
negative value, ret < 0 catches this.

255 - 383 snprintf returns int and wraps twice,
and result will seem valid.


Take a look at /usr/src/lib/libc/stdio/snprintf.c; this situation
seems to go unchecked. AFAICT.


Or the suggestion of someone who mailed me to use long for ret:

long ret;
char foo[100];

...
ret = snprintf(foo, sizeof(foo), "%s", input);
if (ret == -1 || ret >= sizeof(foo))
...


input size: what happens:
--------------------------------------------
illegal input snprintf returns -1, ret < 0 works ok

0 - 99 none, cause everything is fine

100 - 127 ret >= sizeof(foo)

128 - 255 snprintf returns int, result will wrap and returns
negative value, ret < 0 catches this.

255 - 383 snprintf return int and wraps twice,
and result will seem valid.

So that also doesn't help.

So to sum up: the following solution seems the best to me at this
moment, but only if snprintf checks wrapping internally and
returns -1 when that happens.

int ret;
char foo[100];

...
ret = snprintf(foo, (int)sizeof(foo), "%s", input);
if (ret == -1 || ret >= sizeof(foo))
...

The manpage does not yet explain what happens when return values
overflow:

RETURN VALUES
The printf(), fprintf(), sprintf(), vprintf(), vfprintf(), vsprintf(),
and vasprintf() functions return the number of characters printed (not
including the trailing `\0' used to end output to strings).

The snprintf() and vsnprintf() functions return the number of characters
that would have been output if the size were unlimited (again, not
including the final `\0'). If an output or encoding error occurs, a val-
ue of -1 is returned instead.


The right final sentence would be:

If an input, output or encoding error occurs, a value of -1 is
returned instead.



# Han

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 01:32 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com