Skip to content

Commit cd945c2

Browse files
committed
Test: fix Esc(wchar_t) crash under _FORTIFY_SOURCE=3
Cygwin's snprintf returns -1 for %lc with wide chars that are not representable in the C locale, even when iswprint() reports them as printable (e.g., U+FFFD). Under NDEBUG (Release/RelWithDebInfo), the assert(n > 0) is compiled away, and std::string(buf, SIZE_MAX) throws std::length_error. Always use hex representation for wchar_t in Esc(), avoiding the platform-specific %lc divergence entirely.
1 parent 8a9409a commit cd945c2

1 file changed

Lines changed: 7 additions & 6 deletions

File tree

absl/strings/internal/str_format/convert_test.cc

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,13 @@ std::string Esc(unsigned char v) { return EscCharImpl(v); }
151151

152152
std::string Esc(wchar_t v) {
153153
char buf[64];
154-
int n = std::iswprint(static_cast<wint_t>(v))
155-
? snprintf(buf, sizeof(buf), "L'%lc'", static_cast<wint_t>(v))
156-
: snprintf(buf, sizeof(buf), "L'\\x%.*llx'",
157-
static_cast<int>(sizeof(wchar_t) * CHAR_BIT / 4),
158-
static_cast<unsigned long long>(
159-
static_cast<std::make_unsigned_t<wchar_t>>(v)));
154+
// Cygwin's snprintf returns -1 for %lc with non-representable wide chars
155+
// in the C locale, even when iswprint() reports them as printable.
156+
// Always use the hex representation to avoid this platform divergence.
157+
int n = snprintf(buf, sizeof(buf), "L'\\x%.*llx'",
158+
static_cast<int>(sizeof(wchar_t) * CHAR_BIT / 4),
159+
static_cast<unsigned long long>(
160+
static_cast<std::make_unsigned_t<wchar_t>>(v)));
160161
assert(n > 0 && static_cast<size_t>(n) < sizeof(buf));
161162
return std::string(buf, static_cast<size_t>(n));
162163
}

0 commit comments

Comments
 (0)