From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/9303 Path: news.gmane.org!not-for-mail From: Rich Felker Newsgroups: gmane.linux.lib.musl.general Subject: Re: fread, fwrite with size 0 Date: Wed, 10 Feb 2016 19:42:34 -0500 Message-ID: <20160211004234.GH9349@brightrain.aerifal.cx> References: <56B1C001.7020603@gmx.at> <20160204043948.GM9349@brightrain.aerifal.cx> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1455151370 11636 80.91.229.3 (11 Feb 2016 00:42:50 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Thu, 11 Feb 2016 00:42:50 +0000 (UTC) To: musl@lists.openwall.com Original-X-From: musl-return-9316-gllmg-musl=m.gmane.org@lists.openwall.com Thu Feb 11 01:42:50 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 1aTfLN-0000U2-Rq for gllmg-musl@m.gmane.org; Thu, 11 Feb 2016 01:42:50 +0100 Original-Received: (qmail 22180 invoked by uid 550); 11 Feb 2016 00:42:47 -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 22159 invoked from network); 11 Feb 2016 00:42:47 -0000 Content-Disposition: inline In-Reply-To: <20160204043948.GM9349@brightrain.aerifal.cx> User-Agent: Mutt/1.5.21 (2010-09-15) Original-Sender: Rich Felker Xref: news.gmane.org gmane.linux.lib.musl.general:9303 Archived-At: On Wed, Feb 03, 2016 at 11:39:48PM -0500, Rich Felker wrote: > On Wed, Feb 03, 2016 at 09:53:21AM +0100, hombre wrote: > > Hello, > > > > I think that fread and fwrite does not return 0 when parameter size > > is 0 (when nmemb is 0, it does). > > Clib spec says: If size or nmemb is zero, fread/fwrite returns zero > > > > I did the following changes to make it work: > > > > fread: > > from > > return nmemb; > > to > > return len == 0 ? 0 : nmemb; > > > > fwrite: > > from > > return k == l ? nmemb : k / size; > > to > > if (l == 0) > > return 0; > > else > > return k == l ? nmemb : k / size; > > > > Regards, > > Erwin > > Thanks. Sadly the POSIX version of the text is contradictory on this: > > "Upon successful completion, fread() shall return the number of > elements successfully read which is less than nitems only if a read > error or end-of-file is encountered. If size or nitems is 0, fread() > shall return 0 and the contents of the array and the state of the > stream remain unchanged." > > First it says that the return value can be less than nitems only if an > error of EOF happens, but then it gives another way the return value > can be less than nitems (if size is 0). > > Fortunately the ISO C text is not so broken and agrees with you: > > "The fread function returns the number of elements successfully read, > which may be less than nmemb if a read error or end-of-file is > encountered. If size or nmemb is zero, fread returns zero and the > contents of the array and the state of the stream remain unchanged." > > There's another issue I want to fix here too, but I might do it in two > commits. Thanks for the report. I'm fixing this by adding: if (!size) nmemb = 0; to the top of both functions. This is preferable because, at least for fread, I'm also going to have to check for nmemb>=SIZE_MAX/size in order to properly handle this case (see glibc bug 19165), and having already ruled out size==0 (i.e. only doing the overflow check in the 'else' path for the above 'if') makes that division safe. Rich