Coverage Report

Created: 2026-11-12 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ada-url/fuzz/can_parse.cc
Line
Count
Source
1
#include <fuzzer/FuzzedDataProvider.h>
2
3
#include <cstdio>
4
#include <string>
5
#include <string_view>
6
7
#include "ada.cpp"
8
#include "ada.h"
9
10
12.1k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
11
12.1k
  FuzzedDataProvider fdp(data, size);
12
12.1k
  std::string source = fdp.ConsumeRandomLengthString(256);
13
12.1k
  std::string base_source = fdp.ConsumeRandomLengthString(256);
14
15
12.1k
  bool can_parse_result = ada::can_parse(source);
16
12.1k
  auto parsed_agg = ada::parse<ada::url_aggregator>(source);
17
12.1k
  auto parsed_url = ada::parse<ada::url>(source);
18
19
12.1k
  if (can_parse_result != parsed_agg.has_value()) {
20
0
    printf("can_parse vs parse<url_aggregator> inconsistency for: %s\n",
21
0
           source.c_str());
22
0
    abort();
23
0
  }
24
12.1k
  if (can_parse_result != parsed_url.has_value()) {
25
0
    printf("can_parse vs parse<url> inconsistency for: %s\n", source.c_str());
26
0
    abort();
27
0
  }
28
12.1k
  if (parsed_url.has_value() != parsed_agg.has_value()) {
29
0
    printf("parse<url> vs parse<url_aggregator> disagreement for: %s\n",
30
0
           source.c_str());
31
0
    abort();
32
0
  }
33
12.1k
  if (parsed_url && parsed_agg &&
34
8.10k
      parsed_url->get_href() != std::string(parsed_agg->get_href())) {
35
0
    printf("parse href disagreement for: %s\n", source.c_str());
36
0
    abort();
37
0
  }
38
39
12.1k
  auto base_source_view =
40
12.1k
      std::string_view(base_source.data(), base_source.length());
41
12.1k
  bool can_parse_with_base = ada::can_parse(source, &base_source_view);
42
43
12.1k
  auto base_agg = ada::parse<ada::url_aggregator>(base_source);
44
12.1k
  auto base_url = ada::parse<ada::url>(base_source);
45
12.1k
  if (base_agg.has_value() != base_url.has_value()) {
46
0
    printf("base parse type disagreement for: %s\n", base_source.c_str());
47
0
    abort();
48
0
  }
49
50
12.1k
  if (base_agg && base_url) {
51
4.35k
    auto ra = ada::parse<ada::url_aggregator>(source, &*base_agg);
52
4.35k
    auto ru = ada::parse<ada::url>(source, &*base_url);
53
4.35k
    if (can_parse_with_base != ra.has_value()) {
54
0
      printf(
55
0
          "can_parse_with_base vs parse inconsistency for source=%s base=%s\n",
56
0
          source.c_str(), base_source.c_str());
57
0
      abort();
58
0
    }
59
4.35k
    if (ra.has_value() != ru.has_value()) {
60
0
      printf("relative parse type disagreement source=%s base=%s\n",
61
0
             source.c_str(), base_source.c_str());
62
0
      abort();
63
0
    }
64
4.35k
    if (ra && ru && ru->get_href() != std::string(ra->get_href())) {
65
0
      printf("relative parse href disagreement source=%s base=%s\n",
66
0
             source.c_str(), base_source.c_str());
67
0
      abort();
68
0
    }
69
7.82k
  } else if (can_parse_with_base) {
70
0
    printf("can_parse_with_base true with invalid base=%s\n",
71
0
           base_source.c_str());
72
0
    abort();
73
0
  }
74
75
12.1k
  {
76
12.1k
    bool empty_cp = ada::can_parse("");
77
12.1k
    auto empty_agg = ada::parse<ada::url_aggregator>("");
78
12.1k
    auto empty_url = ada::parse<ada::url>("");
79
12.1k
    if (empty_cp != empty_agg.has_value() ||
80
12.1k
        empty_cp != empty_url.has_value()) {
81
0
      printf("Empty string can_parse/parse disagreement\n");
82
0
      abort();
83
0
    }
84
12.1k
  }
85
86
12.1k
  if (parsed_agg) {
87
8.10k
    std::string href = std::string(parsed_agg->get_href());
88
8.10k
    if (!ada::can_parse(href)) {
89
0
      printf("can_parse rejected normalised href: '%s'\n", href.c_str());
90
0
      abort();
91
0
    }
92
8.10k
    auto reparsed = ada::parse<ada::url_aggregator>(href);
93
8.10k
    if (!reparsed || std::string(reparsed->get_href()) != href) {
94
0
      printf("href re-parse failure for: '%s'\n", href.c_str());
95
0
      abort();
96
0
    }
97
8.10k
    auto reparsed_url = ada::parse<ada::url>(href);
98
8.10k
    if (!reparsed_url || reparsed_url->get_href() != href) {
99
0
      printf("parse<url> re-parse disagreement on href: '%s'\n", href.c_str());
100
0
      abort();
101
0
    }
102
8.10k
  }
103
104
12.1k
  return 0;
105
12.1k
}