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 2025/02/04 02:43:25 UTC

(logging-log4cxx) branch master updated: Restrict pattern layout min/max field width specifiers to 3 digits (#475)

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 1d7dda07 Restrict pattern layout min/max field width specifiers to 3 digits (#475)
1d7dda07 is described below

commit 1d7dda076acff30aa34e3751d445e822be1d73a7
Author: Stephen Webb <st...@ieee.org>
AuthorDate: Tue Feb 4 13:43:19 2025 +1100

    Restrict pattern layout min/max field width specifiers to 3 digits (#475)
---
 src/main/cpp/patternparser.cpp                 |  9 +++++++--
 src/main/include/log4cxx/patternlayout.h       |  4 ++--
 src/test/cpp/pattern/patternparsertestcase.cpp | 11 +++++++++++
 3 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/src/main/cpp/patternparser.cpp b/src/main/cpp/patternparser.cpp
index fe6c420f..d27ba07e 100644
--- a/src/main/cpp/patternparser.cpp
+++ b/src/main/cpp/patternparser.cpp
@@ -125,6 +125,7 @@ void PatternParser::parse(
 	int state = LITERAL_STATE;
 	logchar c;
 	size_t i = 0;
+	int minDigitCount{ 0 }, maxDigitCount{ 0 };
 	FormattingInfoPtr formattingInfo(FormattingInfo::getDefault());
 
 	while (i < patternLength)
@@ -198,6 +199,7 @@ void PatternParser::parse(
 										formattingInfo->isLeftAligned(), c - 0x30 /* '0' */,
 										formattingInfo->getMaxLength());
 							state = MIN_STATE;
+							minDigitCount = 1;
 						}
 						else
 						{
@@ -221,12 +223,13 @@ void PatternParser::parse(
 			case MIN_STATE:
 				currentLiteral.append(1, c);
 
-				if ((c >= 0x30 /* '0' */) && (c <= 0x39 /* '9' */))
+				if ((c >= 0x30 /* '0' */) && (c <= 0x39 /* '9' */) && minDigitCount < 3)
 				{
 					formattingInfo = std::make_shared<FormattingInfo>(
 								formattingInfo->isLeftAligned(),
 								(formattingInfo->getMinLength() * 10) + (c - 0x30 /* '0' */),
 								formattingInfo->getMaxLength());
+					++minDigitCount;
 				}
 				else if (c == 0x2E /* '.' */)
 				{
@@ -257,6 +260,7 @@ void PatternParser::parse(
 								formattingInfo->isLeftAligned(), formattingInfo->getMinLength(),
 								c - 0x30 /* '0' */);
 					state = MAX_STATE;
+					maxDigitCount = 1;
 				}
 				else
 				{
@@ -270,11 +274,12 @@ void PatternParser::parse(
 			case MAX_STATE:
 				currentLiteral.append(1, c);
 
-				if ((c >= 0x30 /* '0' */) && (c <= 0x39 /* '9' */))
+				if ((c >= 0x30 /* '0' */) && (c <= 0x39 /* '9' */) && maxDigitCount < 3)
 				{
 					formattingInfo = std::make_shared<FormattingInfo>(
 								formattingInfo->isLeftAligned(), formattingInfo->getMinLength(),
 								(formattingInfo->getMaxLength() * 10) + (c - 0x30 /* '0' */));
+					++maxDigitCount;
 				}
 				else
 				{
diff --git a/src/main/include/log4cxx/patternlayout.h b/src/main/include/log4cxx/patternlayout.h
index c20242aa..7420266d 100644
--- a/src/main/include/log4cxx/patternlayout.h
+++ b/src/main/include/log4cxx/patternlayout.h
@@ -283,7 +283,7 @@ LOG4CXX_LIST_DEF(FormattingInfoList, LOG4CXX_NS::pattern::FormattingInfoPtr);
  * <p>
  *  The first optional format modifier is the <em>left justification flag</em> which is
  *  just the minus (-) character. Then comes the optional <em>minimum field width</em>
- *  modifier. This is a decimal constant that represents the minimum number of characters
+ *  modifier. This is a 1 to 3 decimal digit constant that represents the minimum number of characters
  *  to output. If the data item requires fewer characters, it is padded on either the left
  *  or the right until the minimum width is reached. The default is to pad on the left
  *  (right justify) but you can specify right padding with the left justification flag. The
@@ -293,7 +293,7 @@ LOG4CXX_LIST_DEF(FormattingInfoList, LOG4CXX_NS::pattern::FormattingInfoPtr);
  *
  * <p>
  *  This behavior can be changed using the <em>maximum field width</em> modifier which is
- *  designated by a period followed by a decimal constant. If the data item is longer than
+ *  designated by a period followed by a 1 to 3 decimal digit constant. If the data item is longer than
  *  the maximum field, then the extra characters are removed from the <em>beginning</em> of
  *  the data item and not from the end. For example, it the maximum field width is eight
  *  and the data item is ten characters long, then the first two characters of the data
diff --git a/src/test/cpp/pattern/patternparsertestcase.cpp b/src/test/cpp/pattern/patternparsertestcase.cpp
index 746572da..88db4116 100644
--- a/src/test/cpp/pattern/patternparsertestcase.cpp
+++ b/src/test/cpp/pattern/patternparsertestcase.cpp
@@ -80,6 +80,7 @@ LOGUNIT_CLASS(PatternParserTestCase)
 	LOGUNIT_TEST(testBasic2);
 	LOGUNIT_TEST(testMultiOption);
 	LOGUNIT_TEST(testThreadUsername);
+	LOGUNIT_TEST(testInvalidPatterns);
 	LOGUNIT_TEST_SUITE_END();
 
 	LoggingEventPtr event;
@@ -293,6 +294,16 @@ public:
 			expected);
 	}
 
+	void testInvalidPatterns()
+	{
+		assertFormattedEquals(LOG4CXX_STR("%6666c"),
+			getFormatSpecifiers(),
+			LOG4CXX_STR("%6666c"));
+		assertFormattedEquals(LOG4CXX_STR("%6.6666c"),
+			getFormatSpecifiers(),
+			LOG4CXX_STR("%6.6666c"));
+	}
+
 };
 
 //