diff --git a/libc/async_safe/async_safe_log.cpp b/libc/async_safe/async_safe_log.cpp index d31fe0303d..420560f7b0 100644 --- a/libc/async_safe/async_safe_log.cpp +++ b/libc/async_safe/async_safe_log.cpp @@ -254,7 +254,7 @@ static void out_vformat(Out& o, const char* format, va_list args) { bool alternate = false; size_t bytelen = sizeof(int); int slen; - char buffer[32]; /* temporary buffer used to format numbers */ + char buffer[64]; // temporary buffer used to format numbers/format errno string char c; @@ -345,7 +345,6 @@ static void out_vformat(Out& o, const char* format, va_list args) { /* conversion specifier */ const char* str = buffer; - char strerror_buf[256]; if (c == 's') { /* string */ str = va_arg(args, const char*); @@ -360,7 +359,7 @@ static void out_vformat(Out& o, const char* format, va_list args) { buffer[1] = 'x'; format_integer(buffer + 2, sizeof(buffer) - 2, value, 'x'); } else if (c == 'm') { - str = strerror_r(errno, strerror_buf, sizeof(strerror_buf)); + strerror_r(errno, buffer, sizeof(buffer)); } else if (c == 'd' || c == 'i' || c == 'o' || c == 'u' || c == 'x' || c == 'X') { /* integers - first read value from stack */ uint64_t value; diff --git a/tests/async_safe_test.cpp b/tests/async_safe_test.cpp index f52387e97d..dc4db07dc0 100644 --- a/tests/async_safe_test.cpp +++ b/tests/async_safe_test.cpp @@ -16,6 +16,8 @@ #include +#include + #if defined(__BIONIC__) #include #endif // __BIONIC__ @@ -227,3 +229,19 @@ TEST(async_safe_log, buffer_overrun) { GTEST_SKIP() << "bionic-only test"; #endif // __BIONIC__ } + +// Verify that using %m is never cut off. +TEST(async_safe_format_buffer, percent_m_fits_in_buffer) { +#if defined(__BIONIC__) + for (int i = 0; i < 256; i++) { + errno = i; + char async_buf[256]; + async_safe_format_buffer(async_buf, sizeof(async_buf), "%m"); + char strerror_buf[1024]; + strerror_r(errno, strerror_buf, sizeof(strerror_buf)); + ASSERT_STREQ(strerror_buf, async_buf); + } +#else // __BIONIC__ + GTEST_SKIP() << "bionic-only test"; +#endif // __BIONIC__ +}