[libc-commits] [libc] [libc] Add Annex K strnlen_s function (PR #186112)
Victor Campos via libc-commits
libc-commits at lists.llvm.org
Tue Mar 17 09:25:31 PDT 2026
https://github.com/vhscampos updated https://github.com/llvm/llvm-project/pull/186112
>From 91882b2faaf236585df8d24eb67580ad27c22d0c Mon Sep 17 00:00:00 2001
From: Victor Campos <victor.campos at arm.com>
Date: Fri, 6 Mar 2026 13:44:38 +0000
Subject: [PATCH 1/2] [libc] Add Annex K strnlen_s function
This patch adds the `strnlen_s` function from Annex K.
In order to reduce duplication between `strnlen` and `strnlen_s`, the
common logic has been extracted to a new internal function which both
now call.
In addition to the function definition, the patch adds a unit test and a
fuzzing test.
---
libc/config/baremetal/aarch64/entrypoints.txt | 1 +
libc/config/baremetal/arm/entrypoints.txt | 1 +
libc/config/darwin/aarch64/entrypoints.txt | 1 +
libc/config/linux/aarch64/entrypoints.txt | 1 +
libc/config/linux/arm/entrypoints.txt | 1 +
libc/config/windows/entrypoints.txt | 1 +
libc/fuzzing/string/CMakeLists.txt | 8 +++
libc/fuzzing/string/strnlen_s_fuzz.cpp | 58 +++++++++++++++++++
libc/include/CMakeLists.txt | 1 +
libc/include/string.yaml | 10 ++++
libc/src/string/CMakeLists.txt | 11 ++++
libc/src/string/string_utils.h | 6 ++
libc/src/string/strnlen.cpp | 4 +-
libc/src/string/strnlen_s.cpp | 16 +++++
libc/src/string/strnlen_s.h | 19 ++++++
libc/test/src/string/CMakeLists.txt | 10 ++++
libc/test/src/string/strnlen_s_test.cpp | 57 ++++++++++++++++++
libc/utils/docgen/string.yaml | 3 +
18 files changed, 206 insertions(+), 3 deletions(-)
create mode 100644 libc/fuzzing/string/strnlen_s_fuzz.cpp
create mode 100644 libc/src/string/strnlen_s.cpp
create mode 100644 libc/src/string/strnlen_s.h
create mode 100644 libc/test/src/string/strnlen_s_test.cpp
diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index c4e040e537cd0..da4b99b53d8d2 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -87,6 +87,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.string.strncpy
libc.src.string.strndup
libc.src.string.strnlen
+ libc.src.string.strnlen_s
libc.src.string.strpbrk
libc.src.string.strrchr
libc.src.string.strsep
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 7acaca15d39ae..7480560407db1 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -87,6 +87,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.string.strncpy
libc.src.string.strndup
libc.src.string.strnlen
+ libc.src.string.strnlen_s
libc.src.string.strpbrk
libc.src.string.strrchr
libc.src.string.strsep
diff --git a/libc/config/darwin/aarch64/entrypoints.txt b/libc/config/darwin/aarch64/entrypoints.txt
index 2d26763e29d03..a7e3f9d4a5af8 100644
--- a/libc/config/darwin/aarch64/entrypoints.txt
+++ b/libc/config/darwin/aarch64/entrypoints.txt
@@ -46,6 +46,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.string.strncmp
libc.src.string.strncpy
libc.src.string.strnlen
+ libc.src.string.strnlen_s
libc.src.string.strpbrk
libc.src.string.strrchr
libc.src.string.strspn
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 380c91e1ac396..0272fb80ccd0c 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -79,6 +79,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.string.strncpy
libc.src.string.strndup
libc.src.string.strnlen
+ libc.src.string.strnlen_s
libc.src.string.strpbrk
libc.src.string.strrchr
libc.src.string.strsep
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 8611082f87003..dd1f48bf2bb5d 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -49,6 +49,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.string.strncmp
libc.src.string.strncpy
libc.src.string.strnlen
+ libc.src.string.strnlen_s
libc.src.string.strpbrk
libc.src.string.strrchr
libc.src.string.strsep
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index 02b56ab01081b..7739773cafec1 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -43,6 +43,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.string.strncmp
libc.src.string.strncpy
libc.src.string.strnlen
+ libc.src.string.strnlen_s
libc.src.string.strpbrk
libc.src.string.strrchr
libc.src.string.strspn
diff --git a/libc/fuzzing/string/CMakeLists.txt b/libc/fuzzing/string/CMakeLists.txt
index 0918e92552ea7..92880d7e37407 100644
--- a/libc/fuzzing/string/CMakeLists.txt
+++ b/libc/fuzzing/string/CMakeLists.txt
@@ -48,3 +48,11 @@ add_libc_fuzzer(
DEPENDS
libc.src.string.strlen
)
+
+add_libc_fuzzer(
+ strnlen_s_fuzz
+ SRCS
+ strnlen_s_fuzz.cpp
+ DEPENDS
+ libc.src.string.strnlen_s
+)
diff --git a/libc/fuzzing/string/strnlen_s_fuzz.cpp b/libc/fuzzing/string/strnlen_s_fuzz.cpp
new file mode 100644
index 0000000000000..93176ae871a65
--- /dev/null
+++ b/libc/fuzzing/string/strnlen_s_fuzz.cpp
@@ -0,0 +1,58 @@
+//===-- strnlen_s_fuzz.cpp ------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// Fuzzing test for llvm-libc strnlen_s implementation.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/string/strnlen_s.h"
+#define __STDC_WANT_LIB_EXT1__ 1
+#include <stdint.h>
+#include <string.h>
+
+extern "C" size_t LLVMFuzzerMutate(uint8_t *data, size_t size, size_t max_size);
+extern "C" size_t LLVMFuzzerCustomMutator(uint8_t *data, size_t size,
+ size_t max_size,
+ unsigned int /*seed*/) {
+ // The buffer is constructed as follows:
+ // data = max_len (size_t) + null-terminated string
+ if (max_size < sizeof(size_t) + 1)
+ return size;
+
+ do {
+ size = LLVMFuzzerMutate(data, size, max_size);
+ } while (size < sizeof(size_t) + 1);
+
+ data[size - 1] = '\0';
+ return size;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ if (size < sizeof(size_t) + 1)
+ return 0;
+
+ size_t max_len;
+ ::memcpy(&max_len, data, sizeof(size_t));
+ data += sizeof(size_t);
+
+ // If Annex K is not available in the system's C library, we compare against
+ // strnlen instead. We can assume this is valid because in the case where the
+ // input string is not null, the two functions must have identical semantics.
+#ifdef __STDC_LIB_EXT1__
+ size_t ref = ::strnlen_s(reinterpret_cast<const char *>(data), max_len);
+#else
+ size_t ref = ::strnlen(reinterpret_cast<const char *>(data), max_len);
+#endif
+ size_t impl =
+ LIBC_NAMESPACE::strnlen_s(reinterpret_cast<const char *>(data), max_len);
+
+ if (ref != impl)
+ __builtin_trap();
+
+ return 0;
+}
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index b2ebd035872aa..b1c437059d6be 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -252,6 +252,7 @@ add_header_macro(
string.h
DEPENDS
.llvm_libc_common_h
+ .llvm-libc-macros.annex_k_macros
.llvm-libc-macros.null_macro
.llvm-libc-types.size_t
)
diff --git a/libc/include/string.yaml b/libc/include/string.yaml
index 22010f4afa812..b52f2bb1a5933 100644
--- a/libc/include/string.yaml
+++ b/libc/include/string.yaml
@@ -4,6 +4,8 @@ standards:
macros:
- macro_name: "NULL"
macro_header: null-macro.h
+ - macro_name: LIBC_HAS_ANNEX_K
+ macro_header: annex-k-macros.h
types:
- type_name: locale_t
- type_name: size_t
@@ -249,6 +251,14 @@ functions:
arguments:
- type: const char *
- type: size_t
+ - name: strnlen_s
+ standards:
+ - stdc
+ return_type: size_t
+ arguments:
+ - type: const char *
+ - type: size_t
+ guard: LIBC_HAS_ANNEX_K
- name: strpbrk
standards:
- stdc
diff --git a/libc/src/string/CMakeLists.txt b/libc/src/string/CMakeLists.txt
index a640e1d2cc774..2a38c6509605e 100644
--- a/libc/src/string/CMakeLists.txt
+++ b/libc/src/string/CMakeLists.txt
@@ -302,6 +302,17 @@ add_entrypoint_object(
.string_utils
)
+add_entrypoint_object(
+ strnlen_s
+ SRCS
+ strnlen_s.cpp
+ HDRS
+ strnlen_s.h
+ DEPENDS
+ libc.hdr.types.size_t
+ .string_utils
+)
+
add_entrypoint_object(
strpbrk
SRCS
diff --git a/libc/src/string/string_utils.h b/libc/src/string/string_utils.h
index b0144e01a9006..8c8879b4886e8 100644
--- a/libc/src/string/string_utils.h
+++ b/libc/src/string/string_utils.h
@@ -124,6 +124,12 @@ LIBC_INLINE void *find_first_character(const unsigned char *src,
return find_first_character_impl(src, ch, max_strlen);
}
+LIBC_INLINE size_t strnlen(const char *s, size_t max_len) {
+ const void *temp = internal::find_first_character(
+ reinterpret_cast<const unsigned char *>(s), '\0', max_len);
+ return temp ? reinterpret_cast<const char *>(temp) - s : max_len;
+}
+
} // namespace internal
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/string/strnlen.cpp b/libc/src/string/strnlen.cpp
index 26fcd5a04c0d7..6bfbb86a5014e 100644
--- a/libc/src/string/strnlen.cpp
+++ b/libc/src/string/strnlen.cpp
@@ -16,9 +16,7 @@
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(size_t, strnlen, (const char *src, size_t n)) {
- const void *temp = internal::find_first_character(
- reinterpret_cast<const unsigned char *>(src), '\0', n);
- return temp ? reinterpret_cast<const char *>(temp) - src : n;
+ return internal::strnlen(src, n);
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/string/strnlen_s.cpp b/libc/src/string/strnlen_s.cpp
new file mode 100644
index 0000000000000..c76591d30d70b
--- /dev/null
+++ b/libc/src/string/strnlen_s.cpp
@@ -0,0 +1,16 @@
+//===-- Implementation header for strnlen_s ----------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/string/strnlen_s.h"
+#include "src/string/string_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(size_t, strnlen_s, (const char *s, size_t n)) {
+ return (s != 0) ? internal::strnlen(s, n) : 0;
+}
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/string/strnlen_s.h b/libc/src/string/strnlen_s.h
new file mode 100644
index 0000000000000..89bbbd53b0494
--- /dev/null
+++ b/libc/src/string/strnlen_s.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for strnlen_s ----------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STRING_STRNLEN_S_H
+#define LLVM_LIBC_SRC_STRING_STRNLEN_S_H
+
+#include "hdr/types/size_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+size_t strnlen_s(const char *src, size_t n);
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STRING_STRNLEN_S_H
diff --git a/libc/test/src/string/CMakeLists.txt b/libc/test/src/string/CMakeLists.txt
index ced60750a45c7..17927ea93ed1e 100644
--- a/libc/test/src/string/CMakeLists.txt
+++ b/libc/test/src/string/CMakeLists.txt
@@ -274,6 +274,16 @@ add_libc_test(
libc.src.string.strnlen
)
+add_libc_test(
+ strnlen_s_test
+ SUITE
+ libc-string-tests
+ SRCS
+ strnlen_s_test.cpp
+ DEPENDS
+ libc.src.string.strnlen_s
+)
+
add_libc_test(
strpbrk_test
SUITE
diff --git a/libc/test/src/string/strnlen_s_test.cpp b/libc/test/src/string/strnlen_s_test.cpp
new file mode 100644
index 0000000000000..4749a544c8fb5
--- /dev/null
+++ b/libc/test/src/string/strnlen_s_test.cpp
@@ -0,0 +1,57 @@
+//===-- Unittests for strnlen_s -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/string/strnlen_s.h"
+#include "test/UnitTest/Test.h"
+#include <stddef.h>
+
+TEST(LlvmLibcStrNLenSTest, NullPointerInput) {
+ const char *str = nullptr;
+ // If the string input is a null pointer, it should return 0 regardless of
+ // the max len arg value.
+ ASSERT_EQ(static_cast<size_t>(0), LIBC_NAMESPACE::strnlen_s(str, 0));
+ ASSERT_EQ(static_cast<size_t>(0), LIBC_NAMESPACE::strnlen_s(str, 1));
+}
+
+// The semantics when the string input is not null are the same as strnlen. The
+// following tests are copied from the latter's tests.
+
+TEST(LlvmLibcStrNLenSTest, EmptyString) {
+ const char *empty = "";
+ ASSERT_EQ(static_cast<size_t>(0), LIBC_NAMESPACE::strnlen_s(empty, 0));
+ // If N is greater than string length, this should still return 0.
+ ASSERT_EQ(static_cast<size_t>(0), LIBC_NAMESPACE::strnlen_s(empty, 1));
+}
+
+TEST(LlvmLibcStrNLenSTest, OneCharacterString) {
+ const char *single = "X";
+ ASSERT_EQ(static_cast<size_t>(1), LIBC_NAMESPACE::strnlen_s(single, 1));
+ // If N is zero, this should return 0.
+ ASSERT_EQ(static_cast<size_t>(0), LIBC_NAMESPACE::strnlen_s(single, 0));
+ // If N is greater than string length, this should still return 1.
+ ASSERT_EQ(static_cast<size_t>(1), LIBC_NAMESPACE::strnlen_s(single, 2));
+}
+
+TEST(LlvmLibcStrNLenSTest, ManyCharacterString) {
+ const char *many = "123456789";
+ ASSERT_EQ(static_cast<size_t>(9), LIBC_NAMESPACE::strnlen_s(many, 9));
+ // If N is smaller than the string length, it should return N.
+ ASSERT_EQ(static_cast<size_t>(3), LIBC_NAMESPACE::strnlen_s(many, 3));
+ // If N is zero, this should return 0.
+ ASSERT_EQ(static_cast<size_t>(0), LIBC_NAMESPACE::strnlen_s(many, 0));
+ // If N is greater than the string length, this should still return 9.
+ ASSERT_EQ(static_cast<size_t>(9), LIBC_NAMESPACE::strnlen_s(many, 42));
+}
+
+TEST(LlvmLibcStrNLenSTest, CharactersAfterNullTerminatorShouldNotBeIncluded) {
+ const char str[5] = {'a', 'b', 'c', '\0', 'd'};
+ ASSERT_EQ(static_cast<size_t>(3), LIBC_NAMESPACE::strnlen_s(str, 3));
+ // This should only read up to the null terminator.
+ ASSERT_EQ(static_cast<size_t>(3), LIBC_NAMESPACE::strnlen_s(str, 4));
+ ASSERT_EQ(static_cast<size_t>(3), LIBC_NAMESPACE::strnlen_s(str, 5));
+}
diff --git a/libc/utils/docgen/string.yaml b/libc/utils/docgen/string.yaml
index d703a8e3593e1..94a6756bed8c0 100644
--- a/libc/utils/docgen/string.yaml
+++ b/libc/utils/docgen/string.yaml
@@ -66,6 +66,9 @@ functions:
strndup:
c-definition: 7.26.2.7
in-latest-posix: ''
+ strnlen_s:
+ c-definition: K.3.7.4.4
+ in-latest-posix: ''
strpbrk:
c-definition: 7.26.5.5
in-latest-posix: ''
>From 5e8726e7ea819d01c42b179b6b93d8b308a9e44a Mon Sep 17 00:00:00 2001
From: Victor Campos <victor.campos at arm.com>
Date: Tue, 17 Mar 2026 14:14:48 +0000
Subject: [PATCH 2/2] Fix issues
---
libc/config/baremetal/riscv/entrypoints.txt | 1 +
libc/config/darwin/x86_64/entrypoints.txt | 1 +
libc/config/gpu/amdgpu/entrypoints.txt | 1 +
libc/config/gpu/nvptx/entrypoints.txt | 1 +
libc/config/gpu/spirv/entrypoints.txt | 1 +
libc/config/linux/riscv/entrypoints.txt | 1 +
libc/config/linux/x86_64/entrypoints.txt | 1 +
libc/fuzzing/string/strnlen_s_fuzz.cpp | 3 ++-
libc/src/string/CMakeLists.txt | 2 ++
libc/src/string/strnlen_s.cpp | 5 +++++
libc/src/string/strnlen_s.h | 2 ++
11 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index fc6201b44149f..89d0fdbbae1e1 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -87,6 +87,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.string.strncpy
libc.src.string.strndup
libc.src.string.strnlen
+ libc.src.string.strnlen_s
libc.src.string.strpbrk
libc.src.string.strrchr
libc.src.string.strsep
diff --git a/libc/config/darwin/x86_64/entrypoints.txt b/libc/config/darwin/x86_64/entrypoints.txt
index b0c247464c850..75f10fa49cae4 100644
--- a/libc/config/darwin/x86_64/entrypoints.txt
+++ b/libc/config/darwin/x86_64/entrypoints.txt
@@ -45,6 +45,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.string.strncmp
libc.src.string.strncpy
libc.src.string.strnlen
+ libc.src.string.strnlen_s
libc.src.string.strpbrk
libc.src.string.strrchr
libc.src.string.strspn
diff --git a/libc/config/gpu/amdgpu/entrypoints.txt b/libc/config/gpu/amdgpu/entrypoints.txt
index 98c27d300ad9d..aa18658236066 100644
--- a/libc/config/gpu/amdgpu/entrypoints.txt
+++ b/libc/config/gpu/amdgpu/entrypoints.txt
@@ -65,6 +65,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.string.strncpy
libc.src.string.strndup
libc.src.string.strnlen
+ libc.src.string.strnlen_s
libc.src.string.strpbrk
libc.src.string.strrchr
libc.src.string.strsep
diff --git a/libc/config/gpu/nvptx/entrypoints.txt b/libc/config/gpu/nvptx/entrypoints.txt
index 532fcda9ab3be..66a3eeb13c9b9 100644
--- a/libc/config/gpu/nvptx/entrypoints.txt
+++ b/libc/config/gpu/nvptx/entrypoints.txt
@@ -65,6 +65,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.string.strncpy
libc.src.string.strndup
libc.src.string.strnlen
+ libc.src.string.strnlen_s
libc.src.string.strpbrk
libc.src.string.strrchr
libc.src.string.strsep
diff --git a/libc/config/gpu/spirv/entrypoints.txt b/libc/config/gpu/spirv/entrypoints.txt
index 5c3c2c7e4303a..11edc358339b7 100644
--- a/libc/config/gpu/spirv/entrypoints.txt
+++ b/libc/config/gpu/spirv/entrypoints.txt
@@ -62,6 +62,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.string.strncpy
libc.src.string.strndup
libc.src.string.strnlen
+ libc.src.string.strnlen_s
libc.src.string.strpbrk
libc.src.string.strrchr
libc.src.string.strsep
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index ddb24c3eea178..01f5a21409a06 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -79,6 +79,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.string.strncpy
libc.src.string.strndup
libc.src.string.strnlen
+ libc.src.string.strnlen_s
libc.src.string.strpbrk
libc.src.string.strrchr
libc.src.string.strsep
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 9102de9bf0417..c4a9875fdc05b 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -81,6 +81,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.string.strncpy
libc.src.string.strndup
libc.src.string.strnlen
+ libc.src.string.strnlen_s
libc.src.string.strpbrk
libc.src.string.strrchr
libc.src.string.strsep
diff --git a/libc/fuzzing/string/strnlen_s_fuzz.cpp b/libc/fuzzing/string/strnlen_s_fuzz.cpp
index 93176ae871a65..741011cf44f6a 100644
--- a/libc/fuzzing/string/strnlen_s_fuzz.cpp
+++ b/libc/fuzzing/string/strnlen_s_fuzz.cpp
@@ -10,8 +10,9 @@
///
//===----------------------------------------------------------------------===//
-#include "src/string/strnlen_s.h"
#define __STDC_WANT_LIB_EXT1__ 1
+
+#include "src/string/strnlen_s.h"
#include <stdint.h>
#include <string.h>
diff --git a/libc/src/string/CMakeLists.txt b/libc/src/string/CMakeLists.txt
index 2a38c6509605e..e28fe7af8cf25 100644
--- a/libc/src/string/CMakeLists.txt
+++ b/libc/src/string/CMakeLists.txt
@@ -311,6 +311,8 @@ add_entrypoint_object(
DEPENDS
libc.hdr.types.size_t
.string_utils
+ libc.src.__support.common
+ libc.src.__support.macros.config
)
add_entrypoint_object(
diff --git a/libc/src/string/strnlen_s.cpp b/libc/src/string/strnlen_s.cpp
index c76591d30d70b..862b1ca4d0fc0 100644
--- a/libc/src/string/strnlen_s.cpp
+++ b/libc/src/string/strnlen_s.cpp
@@ -7,10 +7,15 @@
//===----------------------------------------------------------------------===//
#include "src/string/strnlen_s.h"
+#include "hdr/types/size_t.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
#include "src/string/string_utils.h"
namespace LIBC_NAMESPACE_DECL {
+
LLVM_LIBC_FUNCTION(size_t, strnlen_s, (const char *s, size_t n)) {
return (s != 0) ? internal::strnlen(s, n) : 0;
}
+
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/string/strnlen_s.h b/libc/src/string/strnlen_s.h
index 89bbbd53b0494..2e42d37f49415 100644
--- a/libc/src/string/strnlen_s.h
+++ b/libc/src/string/strnlen_s.h
@@ -13,7 +13,9 @@
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
+
size_t strnlen_s(const char *src, size_t n);
+
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC_STRING_STRNLEN_S_H
More information about the libc-commits
mailing list