From: Guy Harris Date: Tue, 10 Dec 2024 18:55:23 +0000 (-0800) Subject: autotools, CMake: fix issues with snprintf test and sanitizers. X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/88d983dd05b6da66e4e1cd6b1d74ff7b28ad931c autotools, CMake: fix issues with snprintf test and sanitizers. Avoid trying to cast negative values to unsigned types, or doing shifts of signed types, in order not to have the test program fail if we're building with undefined-behavior sanitizers enabled. See the-tcpdump-group/libpcap#1396 for the equivalent libpcap issue. (cherry picked from commit b7bd627c96f7a70446e4837ca7d5acd6d8122ce2) --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 989f7eb9..538e02f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -539,32 +539,50 @@ if (NOT CMAKE_CROSSCOMPILING) #include #include + #if defined(_WIN32) && !defined(_SSIZE_T_DEFINED) + /* + * On UN*Xes, this is a signed integer type of the same size as size_t. + * + * It's not defined by Visual Studio; we assume that ptrdiff_t will + * be a type that is a signed integer type of the same size as size_t. + */ + typedef ptrdiff_t ssize_t; + #endif + + /* + * Avoid trying to cast negative values to unsigned types, or doing + * shifts of signed types, in order not to have the test program fail + * if we're building with undefined-behavior sanitizers enabled. + */ int main() { char buf[100]; - uint64_t t = (uint64_t)1 << 32; + unsigned int ui = sizeof(buf); + int i = sizeof(buf); + int64_t i64 = INT64_C(0x100000000); + uint64_t ui64 = UINT64_C(0x100000000); - snprintf(buf, sizeof(buf), \"%zu\", sizeof(buf)); + snprintf(buf, sizeof(buf), \"%zu\", (size_t)ui); if (strncmp(buf, \"100\", sizeof(buf))) return 1; - snprintf(buf, sizeof(buf), \"%zd\", -sizeof(buf)); + snprintf(buf, sizeof(buf), \"%zd\", (ssize_t)(-i)); if (strncmp(buf, \"-100\", sizeof(buf))) return 2; - snprintf(buf, sizeof(buf), \"%\" PRId64, -t); + snprintf(buf, sizeof(buf), \"%\" PRId64, -i64); if (strncmp(buf, \"-4294967296\", sizeof(buf))) return 3; - snprintf(buf, sizeof(buf), \"0o%\" PRIo64, t); + snprintf(buf, sizeof(buf), \"0o%\" PRIo64, ui64); if (strncmp(buf, \"0o40000000000\", sizeof(buf))) return 4; - snprintf(buf, sizeof(buf), \"0x%\" PRIx64, t); + snprintf(buf, sizeof(buf), \"0x%\" PRIx64, ui64); if (strncmp(buf, \"0x100000000\", sizeof(buf))) return 5; - snprintf(buf, sizeof(buf), \"%\" PRIu64, t); + snprintf(buf, sizeof(buf), \"%\" PRIu64, ui64); if (strncmp(buf, \"4294967296\", sizeof(buf))) return 6; diff --git a/configure.ac b/configure.ac index 510b2624..ae4500e9 100644 --- a/configure.ac +++ b/configure.ac @@ -468,32 +468,50 @@ AC_RUN_IFELSE( #include #include +#if defined(_WIN32) && !defined(_SSIZE_T_DEFINED) +/* + * On UN*Xes, this is a signed integer type of the same size as size_t. + * + * It's not defined by Visual Studio; we assume that ptrdiff_t will + * be a type that is a signed integer type of the same size as size_t. + */ +typedef ptrdiff_t ssize_t; +#endif + +/* + * Avoid trying to cast negative values to unsigned types, or doing + * shifts of signed types, in order not to have the test program fail + * if we're building with undefined-behavior sanitizers enabled. + */ int main() { char buf[100]; - uint64_t t = (uint64_t)1 << 32; + unsigned int ui = sizeof(buf); + int i = sizeof(buf); + int64_t i64 = INT64_C(0x100000000); + uint64_t ui64 = UINT64_C(0x100000000); - snprintf(buf, sizeof(buf), "%zu", sizeof(buf)); + snprintf(buf, sizeof(buf), "%zu", (size_t)ui); if (strncmp(buf, "100", sizeof(buf))) return 1; - snprintf(buf, sizeof(buf), "%zd", -sizeof(buf)); + snprintf(buf, sizeof(buf), "%zd", (ssize_t)(-i)); if (strncmp(buf, "-100", sizeof(buf))) return 2; - snprintf(buf, sizeof(buf), "%" PRId64, -t); + snprintf(buf, sizeof(buf), "%" PRId64, -i64); if (strncmp(buf, "-4294967296", sizeof(buf))) return 3; - snprintf(buf, sizeof(buf), "0o%" PRIo64, t); + snprintf(buf, sizeof(buf), "0o%" PRIo64, ui64); if (strncmp(buf, "0o40000000000", sizeof(buf))) return 4; - snprintf(buf, sizeof(buf), "0x%" PRIx64, t); + snprintf(buf, sizeof(buf), "0x%" PRIx64, ui64); if (strncmp(buf, "0x100000000", sizeof(buf))) return 5; - snprintf(buf, sizeof(buf), "%" PRIu64, t); + snprintf(buf, sizeof(buf), "%" PRIu64, ui64); if (strncmp(buf, "4294967296", sizeof(buf))) return 6;