From owner-freebsd-hackers Thu Jul 15 17:16:29 1999 Delivered-To: freebsd-hackers@freebsd.org Received: from alpo.whistle.com (alpo.whistle.com [207.76.204.38]) by hub.freebsd.org (Postfix) with ESMTP id EFE4B156A5 for ; Thu, 15 Jul 1999 17:16:26 -0700 (PDT) (envelope-from julian@whistle.com) Received: from current1.whistle.com (current1.whistle.com [207.76.205.22]) by alpo.whistle.com (8.9.1a/8.9.1) with SMTP id RAA07554; Thu, 15 Jul 1999 17:14:32 -0700 (PDT) Date: Thu, 15 Jul 1999 17:14:31 -0700 (PDT) From: Julian Elischer To: Mike Smith Cc: freebsd-hackers@FreeBSD.ORG Subject: Re: OpenBSD's strlcpy(3) and strlcat(3) In-Reply-To: <199907152358.QAA01894@dingo.cdrom.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG 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. \\ msmith@freebsd.org > \\ -- Joseph Merrick \\ msmith@cdrom.com > > > > > To Unsubscribe: send mail to majordomo@FreeBSD.org > with "unsubscribe freebsd-hackers" in the body of the message > To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message