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 9b3d2199 Preserve HTMLLayout attribute values during XML normalization
(#666)
9b3d2199 is described below
commit 9b3d21992d6ecc07eff07df95855bc0249cca019
Author: jmestwa-coder <[email protected]>
AuthorDate: Sat May 16 07:51:47 2026 +0530
Preserve HTMLLayout attribute values during XML normalization (#666)
---
src/main/cpp/htmllayout.cpp | 4 +-
src/main/cpp/transform.cpp | 59 ++++++++++++++++++++--------
src/main/include/log4cxx/helpers/transform.h | 13 ++++++
src/test/cpp/xml/xmllayouttest.cpp | 6 ++-
4 files changed, 63 insertions(+), 19 deletions(-)
diff --git a/src/main/cpp/htmllayout.cpp b/src/main/cpp/htmllayout.cpp
index 2655e0b4..d7404435 100644
--- a/src/main/cpp/htmllayout.cpp
+++ b/src/main/cpp/htmllayout.cpp
@@ -97,7 +97,7 @@ void HTMLLayout::format(
LOG4CXX_FORMAT_LAYOUT_FORMAL_PARAMETERS ) const
output.append(LOG4CXX_STR("<td title=\""));
LogString threadName(event->getThreadName());
- Transform::appendLegalCharacters(output, threadName);
+ Transform::appendEscapingAttribute(output, threadName);
output.append(LOG4CXX_STR(" thread\">"));
Transform::appendEscapingTags(output, threadName);
output.append(LOG4CXX_STR("</td>"));
@@ -126,7 +126,7 @@ void HTMLLayout::format(
LOG4CXX_FORMAT_LAYOUT_FORMAL_PARAMETERS ) const
output.append(LOG4CXX_EOL);
output.append(LOG4CXX_STR("<td title=\""));
- Transform::appendLegalCharacters(output, event->getLoggerName());
+ Transform::appendEscapingAttribute(output, event->getLoggerName());
output.append(LOG4CXX_STR(" logger\">"));
Transform::appendEscapingTags(output, event->getLoggerName());
output.append(LOG4CXX_STR("</td>"));
diff --git a/src/main/cpp/transform.cpp b/src/main/cpp/transform.cpp
index 32397a76..ec7c68c4 100644
--- a/src/main/cpp/transform.cpp
+++ b/src/main/cpp/transform.cpp
@@ -26,11 +26,11 @@ using namespace LOG4CXX_NS::helpers;
namespace
{
-using CharProcessor = std::function<void(LogString&, int)>;
+using CharProcessor = std::function<bool(LogString&, int)>;
// Allowable XML 1.0 characters are:
// #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
-void appendValidCharacters(LogString& buf, const LogString& input,
CharProcessor handler = {})
+void appendValidCharacters(LogString& buf, const LogString& input,
CharProcessor handler = {}, bool handleValidCharacters = false)
{
static const unsigned int specials[] =
{ 0x22 /* " */
@@ -46,18 +46,23 @@ void appendValidCharacters(LogString& buf, const LogString&
input, CharProcessor
auto ch = Transcoder::decode(input, nextCodePoint);
if (nextCodePoint == lastCodePoint) // failed to decode input?
nextCodePoint = input.end();
- else if ((0x20 <= ch && ch <= 0xD7FF) &&
- specials[0] != ch &&
- specials[1] != ch &&
- specials[2] != ch &&
- specials[3] != ch)
- {
- continue;
- }
- else if ((0x9 == ch || 0xA == ch || 0xD == ch) ||
- (0xE000 <= ch && ch <= 0xFFFD) ||
- (0x10000 <= ch && ch <= 0x10FFFF))
+ else if (((0x20 <= ch && ch <= 0xD7FF) &&
+ specials[0] != ch &&
+ specials[1] != ch &&
+ specials[2] != ch &&
+ specials[3] != ch) ||
+ (0x9 == ch || 0xA == ch || 0xD == ch) ||
+ (0xE000 <= ch && ch <= 0xFFFD) ||
+ (0x10000 <= ch && ch <= 0x10FFFF))
{
+ LogString escaped;
+ if (handleValidCharacters && handler &&
handler(escaped, ch))
+ {
+ if (start != lastCodePoint)
+ buf.append(start, lastCodePoint);
+ buf.append(escaped);
+ start = nextCodePoint;
+ }
continue;
}
@@ -89,14 +94,31 @@ void appendValidCharacters(LogString& buf, const LogString&
input, CharProcessor
break;
default:
- if (handler)
- handler(buf, ch);
+ if (handler && !handler(buf, ch))
+
Transform::appendCharacterReference(buf, ch);
break;
}
}
buf.append(start, input.end());
}
+bool appendCharacterReferenceHandler(LogString& buf, int ch)
+{
+ Transform::appendCharacterReference(buf, ch);
+ return true;
+}
+
+bool appendAttributeCharacterReference(LogString& buf, int ch)
+{
+ if (0x27 == ch || 0x9 == ch || 0xA == ch || 0xD == ch)
+ {
+ Transform::appendCharacterReference(buf, ch);
+ return true;
+ }
+
+ return false;
+}
+
} // namespace
void Transform::appendEscapingCDATA(
@@ -177,7 +199,12 @@ void Transform::appendCharacterReference(LogString& buf,
unsigned int ch)
void Transform::appendEscapingTags(LogString& buf, const LogString& input)
{
- appendValidCharacters(buf, input, appendCharacterReference);
+ appendValidCharacters(buf, input, appendCharacterReferenceHandler);
+}
+
+void Transform::appendEscapingAttribute(LogString& buf, const LogString& input)
+{
+ appendValidCharacters(buf, input, appendAttributeCharacterReference,
true);
}
void Transform::appendLegalCharacters(LogString& buf, const LogString& input)
diff --git a/src/main/include/log4cxx/helpers/transform.h
b/src/main/include/log4cxx/helpers/transform.h
index 301ea63c..537aeff9 100644
--- a/src/main/include/log4cxx/helpers/transform.h
+++ b/src/main/include/log4cxx/helpers/transform.h
@@ -45,6 +45,19 @@ class LOG4CXX_EXPORT Transform
static void appendEscapingTags(
LogString& buf, const LogString& input);
+ /**
+ * Add \c input to an HTML attribute value while replacing
characters
+ * that can break out of quoted attributes with entity
references.
+ * Any NUL character in \c input is not copied to \c buf.
+ * A character reference is used in place of a character
+ * whose value is not permitted by the XML 1.0 specification.
+ *
+ * @param buf output stream where to write the modified string.
+ * @param input The text to be converted.
+ * */
+ static void appendEscapingAttribute(
+ LogString& buf, const LogString& input);
+
/**
* Add \c input to \c buf while ensuring embedded CDEnd strings
(]]>)
* are handled properly within the message.
diff --git a/src/test/cpp/xml/xmllayouttest.cpp
b/src/test/cpp/xml/xmllayouttest.cpp
index 7869ea81..2ffbb2f0 100644
--- a/src/test/cpp/xml/xmllayouttest.cpp
+++ b/src/test/cpp/xml/xmllayouttest.cpp
@@ -473,7 +473,7 @@ public:
*/
void testHTMLLayout()
{
- LogString problemName = LOG4CXX_STR("com.example.bar<>&\"'");
+ LogString problemName =
LOG4CXX_STR("com.example.bar<>&\"'\n\t");
auto level = std::make_shared<XLevel>(6000, problemName, 7);
NDC context(problemName);
auto event = std::make_shared<LoggingEvent>(problemName, level,
problemName, LOG4CXX_LOCATION);
@@ -491,6 +491,10 @@ public:
encoder->encode(html, iter, buf);
LOGUNIT_ASSERT(iter == html.end());
buf.flip();
+
+ LOGUNIT_ASSERT(html.find(LOG4CXX_STR(
+
"title=\"com.example.bar<>&"'
	 logger\"")) !=
LogString::npos);
+
Pool p;
auto parser = apr_xml_parser_create(p.getAPRPool());
LOGUNIT_ASSERT(parser != 0);