Fixed an infinite loop in "Transcoder::encode" (#34)

Fixed an infinite loop in "Transcoder::encode(const LogString&, std::wstring&)" by appending LOSSCHAR. The most likely alternative would be to throw on any invalid input instead, but that's not the case right now and LOSSCHAR used in other places as well.

https://issues.apache.org/jira/browse/LOGCXX-398

Co-authored-by: Robert Middleton <robert.middleton@rm5248.com>
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 937fc4a..fb2f76f 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -58,6 +58,7 @@
 			<action issue="LOGCXX-411" type="fix">Crash when logging on multiple threads.</action>
 			<action issue="LOGCXX-400" type="fix">C++11 does not allow char literals with highest bit set unless cast</action>
 			<action issue="LOGCXX-399" type="fix">Non-ascii character output wrong.</action>
+			<action issue="LOGCXX-398" type="fix">Infinite loop in Transcoder::encode(const LogString&amp; src, std::wstring&amp; dst)</action>
 			<action issue="LOGCXX-394" type="fix">Levels are not thread safe</action>
 			<action issue="LOGCXX-388" type="fix">Hierarchy::updateParents loops forever on illegal logger-name like '.logger1'</action>
 			<action issue="LOGCXX-382" type="fix">Mingw build type conversion error</action>
diff --git a/src/main/cpp/transcoder.cpp b/src/main/cpp/transcoder.cpp
index d423fb4..76e9361 100644
--- a/src/main/cpp/transcoder.cpp
+++ b/src/main/cpp/transcoder.cpp
@@ -509,11 +509,18 @@
 	dst.append(src);
 #else
 
-	for (LogString::const_iterator i = src.begin();
-		i != src.end();)
+	for (LogString::const_iterator i = src.begin(); i != src.end();)
 	{
 		unsigned int cp = Transcoder::decode(src, i);
-		encode(cp, dst);
+		if (cp != 0xFFFF)
+		{
+			encode(cp, dst);
+		}
+		else
+		{
+			dst.append(1, LOSSCHAR);
+			i++;
+		}
 	}
 
 #endif
diff --git a/src/test/cpp/helpers/transcodertestcase.cpp b/src/test/cpp/helpers/transcodertestcase.cpp
index 4f3a061..e806299 100644
--- a/src/test/cpp/helpers/transcodertestcase.cpp
+++ b/src/test/cpp/helpers/transcodertestcase.cpp
@@ -43,6 +43,7 @@
 	LOGUNIT_TEST(encode2);
 #if LOG4CXX_WCHAR_T_API
 	LOGUNIT_TEST(encode3);
+	LOGUNIT_TEST(encode3_1);
 #endif
 	LOGUNIT_TEST(encode4);
 #if LOG4CXX_WCHAR_T_API
@@ -163,6 +164,19 @@
 		LOGUNIT_ASSERT_EQUAL(manyAs, encoded.substr(0, BUFSIZE - 3));
 		LOGUNIT_ASSERT_EQUAL(std::wstring(L"Hello"), encoded.substr(BUFSIZE - 3));
 	}
+
+	void encode3_1()
+	{
+		// Test invalid multibyte string
+		LogString greeting;
+		greeting.push_back( 0xff );
+		std::wstring encoded;
+		Transcoder::encode(greeting, encoded);
+
+		std::wstring expected;
+		expected.push_back( log4cxx::helpers::Transcoder::LOSSCHAR );
+		LOGUNIT_ASSERT_EQUAL(encoded, expected );
+	}
 #endif
 
 	void encode4()