[-Wstringop-overflow=] strncat(3)

Alejandro Colomar alx.manpages@gmail.com
Wed Dec 14 22:51:11 GMT 2022



On 12/14/22 23:45, Alejandro Colomar wrote:
> Hi,
> 
> I was rewriting the strncat(3) manual page, and when I tried to compile the 
> example program, I got a surprise from the compiler.
> 
> Here goes the page:
> 
> 
>    strncat(3)               Library Functions Manual              strncat(3)
> 
>    NAME
>           strncat  -  concatenate  a  null‐padded  character sequence into a
>           string
> 
>    LIBRARY
>           Standard C library (libc, -lc)
> 
>    SYNOPSIS
>           #include <string.h>
> 
>           char *strncat(char *restrict dst, const char src[restrict .sz],
>                          size_t sz);
> 
>    DESCRIPTION
>           This function catenates the input character sequence contained  in
>           a  null‐padded  fixed‐width  buffer,  into  a string at the buffer
>           pointed to by dst.  The programmer is responsible for allocating a
>           buffer large enough, that is, strlen(dst) + strnlen(src, sz) + 1.
> 
>           An implementation of this function might be:
> 
>               char *
>               strncat(char *restrict dst, const char *restrict src, size_t sz)
>               {
>                   int   len;
>                   char  *end;
> 
>                   len = strnlen(src, sz);
>                   end = dst + strlen(dst);
>                   end = mempcpy(end, src, len);
>                   *end = '\0';
> 
>                   return dst;
>               }
> 
>    RETURN VALUE
>           strncat() returns dest.
> 
>    ATTRIBUTES
>           [...]
> 
>    STANDARDS
>           POSIX.1‐2001, POSIX.1‐2008, C89, C99, SVr4, 4.3BSD.
> 
>    CAVEATS
>           The  name of this function is confusing.  This function has no re‐
>           lation with strncpy(3).
> 
>           If the destination buffer is not large enough, the behavior is un‐
>           defined.  See _FORTIFY_SOURCE in feature_test_macros(7).
> 
>    BUGS
>           This function  can  be  very  inefficient.   Read  about  Shlemiel
>           the       painter      ⟨https://www.joelonsoftware.com/2001/12/11/
>           back-to-basics/⟩.
> 
>    EXAMPLES
>           #include <stdio.h>
>           #include <stdlib.h>
>           #include <string.h>
> 
>           int
>           main(void)
>           {
>               char    buf[BUFSIZ];
>               size_t  len;
> 
>               buf[0] = '\0';  // There’s no ’cpy’ function to this ’cat’.
>               strncat(buf, "Hello ", 6);
>               strncat(buf, "world", 42);  // Padding null bytes ignored.
>               strncat(buf, "!", 1);
>               len = strlen(buf);
>               printf("[len = %zu]: <%s>\n", len, buf);
> 
>               exit(EXIT_SUCCESS);
>           }
> 
>    SEE ALSO
>           string(3), string_copy(3)
> 
>    Linux man‐pages (unreleased)      (date)                       strncat(3)
> 
> 
> And when you compile that, you get:
> 
> $ cc -Wall -Wextra ./strncat.c
> ./strncat.c: In function ‘main’:
> ./strncat.c:12:12: warning: ‘strncat’ specified bound 6 equals source length 
> [-Wstringop-overflow=]
>     12 |            strncat(buf, "Hello ", 6);
>        |            ^~~~~~~~~~~~~~~~~~~~~~~~~
> ./strncat.c:14:12: warning: ‘strncat’ specified bound 1 equals source length 
> [-Wstringop-overflow=]
>     14 |            strncat(buf, "!", 1);
>        |            ^~~~~~~~~~~~~~~~~~~~
> 
> 
> So, what?  Where's the problem?  This function does exactly that: "take an 
> unterminated character sequence and catenate it to an existing string".  Clang 
> seems to be fine with the code.

Maybe it's saying that I should be using strncat(buf, "!"); because the length 
is useless?

> 
> Cheers,
> 
> Alex
> 
> 

-- 
<http://www.alejandro-colomar.es/>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <https://gcc.gnu.org/pipermail/gcc/attachments/20221214/03e85ed0/attachment.sig>


More information about the Gcc mailing list