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 56844c7c Prevent rollover failure with short file name patterns (#671)
56844c7c is described below
commit 56844c7c81c759b532802c06321f742d98d27a6f
Author: jmestwa-coder <[email protected]>
AuthorDate: Fri May 15 06:49:17 2026 +0530
Prevent rollover failure with short file name patterns (#671)
---
src/main/cpp/fixedwindowrollingpolicy.cpp | 4 +--
src/test/cpp/rolling/manualrollingtest.cpp | 18 ++++++++++
src/test/cpp/rolling/sizebasedrollingtest.cpp | 47 ++++++++++++++++++++++++++-
3 files changed, 66 insertions(+), 3 deletions(-)
diff --git a/src/main/cpp/fixedwindowrollingpolicy.cpp
b/src/main/cpp/fixedwindowrollingpolicy.cpp
index 89aec4c6..4f8a442f 100644
--- a/src/main/cpp/fixedwindowrollingpolicy.cpp
+++ b/src/main/cpp/fixedwindowrollingpolicy.cpp
@@ -265,11 +265,11 @@ bool FixedWindowRollingPolicy::purge(int lowIndex, int
highIndex, Pool& p) const
LogString lowFilename(buf);
- if (lowFilename.compare(lowFilename.length() - 3, 3,
LOG4CXX_STR(".gz")) == 0)
+ if (StringHelper::endsWith(lowFilename, LOG4CXX_STR(".gz")))
{
suffixLength = 3;
}
- else if (lowFilename.compare(lowFilename.length() - 4, 4,
LOG4CXX_STR(".zip")) == 0)
+ else if (StringHelper::endsWith(lowFilename, LOG4CXX_STR(".zip")))
{
suffixLength = 4;
}
diff --git a/src/test/cpp/rolling/manualrollingtest.cpp
b/src/test/cpp/rolling/manualrollingtest.cpp
index 2ca4cca6..50bd6681 100644
--- a/src/test/cpp/rolling/manualrollingtest.cpp
+++ b/src/test/cpp/rolling/manualrollingtest.cpp
@@ -54,6 +54,7 @@ LOGUNIT_CLASS(ManualRollingTest)
// LOGUNIT_TEST(test3);
LOGUNIT_TEST(test4);
LOGUNIT_TEST(test5);
+ LOGUNIT_TEST(testShortFileNamePattern);
LOGUNIT_TEST(create_directories);
LOGUNIT_TEST_SUITE_END();
@@ -167,6 +168,23 @@ public:
File("witness/rolling/sbr-test2.1")));
}
+ void testShortFileNamePattern()
+ {
+ FixedWindowRollingPolicyPtr policy =
FixedWindowRollingPolicyPtr(new FixedWindowRollingPolicy());
+ policy->setMinIndex(0);
+ policy->setMaxIndex(1);
+ policy->setFileNamePattern(LOG4CXX_STR("%i"));
+ policy->activateOptions();
+
+ Pool pool;
+ RolloverDescriptionPtr desc = policy->rollover(
+
LOG4CXX_STR("output/manual-short-pattern-active.log"),
+ false,
+ pool);
+
+ LOGUNIT_ASSERT(desc != NULL);
+ }
+
/**
* Same as testBasic but also with GZ compression.
*/
diff --git a/src/test/cpp/rolling/sizebasedrollingtest.cpp
b/src/test/cpp/rolling/sizebasedrollingtest.cpp
index f6001cfc..ef3a6dfe 100644
--- a/src/test/cpp/rolling/sizebasedrollingtest.cpp
+++ b/src/test/cpp/rolling/sizebasedrollingtest.cpp
@@ -56,6 +56,7 @@ LOGUNIT_CLASS(SizeBasedRollingTest)
LOGUNIT_TEST(test4);
LOGUNIT_TEST(test5);
LOGUNIT_TEST(test6);
+ LOGUNIT_TEST(testShortPatternRegression);
LOGUNIT_TEST_SUITE_END();
LoggerPtr root;
@@ -356,7 +357,51 @@ public:
LOGUNIT_ASSERT_EQUAL(true,
Compare::compare(File("output/sbr-test6.log"),
File("witness/rolling/sbr-test3.log")));
}
-};
+ /**
+ * Regression test for FixedWindowRollingPolicy::purge() underflow.
+ * This test uses a very short fileNamePattern ("R%i" -> "R1") which
would
+ * trigger std::out_of_range in the original vulnerable code.
+ */
+ void testShortPatternRegression()
+ {
+ LogString activeFile = LOG4CXX_STR("output/active.log");
+ LogString rolledFile = LOG4CXX_STR("R1");
+ File(activeFile).deleteFile();
+ File(rolledFile).deleteFile();
+
+ PatternLayoutPtr layout = PatternLayoutPtr(new
PatternLayout(LOG4CXX_STR("%m\n")));
+ RollingFileAppenderPtr rfa = RollingFileAppenderPtr(new
RollingFileAppender());
+ rfa->setAppend(false);
+ rfa->setLayout(layout);
+ rfa->setFile(activeFile);
+
+ FixedWindowRollingPolicyPtr swrp =
FixedWindowRollingPolicyPtr(new FixedWindowRollingPolicy());
+ SizeBasedTriggeringPolicyPtr sbtp =
SizeBasedTriggeringPolicyPtr(new SizeBasedTriggeringPolicy());
+ sbtp->setMaxFileSize(5); // Very small to trigger rollover
+ swrp->setMinIndex(1);
+ swrp->setFileNamePattern(LOG4CXX_STR("R%i"));
+ swrp->activateOptions();
+
+ rfa->setRollingPolicy(swrp);
+ rfa->setTriggeringPolicy(sbtp);
+ rfa->activateOptions();
+ root->addAppender(rfa);
+
+ // First log: goes to active.log, size becomes > 5
+ LOG4CXX_INFO(logger, LOG4CXX_STR("123456"));
+ // Second log: triggers rollover
+ LOG4CXX_INFO(logger, LOG4CXX_STR("next"));
+
+ // In the vulnerable code, rollover would fail due to
std::out_of_range
+ // and the rolled file would not exist.
+ LOGUNIT_ASSERT(File(rolledFile).exists());
+
+ // Cleanup
+ File(activeFile).deleteFile();
+ File(rolledFile).deleteFile();
+ }
+
+};
LOGUNIT_TEST_SUITE_REGISTRATION(SizeBasedRollingTest);