[libc-commits] [libc] [libc] Fix off by one error in strftime (PR #165711)
via libc-commits
libc-commits at lists.llvm.org
Thu Oct 30 05:27:43 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: Marcell Leleszi (mleleszi)
<details>
<summary>Changes</summary>
This patch fixes a bug in strftime's return value when the formatted output exactly fills the buffer, not including the null terminator. The previous check failed to account for the null terminator in this case, incorrectly returning the written count instead of 0.
---
Full diff: https://github.com/llvm/llvm-project/pull/165711.diff
3 Files Affected:
- (modified) libc/src/time/strftime.cpp (+1-1)
- (modified) libc/src/time/strftime_l.cpp (+1-1)
- (modified) libc/test/src/time/strftime_test.cpp (+20)
``````````diff
diff --git a/libc/src/time/strftime.cpp b/libc/src/time/strftime.cpp
index f36091bc9736e..89b7d9bb7c1b9 100644
--- a/libc/src/time/strftime.cpp
+++ b/libc/src/time/strftime.cpp
@@ -26,7 +26,7 @@ LLVM_LIBC_FUNCTION(size_t, strftime,
int ret = strftime_core::strftime_main(&writer, format, timeptr);
if (buffsz > 0) // if the buffsz is 0 the buffer may be a null pointer.
wb.buff[wb.buff_cur] = '\0';
- return (ret < 0 || static_cast<size_t>(ret) > buffsz) ? 0 : ret;
+ return (ret < 0 || static_cast<size_t>(ret) >= buffsz) ? 0 : ret;
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/time/strftime_l.cpp b/libc/src/time/strftime_l.cpp
index 201b85da39ee2..409f8683b7289 100644
--- a/libc/src/time/strftime_l.cpp
+++ b/libc/src/time/strftime_l.cpp
@@ -29,7 +29,7 @@ LLVM_LIBC_FUNCTION(size_t, strftime_l,
int ret = strftime_core::strftime_main(&writer, format, timeptr);
if (buffsz > 0) // if the buffsz is 0 the buffer may be a null pointer.
wb.buff[wb.buff_cur] = '\0';
- return (ret < 0 || static_cast<size_t>(ret) > buffsz) ? 0 : ret;
+ return (ret < 0 || static_cast<size_t>(ret) >= buffsz) ? 0 : ret;
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/time/strftime_test.cpp b/libc/test/src/time/strftime_test.cpp
index cac7560b2b945..38176f77804d5 100644
--- a/libc/test/src/time/strftime_test.cpp
+++ b/libc/test/src/time/strftime_test.cpp
@@ -2326,3 +2326,23 @@ TEST(LlvmLibcStrftimeTest, TimeFormatFullDateTime) {
// size_t written = 0;
// SimplePaddedNum spn;
// }
+
+TEST(LlvmLibcStrftimeTest, BufferTooSmall) {
+ struct tm time;
+ char buffer[1];
+
+ time.tm_year = get_adjusted_year(2025);
+ time.tm_mon = 10;
+ time.tm_mday = 24;
+
+ size_t written =
+ LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%F", &time);
+ EXPECT_EQ(written, size_t{0});
+
+ char buffer2[10];
+
+ // The string "2025-11-24" is 10 chars,
+ // so strftime needs 10 + 1 bytes to write the string and the null terminator.
+ written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer2), "%F", &time);
+ EXPECT_EQ(written, size_t{0});
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/165711
More information about the libc-commits
mailing list