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