| 102 | // Fuzzing main function. |
| 103 | // See http://llvm.org/docs/LibFuzzer.html for details. |
| 104 | extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
| 105 | // The first byte can optionally control fuzzing mode. |
| 106 | enum class ControlMode { |
| 107 | // Don't wrap the input data with a stream writer. Allows testing for stream |
| 108 | // writing. |
| 109 | TestStreamWriter, |
| 110 | |
| 111 | // Don't append a 'done' request. This may cause the test to take longer to |
| 112 | // complete (it may have to block on a timeout), but exercises the |
| 113 | // unrecognised-message cases. |
| 114 | DontAppendDoneRequest, |
| 115 | |
| 116 | // Number of control modes in this enum. |
| 117 | Count, |
| 118 | }; |
| 119 | |
| 120 | // Scan first byte for control mode. |
| 121 | bool useContentStreamWriter = true; |
| 122 | bool appendDoneRequest = true; |
| 123 | if (size > 0 && data[0] < static_cast<uint8_t>(ControlMode::Count)) { |
| 124 | useContentStreamWriter = |
| 125 | data[0] != static_cast<uint8_t>(ControlMode::TestStreamWriter); |
| 126 | appendDoneRequest = |
| 127 | data[0] != static_cast<uint8_t>(ControlMode::DontAppendDoneRequest); |
| 128 | data++; |
| 129 | size--; |
| 130 | } |
| 131 | |
| 132 | // in contains the input data |
| 133 | auto in = std::make_shared<dap::StringBuffer>(); |
| 134 | |
| 135 | dap::ContentWriter writer(in); |
| 136 | if (useContentStreamWriter) { |
| 137 | writer.write(std::string(reinterpret_cast<const char*>(data), size)); |
| 138 | } else { |
| 139 | in->write(data, size); |
| 140 | } |
| 141 | |
| 142 | if (appendDoneRequest) { |
| 143 | writer.write(R"( |
| 144 | { |
| 145 | "seq": 10, |
| 146 | "type": "request", |
| 147 | "command": "done", |
| 148 | } |
| 149 | )"); |
| 150 | } |
| 151 | |
| 152 | // Each test is done if we receive a request, or report an error. |
| 153 | Event requestOrError; |
| 154 | |
| 155 | #define DAP_REQUEST(REQUEST, RESPONSE) \ |
| 156 | session->registerHandler([&](const REQUEST&) { \ |
| 157 | requestOrError.fire(); \ |
| 158 | return RESPONSE{}; \ |
| 159 | }); |
| 160 | |
| 161 | auto session = dap::Session::create(); |