Skip to content

Commit 784b74c

Browse files
authored
[libc] Fix off by one error in strftime (#165711)
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.
1 parent b1acd6d commit 784b74c

File tree

3 files changed

+22
-2
lines changed

3 files changed

+22
-2
lines changed

libc/src/time/strftime.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ LLVM_LIBC_FUNCTION(size_t, strftime,
2626
int ret = strftime_core::strftime_main(&writer, format, timeptr);
2727
if (buffsz > 0) // if the buffsz is 0 the buffer may be a null pointer.
2828
wb.buff[wb.buff_cur] = '\0';
29-
return (ret < 0 || static_cast<size_t>(ret) > buffsz) ? 0 : ret;
29+
return (ret < 0 || static_cast<size_t>(ret) >= buffsz) ? 0 : ret;
3030
}
3131

3232
} // namespace LIBC_NAMESPACE_DECL

libc/src/time/strftime_l.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ LLVM_LIBC_FUNCTION(size_t, strftime_l,
2929
int ret = strftime_core::strftime_main(&writer, format, timeptr);
3030
if (buffsz > 0) // if the buffsz is 0 the buffer may be a null pointer.
3131
wb.buff[wb.buff_cur] = '\0';
32-
return (ret < 0 || static_cast<size_t>(ret) > buffsz) ? 0 : ret;
32+
return (ret < 0 || static_cast<size_t>(ret) >= buffsz) ? 0 : ret;
3333
}
3434

3535
} // namespace LIBC_NAMESPACE_DECL

libc/test/src/time/strftime_test.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2326,3 +2326,23 @@ TEST(LlvmLibcStrftimeTest, TimeFormatFullDateTime) {
23262326
// size_t written = 0;
23272327
// SimplePaddedNum spn;
23282328
// }
2329+
2330+
TEST(LlvmLibcStrftimeTest, BufferTooSmall) {
2331+
struct tm time;
2332+
char buffer[1];
2333+
2334+
time.tm_year = get_adjusted_year(2025);
2335+
time.tm_mon = 10;
2336+
time.tm_mday = 24;
2337+
2338+
size_t written =
2339+
LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%F", &time);
2340+
EXPECT_EQ(written, size_t{0});
2341+
2342+
char buffer2[10];
2343+
2344+
// The string "2025-11-24" is 10 chars,
2345+
// so strftime needs 10 + 1 bytes to write the string and the null terminator.
2346+
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer2), "%F", &time);
2347+
EXPECT_EQ(written, size_t{0});
2348+
}

0 commit comments

Comments
 (0)