Coverage Report

Created: 2025-08-29 06:29

/src/logging-log4cxx/src/main/cpp/xmllayout.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
#include <log4cxx/logstring.h>
19
#include <log4cxx/xml/xmllayout.h>
20
#include <log4cxx/spi/loggingevent.h>
21
#include <log4cxx/helpers/optionconverter.h>
22
#include <log4cxx/level.h>
23
#include <log4cxx/helpers/transform.h>
24
#include <log4cxx/helpers/iso8601dateformat.h>
25
#include <log4cxx/helpers/stringhelper.h>
26
#include <log4cxx/helpers/transcoder.h>
27
#include <log4cxx/ndc.h>
28
29
30
using namespace LOG4CXX_NS;
31
using namespace LOG4CXX_NS::helpers;
32
using namespace LOG4CXX_NS::spi;
33
using namespace LOG4CXX_NS::xml;
34
35
struct XMLLayout::XMLLayoutPrivate
36
{
37
  XMLLayoutPrivate()
38
3.89k
    : locationInfo(false)
39
3.89k
    , properties(false)
40
3.89k
    , expectedPatternLength(100)
41
3.89k
    {}
42
43
  // Print no location info by default
44
  bool locationInfo; //= false
45
  bool properties; // = false
46
47
  // Expected length of a formatted event excluding the message text
48
  size_t expectedPatternLength;
49
};
50
51
IMPLEMENT_LOG4CXX_OBJECT(XMLLayout)
52
53
XMLLayout::XMLLayout()
54
3.89k
  : m_priv(std::make_unique<XMLLayoutPrivate>())
55
3.89k
{
56
3.89k
  m_priv->expectedPatternLength = getFormattedEventCharacterCount() * 2;
57
3.89k
}
Unexecuted instantiation: log4cxx::xml::XMLLayout::XMLLayout()
log4cxx::xml::XMLLayout::XMLLayout()
Line
Count
Source
54
3.89k
  : m_priv(std::make_unique<XMLLayoutPrivate>())
55
3.89k
{
56
3.89k
  m_priv->expectedPatternLength = getFormattedEventCharacterCount() * 2;
57
3.89k
}
58
59
3.89k
XMLLayout::~XMLLayout() {}
60
61
void XMLLayout::setOption(const LogString& option,
62
  const LogString& value)
63
0
{
64
0
  if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("LOCATIONINFO"), LOG4CXX_STR("locationinfo")))
65
0
  {
66
0
    setLocationInfo(OptionConverter::toBoolean(value, false));
67
0
    m_priv->expectedPatternLength = getFormattedEventCharacterCount() * 2;
68
0
  }
69
70
0
  if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("PROPERTIES"), LOG4CXX_STR("properties")))
71
0
  {
72
0
    setProperties(OptionConverter::toBoolean(value, false));
73
0
    m_priv->expectedPatternLength = getFormattedEventCharacterCount() * 2;
74
0
  }
