From d80d40e9b289fa9cb88e883817a4348331c3dcf3 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Fri, 5 Dec 2025 18:12:02 +0100 Subject: [PATCH 1/2] autogen.sh: Enable -Werror=stringop-* diagnostics We can't enable -Wstringop-overread because it has bogus diagnostics with legitimate strncat(3) calls. Link: Signed-off-by: Alejandro Colomar --- autogen.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/autogen.sh b/autogen.sh index 1e5278faa9..761a0b21ea 100755 --- a/autogen.sh +++ b/autogen.sh @@ -12,6 +12,8 @@ CFLAGS="$CFLAGS -Werror=incompatible-pointer-types" CFLAGS="$CFLAGS -Werror=int-conversion" CFLAGS="$CFLAGS -Werror=sign-compare" CFLAGS="$CFLAGS -Werror=sizeof-pointer-div" +CFLAGS="$CFLAGS -Werror=stringop-overflow=4" +CFLAGS="$CFLAGS -Werror=stringop-truncation" CFLAGS="$CFLAGS -Werror=unused-but-set-parameter" CFLAGS="$CFLAGS -Werror=unused-function" CFLAGS="$CFLAGS -Werror=unused-label" From 5284b68308cddee6c571dd2959f869128c6bda18 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Fri, 21 Feb 2025 10:22:36 +0100 Subject: [PATCH 2/2] tests/unit/test_strncpy.c: Remove strncpy_a() tests It's just the obvious thin wrapper around strncpy(3); let's trust it's ok. The reason for removing this test is that GCC has bogus diagnostics for strncpy(3). Its diagnostics are geared towards helping people that abuse strncpy(3) as a poor-man's strlcpy(3) not write exploitable code as easily. Using strncpy(3) for that purpose is brain damaged, and those programs should be audited to stop using this API for that. And most importantly, GCC should stop encouraging writing bad code that calls strncpy(3) as that results in diagnostics that are actively harmful for us, legitimate users of strncpy(3). Those false positives should certainly be out of -Wall. We could fill the tests with pragmas, but let's just remove the tests. I don't feel like maintaining code for ignoring GCC's brain bamage. If people want to write a function for truncating strings (because they can't rely on strlcpy(3) being available, or because they don't like it), they certainly should write such an API. strncpy(3) isn't that API. strncpy(3) is a function that takes a string and writes it into a utmpx(5) member, which is NOT a string. (And I heard it might also be useful for implementing tar(1), which also uses non-terminated character arrays, but I never looked at that code.) Link: Signed-off-by: Alejandro Colomar --- tests/unit/Makefile.am | 13 ------ tests/unit/test_strncpy.c | 85 --------------------------------------- 2 files changed, 98 deletions(-) delete mode 100644 tests/unit/test_strncpy.c diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am index 250004ef6a..5b4712517b 100644 --- a/tests/unit/Makefile.am +++ b/tests/unit/Makefile.am @@ -8,7 +8,6 @@ check_PROGRAMS = \ test_atoi_strtoi \ test_chkname \ test_snprintf \ - test_strncpy \ test_strtcpy \ test_typetraits \ test_exit_if_null @@ -92,18 +91,6 @@ test_snprintf_LDADD = \ $(CMOCKA_LIBS) \ $(NULL) -test_strncpy_SOURCES = \ - test_strncpy.c \ - $(NULL) -test_strncpy_CFLAGS = \ - $(AM_CFLAGS) \ - $(NULL) -test_strncpy_LDFLAGS = \ - $(NULL) -test_strncpy_LDADD = \ - $(CMOCKA_LIBS) \ - $(NULL) - test_strtcpy_SOURCES = \ ../../lib/string/strcpy/strtcpy.c \ test_strtcpy.c \ diff --git a/tests/unit/test_strncpy.c b/tests/unit/test_strncpy.c deleted file mode 100644 index 3da043154e..0000000000 --- a/tests/unit/test_strncpy.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023, Alejandro Colomar - * SPDX-License-Identifier: BSD-3-Clause - */ - - -#include "config.h" - -#include - -#include // Required by -#include // Required by -#include // Required by -#include // Required by -#include - -#include "sizeof.h" -#include "string/strcpy/strncpy.h" - - -static void test_strncpy_a_trunc(void **); -static void test_strncpy_a_fit(void **); -static void test_strncpy_a_pad(void **); - - -int -main(void) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(test_strncpy_a_trunc), - cmocka_unit_test(test_strncpy_a_fit), - cmocka_unit_test(test_strncpy_a_pad), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); -} - - -static void -test_strncpy_a_trunc(void **) -{ - char buf[3]; - - char src1[4] = {'f', 'o', 'o', 'o'}; - char res1[3] = {'f', 'o', 'o'}; - assert_true(memcmp(res1, strncpy_a(buf, src1), sizeof(buf)) == 0); - - char src2[5] = "barb"; - char res2[3] = {'b', 'a', 'r'}; - assert_true(memcmp(res2, strncpy_a(buf, src2), sizeof(buf)) == 0); -} - - -static void -test_strncpy_a_fit(void **) -{ - char buf[3]; - - char src1[3] = {'b', 'a', 'z'}; - char res1[3] = {'b', 'a', 'z'}; - assert_true(memcmp(res1, strncpy_a(buf, src1), sizeof(buf)) == 0); - - char src2[4] = "qwe"; - char res2[3] = {'q', 'w', 'e'}; - assert_true(memcmp(res2, strncpy_a(buf, src2), sizeof(buf)) == 0); -} - - -static void -test_strncpy_a_pad(void **) -{ - char buf[3]; - - char src1[3] = "as"; - char res1[3] = {'a', 's', 0}; - assert_true(memcmp(res1, strncpy_a(buf, src1), sizeof(buf)) == 0); - - char src2[3] = ""; - char res2[3] = {0, 0, 0}; - assert_true(memcmp(res2, strncpy_a(buf, src2), sizeof(buf)) == 0); - - char src3[3] = {'a', 0, 'b'}; - char res3[3] = {'a', 0, 0}; - assert_true(memcmp(res3, strncpy_a(buf, src3), sizeof(buf)) == 0); -}