You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by sw...@apache.org on 2026/08/31 06:24:31 UTC

(logging-log4cxx) 01/01: Add some more name abbreviation test cases

This is an automated email from the ASF dual-hosted git repository.

swebb2066 pushed a commit to branch add_more_name_abreviation_tests
in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git

commit 49aacfd55007808e2b194fdcddfe3811fc1626bf
Author: Stephen Webb <sw...@gmail.com>
AuthorDate: Mon Aug 31 16:06:34 2026 +1000

    Add some more name abbreviation test cases
---
 src/main/cpp/classnamepatternconverter.cpp         |  5 +--
 src/main/cpp/loggerpatternconverter.cpp            |  5 +--
 src/main/cpp/nameabbreviator.cpp                   | 29 ++++++----------
 src/main/include/log4cxx/pattern/nameabbreviator.h |  8 ++---
 .../include/log4cxx/pattern/namepatternconverter.h |  5 +--
 src/test/cpp/patternlayouttest.cpp                 | 40 +++++++++++++++++-----
 6 files changed, 56 insertions(+), 36 deletions(-)

diff --git a/src/main/cpp/classnamepatternconverter.cpp b/src/main/cpp/classnamepatternconverter.cpp
index 1afe6b35..1972d7de 100644
--- a/src/main/cpp/classnamepatternconverter.cpp
+++ b/src/main/cpp/classnamepatternconverter.cpp
@@ -42,7 +42,8 @@ PatternConverterPtr ClassNamePatternConverter::newInstance(
 
 void ClassNamePatternConverter::format( LOG4CXX_FORMAT_EVENT_FORMAL_PARAMETERS ) const
 {
-	int initialLength = (int)toAppendTo.length();
+	auto initialLength = toAppendTo.length();
 	append(toAppendTo, event->getLocationInformation().getClassName());
-	abbreviate(initialLength, toAppendTo);
+	if (initialLength < toAppendTo.length())
+		abbreviate(initialLength, toAppendTo);
 }
diff --git a/src/main/cpp/loggerpatternconverter.cpp b/src/main/cpp/loggerpatternconverter.cpp
index e8ce5a31..3704b7dc 100644
--- a/src/main/cpp/loggerpatternconverter.cpp
+++ b/src/main/cpp/loggerpatternconverter.cpp
@@ -42,7 +42,8 @@ PatternConverterPtr LoggerPatternConverter::newInstance(
 
 void LoggerPatternConverter::format( LOG4CXX_FORMAT_EVENT_FORMAL_PARAMETERS ) const
 {
-	int initialLength = (int)toAppendTo.length();
+	auto initialLength = toAppendTo.length();
 	toAppendTo.append(event->getLoggerName());
-	abbreviate(initialLength, toAppendTo);
+	if (initialLength < toAppendTo.length())
+		abbreviate(initialLength, toAppendTo);
 }
diff --git a/src/main/cpp/nameabbreviator.cpp b/src/main/cpp/nameabbreviator.cpp
index 38c8ae90..caafce85 100644
--- a/src/main/cpp/nameabbreviator.cpp
+++ b/src/main/cpp/nameabbreviator.cpp
@@ -94,28 +94,22 @@ class MaxElementAbbreviator : public NameAbbreviator
 		}
 
 		/**
-		 * Abbreviate name.
-		 * @param buf buffer to append abbreviation.
-		 * @param nameStart start of name to abbreviate.
+		 * {@inheritDoc}
 		 */
 		void abbreviate(LogString::size_type nameStart, LogString& buf) const override
 		{
-			// We substract 1 from 'len' when assigning to 'end' to avoid out of
-			// bounds exception in return r.substring(end+1, len). This can happen if
-			// precision is 1 and the logger name ends with a dot.
-			LogString::size_type end = buf.length() - 1;
-
-			for (LogString::size_type i = count; i > 0; i--)
+			logchar separ = 0x2E; // '.'
+			LogString::size_type end = buf.length();
+			for (LogString::size_type i = count; nameStart < end && 0 < i; --i)
 			{
-				end = buf.rfind(0x2E /* '.' */, end - 1);
-
-				if ((end == LogString::npos) || (end < nameStart))
+				end = buf.rfind(separ, end - 1);
+				if (LogString::npos == end)
 				{
 					return;
 				}
 			}
-
-			buf.erase(buf.begin() + nameStart, buf.begin() + (end + 1));
+			if (nameStart < end + 1 && end + 1 < buf.length())
+				buf.erase(buf.begin() + nameStart, buf.begin() + (end + 1));
 		}
 };
 
@@ -259,9 +253,7 @@ class PatternAbbreviator : public NameAbbreviator
 		}
 
 		/**
-		 * Abbreviate name.
-		 * @param buf buffer that abbreviated name is appended.
-		 * @param nameStart start of name.
+		 * {@inheritDoc}
 		 */
 		void abbreviate(LogString::size_type nameStart, LogString& buf) const override
 		{
@@ -279,7 +271,8 @@ class PatternAbbreviator : public NameAbbreviator
 			//
 			//   apply the last pattern to all the remaining name parts
 			//
-			fragments.back().abbreviateAll(buf, pos);
+			if (pos < buf.length())
+				fragments.back().abbreviateAll(buf, pos);
 		}
 };
 }
