Coverage Report

Created: 2026-10-15 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/curl_fuzzer/full_coverage/utility_api.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 "full_coverage/utility_api.h"
8
9
#include <ctime>
10
11
#include <curl/curl.h>
12
13
namespace full_coverage {
14
namespace {
15
16
/** Replay ordinary formats documented by curl and its date-parser tests. */
17
void ExerciseDates()
18
0
{
19
  // Valid formats and ordinary calendar variants follow
20
  // curl/docs/libcurl/curl_getdate.md. Epoch,
21
  // unsupported-format, calendar-range, and time_t-range examples come from
22
  // curl/tests/libtest/lib517.c. Every input is a short, fixed date string.
23
0
  const char *const dates[] = {
24
0
      "Sun, 06 Nov 1994 08:49:37 GMT",
25
0
      "Sunday, 06-Nov-94 08:49:37 GMT",
26
0
      "Sun Nov  6 08:49:37 1994",
27
0
      "06-Jul-94 08:49:37",
28
0
      "GMT 08:49:37 06-Aug-95 Sunday",
29
0
      "94 6 Oct 08:49:37",
30
0
      "1994 Mar 6",
31
0
      "1994.Feb.6",
32
0
      "Sun/Jun/6/93/GMT",
33
0
      "Mon, 06 Nov 1995 08:49:37 CET",
34
0
      "Tue, 06 Nov 2001 08:49:37 EST",
35
0
      "Sun, 12 Sep 2004 15:05:58 -0700",
36
0
      "Fri, 11 Sep 2009 21:32:11 +0200",
37
0
      "20040912 15:05:58 -0700",
38
0
      "20040911 +0200",
39
0
      "Saturday, May 5 GMT 11:56:27 2035",
40
0
      "Sat, 15-Apr-17 21:01:22 GMT",
41
0
      "Wed, 31 Dec 2008 23:59:60 GMT",
42
0
      "Thu, 01-Jan-1970 00:00:00 GMT",
43
0
      "Thu, 31-Dec-1969 23:59:59 GMT",
44
0
      "IAintNoDateFool",
45
0
      "1994-11-06T08:49:37Z",
46
0
      "Thu, 01-Jan-1499 00:00:00 GMT",
47
0
      "Sun, 06 Nov 1900 08:49:37 GMT",
48
0
      "Sun, 06 Nov 2044 08:49:37 GMT",
49
0
      ""};
50
0
  for(const char *date : dates) {
51
0
    const volatile std::time_t parsed = curl_getdate(date, nullptr);
52
0
    (void)parsed;
53
0
  }
54
0
  const volatile std::time_t missing = curl_getdate(nullptr, nullptr);
55
0
  (void)missing;
56
0
}
57
58
/** Cover compatibility aliases and the explicit binary-length API contract. */
59
void ExerciseEscaping()
60
0
{
61
0
  const char *const strings[] = {
62
0
      "",
63
0
      "data to convert",
64
0
      "a/b?c=d&reserved=+ %#",
65
0
      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~"};
66
0
  for(const char *text : strings) {
67
0
    char *encoded = curl_escape(text, 0);
68
0
    if(encoded) {
69
0
      curl_free(curl_unescape(encoded, 0));
70
0
      int length = 0;
71
0
      curl_free(curl_easy_unescape(nullptr, encoded, 0, &length));
72
0
    }
73
0
    curl_free(encoded);
74
0
  }
75
76
  // The escaping documentation specifies byte-oriented encoding. Explicit
77
  // lengths preserve an embedded NUL and a non-ASCII byte through decoding.
78
0
  const char binary[] = {'a', '\0', '%', static_cast<char>(0xff)};
79
0
  char *encoded = curl_escape(binary, static_cast<int>(sizeof(binary)));
80
0
  if(encoded) {
81
0
    int length = 0;
82
0
    curl_free(curl_easy_unescape(nullptr, encoded, 0, &length));
83
0
    curl_free(curl_unescape(encoded, 0));
84
0
  }
85
0
  curl_free(encoded);
86
0
  curl_free(curl_unescape("%00%FF%41", 9));
87
88
  // These rejected length values are ordinary API-contract checks from
89
  // curl/tests/libtest/lib1605.c; no memory or operating-system faults occur.
90
0
  curl_free(curl_easy_escape(nullptr, "", -1));
91
0
  int length = 0;
92
0
  curl_free(curl_easy_unescape(nullptr, "%41%41%41%41", -1, &length));
93
0
}
94
95
}  // namespace
96
97
void ExerciseUtilityApiCoverage()
98
0
{
99
0
  if(curl_global_init(CURL_GLOBAL_DEFAULT) != CURLE_OK)
100
0
    return;
101
102
  // The returned version string has static storage and must not be freed.
103
0
  const char *volatile version = curl_version();
104
0
  (void)version;
105
0
  ExerciseDates();
106
0
  ExerciseEscaping();
107
0
  curl_global_cleanup();
108
0
}
109
110
}  // namespace full_coverage