diff mbox series

[COMMITTED] Fix strnlen doc re array size

Message ID 20240626152549.235799-1-eggert@cs.ucla.edu
State New
Headers show
Series [COMMITTED] Fix strnlen doc re array size | expand

Commit Message

Paul Eggert June 26, 2024, 3:25 p.m. UTC
* 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(-)

Comments

Vincent Lefevre June 26, 2024, 3:52 p.m. UTC | #1
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.
Paul Eggert June 26, 2024, 3:56 p.m. UTC | #2
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).
Florian Weimer June 27, 2024, 6:21 a.m. UTC | #3
* 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 mbox series

Patch

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