Coverage Report

Created: 2025-10-31 09:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/node/test/fuzzers/fuzz_tls_socket_request.cc
Line
Count
Source
1
// Copyright 2025 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include <cstdint>
16
#include <string>
17
#include <fuzzer/FuzzedDataProvider.h>
18
19
#include "fuzz_common.h"
20
#include "fuzz_js_format.h"
21
22
// Static header (existing PEMs + setup; kept intact)
23
static constexpr std::string_view kHeader = R"(const tls = require('tls');
24
const https = require('https');
25
const { setEnvironmentData } = require('worker_threads');
26
const { send } = require('process');
27
28
// Self-signed key/cert (same as your original)
29
const key = `-----BEGIN EC PARAMETERS-----
30
BggqhkjOPQMBBw==
31
-----END EC PARAMETERS-----
32
-----BEGIN EC PRIVATE KEY-----
33
MHcCAQEEIDKfHHbiJMdu2STyHL11fWC7psMY19/gUNpsUpkwgGACoAoGCCqGSM49
34
AwEHoUQDQgAEItqm+pYj3Ca8bi5mBs+H8xSMxuW2JNn4I+kw3aREsetLk8pn3o81
35
PWBiTdSZrGBGQSy+UAlQvYeE6Z/QXQk8aw==
36
-----END EC PRIVATE KEY-----`;
37
38
const cert = `-----BEGIN CERTIFICATE-----
39
MIIBhjCCASsCFDJU1tCo88NYU//pE+DQKO9hUDsFMAoGCCqGSM49BAMCMEUxCzAJ
40
BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l
41
dCBXaWRnaXRzIFB0eSBMdGQwHhcNMjAwOTIyMDg1NDU5WhcNNDgwMjA3MDg1NDU5
42
WjBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwY
43
SW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD
44
QgAEItqm+pYj3Ca8bi5mBs+H8xSMxuW2JNn4I+kw3aREsetLk8pn3o81PWBiTdSZ
45
rGBGQSy+UAlQvYeE6Z/QXQk8azAKBggqhkjOPQQDAgNJADBGAiEA7Bdn4F87KqIe
46
Y/ABy/XIXXpFUb2nyv3zV7POQi2lPcECIQC3UWLmfiedpiIKsf9YRIyO0uEood7+
47
glj2R1NNr1X68w==
48
-----END CERTIFICATE-----`;
49
50
const options = { key, cert };
51
52
let srv;
53
let socket;
54
let receivedResponse = 0;
55
56
async function send_requests() {
57
  socket = tls.connect(4444, 'localhost', { rejectUnauthorized: false }, () => {
58
    const httpRequest = `GET / HTTP/1.1\r\nHost: localhost\r\nConnection: Keep-alive\r\n\r\n`;
59
    socket.write(httpRequest);
60
)";
61
62
// Template for a single POST using a precomputed body Buffer
63
static constexpr std::string_view kPostTemplate = R"(
64
    const body = Buffer.from({0}, 'latin1');
65
    const postRequest = `POST / HTTP/1.1\r\nHost: localhost\r\nContent-Type: application/json\r\nContent-Length: ${body.length}\r\n\r\n${body.toString('latin1')}`;
66
    socket.write(postRequest);
67
)";
68
69
static constexpr std::string_view kFooter = R"(
70
  });
71
72
  socket.on('data', (data) => {
73
    receivedResponse++;
74
    if (receivedResponse === 6) {
75
      socket.end();
76
    }
77
  });
78
79
  socket.on('end', () => {
80
    srv.close(() => {});
81
  });
82
}
83
84
function run_server() {
85
  srv = https.createServer(options, function (req, res) {
86
    let chunks = [];
87
    req.on('data', (c) => chunks.push(c));
88
    req.on('end', () => {
89
      const body = Buffer.concat(chunks);
90
      res.writeHead(200, { 'Content-Type': 'text/html' });
91
      res.end('ok');
92
    });
93
  }).listen(4444);
94
}
95
96
run_server();
97
send_requests();
98
)";
99
100
22.0k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
101
22.0k
  FuzzedDataProvider prov(data, size);
102
22.0k
  std::string b1 = prov.ConsumeRandomLengthString();
103
22.0k
  std::string b2 = prov.ConsumeRandomLengthString();
104
22.0k
  std::string b3 = prov.ConsumeRandomLengthString();
105
106
  // Build the whole script: header + 3 posts + footer
107
22.0k
  std::string js = std::string(kHeader);
108
22.0k
  js += FormatJs(kPostTemplate, ToSingleQuotedJsLiteral(b1));
109
22.0k
  js += FormatJs(kPostTemplate, ToSingleQuotedJsLiteral(b2));
110
22.0k
  js += FormatJs(kPostTemplate, ToSingleQuotedJsLiteral(b3));
111
22.0k
  js += std::string(kFooter);
112
113
22.0k
  fuzz::IsolateScope iso;
114
22.0k
  if (!iso.ok()) return 0;
115
116
  // Give async networking a few ticks.
117
22.0k
  fuzz::EnvRunOptions opts;
118
22.0k
  opts.max_pumps = 8;
119
22.0k
  fuzz::RunEnvString(iso.isolate(), js.c_str(), opts);
120
22.0k
  return 0;
121
22.0k
}