Date: Mon, 2 Sep 2019 09:51:47 -0500 From: Pedro Giffuni <pfg@FreeBSD.org> To: Cy Schubert <Cy.Schubert@cschubert.com>, cem@freebsd.org Cc: src-committers <src-committers@freebsd.org>, svn-src-all <svn-src-all@freebsd.org>, svn-src-head <svn-src-head@freebsd.org> Subject: Re: svn commit: r351659 - in head: contrib/libc++/include contrib/netbsd-tests/lib/libc/ssp gnu/lib/libssp include lib/libc/stdio Message-ID: <df24880b-8fec-fca3-8e31-9c7ca68c5463@FreeBSD.org> In-Reply-To: <201909020336.x823ar42054344@slippy.cwsent.com> References: <201909011612.x81GC5DW097846@repo.freebsd.org> <201909011932.x81JWYts004074@slippy.cwsent.com> <CAG6CVpVMN6BkATaz7qqhaVHhUpqQLrP3kSWHpMzPz2AR5GnaQw@mail.gmail.com> <201909012223.x81MN7jK005967@slippy.cwsent.com> <CAG6CVpW4Mj-w7SeB=nu7MHiH%2BgvkMeB9v8ojLgpnrvmN0Oo%2Bgg@mail.gmail.com> <201909020336.x823ar42054344@slippy.cwsent.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On 01/09/2019 22:36, Cy Schubert wrote: > In message <CAG6CVpW4Mj-w7SeB=nu7MHiH+gvkMeB9v8ojLgpnrvmN0Oo+gg@mail.gmail.c > om> > , Conrad Meyer writes: >> Hi Cy, >> >> On Sun, Sep 1, 2019 at 3:23 PM Cy Schubert <Cy.Schubert@cschubert.com> wrote: >>> In message <CAG6CVpVMN6BkATaz7qqhaVHhUpqQLrP3kSWHpMzPz2AR5GnaQw@mail.gmail. >> c >>> om> >>> , Conrad Meyer writes: >>> >>>> Short version: no, we shouldn't [recommend the use of gets_s]. :-) >>>> >>>> Longer version: Annex K functions like gets_s have zero real adoption >>>> (Microsoft's APIs that inspired Annex K are not actually compatible >>>> with the version in the standards); broadly terrible APIs; and in this >>>> particular case and others, unnecessarily duplicate the functionality >>>> of existing long-standing standard C functions (e.g., fgets(3)). >>> That's not quite true. From the man page: >>> >>> The gets_s() function is equivalent to fgets() with a stream of stdin, >>> except that the newline character (if any) is not stored in the string >> . >> >> I tried to make a distinction earlier that I don't think carried well >> over email. I wrote "unnecessarily duplicate(s) the _functionality_ >> of existing …" — not "is/are an exact duplicate(s) of …" — because >> you're right, gets_s() has (trivial) behavioral differences from >> fgets(stdin). >> >> The thing that is important to me is that fgets(3) is portable, super >> well understood, and provides a superset of the functionality of >> gets_s(). One can easily construct the newline-free version of a line >> from one containing a trailing newline. I don't think this slight >> behavioral difference justifies implementing, using, or especially >> recommending gets_s(). > If Microsoft chooses to ignore or anotherfunctions is their problem. > However in this case, according to the following they do support gets_s(). > https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/gets-s-getw > s-s?view=vs-2019 > > Having said all that, glibc is the odd man out here. In that case I'll pull > back my horns. It's sufficient not to not say anything or to highlight both. > > BTW. we've had gets_s(3) in our tree for 17 months now. We don't need to > add anything. It's already there. > > It is an application developer choice to use one function or another. > > As someone who also works on the ports side, the newline is significant > distinction. As gets_s() is closer in function to gets() than fgets() is, > all one > needs to concern oneself with is buffer length. As there are no _other_ > differences nothing else needs to be addressed. This is important to ports > maintainers and who must replace gets() with something else. Agreed this > shouldn't be an issue every time but gets_s() is still in our toolbox. > >> (IMO, it was probably a historical mistake that gets(3) even had >> different behavior than fgets(3) to begin with. gets(3) maybe >> predated stdio FILE streams?) > I totally agree. > >>> Some apps may be sensitive to this subtle difference. gets_s() preserves >>> this behaviour. >> Correct conversion of gets()-using programs requires more analysis >> than blind replacement with either function. > That's where gets_s() is handy. It requires less analysis. Remember, my > main concern here are our ports maintainers. Upstream developers should > always do analysis. It's not the job of the ports team to perform > significant rewrites of upstream software. IMO, if upsteam software needs > significant rewrite a port maintainer should notify the upstream > maintainer. If the upstream cannot or will not, requiring a maintainer of a > port to make significant changes, DEPRECATED= and EXPIRATION_DATE= are the > best answer. We are not here to rewrite other people's software for them. > >> Anyway, gets() use is largely behind us so the point is mostly moot — >> there are few such programs to convert, and they should be viewed with >> an extremely high level of skepticism given they are still using >> gets(3) in 2019. > I'm not arguing for keeping gets(3). We already have gets_s(3). Let's use > it where it makes sense. Nor am I saying to use it in exclusion of > fgets(3). It (gets_s()) is in our libc. If it eases the job of maintaining > a port, use it instead. > >>> [Annex K functions] are part of the >>> standard >> They're an optional part of the standard. Everyone takes the option >> of "not." Literally no one implements Annex K. It's a bad set of >> APIs. > Microsoft and we have chosen to implement some Annex K functions. We > haven't implemented all of them. I don't know if they implemented all _s > functions. Linux glibc has not. > > I don't agree that it's a completely bad set of APIs. gets_s() will help > ports maintainers. AFAIK, no ports rely on gets() but that's not to say > some new port might not. Don't forget, my motivation for implementing > gets_s(3) in libc was to ease the pain of deprecating gets() for ports. > >>> and though we support some _s functions it would behoove us to one >>> day (*) support them all. >> If and when the C standard committee adopts Annex K as a required part >> of the standard, then I agree we should make every attempt to support >> the full standard library. But in general, I am opposed to the >> further adoption of Annex K, and hope the C2x standard committee >> finally drops the annex.[1] (It is weakly defended[2], just to >> provide a counterargument.) > Again I disagree. > >> [1]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1967.htm (pro-removal) > This explains glibc's not implementing the _s functions. His focus is > almost entirely on string copy and memory copy functions. Implementation of > string and memory copy functions would be more complex than the gets_s() I > added to FreeBSD. In terms of error detection (for calls to constraint > handlers), gets_s() is simple compared to strcpy_s(). I can understand his > issues. It would appear a similar lack of consideration of implementation > details went into defining the _s string functions as the lack of > consistency considerations went into the development of gets() and fgets(). > > https://en.cppreference.com/w/c/string/byte/strcpy, where clobbring the > rest of the destination is IMO "not optimal." Throwing out the baby > (functions which were properly defined) with the bath water (functions > which make one wonder what they were smoking) isn't the right answer either. > >> [2]: https://www.nccgroup.trust/us/our-research/bounds-checking-interfaces-fi >> eld-experience-and-future-directions/ >> (pro-retention) > I don't have time to read completely through all of this tonight. The > assertion that there are unfounded criticisms as well as actual flaws. The > flaws are such that replacing some functions with _s will require some > care. Fortunately with gets_s() this is not a concern, except of course > having to specify a buffer length. A constraint handler is not required. > IMO constraint handlers add unnecessary complexity, good thing they are > optional. > >>> I'm also sure some ports will probably break. >> Check the exp-run PR: 222796 (comment #7). 13 ports. Out of 37601, >> according to FreshPorts. Of those 13, eight don't have a maintainer. > Already did. Should someone choose to fix them we the tools are there. > > I doubt you will convince me nor I convince you. > > I'm not sure if you or anyone else has a copy of the standard. (I suspect > you already have these but maybe someone else might find them useful.) > > http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf > http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3631.pdf FWIW, Intel has a safestringlib project which implements many of the _s functions: https://github.com/intel/safestringlib Microsoft has a related policy since 2012: https://docs.microsoft.com/en-us/previous-versions/bb288454(v=msdn.10) but perhaps nowadays we may want to be ready for rust modules. Cheers, Pedro.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?df24880b-8fec-fca3-8e31-9c7ca68c5463>