Message ID | 20240626152549.235799-1-eggert@cs.ucla.edu |
---|---|
State | New |
Headers | show |
Series | [COMMITTED] Fix strnlen doc re array size | expand |
On 2024-06-26 16:25:43 +0100, Paul Eggert wrote: > diff --git a/manual/string.texi b/manual/string.texi > index b91299fd6a..0b667bd3fb 100644 > --- a/manual/string.texi > +++ b/manual/string.texi > @@ -309,12 +309,12 @@ This function was introduced in @w{Amendment 1} to @w{ISO C90}. > @end deftypefun > > @deftypefun size_t strnlen (const char *@var{s}, size_t @var{maxlen}) > -@standards{GNU, string.h} > +@standards{POSIX.1, string.h} > @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} > -If the array @var{s} of size @var{maxlen} contains a null byte, > -the @code{strnlen} function returns the length of the string @var{s} in > -bytes. Otherwise it > -returns @var{maxlen}. Therefore this function is equivalent to > +This returns the offset of the first null byte in the array @var{s}, > +except that it returns @var{maxlen} if the first @var{maxlen} bytes > +are all non-null. This disagrees with the strnlen(3) man page from Linux man-pages 6.8, which requires s to be a string, i.e. null-terminated (though the null byte may be beyond the first maxlen bytes). However, it seems that POSIX does not have such a requirement. So, what's the actual status? Note: While at run time, there should be no visible difference, this can matter for compiler optimization to regard code as dead code if it can detect that some requirement is not satisfied.
On 6/26/24 11:52, Vincent Lefevre wrote: > This disagrees with the strnlen(3) man page from Linux man-pages 6.8, > which requires s to be a string, i.e. null-terminated (though the > null byte may be beyond the first maxlen bytes). > > However, it seems that POSIX does not have such a requirement. > > So, what's the actual status? The actual status is that the Linux man page is wrong, and needs to be fixed. The glibc code is supposed to conform to POSIX, and to the recently-updated manual which is merely POSIX reworded. (I assume the glibc code does conform but I have not checked this.) If you read the thread I cited, this topic came up because Android got it wrong a while back (fixed in Android 5.1).
* Paul Eggert: > * manual/string.texi: For strnlen (s, maxlen), do not say that s must > be of size maxlen, as it can be smaller if it is null-terminated. > This should help avoid confusion such as seen in > <https://lists.gnu.org/r/bug-gnulib/2024-06/msg00280.html>. > Mention that strnlen and wcsnlen have been in POSIX since > POSIX.1-2008. > --- > manual/string.texi | 17 ++++++++++------- > 1 file changed, 10 insertions(+), 7 deletions(-) > > diff --git a/manual/string.texi b/manual/string.texi > index b91299fd6a..0b667bd3fb 100644 > --- a/manual/string.texi > +++ b/manual/string.texi > @@ -309,12 +309,12 @@ This function was introduced in @w{Amendment 1} to @w{ISO C90}. > @end deftypefun > > @deftypefun size_t strnlen (const char *@var{s}, size_t @var{maxlen}) > -@standards{GNU, string.h} > +@standards{POSIX.1, string.h} > @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} > -If the array @var{s} of size @var{maxlen} contains a null byte, > -the @code{strnlen} function returns the length of the string @var{s} in > -bytes. Otherwise it > -returns @var{maxlen}. Therefore this function is equivalent to > +This returns the offset of the first null byte in the array @var{s}, > +except that it returns @var{maxlen} if the first @var{maxlen} bytes > +are all non-null. > +Therefore this function is equivalent to > @code{(strlen (@var{s}) < @var{maxlen} ? strlen (@var{s}) : @var{maxlen})} > but it > is more efficient and works even if @var{s} is not null-terminated so I have an alternate proposal that makes it possible to use strnlen as bounded strlen (that is, the input does not have to be an array object of the specified size). A lot of software already assumes that implementations provide this extension. Thanks, Florian
diff --git a/manual/string.texi b/manual/string.texi index b91299fd6a..0b667bd3fb 100644 --- a/manual/string.texi +++ b/manual/string.texi @@ -309,12 +309,12 @@ This function was introduced in @w{Amendment 1} to @w{ISO C90}. @end deftypefun @deftypefun size_t strnlen (const char *@var{s}, size_t @var{maxlen}) -@standards{GNU, string.h} +@standards{POSIX.1, string.h} @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} -If the array @var{s} of size @var{maxlen} contains a null byte, -the @code{strnlen} function returns the length of the string @var{s} in -bytes. Otherwise it -returns @var{maxlen}. Therefore this function is equivalent to +This returns the offset of the first null byte in the array @var{s}, +except that it returns @var{maxlen} if the first @var{maxlen} bytes +are all non-null. +Therefore this function is equivalent to @code{(strlen (@var{s}) < @var{maxlen} ? strlen (@var{s}) : @var{maxlen})} but it is more efficient and works even if @var{s} is not null-terminated so @@ -328,7 +328,9 @@ strnlen (string, 5) @result{} 5 @end smallexample -This function is a GNU extension and is declared in @file{string.h}. +This function is part of POSIX.1-2008 and later editions, but was +available in @theglibc{} and other systems as an extension long before +it was standardized. It is declared in @file{string.h}. @end deftypefun @deftypefun size_t wcsnlen (const wchar_t *@var{ws}, size_t @var{maxlen}) @@ -337,7 +339,8 @@ This function is a GNU extension and is declared in @file{string.h}. @code{wcsnlen} is the wide character equivalent to @code{strnlen}. The @var{maxlen} parameter specifies the maximum number of wide characters. -This function is a GNU extension and is declared in @file{wchar.h}. +This function is part of POSIX.1-2008 and later editions, and is +declared in @file{wchar.h}. @end deftypefun @node Copying Strings and Arrays