Coverage Report

Created: 2026-06-15 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/logging-log4cxx/src/fuzzers/cpp/PatternLayoutFuzzer.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 <iostream>   // for `cout`, `endl`
19
#include <cstdlib>    // for `exit()`, `EXIT_FAILURE`
20
#include <unistd.h>   // for `readlink`, `chdir`
21
#include <libgen.h>   // for `dirname`
22
#include <limits.h>   // for `PATH_MAX`
23
#include <iomanip>    // for `put_time()`
24
#include <ctime>    // for `time()`
25
#include <fuzzer/FuzzedDataProvider.h>
26
#include <log4cxx/propertyconfigurator.h>
27
#include <log4cxx/appenderskeleton.h>
28
29
using namespace LOG4CXX_NS;
30
31
namespace LOG4CXX_NS::fuzzer {
32
33
/**
34
 * Appender encoding incoming log events using the provided layout.
35
 * It is intended for appender-agnostic fuzzing.
36
 */
37
class EncodingAppender : public AppenderSkeleton {
38
39
public:
40
  DECLARE_LOG4CXX_OBJECT(EncodingAppender)
41
8
  BEGIN_LOG4CXX_CAST_MAP()
42
8
  LOG4CXX_CAST_ENTRY(EncodingAppender)
43
8
  LOG4CXX_CAST_ENTRY_CHAIN(AppenderSkeleton)
44
2
  END_LOG4CXX_CAST_MAP()
45
46
1
  EncodingAppender() : AppenderSkeleton() {}
47
48
0
  EncodingAppender(const LayoutPtr& layout) : AppenderSkeleton(layout) {}
49
50
1
  void close() override {}
51
52
1
  bool requiresLayout() const override {
53
1
    return true;
54
1
  }
55
56
63.5k
  void append(const spi::LoggingEventPtr& event, helpers::Pool& pool) override {
57
63.5k
    LogString msg;
58
63.5k
    getLayout()->format(msg, event, pool);
59
63.5k
  }
60
61
0
  void setOption(const LogString& option, const LogString& value) override {}
62
63
}; // class
64
65
IMPLEMENT_LOG4CXX_OBJECT(EncodingAppender)
66
67
LOG4CXX_PTR_DEF(EncodingAppender);
68
69
} // namespace
70
71
static std::time_t logTime;
72
static std::tm* logTimeBuffer;
73
#define LOG(stream) \
74
4
  logTime = std::time(nullptr); \
75
4
  logTimeBuffer = std::localtime(&logTime); \
76
4
  stream << std::put_time(logTimeBuffer, "%Y-%m-%d %H:%M:%S") << " [" << __FILE_NAME__ << ":" << __LINE__ << "] "
77
78
1
static void findExecutablePath(char* buffer) {
79
1
    ssize_t length = readlink("/proc/self/exe", buffer, PATH_MAX);
80
1
    if (length == -1) {
81
0
      LOG(std::cerr) << "ERROR: Failed to find the executable path" << std::endl;
82
0
    exit(EXIT_FAILURE);
83
0
  }
84
1
  buffer[length] = '\0';
85
1
}
86
87
1
static void chdirExecutableHome() {
88
1
    char executablePath[PATH_MAX];
89
1
    findExecutablePath(executablePath);
90
1
    char* executableHome = dirname(executablePath);
91
1
  if (chdir(executableHome) != 0) {
92
0
    LOG(std::cerr) << "DEBUG: Executable path: " << executablePath << std::endl;
93
0
    LOG(std::cerr) << "DEBUG: Executable home: " << executableHome << std::endl;
94
0
    LOG(std::cerr) << "ERROR: Failed to `chdir()` the executable path" << std::endl;
95
0
  }
96
1
}
97
98
static int INITIALIZED = 0;
99
100
593
static void init() {
101
593
  if (INITIALIZED != 0) {
102
592
    return;
103
592
  }
104
1
  LOG(std::cout) << "INFO: Produced using the Git commit ID: " << GIT_COMMIT_ID << std::endl;
105
1
  chdirExecutableHome();
106
1
  PropertyConfigurator::configure("PatternLayoutFuzzer.properties");
107
1
  INITIALIZED = 1;
108
1
}
109
110
63.5k
#define MAX_STRING_LENGTH 512
111
112
593
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
113
593
  init();
114
593
  LoggerPtr logger = Logger::getRootLogger();
115
593
    FuzzedDataProvider dataProvider(data, size);
116
64.1k
    while (dataProvider.remaining_bytes() > 0) {
117
63.5k
      std::string message = dataProvider.ConsumeRandomLengthString(MAX_STRING_LENGTH);
118
63.5k
      LOG4CXX_INFO(logger, message);
119
63.5k
    }
120
593
    return 0;
121
593
}