Coverage Report

Created: 2026-09-04 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/logging-log4cxx/src/main/cpp/transform.cpp
Line
Count
Source
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/helpers/transform.h>
20
#include <log4cxx/helpers/transcoder.h>
21
#include <log4cxx/helpers/widelife.h>
22
#include <functional>
23
24
using namespace LOG4CXX_NS;
25
using namespace LOG4CXX_NS::helpers;
26
27
namespace
28
{
29
using CharProcessor = std::function<bool(LogString&, int)>;
30
31
// Allowable XML 1.0 characters are:
32
// #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
33
void appendValidCharacters(LogString& buf, const LogString& input, CharProcessor handler = {}, bool handleValidCharacters = false)
34
106k
{
35
106k
  static const unsigned int specials[] =
36
106k
    { 0x22 /* " */
37
106k
    , 0x26 /* & */
38
106k
    , 0x3C /* < */
39
106k
    , 0x3E /* > */
40
106k
    , 0x00
41
106k
    };
42
106k
  auto start = input.begin();
43
427M
  for (auto nextCodePoint = start; input.end() != nextCodePoint; )
44
427M
  {
45
427M
    auto lastCodePoint = nextCodePoint;
46
427M
    auto ch = Transcoder::getCodePoint(input, nextCodePoint);
47
427M
    if (((0x20 <= ch && ch <= 0xD7FF) &&
48
260M
        specials[0] != ch &&
49
127M
        specials[1] != ch &&
50
124M
        specials[2] != ch &&
51
117M
        specials[3] != ch) ||
52
316M
      (0x9 == ch || 0xA == ch || 0xD == ch) ||
53
315M
      (0xE000 <= ch && ch < 0xFFFD) ||
54
315M
      (0x10000 <= ch && ch <= 0x10FFFF))
55
112M
    {
56
112M
      LogString escaped;
57
112M
      if (handleValidCharacters && handler && handler(escaped, ch))
58
1.67k
      {
59
1.67k
        if (start != lastCodePoint)
60
167
          buf.append(start, lastCodePoint);
61
1.67k
        buf.append(escaped);
62
1.67k
        start = nextCodePoint;
63
1.67k
      }
64
112M
      continue;
65
112M
    }
66
67
315M
    if (start != lastCodePoint)
68
9.52M
      buf.append(start, lastCodePoint);
69
315M
    start = nextCodePoint;
70
315M
    switch (ch)
71
315M
    {
72
133M
      case 0: // Do not output a NUL character
73
133M
        break;
74
133M
      case 0x22:
75
133M
        buf.append(LOG4CXX_STR("&quot;"));
76
133M
        break;
77
78
2.41M
      case 0x26:
79
2.41M
        buf.append(LOG4CXX_STR("&amp;"));
80
2.41M
        break;
81
82
6.72M
      case 0x3C:
83
6.72M
        buf.append(LOG4CXX_STR("&lt;"));
84
6.72M
        break;
85
86
6.52M
      case 0x3E:
87
6.52M
        buf.append(LOG4CXX_STR("&gt;"));
88
6.52M
        break;
89
90
23.0M
      case 0xFFFD: // The Unicode replacement character
91
23.0M
        Transform::appendCharacterReference(buf, 0xFFFD);
92
23.0M
        break;
93
94
9.19M
      default:
95
9.19M
        if (handler && !handler(buf, ch))
96
4.81k
          Transform::appendCharacterReference(buf, ch);
97
9.19M
        break;
98
315M
    }
99
315M
  }
100
106k
  buf.append(start, input.end());
101
106k
}
Unexecuted instantiation: transform.cpp:(anonymous namespace)::appendValidCharacters(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::function<bool (std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, int)>, bool)
transform.cpp:(anonymous namespace)::appendValidCharacters(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >&, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, std::__1::function<bool (std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >&, int)>, bool)
Line
Count
Source
34
106k
{
35
106k
  static const unsigned int specials[] =
36
106k
    { 0x22 /* " */
37
106k
    , 0x26 /* & */
38
106k
    , 0x3C /* < */
39
106k
    , 0x3E /* > */
40
106k
    , 0x00
41
106k
    };
42
106k
  auto start = input.begin();
43
427M
  for (auto nextCodePoint = start; input.end() != nextCodePoint; )
44
427M
  {
45
427M
    auto lastCodePoint = nextCodePoint;
46
427M
    auto ch = Transcoder::getCodePoint(input, nextCodePoint);
47
427M
    if (((0x20 <= ch && ch <= 0xD7FF) &&
48
260M
        specials[0] != ch &&
49
127M
        specials[1] != ch &&
50
124M
        specials[2] != ch &&
51
117M
        specials[3] != ch) ||
52
316M
      (0x9 == ch || 0xA == ch || 0xD == ch) ||
53
315M
      (0xE000 <= ch && ch < 0xFFFD) ||
54
315M
      (0x10000 <= ch && ch <= 0x10FFFF))
55
112M
    {
56
112M
      LogString escaped;
57
112M
      if (handleValidCharacters && handler && handler(escaped, ch))
58
1.67k
      {
59
1.67k
        if (start != lastCodePoint)
60
167
          buf.append(start, lastCodePoint);
61
1.67k
        buf.append(escaped);
62
1.67k
        start = nextCodePoint;
63
1.67k
      }
64
112M
      continue;
65
112M
    }
66
67
315M
    if (start != lastCodePoint)
68
9.52M
      buf.append(start, lastCodePoint);
69
315M
    start = nextCodePoint;
70
315M
    switch (ch)
71
315M
    {
72
133M
      case 0: // Do not output a NUL character
73
133M
        break;
74
133M
      case 0x22:
75
133M
        buf.append(LOG4CXX_STR("&quot;"));
76
133M
        break;
77
78
2.41M
      case 0x26:
79
2.41M
        buf.append(LOG4CXX_STR("&amp;"));
80
2.41M
        break;
81
82
6.72M
      case 0x3C:
83
6.72M
        buf.append(LOG4CXX_STR("&lt;"));
84
6.72M
        break;
85
86
6.52M
      case 0x3E:
87
6.52M
        buf.append(LOG4CXX_STR("&gt;"));
88
6.52M
        break;
89
90
23.0M
      case 0xFFFD: // The Unicode replacement character
91
23.0M
        Transform::appendCharacterReference(buf, 0xFFFD);
92
23.0M
        break;
93
94
9.19M
      default:
95
9.19M
        if (handler && !handler(buf, ch))
96
4.81k
          Transform::appendCharacterReference(buf, ch);
97
9.19M
        break;
98
315M
    }
99
315M
  }
100
106k
  buf.append(start, input.end());
101
106k
}
102
103
bool appendCharacterReferenceHandler(LogString& buf, int ch)
104
9.14M
{
105
9.14M
  Transform::appendCharacterReference(buf, ch);
106
9.14M
  return true;
107
9.14M
}
Unexecuted instantiation: transform.cpp:(anonymous namespace)::appendCharacterReferenceHandler(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, int)
transform.cpp:(anonymous namespace)::appendCharacterReferenceHandler(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >&, int)
Line
Count
Source
104
9.14M
{
105
9.14M
  Transform::appendCharacterReference(buf, ch);
106
9.14M
  return true;
107
9.14M
}
108
109
bool appendAttributeCharacterReference(LogString& buf, int ch)
110
234k
{
111
234k
  if (0x27 == ch || 0x9 == ch || 0xA == ch || 0xD == ch)
112
1.67k
  {
113
1.67k
    Transform::appendCharacterReference(buf, ch);
114
1.67k
    return true;
115
1.67k
  }
116
117
232k
  return false;
118
234k
}
Unexecuted instantiation: transform.cpp:(anonymous namespace)::appendAttributeCharacterReference(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, int)
transform.cpp:(anonymous namespace)::appendAttributeCharacterReference(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >&, int)
Line
Count
Source
110
234k
{
111
234k
  if (0x27 == ch || 0x9 == ch || 0xA == ch || 0xD == ch)
112
1.67k
  {
113
1.67k
    Transform::appendCharacterReference(buf, ch);
114
1.67k
    return true;
115
1.67k
  }
116
117
232k
  return false;
118
234k
}
119
120
} // namespace
121
122
void Transform::appendEscapingCDATA(
123
  LogString& buf, const LogString& input)
