svn commit: r351659 - in head: contrib/libc++/include contrib/netbsd-tests/lib/libc/ssp gnu/lib/libssp include lib/libc/stdio

Pedro Giffuni pfg at FreeBSD.org
Mon Sep 2 14:51:49 UTC 2019


On 01/09/2019 22:36, Cy Schubert wrote:
> In message <CAG6CVpW4Mj-w7SeB=nu7MHiH+gvkMeB9v8ojLgpnrvmN0Oo+gg at mail.gmail.c
> om>
> , Conrad Meyer writes:
>> Hi Cy,
>>
>> On Sun, Sep 1, 2019 at 3:23 PM Cy Schubert <Cy.Schubert at cschubert.com> wrote:
>>> In message <CAG6CVpVMN6BkATaz7qqhaVHhUpqQLrP3kSWHpMzPz2AR5GnaQw at 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.



More information about the svn-src-head mailing list