From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/10328 Path: news.gmane.org!not-for-mail From: Rich Felker Newsgroups: gmane.linux.lib.musl.general Subject: Re: dirname() / basename() - musl vs FreeBSD and OpenBSD Date: Sun, 24 Jul 2016 15:21:07 -0400 Message-ID: <20160724192107.GO15995@brightrain.aerifal.cx> References: Reply-To: musl@lists.openwall.com NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Trace: ger.gmane.org 1469388100 1028 80.91.229.3 (24 Jul 2016 19:21:40 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 24 Jul 2016 19:21:40 +0000 (UTC) To: musl@lists.openwall.com Original-X-From: musl-return-10341-gllmg-musl=m.gmane.org@lists.openwall.com Sun Jul 24 21:21:27 2016 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by plane.gmane.org with smtp (Exim 4.69) (envelope-from ) id 1bROxn-0001rC-A8 for gllmg-musl@m.gmane.org; Sun, 24 Jul 2016 21:21:23 +0200 Original-Received: (qmail 12189 invoked by uid 550); 24 Jul 2016 19:21:21 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 12168 invoked from network); 24 Jul 2016 19:21:20 -0000 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) Original-Sender: Rich Felker Xref: news.gmane.org gmane.linux.lib.musl.general:10328 Archived-At: On Sun, Jul 24, 2016 at 09:12:49PM +0200, Daniel Cegiełka wrote: > Hi, > > I came across a very strange problem when I ports code from OpenBSD to > musl-libc, and it seems, that a lot of problems can be caused by > dirname(). > > http://pubs.opengroup.org/onlinepubs/009695399/functions/dirname.html > > "The dirname() function >>> may <<< modify the string pointed to by > path, and may return a pointer to static storage that may then be > overwritten by subsequent calls to dirname()." There is actually no other option for implementing this function. The contract does not require that the argument string be a valid pathname or have a bounded length like PATH_MAX; it operates on general strings. And "No errors are defined", so failure is not an option. The only way to implement this function is for it to modify its argument. > OpenBSD and FreeBSD: > > http://man.openbsd.org/OpenBSD-5.8/dirname.3 > https://www.freebsd.org/cgi/man.cgi?query=dirname&sektion=3 > > "dirname() returns a pointer to internal static storage space that > will be overwritten by subsequent calls (each function has its own > separate storage). > > Other vendor implementations of dirname() may modify the contents of > the string passed to dirname(); this should be taken into account when > writing code which calls this function if portability is desired." > > NetBSD: > > http://netbsd.gw.com/cgi-bin/man-cgi?dirname+3+NetBSD-7.0 > > "BUGS > (...) > The dirname() function returns a pointer to static storage that > may be overwritten by subse- > quent calls to dirname(). This is not strictly a bug; it is > explicitly allowed by IEEE Std > 1003.1-2001 (``POSIX.1'')." It is a bug because it necessarily returns wrong results for extremely long strings. > so: > > #include /* musl libc dirname() */ > #include > > int main() > { > char s1[] = "/usr/lib/"; > char s2[] = "/usr/lib/"; > char *p1, *p2; > > p1 = dirname(s1); > p2 = openbsd_dirname(s2); > > printf("musl: s1: %s, p1: %s\n", s1, p1); > printf("openbsd_dirname: s2: %s, p2: %s\n", s2, p2); > return 0; > } > > # ./a.out > musl: s1: /usr, p1: /usr > openbsd_dirname: s2: /usr/lib/, p2: /usr > > So if you use the code from OpenBSD or FreeBSD, then you should be > very careful... grep, sed, patch, diff... etc. everything is > potentially error prone. > > musl has very good support for code from *BSD, so is the ability that > dirname() in musl does not overwrite argument of the function? It will > not change anything in relation to the IEEE Std 1003.1-2001, but it > will be much safer for the code from FreeBSD and OpenBSD. Not an option, for the above reason. > btw. the same problem applies to basename(): > > http://netbsd.gw.com/cgi-bin/man-cgi?basename+3+NetBSD-7.0 > > http://man.openbsd.org/OpenBSD-5.8/man3/basename.3 > > https://www.freebsd.org/cgi/man.cgi?query=basename&apropos=0&sektion=3&manpath=FreeBSD+10.3-RELEASE+and+Ports&arch=default&format=html Same applies there. Rich