Re: strncpy clarify result may not be null terminated

Alejandro Colomar
2023-11-09T12:35:45Z

[-- Attachment #1: Type: text/plain, Size: 2310 bytes --]

Hi Matthew,

On Thu, Nov 09, 2023 at 01:23:14PM +0100, Alejandro Colomar wrote:
> > > > reasonable to highlight precisely why strncpy(3)'s output isn't a string
> > >
> > > How about this?:
> > >
> > > diff --git a/man3/stpncpy.3 b/man3/stpncpy.3
> > > index d4c2ce83d..c80c8b640 100644
> > > --- a/man3/stpncpy.3
> > > +++ b/man3/stpncpy.3
> > > @@ -108,7 +108,10 @@ .SH HISTORY
> > > .SH CAVEATS
> > > The name of these functions is confusing.
> > > These functions produce a null-padded character sequence,
> > > -not a string (see
> > > +not a string.
> > > +While strings have a terminating NUL byte,
> > > +character sequences do not have any terminating byte
> > > +(see
> > > .BR string_copying (7)).
> > > .P
> > > It's impossible to distinguish truncation by the result of the call,
> >
> > Yes, I'd be perfectly happy with something like that. That way, the
> > scariness is far more immediate ("the output might not be terminated!?"),
> > and thus more accessible to the typical reader.
>
> Ok; I'll add that.

I think DJ's suggestion of providing an example shows this without
needing a wordy explanation:

<https://www.alejandro-colomar.es/src/alx/linux/man-pages/man-pages.git/commit/?h=contrib&id=f502d3290c9f6f13f870cc041f553073af434949>
Here's the page now:

CAVEATS
The name of these functions is confusing. These functions pro‐
duce a null‐padded character sequence, not a string (see
string_copying(7)). For example:

strncpy(buf, "1", 5); // { '1', 0, 0, 0, 0 }
strncpy(buf, "1234", 5); // { '1', '2', '3', '4', 0 }
strncpy(buf, "12345", 5); // { '1', '2', '3', '4', '5' }
strncpy(buf, "123456", 5); // { '1', '2', '3', '4', '5' }

It’s impossible to distinguish truncation by the result of the
call, from a character sequence that just fits the destination
buffer; truncation should be detected by comparing the length of
the input string with the size of the destination buffer.

I think this is quite clear regarding what this functions does and
doesn't.

I'll leave it like that, I think.

Cheers,
Alex

> --
> <https://www.alejandro-colomar.es/>

--
<https://www.alejandro-colomar.es/>