Coverage Report

Created: 2026-04-27 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/logging-log4cxx/src/main/cpp/optionconverter.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/spi/loggerfactory.h>
20
#include <log4cxx/spi/loggerrepository.h>
21
#include <log4cxx/appenderskeleton.h>
22
#include <log4cxx/helpers/optionconverter.h>
23
#include <algorithm>
24
#include <ctype.h>
25
#include <log4cxx/helpers/stringhelper.h>
26
#include <log4cxx/helpers/exception.h>
27
#include <stdlib.h>
28
#include <log4cxx/helpers/properties.h>
29
#include <log4cxx/helpers/loglog.h>
30
#include <log4cxx/level.h>
31
#include <log4cxx/helpers/object.h>
32
#include <log4cxx/helpers/class.h>
33
#include <log4cxx/helpers/loader.h>
34
#include <log4cxx/helpers/system.h>
35
#include <log4cxx/propertyconfigurator.h>
36
#include <log4cxx/helpers/transcoder.h>
37
#include <log4cxx/file.h>
38
#include <log4cxx/xml/domconfigurator.h>
39
#include <log4cxx/logmanager.h>
40
#if !defined(LOG4CXX)
41
  #define LOG4CXX 1
42
#endif
43
#include <log4cxx/helpers/aprinitializer.h>
44
#include <log4cxx/helpers/filewatchdog.h>
45
#include <log4cxx/helpers/singletonholder.h>
46
47
namespace
48
{
49
using namespace LOG4CXX_NS;
50
51
/// For recursion checking
52
struct LogStringChain
53
{
54
  const LogString& item;
55
  const LogStringChain* parent;
56
};
57
58
/// Is \c item referenced in \c path
59
bool isRecursiveReference(const LogString& newkey, const LogStringChain* path)
60
0
{
61
0
  bool result = false;
62
0
  if (path->item == newkey)
63
0
    result = true;
64
0
  else if (path->parent)
65
0
    result = isRecursiveReference(newkey, path->parent);
66
0
  return result;
67
0
}
Unexecuted instantiation: optionconverter.cpp:(anonymous namespace)::isRecursiveReference(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, (anonymous namespace)::LogStringChain const*)
Unexecuted instantiation: optionconverter.cpp:(anonymous namespace)::isRecursiveReference(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, (anonymous namespace)::LogStringChain const*)
68
69
LogString substVarsSafely(const LogString& val, helpers::Properties& props, const LogStringChain* path = 0)
70
173k
{
71
173k
  LogString sbuf;
72
173k
  const logchar delimStartArray[] = { 0x24, 0x7B, 0 }; // '$', '{'
73
173k
  const LogString delimStart(delimStartArray);
74
173k
  const logchar delimStop = 0x7D; // '}';
75
173k
  const size_t DELIM_START_LEN = 2;
76
173k
  const size_t DELIM_STOP_LEN = 1;
77
78
173k
  size_t i = 0;
79
80
323k
  while (true)
81
323k
  {
82
323k
    size_t j = val.find(delimStart, i);
83
84
323k
    if (j == val.npos)
85
167k
    {
86
      // no more variables
87
167k
      if (i == 0)
88
162k
      {
89
        // this is a simple string
90
162k
        return val;
91
162k
      }
92
5.04k
      else
93
5.04k
      {
94
        // add the tail string which contails no variables and return the result.
95
5.04k
        sbuf.append(val.substr(i, val.length() - i));
96
5.04k
        return sbuf;
97
5.04k
      }
98
167k
    }
99
155k
    else
100
155k
    {
101
155k
      sbuf.append(val.substr(i, j - i));
102
155k
      size_t k = val.find(delimStop, j);
103
104
155k
      if (k == val.npos)
105
5.78k
      {
106
5.78k
        LogString msg(1, (logchar) 0x22 /* '\"' */);
107
5.78k
        msg.append(val);
108
5.78k
        msg.append(LOG4CXX_STR("\" has no closing brace. Opening brace at position "));
109
5.78k
        helpers::Pool p;
110
5.78k
        helpers::StringHelper::toString(j, msg);
111
5.78k
        msg.append(1, (logchar) 0x2E /* '.' */);
112
5.78k
        throw helpers::IllegalArgumentException(msg);
113
5.78k
      }
114
150k
      else
115
150k
      {
116
150k
        j += DELIM_START_LEN;
117
150k
        LogString key = val.substr(j, k - j);
118
150k
        if (path && isRecursiveReference(key, path))
119
0
        {
120
0
          LogString msg(LOG4CXX_STR("The variable ${"));
121
0
          msg.append(key);
122
0
          msg.append(LOG4CXX_STR("} is used recursively"));
123
0
          throw helpers::IllegalArgumentException(msg);
124
0
        }
125
126
        // first try in System properties
127
150k
        LogString replacement(helpers::OptionConverter::getSystemProperty(key, LogString()));
128
129
        // then try props parameter
130
150k
        if (replacement.empty())
131
33.0k
        {
132
33.0k
          replacement = props.getProperty(key);
133
33.0k
        }
134
135
150k
        if (!replacement.empty())
136
119k
        {
137
          // Do variable substitution on the replacement string
138
          // such that we can solve "Hello ${x2}" as "Hello p1"
139
          // the where the properties are
140
          // x1=p1
141
          // x2=${x1}
142
119k
          LogStringChain current{ key, path };
143
119k
          LogString recursiveReplacement = substVarsSafely(replacement, props, &current);
144
119k
          sbuf.append(recursiveReplacement);
145
119k
        }
146
147
150k
        i = k + DELIM_STOP_LEN;
148
150k
      }
149
155k
    }
150
323k
  }
151
173k
}
optionconverter.cpp:(anonymous namespace)::substVarsSafely(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, log4cxx::helpers::Properties&, (anonymous namespace)::LogStringChain const*)
Line
Count
Source
70
162k
{
71
162k
  LogString sbuf;
72
162k
  const logchar delimStartArray[] = { 0x24, 0x7B, 0 }; // '$', '{'
73
162k
  const LogString delimStart(delimStartArray);
74
162k
  const logchar delimStop = 0x7D; // '}';
75
162k
  const size_t DELIM_START_LEN = 2;
76
162k
  const size_t DELIM_STOP_LEN = 1;
77
78
162k
  size_t i = 0;
79
80
302k
  while (true)
81
302k
  {
82
302k
    size_t j = val.find(delimStart, i);
83
84
302k
    if (j == val.npos)
85
157k
    {
86
      // no more variables
87
157k
      if (i == 0)
88
152k
      {
89
        // this is a simple string
90
152k
        return val;
91
152k
      }
92
4.77k
      else
93
4.77k
      {
94
        // add the tail string which contails no variables and return the result.
95
4.77k
        sbuf.append(val.substr(i, val.length() - i));
96
4.77k
        return sbuf;
97
4.77k
      }
98
157k
    }
99
145k
    else
100
145k
    {
101
145k
      sbuf.append(val.substr(i, j - i));
102
145k
      size_t k = val.find(delimStop, j);
103
104
145k
      if (k == val.npos)
105
5.66k
      {
106
5.66k
        LogString msg(1, (logchar) 0x22 /* '\"' */);
107
5.66k
        msg.append(val);
108
5.66k
        msg.append(LOG4CXX_STR("\" has no closing brace. Opening brace at position "));
109
5.66k
        helpers::Pool p;
110
5.66k
        helpers::StringHelper::toString(j, msg);
111
5.66k
        msg.append(1, (logchar) 0x2E /* '.' */);
112
5.66k
        throw helpers::IllegalArgumentException(msg);
113
5.66k
      }
114
139k
      else
115
139k
      {
116
139k
        j += DELIM_START_LEN;
117
139k
        LogString key = val.substr(j, k - j);
118
139k
        if (path && isRecursiveReference(key, path))
119
0
        {
120
0
          LogString msg(LOG4CXX_STR("The variable ${"));
121
0
          msg.append(key);
122
0
          msg.append(LOG4CXX_STR("} is used recursively"));
123
0
          throw helpers::IllegalArgumentException(msg);
124
0
        }
125
126
        // first try in System properties
127
139k
        LogString replacement(helpers::OptionConverter::getSystemProperty(key, LogString()));
128
129
        // then try props parameter
130
139k
        if (replacement.empty())
131
30.7k
        {
132
30.7k
          replacement = props.getProperty(key);
133
30.7k
        }
134
135
139k
        if (!replacement.empty())
136
110k
        {
137
          // Do variable substitution on the replacement string
138
          // such that we can solve "Hello ${x2}" as "Hello p1"
139
          // the where the properties are
140
          // x1=p1
141
          // x2=${x1}
142
110k
          LogStringChain current{ key, path };
143
110k
          LogString recursiveReplacement = substVarsSafely(replacement, props, &current);
144
110k
          sbuf.append(recursiveReplacement);
145
110k
        }
146
147
139k
        i = k + DELIM_STOP_LEN;
148
139k
      }
149
145k
    }
150
302k
  }
151
162k
}
optionconverter.cpp:(anonymous namespace)::substVarsSafely(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, log4cxx::helpers::Properties&, (anonymous namespace)::LogStringChain const*)
Line
Count
Source
70
10.3k
{
71
10.3k
  LogString sbuf;
72
10.3k
  const logchar delimStartArray[] = { 0x24, 0x7B, 0 }; // '$', '{'
73
10.3k
  const LogString delimStart(delimStartArray);
74
10.3k
  const logchar delimStop = 0x7D; // '}';
75
10.3k
  const size_t DELIM_START_LEN = 2;
76
10.3k
  const size_t DELIM_STOP_LEN = 1;
77
78
10.3k
  size_t i = 0;
79
80
20.9k
  while (true)
81
20.9k
  {
82
20.9k
    size_t j = val.find(delimStart, i);
83
84
20.9k
    if (j == val.npos)
85
10.2k
    {
86
      // no more variables
87
10.2k
      if (i == 0)
88
9.96k
      {
89
        // this is a simple string
90
9.96k
        return val;
91
9.96k
      }
92
267
      else
93
267
      {
94
        // add the tail string which contails no variables and return the result.
95
267
        sbuf.append(val.substr(i, val.length() - i));
96
267
        return sbuf;
97
267
      }
98
10.2k
    }
99
10.6k
    else
100
10.6k
    {
101
10.6k
      sbuf.append(val.substr(i, j - i));
102
10.6k
      size_t k = val.find(delimStop, j);
103
104
10.6k
      if (k == val.npos)
105
124
      {
106
124
        LogString msg(1, (logchar) 0x22 /* '\"' */);
107
124
        msg.append(val);
108
124
        msg.append(LOG4CXX_STR("\" has no closing brace. Opening brace at position "));
109
124
        helpers::Pool p;
110
124
        helpers::StringHelper::toString(j, msg);
111
124
        msg.append(1, (logchar) 0x2E /* '.' */);
112
124
        throw helpers::IllegalArgumentException(msg);
113
124
      }
114
10.5k
      else
115
10.5k
      {
116
10.5k
        j += DELIM_START_LEN;
117
10.5k
        LogString key = val.substr(j, k - j);
118
10.5k
        if (path && isRecursiveReference(key, path))
119
0
        {
120
0
          LogString msg(LOG4CXX_STR("The variable ${"));
121
0
          msg.append(key);
122
0
          msg.append(LOG4CXX_STR("} is used recursively"));
123
0
          throw helpers::IllegalArgumentException(msg);
124
0
        }
125
126
        // first try in System properties
127
10.5k
        LogString replacement(helpers::OptionConverter::getSystemProperty(key, LogString()));
128
129
        // then try props parameter
130
10.5k
        if (replacement.empty())
131
2.38k
        {
132
2.38k
          replacement = props.getProperty(key);
133
2.38k
        }
134
135
10.5k
        if (!replacement.empty())
136
8.18k
        {
137
          // Do variable substitution on the replacement string
138
          // such that we can solve "Hello ${x2}" as "Hello p1"
139
          // the where the properties are
140
          // x1=p1
141
          // x2=${x1}
142
8.18k
          LogStringChain current{ key, path };
143
8.18k
          LogString recursiveReplacement = substVarsSafely(replacement, props, &current);
144
8.18k
          sbuf.append(recursiveReplacement);
145
8.18k
        }
146
147
10.5k
        i = k + DELIM_STOP_LEN;
148
10.5k
      }
149
10.6k
    }
150
20.9k
  }
151
10.3k
}
152
153
} // namespace
154
155
namespace LOG4CXX_NS
156
{
157
158
class ConfiguratorWatchdog  : public helpers::FileWatchdog
159
{
160
  spi::ConfiguratorPtr m_config;
161
  public:
162
    ConfiguratorWatchdog(const spi::ConfiguratorPtr& config, const File& filename)
163
0
        : helpers::FileWatchdog(filename)
164
0
        , m_config(config)
165
0
    {
166
0
    }
167
168
    /**
169
    Call PropertyConfigurator#doConfigure(const String& configFileName,
170
    const spi::LoggerRepositoryPtr& hierarchy) with the
171
    <code>filename</code> to reconfigure log4cxx.
172
    */
173
    void doOnChange() override
174
0
    {
175
0
        m_config->doConfigure(file(), LogManager::getLoggerRepository());
176
0
    }
177
178
  static void startWatching(const spi::ConfiguratorPtr& config, const File& filename, long delay)
179
0
  {
180
0
    using WatchdogHolder = helpers::SingletonHolder<ConfiguratorWatchdog>;
181
0
    auto pHolder = helpers::APRInitializer::getOrAddUnique<WatchdogHolder>
182
0
      ( [&config, &filename]() -> helpers::ObjectPtr
183
0
        { return std::make_shared<WatchdogHolder>(config, filename); }
184
0
      );
185
0
    auto& dog = pHolder->value();
186
0
    dog.m_config = config;
187
0
    dog.setFile(filename);
188
0
    dog.setDelay(delay);
189
0
    dog.start();
190
0
  }
191
};
192
193
}
194
195
using namespace LOG4CXX_NS;
196
using namespace LOG4CXX_NS::helpers;
197
using namespace LOG4CXX_NS::spi;
198
199
200
LogString OptionConverter::convertSpecialChars(const LogString& s)
201
2
{
202
2
  logchar c;
203
2
  LogString sbuf;
204
205
2
  LogString::const_iterator i = s.begin();
206
207
48
  while (i != s.end())
208
46
  {
209
46
    c = *i++;
210
211
46
    if (i != s.end() && c == 0x5C /* '\\' */)
212
0
    {
213
0
      c =  *i++;
214
215
0
      switch (c)
216
0
      {
217
0
        case 0x6E: //'n'
218
0
          c = 0x0A;
219
0
          break;
220
221
0
        case 0x72: //'r'
222
0
          c = 0x0D;
223
0
          break;
224
225
0
        case 0x74: //'t'
226
0
          c = 0x09;
227
0
          break;
228
229
0
        case 0x66: //'f'
230
0
          c = 0x0C;
231
0
          break;
232
233
0
        default:
234
0
          break;
235
0
      }
236
0
    }
237
238
46
    sbuf.append(1, c);
239
46
  }
240
241
2
  return sbuf;
242
2
}
log4cxx::helpers::OptionConverter::convertSpecialChars(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Line
Count
Source
201
1
{
202
1
  logchar c;
203
1
  LogString sbuf;
204
205
1
  LogString::const_iterator i = s.begin();
206
207
24
  while (i != s.end())
208
23
  {
209
23
    c = *i++;
210
211
23
    if (i != s.end() && c == 0x5C /* '\\' */)
212
0
    {
213
0
      c =  *i++;
214
215
0
      switch (c)
216
0
      {
217
0
        case 0x6E: //'n'
218
0
          c = 0x0A;
219
0
          break;
220
221
0
        case 0x72: //'r'
222
0
          c = 0x0D;
223
0
          break;
224
225
0
        case 0x74: //'t'
226
0
          c = 0x09;
227
0
          break;
228
229
0
        case 0x66: //'f'
230
0
          c = 0x0C;
231
0
          break;
232
233
0
        default:
234
0
          break;
235
0
      }
236
0
    }
237
238
23
    sbuf.append(1, c);
239
23
  }
240
241
1
  return sbuf;
242
1
}
log4cxx::helpers::OptionConverter::convertSpecialChars(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&)
Line
Count
Source
201
1
{
202
1
  logchar c;
203
1
  LogString sbuf;
204
205
1
  LogString::const_iterator i = s.begin();
206
207
24
  while (i != s.end())
208
23
  {
209
23
    c = *i++;
210
211
23
    if (i != s.end() && c == 0x5C /* '\\' */)
212
0
    {
213
0
      c =  *i++;
214
215
0
      switch (c)
216
0
      {
217
0
        case 0x6E: //'n'
218
0
          c = 0x0A;
219
0
          break;
220
221
0
        case 0x72: //'r'
222
0
          c = 0x0D;
223
0
          break;
224
225
0
        case 0x74: //'t'
226
0
          c = 0x09;
227
0
          break;
228
229
0
        case 0x66: //'f'
230
0
          c = 0x0C;
231
0
          break;
232
233
0
        default:
234
0
          break;
235
0
      }
236
0
    }
237
238
23
    sbuf.append(1, c);
239
23
  }
240
241
1
  return sbuf;
242
1
}
243
244
245
bool OptionConverter::toBoolean(const LogString& value, bool dEfault)
246
27.8k
{
247
27.8k
  if (value.length() >= 4)
248
13.2k
  {
249
13.2k
    if (StringHelper::equalsIgnoreCase(value.substr(0, 4),
250
13.2k
        LOG4CXX_STR("TRUE"), LOG4CXX_STR("true")))
251
11.2k
    {
252
11.2k
      return true;
253
11.2k
    }
254
13.2k
  }
255
256
16.5k
  if (dEfault && value.length() >= 5)
257
1.93k
  {
258
1.93k
    if (StringHelper::equalsIgnoreCase(value.substr(0, 5),
259
1.93k
        LOG4CXX_STR("FALSE"), LOG4CXX_STR("false")))
260
6
    {
261
6
      return false;
262
6
    }
263
1.93k
  }
264
265
16.5k
  return dEfault;
266
16.5k
}
log4cxx::helpers::OptionConverter::toBoolean(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool)
Line
Count
Source
246
21.5k
{
247
21.5k
  if (value.length() >= 4)
248
7.10k
  {
249
7.10k
    if (StringHelper::equalsIgnoreCase(value.substr(0, 4),
250
7.10k
        LOG4CXX_STR("TRUE"), LOG4CXX_STR("true")))
251
5.26k
    {
252
5.26k
      return true;
253
5.26k
    }
254
7.10k
  }
255
256
16.3k
  if (dEfault && value.length() >= 5)
257
1.82k
  {
258
1.82k
    if (StringHelper::equalsIgnoreCase(value.substr(0, 5),
259
1.82k
        LOG4CXX_STR("FALSE"), LOG4CXX_STR("false")))
260
3
    {
261
3
      return false;
262
3
    }
263
1.82k
  }
264
265
16.3k
  return dEfault;
266
16.3k
}
log4cxx::helpers::OptionConverter::toBoolean(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, bool)
Line
Count
Source
246
6.24k
{
247
6.24k
  if (value.length() >= 4)
248
6.15k
  {
249
6.15k
    if (StringHelper::equalsIgnoreCase(value.substr(0, 4),
250
6.15k
        LOG4CXX_STR("TRUE"), LOG4CXX_STR("true")))
251
6.03k
    {
252
6.03k
      return true;
253
6.03k
    }
254
6.15k
  }
255
256
215
  if (dEfault && value.length() >= 5)
257
107
  {
258
107
    if (StringHelper::equalsIgnoreCase(value.substr(0, 5),
259
107
        LOG4CXX_STR("FALSE"), LOG4CXX_STR("false")))
260
3
    {
261
3
      return false;
262
3
    }
263
107
  }
264
265
212
  return dEfault;
266
215
}
267
268
int OptionConverter::toInt(const LogString& value, int dEfault)
269
0
{
270
0
  LogString trimmed(StringHelper::trim(value));
271
272
0
  if (trimmed.empty())
273
0
  {
274
0
    return dEfault;
275
0
  }
276
277
0
  LOG4CXX_ENCODE_CHAR(cvalue, trimmed);
278
279
0
  return (int) atol(cvalue.c_str());
280
0
}
Unexecuted instantiation: log4cxx::helpers::OptionConverter::toInt(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int)
Unexecuted instantiation: log4cxx::helpers::OptionConverter::toInt(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, int)
281
282
long OptionConverter::toFileSize(const LogString& s, long dEfault)
283
0
{
284
0
  if (s.empty())
285
0
  {
286
0
    return dEfault;
287
0
  }
288
289
0
  size_t index = s.find_first_of(LOG4CXX_STR("bB"));
290
291
0
  if (index != LogString::npos && index > 0)
292
0
  {
293
0
    long multiplier = 1;
294
0
    index--;
295
296
0
    if (s[index] == 0x6B /* 'k' */ || s[index] == 0x4B /* 'K' */)
297
0
    {
298
0
      multiplier = 1024;
299
0
    }
300
0
    else if (s[index] == 0x6D /* 'm' */ || s[index] == 0x4D /* 'M' */)
301
0
    {
302
0
      multiplier = 1024 * 1024;
303
0
    }
304
0
    else if (s[index] == 0x67 /* 'g'*/ || s[index] == 0x47 /* 'G' */)
305
0
    {
306
0
      multiplier = 1024 * 1024 * 1024;
307
0
    }
308
309
0
    return toInt(s.substr(0, index), 1) * multiplier;
310
0
  }
311
312
0
  return toInt(s, 1);
313
0
}
Unexecuted instantiation: log4cxx::helpers::OptionConverter::toFileSize(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, long)
Unexecuted instantiation: log4cxx::helpers::OptionConverter::toFileSize(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, long)
314
315
LogString OptionConverter::findAndSubst(const LogString& key, Properties& props)
316
16
{
317
16
  LogString value(props.getProperty(key));
318
319
16
  if (value.empty())
320
6
  {
321
6
    return value;
322
6
  }
323
324
10
  try
325
10
  {
326
10
    return substVars(value, props);
327
10
  }
328
10
  catch (IllegalArgumentException& e)
329
10
  {
330
0
    LogLog::error(((LogString) LOG4CXX_STR("Bad option value ["))
331
0
      + value + LOG4CXX_STR("]."), e);
332
0
    return value;
333
0
  }
334
10
}
log4cxx::helpers::OptionConverter::findAndSubst(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, log4cxx::helpers::Properties&)
Line
Count
Source
316
8
{
317
8
  LogString value(props.getProperty(key));
318
319
8
  if (value.empty())
320
3
  {
321
3
    return value;
322
3
  }
323
324
5
  try
325
5
  {
326
5
    return substVars(value, props);
327
5
  }
328
5
  catch (IllegalArgumentException& e)
329
5
  {
330
0
    LogLog::error(((LogString) LOG4CXX_STR("Bad option value ["))
331
0
      + value + LOG4CXX_STR("]."), e);
332
0
    return value;
333
0
  }
334
5
}
log4cxx::helpers::OptionConverter::findAndSubst(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, log4cxx::helpers::Properties&)
Line
Count
Source
316
8
{
317
8
  LogString value(props.getProperty(key));
318
319
8
  if (value.empty())
320
3
  {
321
3
    return value;
322
3
  }
323
324
5
  try
325
5
  {
326
5
    return substVars(value, props);
327
5
  }
328
5
  catch (IllegalArgumentException& e)
329
5
  {
330
0
    LogLog::error(((LogString) LOG4CXX_STR("Bad option value ["))
331
0
      + value + LOG4CXX_STR("]."), e);
332
0
    return value;
333
0
  }
334
5
}
335
336
LogString OptionConverter::substVars(const LogString& val, Properties& props)
337
54.1k
{
338
54.1k
  return substVarsSafely(val, props);
339
54.1k
}
log4cxx::helpers::OptionConverter::substVars(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, log4cxx::helpers::Properties&)
Line
Count
Source
337
51.9k
{
338
51.9k
  return substVarsSafely(val, props);
339
51.9k
}
log4cxx::helpers::OptionConverter::substVars(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, log4cxx::helpers::Properties&)
Line
Count
Source
337
2.16k
{
338
2.16k
  return substVarsSafely(val, props);
339
2.16k
}
340
341
LogString OptionConverter::getSystemProperty(const LogString& key, const LogString& def)
342
150k
{
343
150k
  if (!key.empty())
344
143k
  {
345
143k
    LogString value(System::getProperty(key));
346
347
143k
    if (!value.empty())
348
117k
    {
349
117k
      return value;
350
117k
    }
351
143k
  }
352
353
33.1k
  return def;
354
150k
}
log4cxx::helpers::OptionConverter::getSystemProperty(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&)
Line
Count
Source
342
139k
{
343
139k
  if (!key.empty())
344
133k
  {
345
133k
    LogString value(System::getProperty(key));
346
347
133k
    if (!value.empty())
348
108k
    {
349
108k
      return value;
350
108k
    }
351
133k
  }
352
353
30.7k
  return def;
354
139k
}
log4cxx::helpers::OptionConverter::getSystemProperty(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&)
Line
Count
Source
342
10.5k
{
343
10.5k
  if (!key.empty())
344
10.4k
  {
345
10.4k
    LogString value(System::getProperty(key));
346
347
10.4k
    if (!value.empty())
348
8.17k
    {
349
8.17k
      return value;
350
8.17k
    }
351
10.4k
  }
352
353
2.38k
  return def;
354
10.5k
}
355
356
LevelPtr OptionConverter::toLevel(const LogString& value,
357
  const LevelPtr& defaultValue)
358
660
{
359
660
  size_t hashIndex = value.find(LOG4CXX_STR("#"));
360
361
660
  if (hashIndex == LogString::npos)
362
182
  {
363
    // no class name specified : use standard Level class
364
182
    if (value.empty())
365
0
    {
366
0
      return defaultValue;
367
0
    }
368
182
    else
369
182
    {
370
182
      return Level::toLevelLS(value, defaultValue);
371
182
    }
372
182
  }
373
374
478
  LogString clazz = value.substr(hashIndex + 1);
375
478
  LogString levelName = value.substr(0, hashIndex);
376
377
  // This is degenerate case but you never know.
378
478
  if (levelName.empty() || clazz.empty())
379
41
  {
380
41
    return Level::toLevelLS(value, defaultValue);
381
41
  }
382
437
  if (LogLog::isDebugEnabled())
383
437
  {
384
437
    LogLog::debug(LOG4CXX_STR("Desired ") + Level::getStaticClass().getName()
385
437
        + LOG4CXX_STR(" sub-class: [") + clazz + LOG4CXX_STR("]"));
386
437
  }
387
388
437
  try
389
437
  {
390
    // Note: the dynamic_cast could fail across DLL boundaries.
391
    // However, without the dynamic_cast a poorly formed XML file
392
    // could attempt to load an invalid class as a filter, causing
393
    // a crash.  If it can't be converted, a std::bad_cast should be
394
    // thrown(and caught by the exception handler below)
395
437
    const Level::LevelClass& levelClass =
396
437
      dynamic_cast<const Level::LevelClass&>(Loader::loadClass(clazz));
397
437
    return levelClass.toLevel(levelName);
398
437
  }
399
437
  catch (Exception& oops)
400
437
  {
401
429
    LogLog::error(LOG4CXX_STR("Could not create ") + Level::getStaticClass().getName() + LOG4CXX_STR(" sub-class"), oops);
402
429
  }
403
437
  catch (const std::bad_cast&)
404
437
  {
405
3
    LogLog::warn(
406
3
      LOG4CXX_STR("class [") + clazz + LOG4CXX_STR("] unable to be converted to "
407
3
      "Level::LevelClass"));
408
3
  }
409
437
  catch (...)
410
437
  {
411
0
    LogLog::warn(
412
0
      LOG4CXX_STR("class [") + clazz + LOG4CXX_STR("], level [") + levelName +
413
0
      LOG4CXX_STR("] conversion) failed."));
414
0
  }
415
416
432
  return defaultValue;
417
437
}
log4cxx::helpers::OptionConverter::toLevel(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::shared_ptr<log4cxx::Level> const&)
Line
Count
Source
358
468
{
359
468
  size_t hashIndex = value.find(LOG4CXX_STR("#"));
360
361
468
  if (hashIndex == LogString::npos)
362
131
  {
363
    // no class name specified : use standard Level class
364
131
    if (value.empty())
365
0
    {
366
0
      return defaultValue;
367
0
    }
368
131
    else
369
131
    {
370
131
      return Level::toLevelLS(value, defaultValue);
371
131
    }
372
131
  }
373
374
337
  LogString clazz = value.substr(hashIndex + 1);
375
337
  LogString levelName = value.substr(0, hashIndex);
376
377
  // This is degenerate case but you never know.
378
337
  if (levelName.empty() || clazz.empty())
379
34
  {
380
34
    return Level::toLevelLS(value, defaultValue);
381
34
  }
382
303
  if (LogLog::isDebugEnabled())
383
303
  {
384
303
    LogLog::debug(LOG4CXX_STR("Desired ") + Level::getStaticClass().getName()
385
303
        + LOG4CXX_STR(" sub-class: [") + clazz + LOG4CXX_STR("]"));
386
303
  }
387
388
303
  try
389
303
  {
390
    // Note: the dynamic_cast could fail across DLL boundaries.
391
    // However, without the dynamic_cast a poorly formed XML file
392
    // could attempt to load an invalid class as a filter, causing
393
    // a crash.  If it can't be converted, a std::bad_cast should be
394
    // thrown(and caught by the exception handler below)
395
303
    const Level::LevelClass& levelClass =
396
303
      dynamic_cast<const Level::LevelClass&>(Loader::loadClass(clazz));
397
303
    return levelClass.toLevel(levelName);
398
303
  }
399
303
  catch (Exception& oops)
400
303
  {
401
298
    LogLog::error(LOG4CXX_STR("Could not create ") + Level::getStaticClass().getName() + LOG4CXX_STR(" sub-class"), oops);
402
298
  }
403
303
  catch (const std::bad_cast&)
404
303
  {
405
2
    LogLog::warn(
406
2
      LOG4CXX_STR("class [") + clazz + LOG4CXX_STR("] unable to be converted to "
407
2
      "Level::LevelClass"));
408
2
  }
409
303
  catch (...)
410
303
  {
411
0
    LogLog::warn(
412
0
      LOG4CXX_STR("class [") + clazz + LOG4CXX_STR("], level [") + levelName +
413
0
      LOG4CXX_STR("] conversion) failed."));
414
0
  }
415
416
300
  return defaultValue;
417
303
}
log4cxx::helpers::OptionConverter::toLevel(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, std::__1::shared_ptr<log4cxx::Level> const&)
Line
Count
Source
358
192
{
359
192
  size_t hashIndex = value.find(LOG4CXX_STR("#"));
360
361
192
  if (hashIndex == LogString::npos)
362
51
  {
363
    // no class name specified : use standard Level class
364
51
    if (value.empty())
365
0
    {
366
0
      return defaultValue;
367
0
    }
368
51
    else
369
51
    {
370
51
      return Level::toLevelLS(value, defaultValue);
371
51
    }
372
51
  }
373
374
141
  LogString clazz = value.substr(hashIndex + 1);
375
141
  LogString levelName = value.substr(0, hashIndex);
376
377
  // This is degenerate case but you never know.
378
141
  if (levelName.empty() || clazz.empty())
379
7
  {
380
7
    return Level::toLevelLS(value, defaultValue);
381
7
  }
382
134
  if (LogLog::isDebugEnabled())
383
134
  {
384
134
    LogLog::debug(LOG4CXX_STR("Desired ") + Level::getStaticClass().getName()
385
134
        + LOG4CXX_STR(" sub-class: [") + clazz + LOG4CXX_STR("]"));
386
134
  }
387
388
134
  try
389
134
  {
390
    // Note: the dynamic_cast could fail across DLL boundaries.
391
    // However, without the dynamic_cast a poorly formed XML file
392
    // could attempt to load an invalid class as a filter, causing
393
    // a crash.  If it can't be converted, a std::bad_cast should be
394
    // thrown(and caught by the exception handler below)
395
134
    const Level::LevelClass& levelClass =
396
134
      dynamic_cast<const Level::LevelClass&>(Loader::loadClass(clazz));
397
134
    return levelClass.toLevel(levelName);
398
134
  }
399
134
  catch (Exception& oops)
400
134
  {
401
131
    LogLog::error(LOG4CXX_STR("Could not create ") + Level::getStaticClass().getName() + LOG4CXX_STR(" sub-class"), oops);
402
131
  }
403
134
  catch (const std::bad_cast&)
404
134
  {
405
1
    LogLog::warn(
406
1
      LOG4CXX_STR("class [") + clazz + LOG4CXX_STR("] unable to be converted to "
407
1
      "Level::LevelClass"));
408
1
  }
409
134
  catch (...)
410
134
  {
411
0
    LogLog::warn(
412
0
      LOG4CXX_STR("class [") + clazz + LOG4CXX_STR("], level [") + levelName +
413
0
      LOG4CXX_STR("] conversion) failed."));
414
0
  }
415
416
132
  return defaultValue;
417
134
}
418
419
420
ObjectPtr OptionConverter::instantiateByKey(Properties& props, const LogString& key,
421
  const Class& superClass, const ObjectPtr& defaultValue)
422
4
{
423
  // Get the value of the property in string form
424
4
  LogString className(findAndSubst(key, props));
425
426
4
  if (className.empty())
427
0
  {
428
0
    LogLog::error(
429
0
      ((LogString) LOG4CXX_STR("Could not find value for key ")) + key);
430
0
    return defaultValue;
431
0
  }
432
433
  // Trim className to avoid trailing spaces that cause problems.
434
4
  return OptionConverter::instantiateByClassName(
435
4
      StringHelper::trim(className), superClass, defaultValue);
436
4
}
log4cxx::helpers::OptionConverter::instantiateByKey(log4cxx::helpers::Properties&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, log4cxx::helpers::Class const&, std::__1::shared_ptr<log4cxx::helpers::Object> const&)
Line
Count
Source
422
2
{
423
  // Get the value of the property in string form
424
2
  LogString className(findAndSubst(key, props));
425
426
2
  if (className.empty())
427
0
  {
428
0
    LogLog::error(
429
0
      ((LogString) LOG4CXX_STR("Could not find value for key ")) + key);
430
0
    return defaultValue;
431
0
  }
432
433
  // Trim className to avoid trailing spaces that cause problems.
434
2
  return OptionConverter::instantiateByClassName(
435
2
      StringHelper::trim(className), superClass, defaultValue);
436
2
}
log4cxx::helpers::OptionConverter::instantiateByKey(log4cxx::helpers::Properties&, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, log4cxx::helpers::Class const&, std::__1::shared_ptr<log4cxx::helpers::Object> const&)
Line
Count
Source
422
2
{
423
  // Get the value of the property in string form
424
2
  LogString className(findAndSubst(key, props));
425
426
2
  if (className.empty())
427
0
  {
428
0
    LogLog::error(
429
0
      ((LogString) LOG4CXX_STR("Could not find value for key ")) + key);
430
0
    return defaultValue;
431
0
  }
432
433
  // Trim className to avoid trailing spaces that cause problems.
434
2
  return OptionConverter::instantiateByClassName(
435
2
      StringHelper::trim(className), superClass, defaultValue);
436
2
}
437
438
ObjectPtr OptionConverter::instantiateByClassName(const LogString& className,
439
  const Class& superClass, const ObjectPtr& defaultValue)
440
4
{
441
4
  if (LogLog::isDebugEnabled())
442
0
  {
443
0
    LogLog::debug(LOG4CXX_STR("Desired ") + superClass.getName()
444
0
      + LOG4CXX_STR(" sub-class: [") + className + LOG4CXX_STR("]"));
445
0
  }
446
4
  try
447
4
  {
448
4
    const Class& classObj = Loader::loadClass(className);
449
4
    ObjectPtr newObject =  ObjectPtr(classObj.newInstance());
450
451
4
    if (!newObject->instanceof(superClass))
452
0
    {
453
0
      LogLog::error(LOG4CXX_STR("Not a ") + superClass.getName() + LOG4CXX_STR(" sub-class"));
454
0
      return defaultValue;
455
0
    }
456
457
4
    return newObject;
458
4
  }
459
4
  catch (Exception& e)
460
4
  {
461
0
    LogLog::error(LOG4CXX_STR("Could not create ") + superClass.getName() + LOG4CXX_STR(" sub-class"), e);
462
0
  }
463
464
0
  return defaultValue;
465
4
}
log4cxx::helpers::OptionConverter::instantiateByClassName(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, log4cxx::helpers::Class const&, std::__1::shared_ptr<log4cxx::helpers::Object> const&)
Line
Count
Source
440
2
{
441
2
  if (LogLog::isDebugEnabled())
442
0
  {
443
0
    LogLog::debug(LOG4CXX_STR("Desired ") + superClass.getName()
444
0
      + LOG4CXX_STR(" sub-class: [") + className + LOG4CXX_STR("]"));
445
0
  }
446
2
  try
447
2
  {
448
2
    const Class& classObj = Loader::loadClass(className);
449
2
    ObjectPtr newObject =  ObjectPtr(classObj.newInstance());
450
451
2
    if (!newObject->instanceof(superClass))
452
0
    {
453
0
      LogLog::error(LOG4CXX_STR("Not a ") + superClass.getName() + LOG4CXX_STR(" sub-class"));
454
0
      return defaultValue;
455
0
    }
456
457
2
    return newObject;
458
2
  }
459
2
  catch (Exception& e)
460
2
  {
461
0
    LogLog::error(LOG4CXX_STR("Could not create ") + superClass.getName() + LOG4CXX_STR(" sub-class"), e);
462
0
  }
463
464
0
  return defaultValue;
465
2
}
log4cxx::helpers::OptionConverter::instantiateByClassName(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, log4cxx::helpers::Class const&, std::__1::shared_ptr<log4cxx::helpers::Object> const&)
Line
Count
Source
440
2
{
441
2
  if (LogLog::isDebugEnabled())
442
0
  {
443
0
    LogLog::debug(LOG4CXX_STR("Desired ") + superClass.getName()
444
0
      + LOG4CXX_STR(" sub-class: [") + className + LOG4CXX_STR("]"));
445
0
  }
446
2
  try
447
2
  {
448
2
    const Class& classObj = Loader::loadClass(className);
449
2
    ObjectPtr newObject =  ObjectPtr(classObj.newInstance());
450
451
2
    if (!newObject->instanceof(superClass))
452
0
    {
453
0
      LogLog::error(LOG4CXX_STR("Not a ") + superClass.getName() + LOG4CXX_STR(" sub-class"));
454
0
      return defaultValue;
455
0
    }
456
457
2
    return newObject;
458
2
  }
459
2
  catch (Exception& e)
460
2
  {
461
0
    LogLog::error(LOG4CXX_STR("Could not create ") + superClass.getName() + LOG4CXX_STR(" sub-class"), e);
462
0
  }
463
464
0
  return defaultValue;
465
2
}
466
467
void OptionConverter::selectAndConfigure(const File& configFileName,
468
  const LogString& _clazz, spi::LoggerRepositoryPtr hierarchy, int delay)
469
0
{
470
0
  ConfiguratorPtr configurator;
471
0
  LogString clazz = _clazz;
472
473
0
  LogString filename(configFileName.getPath());
474
475
0
#if LOG4CXX_HAS_DOMCONFIGURATOR
476
0
  if (clazz.empty()
477
0
    && filename.length() > 4
478
0
    && StringHelper::equalsIgnoreCase(
479
0
      filename.substr(filename.length() - 4),
480
0
      LOG4CXX_STR(".XML"), LOG4CXX_STR(".xml")))
481
0
  {
482
0
    clazz = LOG4CXX_NS::xml::DOMConfigurator::getStaticClass().getName();
483
0
  }
484
0
#endif
485
486
0
  if (!clazz.empty())
487
0
  {
488
0
    if (LogLog::isDebugEnabled())
489
0
      LogLog::debug(LOG4CXX_STR("Preferred configurator class: ") + clazz);
490
0
    const Class& clazzObj = Loader::loadClass(clazz);
491
0
    ObjectPtr obj = ObjectPtr(clazzObj.newInstance());
492
0
    configurator = LOG4CXX_NS::cast<Configurator>(obj);
493
494
0
    if (configurator == 0)
495
0
    {
496
0
      LogLog::error(LOG4CXX_STR("Could not instantiate configurator [")
497
0
        + clazz + LOG4CXX_STR("]."));
498
0
      return;
499
0
    }
500
0
  }
501
0
  else
502
0
  {
503
0
    configurator = std::make_shared<PropertyConfigurator>();
504
0
  }
505
506
0
  if (0 < delay)
507
0
    ConfiguratorWatchdog::startWatching(configurator, configFileName, delay);
508
0
  else
509
0
    configurator->doConfigure(configFileName, hierarchy);
510
0
}
Unexecuted instantiation: log4cxx::helpers::OptionConverter::selectAndConfigure(log4cxx::File const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::shared_ptr<log4cxx::spi::LoggerRepository>, int)
Unexecuted instantiation: log4cxx::helpers::OptionConverter::selectAndConfigure(log4cxx::File const&, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, std::__1::shared_ptr<log4cxx::spi::LoggerRepository>, int)