but what about

While ( more data items)
{
  copy data items onto end of buffer
  if full{
     write out buffer
     clear buffer, copy in rest of last item.
  }
}


I'd certainly not want to use xxprintf() for that


On Thu, 15 Jul 1999, Mike Smith wrote:

> > On Thu, 15 Jul 1999, Mike Smith wrote:
> > 
> > > Ugh.  Take the first example in the paper; it rewrites as
> > > 
> > >   len = asprintf(&path, "%s/.foorc");
> > > 
> > > as opposed to
> > > 
> > >   strlcat(path, homedir, sizeof(path));
> > >   strlcat(path, "/", sizeof(path));
> > >   strlcat(path, ".foord", sizeof(path));
> > >   len = strlen(path);
> > > 
> > > Yes, they're a better str*cat/cpy, but they're not the solution that 
> > > they claim to be.
> > 
> > I don't think that anyone has intended them to be anything other than a
> > better replacement for strcpy/strcat than strncpy/strncat (which they
> > certainly are).  Sure, you could go around telling people "use snprintf
> > instead" or "use asprintf instead", but is that the issue at hand?
> 
> In context, yes it is.
> 
> The paper talks about dealing with the construction of composite 
> strings into static buffers, and points out that there's a real problem 
> when you hit the edge of the buffer (overflow, truncation, etc.)
> 
> But they don't address the core of the problem, which is the use of a 
> static buffer in the first place.  This and other habitual programming 
> style items are what's at the real core of the "C is an insecure 
> language" argument; people are so used to these idiomatic programming 
> techniques they refuse to look for better solutions to the larger 
> problem.
> 
> Going back to the example they gave, let's put it in context.  You 
> probably have something like this:
> 
> 
> {
>       struct passwd *pw;
>       char    buf[MAXPATHLEN];
>       FILE    *fp;
>       
>       pw = getpwuid(getuid());
>       strlcpy(buf, pw->dir, sizeof(buf));
>       strlcat(buf, "/.appname/", sizeof(buf));
>       strlcat(buf, conffilename, sizeof(buf));
>       if (strlen(buf) >= sizeof(buf))
>               return(error);
>       fp = fopen(buf, "r");
>       ...
> 
> That works, as long as MAXPATHLEN is actually long enough.  In this 
> particular case it will be (because fopen will fail otherwise), but 
> there's no guarantee that you're going to know in advance.
> 
> OTOH, here it is with asprintf:
> 
> {
>       struct passwd *pw;
>       char    *buf;
>       FILE    *fp;
>       
>       pw = getpwuid(getuid());
>       if (asprintf(&buf, "%s/.appname/%s", pw->dir, conffilename) == -1)
>               return(error);
>       fp = fopen(buf, "r");
>       free(buf);
>       ...
> 
> The latter has a few really clear advantages:
> 
>  - you can see what the string is meant to look like.
>  - it doesn't matter how long any of the components are.
>  - the constructed value is on the heap, so you can return it (just 
>    imagine how much nicer ctime() would be if it did this).
> 
> -- 
> \\  The mind's the standard       \\  Mike Smith
> \\  of the man.                   \\  [EMAIL PROTECTED]
> \\    -- Joseph Merrick           \\  [EMAIL PROTECTED]
> 
> 
> 
> 
> To Unsubscribe: send mail to [EMAIL PROTECTED]
> with "unsubscribe freebsd-hackers" in the body of the message
> 



To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message

Reply via email to