Coverage Report

Created: 2026-09-14 07:12

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
    "smtp",   "smtps",  "tftp",   "ws",     "wss",    nullptr};
28
29
/**
30
 * Tests support against libcurl's authoritative runtime protocol list so a
31
 * dependency variant cannot poison the complete CURLOPT_PROTOCOLS_STR value.
32
 */
33
bool IsSupported(const char *candidate,
34
29
                 const char *const *supported_protocols) {
35
29
  if (!supported_protocols) {
36
0
    return false;
37
0
  }
38
39
434
  for (const char *const *protocol = supported_protocols; *protocol;
40
426
       ++protocol) {
41
426
    if (std::strcmp(candidate, *protocol) == 0) {
42
21
      return true;
43
21
    }
44
426
  }
45
8
  return false;
46
29
}
47
48
}  // namespace
49
50
1
std::string Build(const char *const *supported_protocols) {
51
1
  std::string allowed;
52
30
  for (const char *const *candidate = kIntendedProtocols; *candidate;
53
29
       ++candidate) {
54
29
    if (!IsSupported(*candidate, supported_protocols)) {
55
8
      continue;
56
8
    }
57
21
    if (!allowed.empty()) {
58
20
      allowed.push_back(',');
59
20
    }
60
21
    allowed.append(*candidate);
61
21
  }
62
1
  return allowed;
63
1
}
64
65
22.3k
const std::string &ForCurrentCurl() {
66
22.3k
  static const std::string allowed = []() {
67
1
    const curl_version_info_data *const info =
68
1
        curl_version_info(CURLVERSION_NOW);
69
1
    return Build(info ? info->protocols : nullptr);
70
1
  }();
71
22.3k
  return allowed;
72
22.3k
}
73
74
}  // namespace legacy_protocol_allowlist