124
9.22k
{
125
9.22k
  static const LogString CDATA_END(LOG4CXX_STR("]]>"));
126
9.22k
  const LogString::size_type CDATA_END_LEN = 3;
127
9.22k
  static const LogString CDATA_EMBEDED_END(LOG4CXX_STR("]]&gt;<![CDATA["));
128
9.22k
  auto start = input.begin();
129
254M
  for (auto nextCodePoint = start; input.end() != nextCodePoint; )
130
254M
  {
131
254M
    bool cdataEnd = false;
132
254M
    auto lastCodePoint = nextCodePoint;
133
254M
    auto ch = Transcoder::getCodePoint(input, nextCodePoint);
134
254M
    if (CDATA_END[0] == ch && input.end() != nextCodePoint)
135
212k
    {
136
212k
      lastCodePoint = nextCodePoint;
137
212k
      if (CDATA_END[1] != Transcoder::decode(input, nextCodePoint) ||
138
180k
        input.end() == nextCodePoint ||
139
179k
        CDATA_END[2] != Transcoder::decode(input, nextCodePoint))
140
73.9k
      {
141
73.9k
        nextCodePoint = lastCodePoint;
142
73.9k
        continue;
143
73.9k
      }
144
138k
      lastCodePoint = nextCodePoint;
145
138k
      cdataEnd = true;
146
138k
    }
147
254M
    else if ((0x20 <= ch && ch <= 0xD7FF) ||
148
131M
        (0x9 == ch || 0xA == ch || 0xD == ch) ||
149
131M
        (0xE000 <= ch && ch < 0xFFFD) ||
150
131M
        (0x10000 <= ch && ch <= 0x10FFFF))
151
122M
    {
152
122M
      continue;
153
122M
    }
154
155
131M
    if (start != lastCodePoint)
156
1.58M
      buf.append(start, lastCodePoint);
157
131M
    if (cdataEnd)
158
138k
      buf.append(CDATA_EMBEDED_END);
159
131M
    else if (0 != ch)
160
23.4M
      appendCharacterReference(buf, ch);
161
131M
    start = nextCodePoint;
162
131M
  }
163
9.22k
  buf.append(start, input.end());
164
9.22k
}
Unexecuted instantiation: log4cxx::helpers::Transform::appendEscapingCDATA(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
log4cxx::helpers::Transform::appendEscapingCDATA(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >&, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&)
Line
Count
Source
124
9.22k
{
125
9.22k
  static const LogString CDATA_END(LOG4CXX_STR("]]>"));
126
9.22k
  const LogString::size_type CDATA_END_LEN = 3;
127
9.22k
  static const LogString CDATA_EMBEDED_END(LOG4CXX_STR("]]&gt;<![CDATA["));
128
9.22k
  auto start = input.begin();
129
254M
  for (auto nextCodePoint = start; input.end() != nextCodePoint; )
130
254M
  {
131
254M
    bool cdataEnd = false;
132
254M
    auto lastCodePoint = nextCodePoint;
133
254M
    auto ch = Transcoder::getCodePoint(input, nextCodePoint);
134
254M
    if (CDATA_END[0] == ch && input.end() != nextCodePoint)
135
212k
    {
136
212k
      lastCodePoint = nextCodePoint;
137
212k
      if (CDATA_END[1] != Transcoder::decode(input, nextCodePoint) ||
138
180k
        input.end() == nextCodePoint ||
139
179k
        CDATA_END[2] != Transcoder::decode(input, nextCodePoint))
140
73.9k
      {
141
73.9k
        nextCodePoint = lastCodePoint;
142
73.9k
        continue;
143
73.9k
      }
144
138k
      lastCodePoint = nextCodePoint;
145
138k
      cdataEnd = true;
146
138k
    }
147
254M
    else if ((0x20 <= ch && ch <= 0xD7FF) ||
148
131M
        (0x9 == ch || 0xA == ch || 0xD == ch) ||
149
131M
        (0xE000 <= ch && ch < 0xFFFD) ||
150
131M
        (0x10000 <= ch && ch <= 0x10FFFF))
151
122M
    {
152
122M
      continue;
153
122M
    }
154
155
131M
    if (start != lastCodePoint)
156
1.58M
      buf.append(start, lastCodePoint);
157
131M
    if (cdataEnd)
158
138k
      buf.append(CDATA_EMBEDED_END);
159
131M
    else if (0 != ch)
160
23.4M
      appendCharacterReference(buf, ch);
161
131M
    start = nextCodePoint;
162
131M
  }
163
9.22k
  buf.append(start, input.end());
164
9.22k
}
165
166
void Transform::appendCharacterReference(LogString& buf, unsigned int ch)
167
55.6M
{
168
55.6M
  auto toHexDigit = [](int ch) -> int
169
159M
  {
170
159M
    return (10 <= ch ? (0x61 - 10) : 0x30) + ch;
171
159M
  };
Unexecuted instantiation: transform.cpp:log4cxx::helpers::Transform::appendCharacterReference(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned int)::$_0::operator()(int) const
transform.cpp:log4cxx::helpers::Transform::appendCharacterReference(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >&, unsigned int)::$_0::operator()(int) const
Line
Count
Source
169
159M
  {
170
159M
    return (10 <= ch ? (0x61 - 10) : 0x30) + ch;
171
159M
  };
172
55.6M
  buf.push_back('&');
173
55.6M
  buf.push_back('#');
174
55.6M
  buf.push_back('x');
175
55.6M
  if (0xFFFFFFF < ch)
176
0
    buf.push_back(toHexDigit((ch & 0xF0000000) >> 28));
177
55.6M
  if (0xFFFFFF < ch)
178
0
    buf.push_back(toHexDigit((ch & 0xF000000) >> 24));
179
55.6M
  if (0xFFFFF < ch)
180
0
    buf.push_back(toHexDigit((ch & 0xF00000) >> 20));
181
55.6M
  if (0xFFFF < ch)
182
0
    buf.push_back(toHexDigit((ch & 0xF0000) >> 16));
183
55.6M
  if (0xFFF < ch)
184
29.7M
    buf.push_back(toHexDigit((ch & 0xF000) >> 12));
185
55.6M
  if (0xFF < ch)
186
29.7M
    buf.push_back(toHexDigit((ch & 0xF00) >> 8));
187
55.6M
  if (0xF < ch)
188
44.5M
    buf.push_back(toHexDigit((ch & 0xF0) >> 4));
189
55.6M
  buf.push_back(toHexDigit(ch & 0xF));
190
55.6M
  buf.push_back(';');
191
55.6M
}
Unexecuted instantiation: log4cxx::helpers::Transform::appendCharacterReference(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned int)
log4cxx::helpers::Transform::appendCharacterReference(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >&, unsigned int)
Line
Count
Source
167
55.6M
{
168
55.6M
  auto toHexDigit = [](int ch) -> int
169
55.6M
  {
170
55.6M
    return (10 <= ch ? (0x61 - 10) : 0x30) + ch;
171
55.6M
  };
172
55.6M
  buf.push_back('&');
173
55.6M
  buf.push_back('#');
174
55.6M
  buf.push_back('x');
175
55.6M
  if (0xFFFFFFF < ch)
176
0
    buf.push_back(toHexDigit((ch & 0xF0000000) >> 28));
177
55.6M
  if (0xFFFFFF < ch)
178
0
    buf.push_back(toHexDigit((ch & 0xF000000) >> 24));
179
55.6M
  if (0xFFFFF < ch)
180
0
    buf.push_back(toHexDigit((ch & 0xF00000) >> 20));
181
55.6M
  if (0xFFFF < ch)
182
0
    buf.push_back(toHexDigit((ch & 0xF0000) >> 16));
183
55.6M
  if (0xFFF < ch)
184
29.7M
    buf.push_back(toHexDigit((ch & 0xF000) >> 12));
185
55.6M
  if (0xFF < ch)
186
29.7M
    buf.push_back(toHexDigit((ch & 0xF00) >> 8));
187
55.6M
  if (0xF < ch)
188
44.5M
    buf.push_back(toHexDigit((ch & 0xF0) >> 4));
189
55.6M
  buf.push_back(toHexDigit(ch & 0xF));
190
55.6M
  buf.push_back(';');
191
55.6M
}
192
193
void Transform::appendEscapingTags(LogString& buf, const LogString& input)
194
47.5k
{
195
47.5k
  appendValidCharacters(buf, input, appendCharacterReferenceHandler);
196
47.5k
}
Unexecuted instantiation: log4cxx::helpers::Transform::appendEscapingTags(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
log4cxx::helpers::Transform::appendEscapingTags(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >&, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&)
Line
Count
Source
194
47.5k
{
195
47.5k
  appendValidCharacters(buf, input, appendCharacterReferenceHandler);
196
47.5k
}
197
198
void Transform::appendEscapingAttribute(LogString& buf, const LogString& input)
199
19.1k
{
200
19.1k
  appendValidCharacters(buf, input, appendAttributeCharacterReference, true);
201
19.1k
}
Unexecuted instantiation: log4cxx::helpers::Transform::appendEscapingAttribute(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
log4cxx::helpers::Transform::appendEscapingAttribute(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >&, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&)
Line
Count
Source
199
19.1k
{
200
19.1k
  appendValidCharacters(buf, input, appendAttributeCharacterReference, true);
201
19.1k
}
202
203
void Transform::appendLegalCharacters(LogString& buf, const LogString& input)
204
39.9k
{
205
39.9k
  appendValidCharacters(buf, input);
206
39.9k
}
Unexecuted instantiation: log4cxx::helpers::Transform::appendLegalCharacters(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
log4cxx::helpers::Transform::appendLegalCharacters(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >&, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&)
Line
Count
Source
204
39.9k
{
205
39.9k
  appendValidCharacters(buf, input);
206
39.9k
}