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 1c599de9 Escape any logger name '&' or '"' in html attribute data
(#509)
1c599de9 is described below
commit 1c599de956ae9eedd8b5e3f744bfb867c39e8bba
Author: Stephen Webb <[email protected]>
AuthorDate: Sat Jul 12 10:19:03 2025 +1000
Escape any logger name '&' or '"' in html attribute data (#509)
---
src/main/cpp/htmllayout.cpp | 8 +++----
src/test/cpp/xml/xmllayouttest.cpp | 49 ++++++++++++++++++++++++++++++++++++++
2 files changed, 53 insertions(+), 4 deletions(-)
diff --git a/src/main/cpp/htmllayout.cpp b/src/main/cpp/htmllayout.cpp
index c2411ece..ed6e61d7 100644
--- a/src/main/cpp/htmllayout.cpp
+++ b/src/main/cpp/htmllayout.cpp
@@ -109,25 +109,25 @@ void HTMLLayout::format(LogString& output,
if (event->getLevel()->equals(Level::getDebug()))
{
output.append(LOG4CXX_STR("<font color=\"#339933\">"));
- output.append(event->getLevel()->toString());
+ Transform::appendEscapingTags(output,
event->getLevel()->toString());
output.append(LOG4CXX_STR("</font>"));
}
else if (event->getLevel()->isGreaterOrEqual(Level::getWarn()))
{
output.append(LOG4CXX_STR("<font color=\"#993300\"><strong>"));
- output.append(event->getLevel()->toString());
+ Transform::appendEscapingTags(output,
event->getLevel()->toString());
output.append(LOG4CXX_STR("</strong></font>"));
}
else
{
- output.append(event->getLevel()->toString());
+ Transform::appendEscapingTags(output,
event->getLevel()->toString());
}
output.append(LOG4CXX_STR("</td>"));
output.append(LOG4CXX_EOL);
output.append(LOG4CXX_STR("<td title=\""));
- output.append(event->getLoggerName());
+ Transform::appendEscapingTags(output, event->getLoggerName());
output.append(LOG4CXX_STR(" logger\">"));
Transform::appendEscapingTags(output, event->getLoggerName());
output.append(LOG4CXX_STR("</td>"));
diff --git a/src/test/cpp/xml/xmllayouttest.cpp
b/src/test/cpp/xml/xmllayouttest.cpp
index 78f1c118..710e9fca 100644
--- a/src/test/cpp/xml/xmllayouttest.cpp
+++ b/src/test/cpp/xml/xmllayouttest.cpp
@@ -18,6 +18,7 @@
#include "../logunit.h"
#include <log4cxx/logger.h>
#include <log4cxx/xml/xmllayout.h>
+#include <log4cxx/htmllayout.h>
#include <log4cxx/fileappender.h>
#include <log4cxx/mdc.h>
@@ -37,6 +38,7 @@
#include "../xml/xlevel.h"
#include <log4cxx/helpers/bytebuffer.h>
#include <log4cxx/helpers/transcoder.h>
+#include <log4cxx/helpers/loglog.h>
using namespace log4cxx;
@@ -67,6 +69,7 @@ LOGUNIT_CLASS(XMLLayoutTest)
LOGUNIT_TEST(testActivateOptions);
LOGUNIT_TEST(testProblemCharacters);
LOGUNIT_TEST(testNDCWithCDATA);
+ LOGUNIT_TEST(testHTMLLayout);
LOGUNIT_TEST_SUITE_END();
@@ -453,6 +456,52 @@ public:
LOGUNIT_ASSERT_EQUAL(1, ndcCount);
}
+ /**
+ * Tests problematic characters in multiple fields.
+ * @throws Exception if parser can not be constructed or source is not
a valid XML document.
+ */
+ void testHTMLLayout()
+ {
+ LogString problemName = LOG4CXX_STR("com.example.bar<>&\"'");
+ auto level = std::make_shared<XLevel>(6000, problemName, 7);
+ NDC context(problemName);
+ auto event = std::make_shared<LoggingEvent>(problemName, level,
problemName, LOG4CXX_LOCATION);
+
+ HTMLLayout layout;
+ Pool p;
+ LogString html(LOG4CXX_STR("<body>"));
+ layout.format(html, event, p);
+ html += LOG4CXX_STR("</body>");
+
+ LogLog::debug(html);
+ char backing[3000];
+ ByteBuffer buf(backing, sizeof(backing));
+ CharsetEncoderPtr encoder(CharsetEncoder::getUTF8Encoder());
+ LogString::const_iterator iter{ html.begin() };
+ encoder->encode(html, iter, buf);
+ LOGUNIT_ASSERT(iter == html.end());
+ buf.flip();
+ auto parser = apr_xml_parser_create(p.getAPRPool());
+ LOGUNIT_ASSERT(parser != 0);
+ auto stat = apr_xml_parser_feed(parser, buf.data(),
buf.remaining());
+ LOGUNIT_ASSERT(stat == APR_SUCCESS);
+ apr_xml_doc* doc = 0;
+ stat = apr_xml_parser_done(parser, &doc);
+ LOGUNIT_ASSERT(doc != 0);
+ auto parsedResult = doc->root;
+ LOGUNIT_ASSERT(parsedResult != 0);
+
+ int childElementCount = 0;
+ for ( auto node = parsedResult->first_child
+ ; node != NULL
+ ; node = node->next)
+ {
+ ++childElementCount;
+ LOGUNIT_ASSERT_EQUAL(std::string("tr"),
std::string(node->name));
+ }
+ LOGUNIT_ASSERT(1 < childElementCount);
+ }
+
};