Hi Joseph, On Wed, Oct 09, 2024 at 05:05:16PM GMT, Joseph Myers wrote: > On Wed, 9 Oct 2024, Alejandro Colomar wrote: > > > I'm not fabricating, BTW. Here's a list of off-by-one bugs in login > > code, precisely due to this size-length naming issue: > > <https://github.com/shadow-maint/shadow/commit/6551709e96b2bc6f084fdf170ad5bcc11f0038ab> > > <https://github.com/shadow-maint/shadow/commit/15882a5f904b3c277d73254a6953c1051db55df4> > > Those don't look to me like they're much to do with size/length *naming* > confusion. It's a conceptual confusion about whether the value needed by > a particular API includes a null terminator or not, not about what you > call size and what you call length.
The documentation of an API starts by its prototype. void login_prompt(char *name, int len); void login_prompt(char *name, int size); The former should _not_ include a NUL terminator in the argument. The latter should. If those names are meaningless, there are more chances of being confused. The bugs were introduced in <https://github.com/shadow-maint/shadow/commit/3b7cc053872cf4ce77fd74dc037f43f34e951e83> which changed old code that was misusing the term length for referring to the size (or number of elements, pedantically), for code that used the actual size. The author of the change didn't give much meaning to the difference between size and length, and thought they were interchangeable, and so the bugs were introduced. As long as one has a clear distinction, that wouldn't have happened. > As such, a name without "length" > wouldn't help, because if you say countof, there would still be the same > confusion about whether the bytes you are counting are meant to include a > null terminator or not. There are 3 terms: - size: Size in bytes of an object (possibly an array). - length: Number of non-null characters in a string. - n: Number of elements of an array. When the array is of char, since sizeof(char)==1, size and n are interchangeable, and both obviously include the NUL terminator. If you prefer nelementsof() over countof(), I'm all-in for it. Just ask for it, and I'll send a patch using nelementsof(). countof() is a new term, so it doesn't yet have a meaning (except as given by the attribute), but it naturally fits more with number of elements. But from all of the terms that there are, length is the only one that doesn't include the NUL, so count is fine. As long as you don't use length, it should include the NUL. > > You could maybe avoid some cases of such off-by-one errors by language > features that tie an array length more closely to a pointer (such as > .IDENTIFIER proposals where IDENTIFIER is required to be const size_t, in > cases where a pointer-to-VLA is passed, if there were appropriate > constraints to require a matching pair of const size_t object and pointer > to [.IDENTIFIER] VLA to be passed from caller to callee - more general > versions with such strict requirements about passing matching pairs would > be less likely to ensure correct sizes everywhere, and this idea about > ensuring matching pairs isn't in N3188, it's an idea combining things from > multiple papers). Yeah, Martin and I have the intention of moving in that direction. countof() [or whatever the name is] will hopefully soon work on array parameters. > But I think naming is essentially orthogonal to any > kind of language feature that might enable reliable bounded pointers. I still think conceptual confusions like this one (two) start with API design and documentation, which itself starts in API naming. Have a lovely night! Alex -- <https://www.alejandro-colomar.es/>
signature.asc
Description: PGP signature