75
0
}
Unexecuted instantiation: log4cxx::xml::XMLLayout::setOption(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Unexecuted instantiation: log4cxx::xml::XMLLayout::setOption(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&)
76
77
void XMLLayout::format(LogString& output,
78
  const spi::LoggingEventPtr& event,
79
  Pool& p) const
80
7.79k
{
81
7.79k
  output.reserve(m_priv->expectedPatternLength + event->getMessage().size());
82
7.79k
  output.append(LOG4CXX_STR("<log4j:event logger=\""));
83
7.79k
  Transform::appendEscapingTags(output, event->getLoggerName());
84
7.79k
  output.append(LOG4CXX_STR("\" timestamp=\""));
85
7.79k
  StringHelper::toString(event->getTimeStamp() / 1000L, p, output);
86
7.79k
  output.append(LOG4CXX_STR("\" level=\""));
87
7.79k
  Transform::appendEscapingTags(output, event->getLevel()->toString());
88
7.79k
  output.append(LOG4CXX_STR("\" thread=\""));
89
7.79k
  Transform::appendEscapingTags(output, event->getThreadName());
90
7.79k
  output.append(LOG4CXX_STR("\">"));
91
7.79k
  output.append(LOG4CXX_EOL);
92
93
7.79k
  output.append(LOG4CXX_STR("<log4j:message><![CDATA["));
94
  // Append the rendered message. Also make sure to escape any
95
  // existing CDATA sections.
96
7.79k
  Transform::appendEscapingCDATA(output, event->getRenderedMessage());
97
7.79k
  output.append(LOG4CXX_STR("]]></log4j:message>"));
98
7.79k
  output.append(LOG4CXX_EOL);
99
100
7.79k
  LogString ndc;
101
102
7.79k
  if (event->getNDC(ndc))
103
3.89k
  {
104
3.89k
    output.append(LOG4CXX_STR("<log4j:NDC><![CDATA["));
105
3.89k
    Transform::appendEscapingCDATA(output, ndc);
106
3.89k
    output.append(LOG4CXX_STR("]]></log4j:NDC>"));
107
3.89k
    output.append(LOG4CXX_EOL);
108
3.89k
  }
109
110
7.79k
  if (m_priv->locationInfo)
111
3.89k
  {
112
3.89k
    output.append(LOG4CXX_STR("<log4j:locationInfo class=\""));
113
3.89k
    const LocationInfo& locInfo = event->getLocationInformation();
114
3.89k
    LOG4CXX_DECODE_CHAR(className, locInfo.getClassName());
115
3.89k
    Transform::appendEscapingTags(output, className);
116
3.89k
    output.append(LOG4CXX_STR("\" method=\""));
117
3.89k
    LOG4CXX_DECODE_CHAR(method, locInfo.getMethodName());
118
3.89k
    Transform::appendEscapingTags(output, method);
119
3.89k
    output.append(LOG4CXX_STR("\" file=\""));
120
3.89k
    LOG4CXX_DECODE_CHAR(fileName, locInfo.getFileName());
121
3.89k
    Transform::appendEscapingTags(output, fileName);
122
3.89k
    output.append(LOG4CXX_STR("\" line=\""));
123
3.89k
    StringHelper::toString(locInfo.getLineNumber(), p, output);
124
3.89k
    output.append(LOG4CXX_STR("\"/>"));
125
3.89k
    output.append(LOG4CXX_EOL);
126
3.89k
  }
127
128
7.79k
  if (m_priv->properties)
129
3.89k
  {
130
3.89k
    LoggingEvent::KeySet propertySet(event->getPropertyKeySet());
131
3.89k
    LoggingEvent::KeySet keySet(event->getMDCKeySet());
132
133
3.89k
    if (!(keySet.empty() && propertySet.empty()))
134
3.89k
    {
135
3.89k
      output.append(LOG4CXX_STR("<log4j:properties>"));
136
3.89k
      output.append(LOG4CXX_EOL);
137
138
3.89k
      for (auto key : keySet)
139
3.89k
      {
140
3.89k
        LogString value;
141
142
3.89k
        if (event->getMDC(key, value))
143
3.89k
        {
144
3.89k
          output.append(LOG4CXX_STR("<log4j:data name=\""));
145
3.89k
          Transform::appendEscapingTags(output, key);
146
3.89k
          output.append(LOG4CXX_STR("\" value=\""));
147
3.89k
          Transform::appendEscapingTags(output, value);
148
3.89k
          output.append(LOG4CXX_STR("\"/>"));
149
3.89k
          output.append(LOG4CXX_EOL);
150
3.89k
        }
151
3.89k
      }
152
153
3.89k
      for (auto key : propertySet)
154
3.89k
      {
155
3.89k
        LogString value;
156
157
3.89k
        if (event->getProperty(key, value))
158
3.89k
        {
159
3.89k
          output.append(LOG4CXX_STR("<log4j:data name=\""));
160
3.89k
          Transform::appendEscapingTags(output, key);
161
3.89k
          output.append(LOG4CXX_STR("\" value=\""));
162
3.89k
          Transform::appendEscapingTags(output, value);
163
3.89k
          output.append(LOG4CXX_STR("\"/>"));
164
3.89k
          output.append(LOG4CXX_EOL);
165
3.89k
        }
166
3.89k
      }
167
168
3.89k
      output.append(LOG4CXX_STR("</log4j:properties>"));
169
3.89k
      output.append(LOG4CXX_EOL);
170
3.89k
    }
171
3.89k
  }
172
173
7.79k
  output.append(LOG4CXX_STR("</log4j:event>"));
174
7.79k
  output.append(LOG4CXX_EOL);
175
7.79k
  output.append(LOG4CXX_EOL);
176
7.79k
}
log4cxx::xml::XMLLayout::format(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, std::__1::shared_ptr<log4cxx::spi::LoggingEvent> const&, log4cxx::helpers::Pool&) const
Line
Count
Source
80
3.52k
{
81
3.52k
  output.reserve(m_priv->expectedPatternLength + event->getMessage().size());
82
3.52k
  output.append(LOG4CXX_STR("<log4j:event logger=\""));
83
3.52k
  Transform::appendEscapingTags(output, event->getLoggerName());
84
3.52k
  output.append(LOG4CXX_STR("\" timestamp=\""));
85
3.52k
  StringHelper::toString(event->getTimeStamp() / 1000L, p, output);
86
3.52k
  output.append(LOG4CXX_STR("\" level=\""));
87
3.52k
  Transform::appendEscapingTags(output, event->getLevel()->toString());
88
3.52k
  output.append(LOG4CXX_STR("\" thread=\""));
89
3.52k
  Transform::appendEscapingTags(output, event->getThreadName());
90
3.52k
  output.append(LOG4CXX_STR("\">"));
91
3.52k
  output.append(LOG4CXX_EOL);
92
93
3.52k
  output.append(LOG4CXX_STR("<log4j:message><![CDATA["));
94
  // Append the rendered message. Also make sure to escape any
95
  // existing CDATA sections.
96
3.52k
  Transform::appendEscapingCDATA(output, event->getRenderedMessage());
97
3.52k
  output.append(LOG4CXX_STR("]]></log4j:message>"));
98
3.52k
  output.append(LOG4CXX_EOL);
99
100
3.52k
  LogString ndc;
101
102
3.52k
  if (event->getNDC(ndc))
103
1.76k
  {
104
1.76k
    output.append(LOG4CXX_STR("<log4j:NDC><![CDATA["));
105
1.76k
    Transform::appendEscapingCDATA(output, ndc);
106
1.76k
    output.append(LOG4CXX_STR("]]></log4j:NDC>"));
107
1.76k
    output.append(LOG4CXX_EOL);
108
1.76k
  }
109
110
3.52k
  if (m_priv->locationInfo)
111
1.76k
  {
112
1.76k
    output.append(LOG4CXX_STR("<log4j:locationInfo class=\""));
113
1.76k
    const LocationInfo& locInfo = event->getLocationInformation();
114
1.76k
    LOG4CXX_DECODE_CHAR(className, locInfo.getClassName());
115
1.76k
    Transform::appendEscapingTags(output, className);
116
1.76k
    output.append(LOG4CXX_STR("\" method=\""));
117
1.76k
    LOG4CXX_DECODE_CHAR(method, locInfo.getMethodName());
118
1.76k
    Transform::appendEscapingTags(output, method);
119
1.76k
    output.append(LOG4CXX_STR("\" file=\""));
120
1.76k
    LOG4CXX_DECODE_CHAR(fileName, locInfo.getFileName());
121
1.76k
    Transform::appendEscapingTags(output, fileName);
122
1.76k
    output.append(LOG4CXX_STR("\" line=\""));
123
1.76k
    StringHelper::toString(locInfo.getLineNumber(), p, output);
124
1.76k
    output.append(LOG4CXX_STR("\"/>"));
125
1.76k
    output.append(LOG4CXX_EOL);
126
1.76k
  }
127
128
3.52k
  if (m_priv->properties)
129
1.76k
  {
130
1.76k
    LoggingEvent::KeySet propertySet(event->getPropertyKeySet());
131
1.76k
    LoggingEvent::KeySet keySet(event->getMDCKeySet());
132
133
1.76k
    if (!(keySet.empty() && propertySet.empty()))
134
1.76k
    {
135
1.76k
      output.append(LOG4CXX_STR("<log4j:properties>"));
136
1.76k
      output.append(LOG4CXX_EOL);
137
138
1.76k
      for (auto key : keySet)
139
1.76k
      {
140
1.76k
        LogString value;
141
142
1.76k
        if (event->getMDC(key, value))
143
1.76k
        {
144
1.76k
          output.append(LOG4CXX_STR("<log4j:data name=\""));
145
1.76k
          Transform::appendEscapingTags(output, key);
146
1.76k
          output.append(LOG4CXX_STR("\" value=\""));
147
1.76k
          Transform::appendEscapingTags(output, value);
148
1.76k
          output.append(LOG4CXX_STR("\"/>"));
149
1.76k
          output.append(LOG4CXX_EOL);
150
1.76k
        }
151
1.76k
      }
152
153
1.76k
      for (auto key : propertySet)
154
1.76k
      {
155
1.76k
        LogString value;
156
157
1.76k
        if (event->getProperty(key, value))
158
1.76k
        {
159
1.76k
          output.append(LOG4CXX_STR("<log4j:data name=\""));
160
1.76k
          Transform::appendEscapingTags(output, key);
161
1.76k
          output.append(LOG4CXX_STR("\" value=\""));
162
1.76k
          Transform::appendEscapingTags(output, value);
163
1.76k
          output.append(LOG4CXX_STR("\"/>"));
164
1.76k
          output.append(LOG4CXX_EOL);
165
1.76k
        }
166
1.76k
      }
167
168
1.76k
      output.append(LOG4CXX_STR("</log4j:properties>"));
169
1.76k
      output.append(LOG4CXX_EOL);
170
1.76k
    }
171
1.76k
  }
172
173
3.52k
  output.append(LOG4CXX_STR("</log4j:event>"));
174
3.52k
  output.append(LOG4CXX_EOL);
175
3.52k
  output.append(LOG4CXX_EOL);
176
3.52k
}
log4cxx::xml::XMLLayout::format(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >&, std::__1::shared_ptr<log4cxx::spi::LoggingEvent> const&, log4cxx::helpers::Pool&) const
Line
Count
Source
80
4.27k
{
81
4.27k
  output.reserve(m_priv->expectedPatternLength + event->getMessage().size());
82
4.27k
  output.append(LOG4CXX_STR("<log4j:event logger=\""));
83
4.27k
  Transform::appendEscapingTags(output, event->getLoggerName());
84
4.27k
  output.append(LOG4CXX_STR("\" timestamp=\""));
85
4.27k
  StringHelper::toString(event->getTimeStamp() / 1000L, p, output);
86
4.27k
  output.append(LOG4CXX_STR("\" level=\""));
87
4.27k
  Transform::appendEscapingTags(output, event->getLevel()->toString());
88
4.27k
  output.append(LOG4CXX_STR("\" thread=\""));
89
4.27k
  Transform::appendEscapingTags(output, event->getThreadName());
90
4.27k
  output.append(LOG4CXX_STR("\">"));
91
4.27k
  output.append(LOG4CXX_EOL);
92
93
4.27k
  output.append(LOG4CXX_STR("<log4j:message><![CDATA["));
94
  // Append the rendered message. Also make sure to escape any
95
  // existing CDATA sections.
96
4.27k
  Transform::appendEscapingCDATA(output, event->getRenderedMessage());
97
4.27k
  output.append(LOG4CXX_STR("]]></log4j:message>"));
98
4.27k
  output.append(LOG4CXX_EOL);
99
100
4.27k
  LogString ndc;
101
102
4.27k
  if (event->getNDC(ndc))
103
2.13k
  {
104
2.13k
    output.append(LOG4CXX_STR("<log4j:NDC><![CDATA["));
105
2.13k
    Transform::appendEscapingCDATA(output, ndc);
106
2.13k
    output.append(LOG4CXX_STR("]]></log4j:NDC>"));
107
2.13k
    output.append(LOG4CXX_EOL);
108
2.13k
  }
109
110
4.27k
  if (m_priv->locationInfo)
111
2.13k
  {
112
2.13k
    output.append(LOG4CXX_STR("<log4j:locationInfo class=\""));
113
2.13k
    const LocationInfo& locInfo = event->getLocationInformation();
114
2.13k
    LOG4CXX_DECODE_CHAR(className, locInfo.getClassName());
115
2.13k
    Transform::appendEscapingTags(output, className);
116
2.13k
    output.append(LOG4CXX_STR("\" method=\""));
117
2.13k
    LOG4CXX_DECODE_CHAR(method, locInfo.getMethodName());
118
2.13k
    Transform::appendEscapingTags(output, method);
119
2.13k
    output.append(LOG4CXX_STR("\" file=\""));
120
2.13k
    LOG4CXX_DECODE_CHAR(fileName, locInfo.getFileName());
121
2.13k
    Transform::appendEscapingTags(output, fileName);
122
2.13k
    output.append(LOG4CXX_STR("\" line=\""));
123
2.13k
    StringHelper::toString(locInfo.getLineNumber(), p, output);
124
2.13k
    output.append(LOG4CXX_STR("\"/>"));
125
2.13k
    output.append(LOG4CXX_EOL);
126
2.13k
  }
127
128
4.27k
  if (m_priv->properties)
129
2.13k
  {
130
2.13k
    LoggingEvent::KeySet propertySet(event->getPropertyKeySet());
131
2.13k
    LoggingEvent::KeySet keySet(event->getMDCKeySet());
132
133
2.13k
    if (!(keySet.empty() && propertySet.empty()))
134
2.13k
    {
135
2.13k
      output.append(LOG4CXX_STR("<log4j:properties>"));
136
2.13k
      output.append(LOG4CXX_EOL);
137
138
2.13k
      for (auto key : keySet)
139
2.13k
      {
140
2.13k
        LogString value;
141
142
2.13k
        if (event->getMDC(key, value))
143
2.13k
        {
144
2.13k
          output.append(LOG4CXX_STR("<log4j:data name=\""));
145
2.13k
          Transform::appendEscapingTags(output, key);
146
2.13k
          output.append(LOG4CXX_STR("\" value=\""));
147
2.13k
          Transform::appendEscapingTags(output, value);
148
2.13k
          output.append(LOG4CXX_STR("\"/>"));
149
2.13k
          output.append(LOG4CXX_EOL);
150
2.13k
        }
151
2.13k
      }
152
153
2.13k
      for (auto key : propertySet)
154
2.13k
      {
155
2.13k
        LogString value;
156
157
2.13k
        if (event->getProperty(key, value))
158
2.13k
        {
159
2.13k
          output.append(LOG4CXX_STR("<log4j:data name=\""));
160
2.13k
          Transform::appendEscapingTags(output, key);
161
2.13k
          output.append(LOG4CXX_STR("\" value=\""));
162
2.13k
          Transform::appendEscapingTags(output, value);
163
2.13k
          output.append(LOG4CXX_STR("\"/>"));
164
2.13k
          output.append(LOG4CXX_EOL);
165
2.13k
        }
166
2.13k
      }
167
168
2.13k
      output.append(LOG4CXX_STR("</log4j:properties>"));
169
2.13k
      output.append(LOG4CXX_EOL);
170
2.13k
    }
171
2.13k
  }
172
173
4.27k
  output.append(LOG4CXX_STR("</log4j:event>"));
174
4.27k
  output.append(LOG4CXX_EOL);
175
4.27k
  output.append(LOG4CXX_EOL);
176
4.27k
}
177
178
void XMLLayout::setLocationInfo(bool locationInfo1)
179
3.89k
{
180
3.89k
  m_priv->locationInfo = locationInfo1;
181
3.89k
}
182
183
bool XMLLayout::getLocationInfo() const
184
0
{
185
0
  return m_priv->locationInfo;
186
0
}
187
188
void XMLLayout::setProperties(bool flag)
189
3.89k
{
190
3.89k
  m_priv->properties = flag;
191
3.89k
}
192
193
bool XMLLayout::getProperties()
194
0
{
195
0
  return m_priv->properties;
196
0
}
197