|
Message-ID: <20171117175701.GE1627@brightrain.aerifal.cx> Date: Fri, 17 Nov 2017 12:57:01 -0500 From: Rich Felker <dalias@...c.org> To: musl@...ts.openwall.com Subject: Re: [PATCH v7] stdio: implement fopencookie(3) On Fri, Nov 17, 2017 at 12:35:41PM -0500, Rich Felker wrote: > On Thu, Nov 16, 2017 at 06:00:55AM +0000, William Pitcock wrote: > > The fopencookie(3) function allows the programmer to create a custom > > stdio implementation, using four hook functions which operate on a > > "cookie" data type. > > > > [...] > > + > > +struct fcookie { > > + void *cookie; > > + cookie_io_functions_t iofuncs; > > +}; > > + > > +struct cookie_FILE { > > + FILE f; > > + struct fcookie fc; > > + unsigned char buf[UNGET+BUFSIZ]; > > +}; > > + > > +static size_t cookieread(FILE *f, unsigned char *buf, size_t len) > > +{ > > + struct fcookie *fc = f->cookie; > > + ssize_t ret = -1; > > + size_t remain = len, readlen = 0; > > + > > + if (!fc->iofuncs.read) goto bail; > > + > > + ret = fc->iofuncs.read(fc->cookie, (char *) buf, len > 1 ? (len - 1) : 1); > > + if (ret <= 0) goto bail; > > + > > + readlen += ret; > > + remain -= ret; > > + > > + f->rpos = f->buf; > > + ret = fc->iofuncs.read(fc->cookie, (char *) f->rpos, f->buf_size); > > + if (ret <= 0) goto bail; > > + f->rend = f->rpos + ret; > > + > > + if (remain > 0) { > > + if (remain > f->buf_size) remain = f->buf_size; > > + memcpy(buf + readlen, f->rpos, remain); > > + readlen += remain; > > + f->rpos += remain; > > + } > > + > > + return readlen; > > + > > +bail: > > + f->flags |= F_EOF ^ ((F_ERR^F_EOF) & ret); > > + f->rpos = f->rend = f->buf; > > + return readlen; > > +} > > At least the following bugs are still present: > > 1. If len==1, the read func is called twice, and might block the > second time even though the requested read of 1 byte succeeded. > > 2. The return value is wrong. It must be between 0 and len and > represent the amount of data made available to the caller. Buffer > filling is not supposed to be included in that since it's an > internal matter, not something the caller sees. > > 3. A return value <=0 from buffer filling step is not cause to set the > EOF or error indicators, since the part the caller requested > succeeded. But see below... Also: 4. The return value of the second read call is basically ignored, except checking for error/eof. The code just assumes at least `f->buf_size` bytes were read successfully, copying junk out of the buffer back to the caller if fewer were read. Rich
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.