diff --git a/src/main/include/log4cxx/pattern/nameabbreviator.h b/src/main/include/log4cxx/pattern/nameabbreviator.h
index 70fa212c..0fb10c8f 100644
--- a/src/main/include/log4cxx/pattern/nameabbreviator.h
+++ b/src/main/include/log4cxx/pattern/nameabbreviator.h
@@ -70,10 +70,10 @@ class LOG4CXX_EXPORT NameAbbreviator : public LOG4CXX_NS::helpers::Object
 		static NameAbbreviatorPtr getDefaultAbbreviator();
 
 		/**
-		 * Abbreviates a name in a StringBuffer.
-		 *
-		 * @param nameStart starting position of name in buf.
-		 * @param buf buffer, may not be null.
+		 * Modify \c buf by abbreviating the name at index \c nameStart.
+		 * @pre !buf.empty() && nameStart < buf.length()
+		 * @param nameStart an index into \c buf of the name.
+		 * @param buf string buffer containing name.
 		 */
 		virtual void abbreviate(LogString::size_type nameStart, LogString& buf) const = 0;
 
diff --git a/src/main/include/log4cxx/pattern/namepatternconverter.h b/src/main/include/log4cxx/pattern/namepatternconverter.h
index 87094362..397287b7 100644
--- a/src/main/include/log4cxx/pattern/namepatternconverter.h
+++ b/src/main/include/log4cxx/pattern/namepatternconverter.h
@@ -58,8 +58,9 @@ class LOG4CXX_EXPORT NamePatternConverter : public LoggingEventPatternConverter
 			const std::vector<LogString>& options);
 
 		/**
-		 * Abbreviate name in string buffer.
-		 * @param nameStart starting position of name to abbreviate.
+		 * Modify \c buf by abbreviating the name at index \c nameStart.
+		 * @pre !buf.empty() && nameStart < buf.length()
+		 * @param nameStart an index into \c buf of the name.
 		 * @param buf string buffer containing name.
 		 */
 		void abbreviate(LogString::size_type nameStart, LogString& buf) const;
diff --git a/src/test/cpp/patternlayouttest.cpp b/src/test/cpp/patternlayouttest.cpp
index 0602660b..0c7f80db 100644
--- a/src/test/cpp/patternlayouttest.cpp
+++ b/src/test/cpp/patternlayouttest.cpp
@@ -95,6 +95,7 @@ LOGUNIT_CLASS(PatternLayoutTest)
 	LOGUNIT_TEST(testAbbreviateLeadingDot);
 	LOGUNIT_TEST(testAbbreviateTrailingDot);
 	LOGUNIT_TEST(testAbbreviateEmptyName);
+	LOGUNIT_TEST(testAbbreviateDegenerateName);
 	LOGUNIT_TEST(testAbbreviateSegmentEqualToCharCountBoundary);
 	LOGUNIT_TEST(testAbbreviateSegmentOneCharOverBoundary);
 	LOGUNIT_TEST(testAbbreviateManySegmentsDeepHierarchy);
@@ -780,16 +781,18 @@ public:
 	 */
 	void testAbbreviateTrailingDot()
 	{
-		PatternLayout layout(LOG4CXX_STR("%c{1.}"));
 		auto event = std::make_shared<spi::LoggingEvent>
 			( LOG4CXX_STR("org.apache.")
 			, Level::getInfo()
 			, LOG4CXX_STR("msg")
 			, LOG4CXX_LOCATION
 			);
-		LogString result;
-		layout.format(result, event);
-		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("o.a.")), result);
+		LogString maxElementCharCountResult;
+		PatternLayout(LOG4CXX_STR("%c{1.}")).format(maxElementCharCountResult, event);
+		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("o.a.")), maxElementCharCountResult);
+		LogString maxElementCountResult;
+		PatternLayout(LOG4CXX_STR("%c{2}")).format(maxElementCountResult, event);
+		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("apache.")), maxElementCountResult);
 	}
 
 	/**
@@ -798,16 +801,37 @@ public:
 	 */
 	void testAbbreviateEmptyName()
 	{
-		PatternLayout layout(LOG4CXX_STR("%c{2}"));
 		auto event = std::make_shared<spi::LoggingEvent>
 			( LOG4CXX_STR("")
 			, Level::getInfo()
 			, LOG4CXX_STR("msg")
 			, LOG4CXX_LOCATION
 			);
-		LogString result;
-		layout.format(result, event);
-		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("")), result);
+		LogString maxElementCountResult;
+		PatternLayout(LOG4CXX_STR("%c{2}")).format(maxElementCountResult, event);
+		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("")), maxElementCountResult);
+		LogString maxElementCharCountResult;
+		PatternLayout(LOG4CXX_STR("%c{1.}")).format(maxElementCharCountResult, event);
+		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("")), maxElementCharCountResult);
+	}
+
+	/**
+	 * Degenerate logger name.
+	 */
+	void testAbbreviateDegenerateName()
+	{
+		auto event = std::make_shared<spi::LoggingEvent>
+			( LOG4CXX_STR(".")
+			, Level::getInfo()
+			, LOG4CXX_STR("msg")
+			, LOG4CXX_LOCATION
+			);
+		LogString maxElementCountResult;
+		PatternLayout(LOG4CXX_STR("%c{1}")).format(maxElementCountResult, event);
+		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR(".")), maxElementCountResult);
+		LogString maxElementCharCountResult;
+		PatternLayout(LOG4CXX_STR("%c{1.}")).format(maxElementCharCountResult, event);
+		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR(".")), maxElementCharCountResult);
 	}
 
 	/**