Add support for fuzzing cppdap
Add build rules, scripts, basic corpus, and dictionary. Currently requires recent clang toolchain.
This commit is contained in:
parent
cc93ba9747
commit
773f0dff68
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,4 +1,6 @@
|
|||||||
build/
|
build/
|
||||||
|
fuzz/corpus
|
||||||
|
fuzz/logs
|
||||||
.vs/
|
.vs/
|
||||||
.vscode/settings.json
|
.vscode/settings.json
|
||||||
CMakeSettings.json
|
CMakeSettings.json
|
||||||
|
8
.vscode/launch.json
vendored
8
.vscode/launch.json
vendored
@ -17,6 +17,14 @@
|
|||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"args": []
|
"args": []
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "fuzzer (lldb)",
|
||||||
|
"program": "${workspaceFolder}/fuzz/build/cppdap-fuzzer",
|
||||||
|
"cwd": "${workspaceRoot}",
|
||||||
|
"args": []
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "unittests (gdb)",
|
"name": "unittests (gdb)",
|
||||||
"type": "cppdbg",
|
"type": "cppdbg",
|
||||||
|
@ -31,6 +31,7 @@ endfunction()
|
|||||||
option_if_not_defined(CPPDAP_WARNINGS_AS_ERRORS "Treat warnings as errors" OFF)
|
option_if_not_defined(CPPDAP_WARNINGS_AS_ERRORS "Treat warnings as errors" OFF)
|
||||||
option_if_not_defined(CPPDAP_BUILD_EXAMPLES "Build example applications" OFF)
|
option_if_not_defined(CPPDAP_BUILD_EXAMPLES "Build example applications" OFF)
|
||||||
option_if_not_defined(CPPDAP_BUILD_TESTS "Build tests" OFF)
|
option_if_not_defined(CPPDAP_BUILD_TESTS "Build tests" OFF)
|
||||||
|
option_if_not_defined(CPPDAP_BUILD_FUZZER "Build fuzzer" OFF)
|
||||||
option_if_not_defined(CPPDAP_ASAN "Build dap with address sanitizer" OFF)
|
option_if_not_defined(CPPDAP_ASAN "Build dap with address sanitizer" OFF)
|
||||||
option_if_not_defined(CPPDAP_MSAN "Build dap with memory sanitizer" OFF)
|
option_if_not_defined(CPPDAP_MSAN "Build dap with memory sanitizer" OFF)
|
||||||
option_if_not_defined(CPPDAP_TSAN "Build dap with thread sanitizer" OFF)
|
option_if_not_defined(CPPDAP_TSAN "Build dap with thread sanitizer" OFF)
|
||||||
@ -223,6 +224,26 @@ if(CPPDAP_BUILD_TESTS)
|
|||||||
target_link_libraries(cppdap-unittests cppdap "${CPPDAP_OS_LIBS}")
|
target_link_libraries(cppdap-unittests cppdap "${CPPDAP_OS_LIBS}")
|
||||||
endif(CPPDAP_BUILD_TESTS)
|
endif(CPPDAP_BUILD_TESTS)
|
||||||
|
|
||||||
|
# fuzzer
|
||||||
|
if(CPPDAP_BUILD_FUZZER)
|
||||||
|
if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
|
message(FATAL_ERROR "CPPDAP_BUILD_FUZZER can currently only be used with the clang toolchain")
|
||||||
|
endif()
|
||||||
|
set(DAP_FUZZER_LIST
|
||||||
|
${CPPDAP_LIST}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/fuzz/fuzz.cpp
|
||||||
|
)
|
||||||
|
add_executable(cppdap-fuzzer ${DAP_FUZZER_LIST})
|
||||||
|
target_compile_options(cppdap-fuzzer PUBLIC "-fsanitize=fuzzer,address")
|
||||||
|
target_link_libraries(cppdap-fuzzer "-fsanitize=fuzzer,address")
|
||||||
|
target_include_directories(cppdap-fuzzer PUBLIC
|
||||||
|
${CPPDAP_INCLUDE_DIR}
|
||||||
|
${CPPDAP_SRC_DIR}
|
||||||
|
${CPPDAP_JSON_DIR}/include/
|
||||||
|
)
|
||||||
|
target_link_libraries(cppdap-fuzzer cppdap "${CPPDAP_OS_LIBS}")
|
||||||
|
endif(CPPDAP_BUILD_FUZZER)
|
||||||
|
|
||||||
# examples
|
# examples
|
||||||
if(CPPDAP_BUILD_EXAMPLES)
|
if(CPPDAP_BUILD_EXAMPLES)
|
||||||
function(build_example target)
|
function(build_example target)
|
||||||
|
225
fuzz/dictionary.txt
Normal file
225
fuzz/dictionary.txt
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
"accessType"
|
||||||
|
"adapterData"
|
||||||
|
"adapterID"
|
||||||
|
"additionalModuleColumns"
|
||||||
|
"address"
|
||||||
|
"addressRange"
|
||||||
|
"algorithm"
|
||||||
|
"allThreadsContinued"
|
||||||
|
"allThreadsStopped"
|
||||||
|
"args"
|
||||||
|
"arguments"
|
||||||
|
"attach"
|
||||||
|
"attributeName"
|
||||||
|
"attributes"
|
||||||
|
"breakMode"
|
||||||
|
"breakpoint"
|
||||||
|
"breakpointLocations"
|
||||||
|
"breakpoints"
|
||||||
|
"cancel"
|
||||||
|
"cancellable"
|
||||||
|
"capabilities"
|
||||||
|
"category"
|
||||||
|
"checksum"
|
||||||
|
"checksums"
|
||||||
|
"clientID"
|
||||||
|
"clientName"
|
||||||
|
"column"
|
||||||
|
"columnsStartAt1"
|
||||||
|
"command"
|
||||||
|
"completions"
|
||||||
|
"completionTriggerCharacters"
|
||||||
|
"condition"
|
||||||
|
"configurationDone"
|
||||||
|
"context"
|
||||||
|
"continue"
|
||||||
|
"continued"
|
||||||
|
"count"
|
||||||
|
"cwd"
|
||||||
|
"data"
|
||||||
|
"dataBreakpointInfo"
|
||||||
|
"dataId"
|
||||||
|
"dateTimeStamp"
|
||||||
|
"default"
|
||||||
|
"description"
|
||||||
|
"disassemble"
|
||||||
|
"disconnect"
|
||||||
|
"endColumn"
|
||||||
|
"endLine"
|
||||||
|
"env"
|
||||||
|
"evaluate"
|
||||||
|
"evaluateName"
|
||||||
|
"exceptionBreakpointFilters"
|
||||||
|
"exceptionInfo"
|
||||||
|
"exceptionOptions"
|
||||||
|
"exitCode"
|
||||||
|
"exited"
|
||||||
|
"expensive"
|
||||||
|
"expression"
|
||||||
|
"expression"
|
||||||
|
"filter"
|
||||||
|
"filter"
|
||||||
|
"filters"
|
||||||
|
"format"
|
||||||
|
"frameId"
|
||||||
|
"fullTypeName"
|
||||||
|
"goto"
|
||||||
|
"gotoTargets"
|
||||||
|
"group"
|
||||||
|
"hex"
|
||||||
|
"hitCondition"
|
||||||
|
"id"
|
||||||
|
"includeAll"
|
||||||
|
"indexedVariables"
|
||||||
|
"indexedVariables"
|
||||||
|
"initialized"
|
||||||
|
"innerException"
|
||||||
|
"instruction"
|
||||||
|
"instructionBytes"
|
||||||
|
"instructionCount"
|
||||||
|
"instructionOffset"
|
||||||
|
"instructionPointerReference"
|
||||||
|
"isLocalProcess"
|
||||||
|
"isOptimized"
|
||||||
|
"isUserCode"
|
||||||
|
"kind"
|
||||||
|
"label"
|
||||||
|
"launch"
|
||||||
|
"length"
|
||||||
|
"levels"
|
||||||
|
"line"
|
||||||
|
"lines"
|
||||||
|
"linesStartAt1"
|
||||||
|
"loadedSource"
|
||||||
|
"loadedSources"
|
||||||
|
"locale"
|
||||||
|
"location"
|
||||||
|
"logMessage"
|
||||||
|
"memoryReference"
|
||||||
|
"message"
|
||||||
|
"module"
|
||||||
|
"moduleCount"
|
||||||
|
"moduleId"
|
||||||
|
"modules"
|
||||||
|
"name"
|
||||||
|
"namedVariables"
|
||||||
|
"names"
|
||||||
|
"negate"
|
||||||
|
"next"
|
||||||
|
"noDebug"
|
||||||
|
"offset"
|
||||||
|
"origin"
|
||||||
|
"output"
|
||||||
|
"parameterNames"
|
||||||
|
"parameters"
|
||||||
|
"parameterTypes"
|
||||||
|
"parameterValues"
|
||||||
|
"path"
|
||||||
|
"pathFormat"
|
||||||
|
"pause"
|
||||||
|
"percentage"
|
||||||
|
"pointerSize"
|
||||||
|
"presentationHint"
|
||||||
|
"preserveFocusHint"
|
||||||
|
"process"
|
||||||
|
"progressEnd"
|
||||||
|
"progressId"
|
||||||
|
"progressStart"
|
||||||
|
"progressUpdate"
|
||||||
|
"readMemory"
|
||||||
|
"reason"
|
||||||
|
"requestId"
|
||||||
|
"resolveSymbols"
|
||||||
|
"restart"
|
||||||
|
"restartFrame"
|
||||||
|
"reverseContinue"
|
||||||
|
"runInTerminal"
|
||||||
|
"scopes"
|
||||||
|
"selectionLength"
|
||||||
|
"selectionStart"
|
||||||
|
"sendTelemetry"
|
||||||
|
"seq"
|
||||||
|
"setBreakpoints"
|
||||||
|
"setDataBreakpoints"
|
||||||
|
"setExceptionBreakpoints"
|
||||||
|
"setExpression"
|
||||||
|
"setFunctionBreakpoints"
|
||||||
|
"setVariable"
|
||||||
|
"showUser"
|
||||||
|
"sortText"
|
||||||
|
"source"
|
||||||
|
"sourceModified"
|
||||||
|
"sourceReference"
|
||||||
|
"sources"
|
||||||
|
"stackTrace"
|
||||||
|
"start"
|
||||||
|
"startFrame"
|
||||||
|
"startMethod"
|
||||||
|
"startModule"
|
||||||
|
"stepBack"
|
||||||
|
"stepIn"
|
||||||
|
"stepInTargets"
|
||||||
|
"stepOut"
|
||||||
|
"stopped"
|
||||||
|
"supportedChecksumAlgorithms"
|
||||||
|
"supportsBreakpointLocationsRequest"
|
||||||
|
"supportsCancelRequest"
|
||||||
|
"supportsClipboardContext"
|
||||||
|
"supportsCompletionsRequest"
|
||||||
|
"supportsConditionalBreakpoints"
|
||||||
|
"supportsConfigurationDoneRequest"
|
||||||
|
"supportsDataBreakpoints"
|
||||||
|
"supportsDelayedStackTraceLoading"
|
||||||
|
"supportsDisassembleRequest"
|
||||||
|
"supportsEvaluateForHovers"
|
||||||
|
"supportsExceptionInfoRequest"
|
||||||
|
"supportsExceptionOptions"
|
||||||
|
"supportsFunctionBreakpoints"
|
||||||
|
"supportsGotoTargetsRequest"
|
||||||
|
"supportsHitConditionalBreakpoints"
|
||||||
|
"supportsLoadedSourcesRequest"
|
||||||
|
"supportsLogPoints"
|
||||||
|
"supportsMemoryReferences"
|
||||||
|
"supportsModulesRequest"
|
||||||
|
"supportsProgressReporting"
|
||||||
|
"supportsReadMemoryRequest"
|
||||||
|
"supportsRestartFrame"
|
||||||
|
"supportsRestartRequest"
|
||||||
|
"supportsRunInTerminalRequest"
|
||||||
|
"supportsSetExpression"
|
||||||
|
"supportsSetVariable"
|
||||||
|
"supportsStepBack"
|
||||||
|
"supportsStepInTargetsRequest"
|
||||||
|
"supportsTerminateRequest"
|
||||||
|
"supportsTerminateThreadsRequest"
|
||||||
|
"supportsValueFormattingOptions"
|
||||||
|
"supportsVariablePaging"
|
||||||
|
"supportsVariableType"
|
||||||
|
"supportTerminateDebuggee"
|
||||||
|
"symbol"
|
||||||
|
"symbolFilePath"
|
||||||
|
"symbolStatus"
|
||||||
|
"systemProcessId"
|
||||||
|
"targetId"
|
||||||
|
"terminate"
|
||||||
|
"terminated"
|
||||||
|
"terminateDebuggee"
|
||||||
|
"terminateThreads"
|
||||||
|
"text"
|
||||||
|
"thread"
|
||||||
|
"threadId"
|
||||||
|
"threadIds"
|
||||||
|
"threads"
|
||||||
|
"title"
|
||||||
|
"title"
|
||||||
|
"type"
|
||||||
|
"typeName"
|
||||||
|
"url"
|
||||||
|
"urlLabel"
|
||||||
|
"value"
|
||||||
|
"variables"
|
||||||
|
"variablesReference"
|
||||||
|
"verified"
|
||||||
|
"version"
|
||||||
|
"visibility"
|
||||||
|
"width"
|
173
fuzz/fuzz.cpp
Normal file
173
fuzz/fuzz.cpp
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
// Copyright 2020 Google LLC
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
// cppdap fuzzer program.
|
||||||
|
// Run with: ${CPPDAP_PATH}/fuzz/run.sh
|
||||||
|
// Requires modern clang toolchain.
|
||||||
|
|
||||||
|
#include "content_stream.h"
|
||||||
|
#include "string_buffer.h"
|
||||||
|
|
||||||
|
#include "dap/protocol.h"
|
||||||
|
#include "dap/session.h"
|
||||||
|
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Event provides a basic wait and signal synchronization primitive.
|
||||||
|
class Event {
|
||||||
|
public:
|
||||||
|
// wait() blocks until the event is fired or the given timeout is reached.
|
||||||
|
template <typename DURATION>
|
||||||
|
inline void wait(const DURATION& duration) {
|
||||||
|
std::unique_lock<std::mutex> lock(mutex);
|
||||||
|
cv.wait_for(lock, duration, [&] { return fired; });
|
||||||
|
}
|
||||||
|
|
||||||
|
// fire() sets signals the event, and unblocks any calls to wait().
|
||||||
|
inline void fire() {
|
||||||
|
std::unique_lock<std::mutex> lock(mutex);
|
||||||
|
fired = true;
|
||||||
|
cv.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::mutex mutex;
|
||||||
|
std::condition_variable cv;
|
||||||
|
bool fired = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// List of requests that we handle for fuzzing.
|
||||||
|
#define DAP_REQUEST_LIST() \
|
||||||
|
DAP_REQUEST(dap::AttachRequest, dap::AttachResponse) \
|
||||||
|
DAP_REQUEST(dap::BreakpointLocationsRequest, \
|
||||||
|
dap::BreakpointLocationsResponse) \
|
||||||
|
DAP_REQUEST(dap::CancelRequest, dap::CancelResponse) \
|
||||||
|
DAP_REQUEST(dap::CompletionsRequest, dap::CompletionsResponse) \
|
||||||
|
DAP_REQUEST(dap::ConfigurationDoneRequest, dap::ConfigurationDoneResponse) \
|
||||||
|
DAP_REQUEST(dap::ContinueRequest, dap::ContinueResponse) \
|
||||||
|
DAP_REQUEST(dap::DataBreakpointInfoRequest, dap::DataBreakpointInfoResponse) \
|
||||||
|
DAP_REQUEST(dap::DisassembleRequest, dap::DisassembleResponse) \
|
||||||
|
DAP_REQUEST(dap::DisconnectRequest, dap::DisconnectResponse) \
|
||||||
|
DAP_REQUEST(dap::EvaluateRequest, dap::EvaluateResponse) \
|
||||||
|
DAP_REQUEST(dap::ExceptionInfoRequest, dap::ExceptionInfoResponse) \
|
||||||
|
DAP_REQUEST(dap::GotoRequest, dap::GotoResponse) \
|
||||||
|
DAP_REQUEST(dap::GotoTargetsRequest, dap::GotoTargetsResponse) \
|
||||||
|
DAP_REQUEST(dap::InitializeRequest, dap::InitializeResponse) \
|
||||||
|
DAP_REQUEST(dap::LaunchRequest, dap::LaunchResponse) \
|
||||||
|
DAP_REQUEST(dap::LoadedSourcesRequest, dap::LoadedSourcesResponse) \
|
||||||
|
DAP_REQUEST(dap::ModulesRequest, dap::ModulesResponse) \
|
||||||
|
DAP_REQUEST(dap::NextRequest, dap::NextResponse) \
|
||||||
|
DAP_REQUEST(dap::PauseRequest, dap::PauseResponse) \
|
||||||
|
DAP_REQUEST(dap::ReadMemoryRequest, dap::ReadMemoryResponse) \
|
||||||
|
DAP_REQUEST(dap::RestartFrameRequest, dap::RestartFrameResponse) \
|
||||||
|
DAP_REQUEST(dap::RestartRequest, dap::RestartResponse) \
|
||||||
|
DAP_REQUEST(dap::ReverseContinueRequest, dap::ReverseContinueResponse) \
|
||||||
|
DAP_REQUEST(dap::RunInTerminalRequest, dap::RunInTerminalResponse) \
|
||||||
|
DAP_REQUEST(dap::ScopesRequest, dap::ScopesResponse) \
|
||||||
|
DAP_REQUEST(dap::SetBreakpointsRequest, dap::SetBreakpointsResponse) \
|
||||||
|
DAP_REQUEST(dap::SetDataBreakpointsRequest, dap::SetDataBreakpointsResponse) \
|
||||||
|
DAP_REQUEST(dap::SetExceptionBreakpointsRequest, \
|
||||||
|
dap::SetExceptionBreakpointsResponse) \
|
||||||
|
DAP_REQUEST(dap::SetExpressionRequest, dap::SetExpressionResponse) \
|
||||||
|
DAP_REQUEST(dap::SetFunctionBreakpointsRequest, \
|
||||||
|
dap::SetFunctionBreakpointsResponse) \
|
||||||
|
DAP_REQUEST(dap::SetVariableRequest, dap::SetVariableResponse) \
|
||||||
|
DAP_REQUEST(dap::SourceRequest, dap::SourceResponse) \
|
||||||
|
DAP_REQUEST(dap::StackTraceRequest, dap::StackTraceResponse) \
|
||||||
|
DAP_REQUEST(dap::StepBackRequest, dap::StepBackResponse) \
|
||||||
|
DAP_REQUEST(dap::StepInRequest, dap::StepInResponse) \
|
||||||
|
DAP_REQUEST(dap::StepInTargetsRequest, dap::StepInTargetsResponse) \
|
||||||
|
DAP_REQUEST(dap::StepOutRequest, dap::StepOutResponse) \
|
||||||
|
DAP_REQUEST(dap::TerminateRequest, dap::TerminateResponse) \
|
||||||
|
DAP_REQUEST(dap::TerminateThreadsRequest, dap::TerminateThreadsResponse) \
|
||||||
|
DAP_REQUEST(dap::ThreadsRequest, dap::ThreadsResponse) \
|
||||||
|
DAP_REQUEST(dap::VariablesRequest, dap::VariablesResponse)
|
||||||
|
|
||||||
|
// Fuzzing main function.
|
||||||
|
// See http://llvm.org/docs/LibFuzzer.html for details.
|
||||||
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||||
|
// The first byte can optionally control fuzzing mode.
|
||||||
|
enum class ControlMode {
|
||||||
|
// Don't wrap the input data with a stream writer. Allows testing for stream
|
||||||
|
// writing.
|
||||||
|
TestStreamWriter,
|
||||||
|
|
||||||
|
// Don't append a 'done' request. This may cause the test to take longer to
|
||||||
|
// complete (it may have to block on a timeout), but exercises the
|
||||||
|
// unrecognised-message cases.
|
||||||
|
DontAppendDoneRequest,
|
||||||
|
|
||||||
|
// Number of control modes in this enum.
|
||||||
|
Count,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Scan first byte for control mode.
|
||||||
|
bool useContentStreamWriter = true;
|
||||||
|
bool appendDoneRequest = true;
|
||||||
|
if (size > 0 && data[0] < static_cast<uint8_t>(ControlMode::Count)) {
|
||||||
|
useContentStreamWriter =
|
||||||
|
data[0] != static_cast<uint8_t>(ControlMode::TestStreamWriter);
|
||||||
|
appendDoneRequest =
|
||||||
|
data[0] != static_cast<uint8_t>(ControlMode::DontAppendDoneRequest);
|
||||||
|
data++;
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// in contains the input data
|
||||||
|
auto in = std::make_shared<dap::StringBuffer>();
|
||||||
|
|
||||||
|
dap::ContentWriter writer(in);
|
||||||
|
if (useContentStreamWriter) {
|
||||||
|
writer.write(std::string(reinterpret_cast<const char*>(data), size));
|
||||||
|
} else {
|
||||||
|
in->write(data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (appendDoneRequest) {
|
||||||
|
writer.write(R"(
|
||||||
|
{
|
||||||
|
"seq": 10,
|
||||||
|
"type": "request",
|
||||||
|
"command": "done",
|
||||||
|
}
|
||||||
|
)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Each test is done if we receive a request, or report an error.
|
||||||
|
Event requestOrError;
|
||||||
|
|
||||||
|
#define DAP_REQUEST(REQUEST, RESPONSE) \
|
||||||
|
session->registerHandler([&](const REQUEST&) { \
|
||||||
|
requestOrError.fire(); \
|
||||||
|
return RESPONSE{}; \
|
||||||
|
});
|
||||||
|
|
||||||
|
auto session = dap::Session::create();
|
||||||
|
DAP_REQUEST_LIST();
|
||||||
|
|
||||||
|
session->onError([&](const char*) { requestOrError.fire(); });
|
||||||
|
|
||||||
|
auto out = std::make_shared<dap::StringBuffer>();
|
||||||
|
session->bind(dap::ReaderWriter::create(in, out));
|
||||||
|
|
||||||
|
// Give up after a second if we don't get a request or error reported.
|
||||||
|
requestOrError.wait(std::chrono::seconds(1));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
19
fuzz/run.sh
Executable file
19
fuzz/run.sh
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e # Fail on any error.
|
||||||
|
|
||||||
|
FUZZ_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd )"
|
||||||
|
cd ${FUZZ_DIR}
|
||||||
|
|
||||||
|
# Ensure we're testing with latest build
|
||||||
|
[ ! -d "build" ] && mkdir "build"
|
||||||
|
cd "build"
|
||||||
|
cmake ../.. -GNinja -DCPPDAP_BUILD_FUZZER=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||||
|
ninja
|
||||||
|
|
||||||
|
cd ${FUZZ_DIR}
|
||||||
|
[ ! -d "corpus" ] && mkdir "corpus"
|
||||||
|
[ ! -d "logs" ] && mkdir "logs"
|
||||||
|
cd "logs"
|
||||||
|
rm crash-* fuzz-* || true
|
||||||
|
${FUZZ_DIR}/build/cppdap-fuzzer ${FUZZ_DIR}/corpus ${FUZZ_DIR}/seed -dict=${FUZZ_DIR}/dictionary.txt -jobs=128
|
1
fuzz/seed/empty_json
Normal file
1
fuzz/seed/empty_json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{}
|
8
fuzz/seed/request
Normal file
8
fuzz/seed/request
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"seq": 153,
|
||||||
|
"type": "request",
|
||||||
|
"command": "next",
|
||||||
|
"arguments": {
|
||||||
|
"threadId": 3
|
||||||
|
}
|
||||||
|
}
|
@ -52,6 +52,7 @@ class Writer : virtual public Closable {
|
|||||||
|
|
||||||
// ReaderWriter is an interface that combines the Reader and Writer interfaces.
|
// ReaderWriter is an interface that combines the Reader and Writer interfaces.
|
||||||
class ReaderWriter : public Reader, public Writer {
|
class ReaderWriter : public Reader, public Writer {
|
||||||
|
public:
|
||||||
// create() returns a ReaderWriter that delegates the interface methods on to
|
// create() returns a ReaderWriter that delegates the interface methods on to
|
||||||
// the provided Reader and Writer.
|
// the provided Reader and Writer.
|
||||||
// isOpen() returns true if the Reader and Writer both return true for
|
// isOpen() returns true if the Reader and Writer both return true for
|
||||||
|
Loading…
x
Reference in New Issue
Block a user