xref: /aosp_15_r20/external/cronet/url/gurl_fuzzer.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2015 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/at_exit.h"
6*6777b538SAndroid Build Coastguard Worker #include "base/check_op.h"
7*6777b538SAndroid Build Coastguard Worker #include "base/i18n/icu_util.h"
8*6777b538SAndroid Build Coastguard Worker #include "base/no_destructor.h"
9*6777b538SAndroid Build Coastguard Worker #include "url/gurl.h"
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker struct TestCase {
TestCaseTestCase12*6777b538SAndroid Build Coastguard Worker   TestCase() { CHECK(base::i18n::InitializeICU()); }
13*6777b538SAndroid Build Coastguard Worker 
14*6777b538SAndroid Build Coastguard Worker   // used by ICU integration.
15*6777b538SAndroid Build Coastguard Worker   base::AtExitManager at_exit_manager;
16*6777b538SAndroid Build Coastguard Worker };
17*6777b538SAndroid Build Coastguard Worker 
18*6777b538SAndroid Build Coastguard Worker TestCase* test_case = new TestCase();
19*6777b538SAndroid Build Coastguard Worker 
20*6777b538SAndroid Build Coastguard Worker // Checks that GURL's canonicalization is idempotent. This can help discover
21*6777b538SAndroid Build Coastguard Worker // issues like https://crbug.com/1128999.
CheckIdempotency(const GURL & url)22*6777b538SAndroid Build Coastguard Worker void CheckIdempotency(const GURL& url) {
23*6777b538SAndroid Build Coastguard Worker   if (!url.is_valid())
24*6777b538SAndroid Build Coastguard Worker     return;
25*6777b538SAndroid Build Coastguard Worker   const std::string& spec = url.spec();
26*6777b538SAndroid Build Coastguard Worker   GURL recanonicalized(spec);
27*6777b538SAndroid Build Coastguard Worker   CHECK(recanonicalized.is_valid());
28*6777b538SAndroid Build Coastguard Worker   CHECK_EQ(spec, recanonicalized.spec());
29*6777b538SAndroid Build Coastguard Worker }
30*6777b538SAndroid Build Coastguard Worker 
31*6777b538SAndroid Build Coastguard Worker // Checks that |url.spec()| is preserved across a call to ReplaceComponents with
32*6777b538SAndroid Build Coastguard Worker // zero replacements, which is effectively a copy. This can help discover issues
33*6777b538SAndroid Build Coastguard Worker // like https://crbug.com/1075515.
CheckReplaceComponentsPreservesSpec(const GURL & url)34*6777b538SAndroid Build Coastguard Worker void CheckReplaceComponentsPreservesSpec(const GURL& url) {
35*6777b538SAndroid Build Coastguard Worker   static const base::NoDestructor<GURL::Replacements> no_op;
36*6777b538SAndroid Build Coastguard Worker   GURL copy = url.ReplaceComponents(*no_op);
37*6777b538SAndroid Build Coastguard Worker   CHECK_EQ(url.is_valid(), copy.is_valid());
38*6777b538SAndroid Build Coastguard Worker   if (url.is_valid()) {
39*6777b538SAndroid Build Coastguard Worker     CHECK_EQ(url.spec(), copy.spec());
40*6777b538SAndroid Build Coastguard Worker   }
41*6777b538SAndroid Build Coastguard Worker }
42*6777b538SAndroid Build Coastguard Worker 
43*6777b538SAndroid Build Coastguard Worker // Entry point for LibFuzzer.
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)44*6777b538SAndroid Build Coastguard Worker extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
45*6777b538SAndroid Build Coastguard Worker   if (size < 1)
46*6777b538SAndroid Build Coastguard Worker     return 0;
47*6777b538SAndroid Build Coastguard Worker   {
48*6777b538SAndroid Build Coastguard Worker     std::string_view string_piece_input(reinterpret_cast<const char*>(data),
49*6777b538SAndroid Build Coastguard Worker                                         size);
50*6777b538SAndroid Build Coastguard Worker     const GURL url_from_string_piece(string_piece_input);
51*6777b538SAndroid Build Coastguard Worker     CheckIdempotency(url_from_string_piece);
52*6777b538SAndroid Build Coastguard Worker     CheckReplaceComponentsPreservesSpec(url_from_string_piece);
53*6777b538SAndroid Build Coastguard Worker   }
54*6777b538SAndroid Build Coastguard Worker   // Test for std::u16string_view if size is even.
55*6777b538SAndroid Build Coastguard Worker   if (size % sizeof(char16_t) == 0) {
56*6777b538SAndroid Build Coastguard Worker     std::u16string_view string_piece_input16(
57*6777b538SAndroid Build Coastguard Worker         reinterpret_cast<const char16_t*>(data), size / sizeof(char16_t));
58*6777b538SAndroid Build Coastguard Worker     const GURL url_from_string_piece16(string_piece_input16);
59*6777b538SAndroid Build Coastguard Worker     CheckIdempotency(url_from_string_piece16);
60*6777b538SAndroid Build Coastguard Worker     CheckReplaceComponentsPreservesSpec(url_from_string_piece16);
61*6777b538SAndroid Build Coastguard Worker   }
62*6777b538SAndroid Build Coastguard Worker   // Resolve relative url tests.
63*6777b538SAndroid Build Coastguard Worker   {
64*6777b538SAndroid Build Coastguard Worker     size_t size_t_bytes = sizeof(size_t);
65*6777b538SAndroid Build Coastguard Worker     if (size < size_t_bytes + 1) {
66*6777b538SAndroid Build Coastguard Worker       return 0;
67*6777b538SAndroid Build Coastguard Worker     }
68*6777b538SAndroid Build Coastguard Worker     size_t relative_size =
69*6777b538SAndroid Build Coastguard Worker         *reinterpret_cast<const size_t*>(data) % (size - size_t_bytes);
70*6777b538SAndroid Build Coastguard Worker     std::string relative_string(
71*6777b538SAndroid Build Coastguard Worker         reinterpret_cast<const char*>(data + size_t_bytes), relative_size);
72*6777b538SAndroid Build Coastguard Worker     std::string_view string_piece_part_input(
73*6777b538SAndroid Build Coastguard Worker         reinterpret_cast<const char*>(data + size_t_bytes + relative_size),
74*6777b538SAndroid Build Coastguard Worker         size - relative_size - size_t_bytes);
75*6777b538SAndroid Build Coastguard Worker     const GURL url_from_string_piece_part(string_piece_part_input);
76*6777b538SAndroid Build Coastguard Worker     CheckIdempotency(url_from_string_piece_part);
77*6777b538SAndroid Build Coastguard Worker     CheckReplaceComponentsPreservesSpec(url_from_string_piece_part);
78*6777b538SAndroid Build Coastguard Worker 
79*6777b538SAndroid Build Coastguard Worker     url_from_string_piece_part.Resolve(relative_string);
80*6777b538SAndroid Build Coastguard Worker 
81*6777b538SAndroid Build Coastguard Worker     if (relative_size % sizeof(char16_t) == 0) {
82*6777b538SAndroid Build Coastguard Worker       std::u16string relative_string16(
83*6777b538SAndroid Build Coastguard Worker           reinterpret_cast<const char16_t*>(data + size_t_bytes),
84*6777b538SAndroid Build Coastguard Worker           relative_size / sizeof(char16_t));
85*6777b538SAndroid Build Coastguard Worker       url_from_string_piece_part.Resolve(relative_string16);
86*6777b538SAndroid Build Coastguard Worker     }
87*6777b538SAndroid Build Coastguard Worker   }
88*6777b538SAndroid Build Coastguard Worker   return 0;
89*6777b538SAndroid Build Coastguard Worker }
90