This is an automated email from the ASF dual-hosted git repository.
rmiddleton 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 2cbae954 Fix possible invalid cast (#470)
2cbae954 is described below
commit 2cbae9546303bdfbbf05c7635a3079720b22fd96
Author: Robert Middleton <[email protected]>
AuthorDate: Sun Feb 2 10:26:35 2025 -0500
Fix possible invalid cast (#470)
If a user attempts to load a config file with an improper level set such
that a non-level class is attempted to be used, throw an exception instead
of accessing invalid memory.
---
src/main/cpp/optionconverter.cpp | 15 +++++++++++++--
src/test/cpp/xml/domtestcase.cpp | 8 ++++++++
src/test/resources/input/xml/DOMInvalidLevel.xml | 11 +++++++++++
3 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/src/main/cpp/optionconverter.cpp b/src/main/cpp/optionconverter.cpp
index 59343410..be7dee76 100644
--- a/src/main/cpp/optionconverter.cpp
+++ b/src/main/cpp/optionconverter.cpp
@@ -343,8 +343,13 @@ LevelPtr OptionConverter::toLevel(const LogString& value,
try
{
- Level::LevelClass& levelClass =
- (Level::LevelClass&)Loader::loadClass(clazz);
+ // Note: the dynamic_cast could fail across DLL boundaries.
+ // However, without the dynamic_cast a poorly formed XML file
+ // could attempt to load an invalid class as a filter, causing
+ // a crash. If it can't be converted, a std::bad_cast should be
+ // thrown(and caught by the exception handler below)
+ const Level::LevelClass& levelClass =
+ dynamic_cast<const
Level::LevelClass&>(Loader::loadClass(clazz));
return levelClass.toLevel(levelName);
}
catch (ClassNotFoundException&)
@@ -358,6 +363,12 @@ LevelPtr OptionConverter::toLevel(const LogString& value,
LOG4CXX_STR("class [") + clazz + LOG4CXX_STR("], level
[") + levelName +
LOG4CXX_STR("] conversion) failed."), oops);
}
+ catch(const std::bad_cast&)
+ {
+ LogLog::warn(
+ LOG4CXX_STR("class [") + clazz + LOG4CXX_STR("] unable
to be converted to "
+ "Level::LevelClass"));
+ }
catch (...)
{
LogLog::warn(
diff --git a/src/test/cpp/xml/domtestcase.cpp b/src/test/cpp/xml/domtestcase.cpp
index e254868b..29d83a48 100644
--- a/src/test/cpp/xml/domtestcase.cpp
+++ b/src/test/cpp/xml/domtestcase.cpp
@@ -53,6 +53,7 @@ LOGUNIT_CLASS(DOMTestCase)
#endif
LOGUNIT_TEST(test3);
LOGUNIT_TEST(test4);
+ LOGUNIT_TEST(invalidLevel);
LOGUNIT_TEST_SUITE_END();
LoggerPtr root;
@@ -226,6 +227,13 @@ public:
bool exists = file.exists(p);
LOGUNIT_ASSERT(exists);
}
+
+ void invalidLevel()
+ {
+ // Load an XML file that attempts to use a filter as a level.
+ // We should not crash when loading this file.
+
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMInvalidLevel.xml"));
+ }
};
LOGUNIT_TEST_SUITE_REGISTRATION(DOMTestCase);
diff --git a/src/test/resources/input/xml/DOMInvalidLevel.xml
b/src/test/resources/input/xml/DOMInvalidLevel.xml
new file mode 100644
index 00000000..d5a1ca48
--- /dev/null
+++ b/src/test/resources/input/xml/DOMInvalidLevel.xml
@@ -0,0 +1,11 @@
+<log4j:configuration xmlns:log4j=' '>
+ <appender name="TEMP" class="FileAppender">
+ <filter class="LevelMatchFilter">
+ <param name="LevelToMatch" value=" #Filter"/>
+ </filter>
+ </appender>
+
+ <root>
+ <appender-ref ref="TEMP"/>
+ </root>
+</log4j:configuration>