This is an automated email from the ASF dual-hosted git repository.
swebb2066 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git
The following commit(s) were added to refs/heads/master by this push:
new 6f791f0d Prevent potential infinite loop in MbstowcsCharsetDecoder
(#589)
6f791f0d is described below
commit 6f791f0dc49248cdbdbd9d22b978349ae36d3182
Author: OxBat <[email protected]>
AuthorDate: Tue Apr 7 02:32:46 2026 +0200
Prevent potential infinite loop in MbstowcsCharsetDecoder (#589)
* add unit test for mbsrtowcs infinite loop
---
src/main/cpp/charsetdecoder.cpp | 11 +++++++++
src/test/cpp/helpers/charsetdecodertestcase.cpp | 30 ++++++++++++++++++++++++-
2 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/src/main/cpp/charsetdecoder.cpp b/src/main/cpp/charsetdecoder.cpp
index ed79d440..7b364c08 100644
--- a/src/main/cpp/charsetdecoder.cpp
+++ b/src/main/cpp/charsetdecoder.cpp
@@ -208,6 +208,17 @@ class MbstowcsCharsetDecoder : public CharsetDecoder
}
else
{
+ // FIX: Check for incomplete
sequence infinite loop.
+ // If mbsrtowcs returns success
(>=0) but converted 0 bytes while data remains,
+ // we are stuck (e.g.
incomplete multibyte char at EOF).
+ if (converted == 0 &&
in.remaining() > 0)
+ {
+ LogString
msg(LOG4CXX_STR("Incomplete multibyte sequence at end of buffer"));
+ LogLog::warn(msg);
+ stat = APR_BADCH;
+ break; // Break the
infinite loop
+ }
+
wbuf[wCharCount] = 0;
stat = append(out, wbuf);
}
diff --git a/src/test/cpp/helpers/charsetdecodertestcase.cpp
b/src/test/cpp/helpers/charsetdecodertestcase.cpp
index 81497a7a..c99366fa 100644
--- a/src/test/cpp/helpers/charsetdecodertestcase.cpp
+++ b/src/test/cpp/helpers/charsetdecodertestcase.cpp
@@ -38,6 +38,9 @@ LOGUNIT_CLASS(CharsetDecoderTestCase)
LOGUNIT_TEST(decode2);
LOGUNIT_TEST(decode3);
LOGUNIT_TEST(decode4);
+#if LOG4CXX_LOGCHAR_IS_WCHAR && LOG4CXX_HAS_MBSRTOWCS
+ LOGUNIT_TEST(testMbstowcsInfiniteLoop);
+#endif
LOGUNIT_TEST_SUITE_END();
enum { BUFSIZE = 256 };
@@ -147,7 +150,32 @@ public:
}
}
-
+#if LOG4CXX_LOGCHAR_IS_WCHAR && LOG4CXX_HAS_MBSRTOWCS
+ /**
+ * Tests that we don't loop infinitely when mbsrtowcs refuses to consume
+ * an incomplete multibyte sequence at the end of the buffer.
+ */
+ void testMbstowcsInfiniteLoop()
+ {
+ // 1. setup: buffer ending with a partial multibyte sequence.
+ // 0xC2 is a generic start byte for a 2-byte sequence in UTF-8.
+ char input[] = { 'A', (char)0xC2, 0 };
+ ByteBuffer in(input, 2);
+ LogString out;
+
+ // 2. execution:
+ // this decoder is the default on WCHAR builds.
+ CharsetDecoderPtr decoder = CharsetDecoder::getDefaultDecoder();
+
+ // without fix: infinite loop.
+ // with fix: detects the stall and breaks/returns error.
+ decoder->decode(in, out);
+
+ // 3. verify: We survived the call.
+ LOGUNIT_ASSERT(true);
+ }
+#endif
+
};
LOGUNIT_TEST_SUITE_REGISTRATION(CharsetDecoderTestCase);