Coverage Report

Created: 2026-09-01 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/curl_fuzzer/legacy_protocol_allowlist.cc
Line
Count
Source
1
/*
2
 * Copyright (C) Max Dymond, <cmeister2@gmail.com>, et al.
3
 *
4
 * SPDX-License-Identifier: curl
5
 */
6
7
#include "legacy_protocol_allowlist.h"
8
9
#include <curl/curl.h>
10
11
#include <cstring>
12
13
namespace legacy_protocol_allowlist {
14
namespace {
15
16
/*
17
 * This is a harness safety policy, rather than a copy of libcurl's protocol
18
 * registry. In particular, TELNET remains exclusive to the proto fuzzer
19
 * because the legacy harness cannot prevent it from reading stdin. New curl
20
 * protocols must likewise be reviewed before being added here.
21
 */
22
const char *const kIntendedProtocols[] = {
23
    "dict",   "file",   "ftp",    "ftps",   "gopher", "gophers",
24
    "http",   "https",  "imap",   "imaps",  "mqtt",   "pop3",
25
    "pop3s",  "ldap",   "ldaps",  "rtmp",   "rtmpe",  "rtmps",
26
    "rtmpt",  "rtmpte", "rtmpts", "scp",    "sftp",   "rtsp",
27
    "smb",    "smbs",   "smtp",   "smtps",  "tftp",   "ws",
28
    "wss",    nullptr};
29
30
/**
31
 * Tests support against libcurl's authoritative runtime protocol list so a
32
 * dependency variant cannot poison the complete CURLOPT_PROTOCOLS_STR value.
33
 */
34
bool IsSupported(const char *candidate,
35
31
                 const char *const *supported_protocols) {
36
31
  if (!supported_protocols) {
37
0
    return false;
38
0
  }
39
40
482
  for (const char *const *protocol = supported_protocols; *protocol;
41
472
       ++protocol) {
42
472
    if (std::strcmp(candidate, *protocol) == 0) {
43
21
      return true;
44
21
    }
45
472
  }
46
10
  return false;
47
31
}
48
49
}  // namespace
50
51
1
std::string Build(const char *const *supported_protocols) {
52
1
  std::string allowed;
53
32
  for (const char *const *candidate = kIntendedProtocols; *candidate;
54
31
       ++candidate) {
55
31
    if (!IsSupported(*candidate, supported_protocols)) {
56
10
      continue;
57
10
    }
58
21
    if (!allowed.empty()) {
59
20
      allowed.push_back(',');
60
20
    }
61
21
    allowed.append(*candidate);
62
21
  }
63
1
  return allowed;
64
1
}
65
66
5.10k
const std::string &ForCurrentCurl() {
67
5.10k
  static const std::string allowed = []() {
68
1
    const curl_version_info_data *const info =
69
1
        curl_version_info(CURLVERSION_NOW);
70
1
    return Build(info ? info->protocols : nullptr);
71
1
  }();
72
5.10k
  return allowed;
73
5.10k
}
74
75
}  // namespace legacy_protocol_allowlist