From ff844df719d7226a46b8cb0d99aef9480cced247 Mon Sep 17 00:00:00 2001 From: Aly ElAshram <71949028+AlyElashram@users.noreply.github.com> Date: Wed, 4 Jun 2025 20:08:27 +0300 Subject: [PATCH] [libc] Expand usage of libc null checks. (#116262) Fixes #111546 --------- Co-authored-by: alyyelashram <150528548+alyyelashram@users.noreply.github.com> --- libc/src/string/memccpy.cpp | 5 +++++ libc/src/string/memchr.cpp | 3 +++ libc/src/string/memcmp.cpp | 5 +++++ libc/src/string/memcpy.cpp | 5 +++++ libc/src/string/memmove.cpp | 5 +++++ libc/src/string/mempcpy.cpp | 5 +++++ libc/src/string/memrchr.cpp | 5 +++++ libc/src/string/memset.cpp | 4 ++++ libc/src/string/stpncpy.cpp | 5 +++++ libc/src/string/strcasestr.cpp | 4 ++++ libc/src/string/strcat.cpp | 3 +++ libc/src/string/strcoll.cpp | 3 +++ libc/src/string/strcoll_l.cpp | 3 +++ libc/src/string/strcpy.cpp | 2 ++ libc/src/string/strlen.cpp | 2 ++ libc/src/string/strncat.cpp | 5 +++++ libc/src/string/strncmp.cpp | 5 +++++ libc/src/string/strncpy.cpp | 5 +++++ libc/src/string/strsep.cpp | 3 +++ libc/src/string/strspn.cpp | 3 +++ libc/src/string/strstr.cpp | 3 +++ libc/src/strings/rindex.cpp | 2 ++ libc/test/src/string/memchr_test.cpp | 10 ++++++++++ libc/test/src/string/memcmp_test.cpp | 10 ++++++++++ libc/test/src/string/memcpy_test.cpp | 9 +++++++++ libc/test/src/string/memmove_test.cpp | 10 ++++++++++ libc/test/src/string/mempcpy_test.cpp | 11 ++++++++++- libc/test/src/string/memrchr_test.cpp | 10 ++++++++++ libc/test/src/string/memset_test.cpp | 10 ++++++++++ libc/test/src/string/stpncpy_test.cpp | 10 ++++++++++ libc/test/src/string/strcat_test.cpp | 10 ++++++++++ libc/test/src/string/strcoll_test.cpp | 10 ++++++++++ libc/test/src/string/strcpy_test.cpp | 10 ++++++++++ libc/test/src/string/strlcpy_test.cpp | 4 ++-- libc/test/src/string/strsep_test.cpp | 10 ++++++++++ libc/test/src/string/strspn_test.cpp | 10 ++++++++++ 36 files changed, 216 insertions(+), 3 deletions(-) diff --git a/libc/src/string/memccpy.cpp b/libc/src/string/memccpy.cpp index ae90cf9370d4..d5654fc5e46a 100644 --- a/libc/src/string/memccpy.cpp +++ b/libc/src/string/memccpy.cpp @@ -10,6 +10,7 @@ #include "src/__support/common.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" #include // For size_t. namespace LIBC_NAMESPACE_DECL { @@ -17,6 +18,10 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(void *, memccpy, (void *__restrict dest, const void *__restrict src, int c, size_t count)) { + if (count) { + LIBC_CRASH_ON_NULLPTR(dest); + LIBC_CRASH_ON_NULLPTR(src); + } unsigned char end = static_cast(c); const unsigned char *uc_src = static_cast(src); unsigned char *uc_dest = static_cast(dest); diff --git a/libc/src/string/memchr.cpp b/libc/src/string/memchr.cpp index ba52f14afa9d..ccdc262837cd 100644 --- a/libc/src/string/memchr.cpp +++ b/libc/src/string/memchr.cpp @@ -8,6 +8,7 @@ #include "src/string/memchr.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" #include "src/string/string_utils.h" #include "src/__support/common.h" @@ -17,6 +18,8 @@ namespace LIBC_NAMESPACE_DECL { // TODO: Look at performance benefits of comparing words. LLVM_LIBC_FUNCTION(void *, memchr, (const void *src, int c, size_t n)) { + if (n) + LIBC_CRASH_ON_NULLPTR(src); return internal::find_first_character( reinterpret_cast(src), static_cast(c), n); diff --git a/libc/src/string/memcmp.cpp b/libc/src/string/memcmp.cpp index 68996fb78723..d2f67f0478ef 100644 --- a/libc/src/string/memcmp.cpp +++ b/libc/src/string/memcmp.cpp @@ -8,6 +8,7 @@ #include "src/string/memcmp.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" #include "src/string/memory_utils/inline_memcmp.h" #include // size_t @@ -16,6 +17,10 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, memcmp, (const void *lhs, const void *rhs, size_t count)) { + if (count) { + LIBC_CRASH_ON_NULLPTR(lhs); + LIBC_CRASH_ON_NULLPTR(rhs); + } return inline_memcmp(lhs, rhs, count); } diff --git a/libc/src/string/memcpy.cpp b/libc/src/string/memcpy.cpp index 0eb7f2c170e0..4d4ff4dd3872 100644 --- a/libc/src/string/memcpy.cpp +++ b/libc/src/string/memcpy.cpp @@ -9,6 +9,7 @@ #include "src/string/memcpy.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" #include "src/string/memory_utils/inline_memcpy.h" namespace LIBC_NAMESPACE_DECL { @@ -16,6 +17,10 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(void *, memcpy, (void *__restrict dst, const void *__restrict src, size_t size)) { + if (size) { + LIBC_CRASH_ON_NULLPTR(dst); + LIBC_CRASH_ON_NULLPTR(src); + } inline_memcpy(dst, src, size); return dst; } diff --git a/libc/src/string/memmove.cpp b/libc/src/string/memmove.cpp index 26a8c4187f3d..04ed51b84f8f 100644 --- a/libc/src/string/memmove.cpp +++ b/libc/src/string/memmove.cpp @@ -8,6 +8,7 @@ #include "src/string/memmove.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" #include "src/string/memory_utils/inline_memcpy.h" #include "src/string/memory_utils/inline_memmove.h" #include // size_t @@ -16,6 +17,10 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(void *, memmove, (void *dst, const void *src, size_t count)) { + if (count) { + LIBC_CRASH_ON_NULLPTR(dst); + LIBC_CRASH_ON_NULLPTR(src); + } // Memmove may handle some small sizes as efficiently as inline_memcpy. // For these sizes we may not do is_disjoint check. // This both avoids additional code for the most frequent smaller sizes diff --git a/libc/src/string/mempcpy.cpp b/libc/src/string/mempcpy.cpp index 09392ceb966d..b6a9721960ce 100644 --- a/libc/src/string/mempcpy.cpp +++ b/libc/src/string/mempcpy.cpp @@ -8,6 +8,7 @@ #include "src/string/mempcpy.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" #include "src/string/memory_utils/inline_memcpy.h" #include "src/__support/common.h" @@ -18,6 +19,10 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(void *, mempcpy, (void *__restrict dst, const void *__restrict src, size_t count)) { + if (count) { + LIBC_CRASH_ON_NULLPTR(dst); + LIBC_CRASH_ON_NULLPTR(src); + } inline_memcpy(dst, src, count); return reinterpret_cast(dst) + count; } diff --git a/libc/src/string/memrchr.cpp b/libc/src/string/memrchr.cpp index d665e225bbb7..d5c843c733b3 100644 --- a/libc/src/string/memrchr.cpp +++ b/libc/src/string/memrchr.cpp @@ -9,11 +9,16 @@ #include "src/string/memrchr.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" #include namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(void *, memrchr, (const void *src, int c, size_t n)) { + + if (n) + LIBC_CRASH_ON_NULLPTR(src); + const unsigned char *str = reinterpret_cast(src); const unsigned char ch = static_cast(c); for (; n != 0; --n) { diff --git a/libc/src/string/memset.cpp b/libc/src/string/memset.cpp index c2868afa9103..a0b96b3cf88b 100644 --- a/libc/src/string/memset.cpp +++ b/libc/src/string/memset.cpp @@ -9,11 +9,15 @@ #include "src/string/memset.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" #include "src/string/memory_utils/inline_memset.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(void *, memset, (void *dst, int value, size_t count)) { + if (count) + LIBC_CRASH_ON_NULLPTR(dst); + inline_memset(dst, static_cast(value), count); return dst; } diff --git a/libc/src/string/stpncpy.cpp b/libc/src/string/stpncpy.cpp index d2a6e0474982..47bf4c6e86fb 100644 --- a/libc/src/string/stpncpy.cpp +++ b/libc/src/string/stpncpy.cpp @@ -8,6 +8,7 @@ #include "src/string/stpncpy.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" #include "src/string/memory_utils/inline_bzero.h" #include "src/__support/common.h" @@ -17,6 +18,10 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(char *, stpncpy, (char *__restrict dest, const char *__restrict src, size_t n)) { + if (n) { + LIBC_CRASH_ON_NULLPTR(dest); + LIBC_CRASH_ON_NULLPTR(src); + } size_t i; // Copy up until \0 is found. for (i = 0; i < n && src[i] != '\0'; ++i) diff --git a/libc/src/string/strcasestr.cpp b/libc/src/string/strcasestr.cpp index 1da1e3f02507..de8e4bec7fe0 100644 --- a/libc/src/string/strcasestr.cpp +++ b/libc/src/string/strcasestr.cpp @@ -11,6 +11,7 @@ #include "src/__support/common.h" #include "src/__support/ctype_utils.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" #include "src/string/memory_utils/inline_strstr.h" namespace LIBC_NAMESPACE_DECL { @@ -23,6 +24,9 @@ LLVM_LIBC_FUNCTION(char *, strcasestr, return LIBC_NAMESPACE::internal::tolower(a) - LIBC_NAMESPACE::internal::tolower(b); }; + + LIBC_CRASH_ON_NULLPTR(haystack); + LIBC_CRASH_ON_NULLPTR(needle); return inline_strstr(haystack, needle, case_cmp); } diff --git a/libc/src/string/strcat.cpp b/libc/src/string/strcat.cpp index 0eb189ce204f..6a6f068bd475 100644 --- a/libc/src/string/strcat.cpp +++ b/libc/src/string/strcat.cpp @@ -8,6 +8,7 @@ #include "src/string/strcat.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" #include "src/string/strcpy.h" #include "src/string/string_utils.h" @@ -17,6 +18,8 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(char *, strcat, (char *__restrict dest, const char *__restrict src)) { + LIBC_CRASH_ON_NULLPTR(dest); + LIBC_CRASH_ON_NULLPTR(src); size_t dest_length = internal::string_length(dest); size_t src_length = internal::string_length(src); LIBC_NAMESPACE::strcpy(dest + dest_length, src); diff --git a/libc/src/string/strcoll.cpp b/libc/src/string/strcoll.cpp index eeb2c79e3807..aa08f7194c9e 100644 --- a/libc/src/string/strcoll.cpp +++ b/libc/src/string/strcoll.cpp @@ -10,11 +10,14 @@ #include "src/__support/common.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" namespace LIBC_NAMESPACE_DECL { // TODO: Add support for locales. LLVM_LIBC_FUNCTION(int, strcoll, (const char *left, const char *right)) { + LIBC_CRASH_ON_NULLPTR(left); + LIBC_CRASH_ON_NULLPTR(right); for (; *left && *left == *right; ++left, ++right) ; return static_cast(*left) - static_cast(*right); diff --git a/libc/src/string/strcoll_l.cpp b/libc/src/string/strcoll_l.cpp index f664a3c7c03f..e820efa564a3 100644 --- a/libc/src/string/strcoll_l.cpp +++ b/libc/src/string/strcoll_l.cpp @@ -10,12 +10,15 @@ #include "src/__support/common.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" namespace LIBC_NAMESPACE_DECL { // TODO: Add support for locales. LLVM_LIBC_FUNCTION(int, strcoll_l, (const char *left, const char *right, locale_t)) { + LIBC_CRASH_ON_NULLPTR(left); + LIBC_CRASH_ON_NULLPTR(right); for (; *left && *left == *right; ++left, ++right) ; return static_cast(*left) - static_cast(*right); diff --git a/libc/src/string/strcpy.cpp b/libc/src/string/strcpy.cpp index 60b73ab3aa82..2013593db24a 100644 --- a/libc/src/string/strcpy.cpp +++ b/libc/src/string/strcpy.cpp @@ -8,6 +8,7 @@ #include "src/string/strcpy.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" #include "src/string/memory_utils/inline_memcpy.h" #include "src/string/string_utils.h" @@ -17,6 +18,7 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(char *, strcpy, (char *__restrict dest, const char *__restrict src)) { + LIBC_CRASH_ON_NULLPTR(dest); size_t size = internal::string_length(src) + 1; inline_memcpy(dest, src, size); return dest; diff --git a/libc/src/string/strlen.cpp b/libc/src/string/strlen.cpp index ff7ab14dd313..234edb81d4c8 100644 --- a/libc/src/string/strlen.cpp +++ b/libc/src/string/strlen.cpp @@ -8,6 +8,7 @@ #include "src/string/strlen.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" #include "src/string/string_utils.h" #include "src/__support/common.h" @@ -17,6 +18,7 @@ namespace LIBC_NAMESPACE_DECL { // TODO: investigate the performance of this function. // There might be potential for compiler optimization. LLVM_LIBC_FUNCTION(size_t, strlen, (const char *src)) { + LIBC_CRASH_ON_NULLPTR(src); return internal::string_length(src); } diff --git a/libc/src/string/strncat.cpp b/libc/src/string/strncat.cpp index 221881f93c47..4926b7d244d1 100644 --- a/libc/src/string/strncat.cpp +++ b/libc/src/string/strncat.cpp @@ -8,6 +8,7 @@ #include "src/string/strncat.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" #include "src/string/string_utils.h" #include "src/string/strncpy.h" @@ -18,6 +19,10 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(char *, strncat, (char *__restrict dest, const char *__restrict src, size_t count)) { + if (count) { + LIBC_CRASH_ON_NULLPTR(dest); + LIBC_CRASH_ON_NULLPTR(src); + } size_t src_length = internal::string_length(src); size_t copy_amount = src_length > count ? count : src_length; size_t dest_length = internal::string_length(dest); diff --git a/libc/src/string/strncmp.cpp b/libc/src/string/strncmp.cpp index 16d4601fe845..f21fd769f394 100644 --- a/libc/src/string/strncmp.cpp +++ b/libc/src/string/strncmp.cpp @@ -10,6 +10,7 @@ #include "src/__support/common.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" #include "src/string/memory_utils/inline_strcmp.h" #include @@ -18,6 +19,10 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, strncmp, (const char *left, const char *right, size_t n)) { + if (n) { + LIBC_CRASH_ON_NULLPTR(left); + LIBC_CRASH_ON_NULLPTR(right); + } auto comp = [](char l, char r) -> int { return l - r; }; return inline_strncmp(left, right, n, comp); } diff --git a/libc/src/string/strncpy.cpp b/libc/src/string/strncpy.cpp index 4976ad94708c..e271009502f2 100644 --- a/libc/src/string/strncpy.cpp +++ b/libc/src/string/strncpy.cpp @@ -10,6 +10,7 @@ #include "src/__support/common.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" #include // For size_t. namespace LIBC_NAMESPACE_DECL { @@ -17,6 +18,10 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(char *, strncpy, (char *__restrict dest, const char *__restrict src, size_t n)) { + if (n) { + LIBC_CRASH_ON_NULLPTR(dest); + LIBC_CRASH_ON_NULLPTR(src); + } size_t i = 0; // Copy up until \0 is found. for (; i < n && src[i] != '\0'; ++i) diff --git a/libc/src/string/strsep.cpp b/libc/src/string/strsep.cpp index 4c275122de52..555c2f3c9791 100644 --- a/libc/src/string/strsep.cpp +++ b/libc/src/string/strsep.cpp @@ -9,14 +9,17 @@ #include "src/string/strsep.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" #include "src/string/string_utils.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(char *, strsep, (char **__restrict stringp, const char *__restrict delim)) { + LIBC_CRASH_ON_NULLPTR(stringp); if (!*stringp) return nullptr; + LIBC_CRASH_ON_NULLPTR(delim); return internal::string_token(*stringp, delim, stringp); } diff --git a/libc/src/string/strspn.cpp b/libc/src/string/strspn.cpp index 66bb39903ab3..b205bedf80ca 100644 --- a/libc/src/string/strspn.cpp +++ b/libc/src/string/strspn.cpp @@ -11,11 +11,14 @@ #include "src/__support/CPP/bitset.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" #include namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(size_t, strspn, (const char *src, const char *segment)) { + LIBC_CRASH_ON_NULLPTR(src); + LIBC_CRASH_ON_NULLPTR(segment); const char *initial = src; cpp::bitset<256> bitset; diff --git a/libc/src/string/strstr.cpp b/libc/src/string/strstr.cpp index 5132f06ef53f..44797ef670b9 100644 --- a/libc/src/string/strstr.cpp +++ b/libc/src/string/strstr.cpp @@ -10,6 +10,7 @@ #include "src/__support/common.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" #include "src/string/memory_utils/inline_strstr.h" namespace LIBC_NAMESPACE_DECL { @@ -18,6 +19,8 @@ namespace LIBC_NAMESPACE_DECL { // improved upon using well known string matching algorithms. LLVM_LIBC_FUNCTION(char *, strstr, (const char *haystack, const char *needle)) { auto comp = [](char l, char r) -> int { return l - r; }; + LIBC_CRASH_ON_NULLPTR(haystack); + LIBC_CRASH_ON_NULLPTR(needle); return inline_strstr(haystack, needle, comp); } diff --git a/libc/src/strings/rindex.cpp b/libc/src/strings/rindex.cpp index 1242e0faf85f..2540222ffb0e 100644 --- a/libc/src/strings/rindex.cpp +++ b/libc/src/strings/rindex.cpp @@ -10,11 +10,13 @@ #include "src/__support/common.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" #include "src/string/string_utils.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(char *, rindex, (const char *src, int c)) { + LIBC_CRASH_ON_NULLPTR(src); return internal::strrchr_implementation(src, c); } diff --git a/libc/test/src/string/memchr_test.cpp b/libc/test/src/string/memchr_test.cpp index 343958234edc..1455183e4646 100644 --- a/libc/test/src/string/memchr_test.cpp +++ b/libc/test/src/string/memchr_test.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "hdr/signal_macros.h" #include "src/string/memchr.h" #include "test/UnitTest/Test.h" #include @@ -120,3 +121,12 @@ TEST(LlvmLibcMemChrTest, SignedCharacterFound) { // Should find the first character 'c'. ASSERT_EQ(actual[0], c); } + +#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) + +TEST(LlvmLibcMemChrTest, CrashOnNullPtr) { + ASSERT_DEATH([]() { LIBC_NAMESPACE::memchr(nullptr, 1, 1); }, + WITH_SIGNAL(-1)); +} + +#endif // defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) diff --git a/libc/test/src/string/memcmp_test.cpp b/libc/test/src/string/memcmp_test.cpp index 9f85a6d4f222..3dfbceda5953 100644 --- a/libc/test/src/string/memcmp_test.cpp +++ b/libc/test/src/string/memcmp_test.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "hdr/signal_macros.h" #include "memory_utils/memory_check_utils.h" #include "src/__support/macros/config.h" #include "src/string/memcmp.h" @@ -65,4 +66,13 @@ TEST(LlvmLibcMemcmpTest, SizeSweep) { } } +#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) + +TEST(LlvmLibcMemcmpTest, CrashOnNullPtr) { + ASSERT_DEATH([]() { LIBC_NAMESPACE::memcmp(nullptr, nullptr, 1); }, + WITH_SIGNAL(-1)); +} + +#endif // defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) + } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/test/src/string/memcpy_test.cpp b/libc/test/src/string/memcpy_test.cpp index ce267d17591f..8c43ac8b0e60 100644 --- a/libc/test/src/string/memcpy_test.cpp +++ b/libc/test/src/string/memcpy_test.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "hdr/signal_macros.h" #include "memory_utils/memory_check_utils.h" #include "src/__support/macros/config.h" #include "src/__support/macros/properties/os.h" // LIBC_TARGET_OS_IS_LINUX @@ -72,4 +73,12 @@ TEST(LlvmLibcMemcpyTest, CheckAccess) { #endif // !defined(LIBC_FULL_BUILD) && defined(LIBC_TARGET_OS_IS_LINUX) +#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) + +TEST(LlvmLibcMemcpyTest, CrashOnNullPtr) { + ASSERT_DEATH([]() { LIBC_NAMESPACE::memcpy(nullptr, nullptr, 1); }, + WITH_SIGNAL(-1)); +} +#endif // defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) + } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/test/src/string/memmove_test.cpp b/libc/test/src/string/memmove_test.cpp index 1e225e58ca1e..0d476555333d 100644 --- a/libc/test/src/string/memmove_test.cpp +++ b/libc/test/src/string/memmove_test.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "hdr/signal_macros.h" #include "src/__support/macros/config.h" #include "src/string/memmove.h" @@ -103,4 +104,13 @@ TEST(LlvmLibcMemmoveTest, SizeSweep) { } } +#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) + +TEST(LlvmLibcMemmoveTest, CrashOnNullPtr) { + ASSERT_DEATH([]() { LIBC_NAMESPACE::memmove(nullptr, nullptr, 2); }, + WITH_SIGNAL(-1)); +} + +#endif // LIBC_TARGET_OS_IS_LINUX + } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/test/src/string/mempcpy_test.cpp b/libc/test/src/string/mempcpy_test.cpp index 877ee8104880..24482a81352c 100644 --- a/libc/test/src/string/mempcpy_test.cpp +++ b/libc/test/src/string/mempcpy_test.cpp @@ -5,7 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// - +#include "hdr/signal_macros.h" #include "src/string/mempcpy.h" #include "test/UnitTest/Test.h" @@ -26,3 +26,12 @@ TEST(LlvmLibcMempcpyTest, ZeroCount) { void *result = LIBC_NAMESPACE::mempcpy(dest, src, 0); ASSERT_EQ(static_cast(result), dest + 0); } + +#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) + +TEST(LlvmLibcMempcpyTest, CrashOnNullPtr) { + ASSERT_DEATH([]() { LIBC_NAMESPACE::mempcpy(nullptr, nullptr, 1); }, + WITH_SIGNAL(-1)); +} + +#endif // defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) diff --git a/libc/test/src/string/memrchr_test.cpp b/libc/test/src/string/memrchr_test.cpp index 421cb9b98516..c73a47917dd5 100644 --- a/libc/test/src/string/memrchr_test.cpp +++ b/libc/test/src/string/memrchr_test.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "hdr/signal_macros.h" #include "src/string/memrchr.h" #include "test/UnitTest/Test.h" #include @@ -112,3 +113,12 @@ TEST(LlvmLibcMemRChrTest, ZeroLengthShouldReturnNullptr) { // This will iterate over exactly zero characters, so should return nullptr. ASSERT_STREQ(call_memrchr(src, 'd', 0), nullptr); } + +#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) + +TEST(LlvmLibcMemRChrTest, CrashOnNullPtr) { + ASSERT_DEATH([]() { LIBC_NAMESPACE::memrchr(nullptr, 'd', 1); }, + WITH_SIGNAL(-1)); +} + +#endif // defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) diff --git a/libc/test/src/string/memset_test.cpp b/libc/test/src/string/memset_test.cpp index 46d6ce747877..9562d2d2e37a 100644 --- a/libc/test/src/string/memset_test.cpp +++ b/libc/test/src/string/memset_test.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "hdr/signal_macros.h" #include "memory_utils/memory_check_utils.h" #include "src/__support/macros/config.h" #include "src/__support/macros/properties/os.h" // LIBC_TARGET_OS_IS_LINUX @@ -59,4 +60,13 @@ TEST(LlvmLibcMemsetTest, CheckAccess) { #endif // !defined(LIBC_FULL_BUILD) && defined(LIBC_TARGET_OS_IS_LINUX) +#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) + +TEST(LlvmLibcMemsetTest, CrashOnNullPtr) { + ASSERT_DEATH([]() { LIBC_NAMESPACE::memset(nullptr, 0, 1); }, + WITH_SIGNAL(-1)); +} + +#endif // defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) + } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/test/src/string/stpncpy_test.cpp b/libc/test/src/string/stpncpy_test.cpp index 247fa92a0c7b..f5c61e277f66 100644 --- a/libc/test/src/string/stpncpy_test.cpp +++ b/libc/test/src/string/stpncpy_test.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "hdr/signal_macros.h" #include "src/__support/CPP/span.h" #include "src/string/stpncpy.h" #include "test/UnitTest/Test.h" @@ -71,3 +72,12 @@ TEST_F(LlvmLibcStpncpyTest, CopyTwoWithNull) { const char expected[] = {'x', '\0'}; check_stpncpy(dst, src, 2, expected, 1); } + +#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) + +TEST_F(LlvmLibcStpncpyTest, CrashOnNullPtr) { + ASSERT_DEATH([]() { LIBC_NAMESPACE::stpncpy(nullptr, nullptr, 1); }, + WITH_SIGNAL(-1)); +} + +#endif // defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) diff --git a/libc/test/src/string/strcat_test.cpp b/libc/test/src/string/strcat_test.cpp index e4f6c1ee7599..20f8d11d239b 100644 --- a/libc/test/src/string/strcat_test.cpp +++ b/libc/test/src/string/strcat_test.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "hdr/signal_macros.h" #include "src/string/strcat.h" #include "test/UnitTest/Test.h" @@ -35,3 +36,12 @@ TEST(LlvmLibcStrCatTest, NonEmptyDest) { ASSERT_STREQ(dest, result); ASSERT_STREQ(dest, "xyzabc"); } + +#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) + +TEST(LlvmLibcStrCatTest, CrashOnNullPtr) { + ASSERT_DEATH([]() { LIBC_NAMESPACE::strcat(nullptr, nullptr); }, + WITH_SIGNAL(-1)); +} + +#endif // defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) diff --git a/libc/test/src/string/strcoll_test.cpp b/libc/test/src/string/strcoll_test.cpp index a10f98f1ca4d..268e232a9a98 100644 --- a/libc/test/src/string/strcoll_test.cpp +++ b/libc/test/src/string/strcoll_test.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "hdr/signal_macros.h" #include "src/string/strcoll.h" #include "test/UnitTest/Test.h" @@ -28,3 +29,12 @@ TEST(LlvmLibcStrcollTest, SimpleTest) { result = LIBC_NAMESPACE::strcoll(s3, s1); ASSERT_GT(result, 0); } + +#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) + +TEST(LlvmLibcStrcollTest, CrashOnNullPtr) { + ASSERT_DEATH([]() { LIBC_NAMESPACE::strcoll(nullptr, nullptr); }, + WITH_SIGNAL(-1)); +} + +#endif // defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) diff --git a/libc/test/src/string/strcpy_test.cpp b/libc/test/src/string/strcpy_test.cpp index 1a1227aac5d2..ead60be1267d 100644 --- a/libc/test/src/string/strcpy_test.cpp +++ b/libc/test/src/string/strcpy_test.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "hdr/signal_macros.h" #include "src/string/strcpy.h" #include "test/UnitTest/Test.h" @@ -42,3 +43,12 @@ TEST(LlvmLibcStrCpyTest, OffsetDest) { ASSERT_STREQ(dest + 3, result); ASSERT_STREQ(dest, "xyzabc"); } + +#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) + +TEST(LlvmLibcStrCpyTest, CrashOnNullPtr) { + ASSERT_DEATH([]() { LIBC_NAMESPACE::strcpy(nullptr, nullptr); }, + WITH_SIGNAL(-1)); +} + +#endif // defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) diff --git a/libc/test/src/string/strlcpy_test.cpp b/libc/test/src/string/strlcpy_test.cpp index 0914257ecc1f..b42954ca6137 100644 --- a/libc/test/src/string/strlcpy_test.cpp +++ b/libc/test/src/string/strlcpy_test.cpp @@ -14,8 +14,8 @@ TEST(LlvmLibcStrlcpyTest, TooBig) { char buf[2]; EXPECT_EQ(LIBC_NAMESPACE::strlcpy(buf, str, 2), size_t(3)); EXPECT_STREQ(buf, "a"); - - EXPECT_EQ(LIBC_NAMESPACE::strlcpy(nullptr, str, 0), size_t(3)); + char dst[] = ""; + EXPECT_EQ(LIBC_NAMESPACE::strlcpy(dst, str, 0), size_t(3)); } TEST(LlvmLibcStrlcpyTest, Smaller) { diff --git a/libc/test/src/string/strsep_test.cpp b/libc/test/src/string/strsep_test.cpp index 0daa29f6a7ad..6f02ce36edf2 100644 --- a/libc/test/src/string/strsep_test.cpp +++ b/libc/test/src/string/strsep_test.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "hdr/signal_macros.h" #include "src/string/strsep.h" #include "test/UnitTest/Test.h" @@ -51,3 +52,12 @@ TEST(LlvmLibcStrsepTest, DelimitersShouldNotBeIncludedInToken) { ASSERT_STREQ(LIBC_NAMESPACE::strsep(&string, "_:"), expected[i]); } } + +#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) + +TEST(LlvmLibcStrsepTest, CrashOnNullPtr) { + ASSERT_DEATH([]() { LIBC_NAMESPACE::strsep(nullptr, nullptr); }, + WITH_SIGNAL(-1)); +} + +#endif // defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) diff --git a/libc/test/src/string/strspn_test.cpp b/libc/test/src/string/strspn_test.cpp index cdd12af07ee7..adf9a4564a1f 100644 --- a/libc/test/src/string/strspn_test.cpp +++ b/libc/test/src/string/strspn_test.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "hdr/signal_macros.h" #include "src/string/strspn.h" #include "test/UnitTest/Test.h" @@ -83,3 +84,12 @@ TEST(LlvmLibcStrSpnTest, DuplicatedCharactersToBeSearchedForShouldStillMatch) { EXPECT_EQ(LIBC_NAMESPACE::strspn("aaa", "aa"), size_t{3}); EXPECT_EQ(LIBC_NAMESPACE::strspn("aaaa", "aa"), size_t{4}); } + +#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) + +TEST(LlvmLibcStrSpnTest, CrashOnNullPtr) { + ASSERT_DEATH([]() { LIBC_NAMESPACE::strspn(nullptr, nullptr); }, + WITH_SIGNAL(-1)); +} + +#endif // defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)