/src/libphonenumber/cpp/test/phonenumbers/fuzz_matcher.cc
Line | Count | Source |
1 | | /* Copyright 2025 Google Inc. |
2 | | |
3 | | Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | you may not use this file except in compliance with the License. |
5 | | You may obtain a copy of the License at |
6 | | |
7 | | http://www.apache.org/licenses/LICENSE-2.0 |
8 | | |
9 | | Unless required by applicable law or agreed to in writing, software |
10 | | distributed under the License is distributed on an "AS IS" BASIS, |
11 | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | See the License for the specific language governing permissions and |
13 | | limitations under the License. |
14 | | */ |
15 | | #include "phonenumbers/phonenumbermatcher.h" |
16 | | #include <memory> |
17 | | #include <string> |
18 | | #include <vector> |
19 | | #include <limits> |
20 | | #include <unicode/unistr.h> |
21 | | |
22 | | #include "phonenumbers/base/basictypes.h" |
23 | | #include "phonenumbers/base/memory/scoped_ptr.h" |
24 | | #include "phonenumbers/base/memory/singleton.h" |
25 | | #include "phonenumbers/default_logger.h" |
26 | | #include "phonenumbers/phonenumber.h" |
27 | | #include "phonenumbers/phonenumbermatch.h" |
28 | | #include "phonenumbers/regexp_adapter_icu.h" |
29 | | #include "phonenumbers/phonenumberutil.h" |
30 | | #include "phonenumbers/stringutil.h" |
31 | | #include "phonenumbers/asyoutypeformatter.h" |
32 | | #include "phonenumbers/shortnumberinfo.h" |
33 | | #include <fuzzer/FuzzedDataProvider.h> |
34 | | |
35 | | // returns a leniency level based on the data we got from libfuzzer |
36 | | i18n::phonenumbers::PhoneNumberMatcher::Leniency ConsumeLeniency( |
37 | 6.61k | FuzzedDataProvider& fuzzed_data) { |
38 | 6.61k | switch (fuzzed_data.ConsumeIntegralInRange(0, 3)) { |
39 | 2.25k | case 0: |
40 | 2.25k | return i18n::phonenumbers::PhoneNumberMatcher::Leniency::POSSIBLE; |
41 | 1.31k | case 1: |
42 | 1.31k | return i18n::phonenumbers::PhoneNumberMatcher::Leniency::VALID; |
43 | 1.39k | case 2: |
44 | 1.39k | return i18n::phonenumbers::PhoneNumberMatcher::Leniency::STRICT_GROUPING; |
45 | 1.64k | default: |
46 | 1.64k | return i18n::phonenumbers::PhoneNumberMatcher::Leniency::EXACT_GROUPING; |
47 | 6.61k | } |
48 | 6.61k | } |
49 | | |
50 | 6.61k | extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
51 | | // Setup the data provider and util |
52 | 6.61k | FuzzedDataProvider fuzzed_data(data, size); |
53 | 6.61k | i18n::phonenumbers::PhoneNumberUtil* phone_util = |
54 | 6.61k | i18n::phonenumbers::PhoneNumberUtil::GetInstance(); |
55 | | |
56 | | // this should be enought to get at least 2 matches |
57 | 6.61k | std::string text = fuzzed_data.ConsumeBytesAsString(128); |
58 | | |
59 | | // the region is either 2 or 3 characters long |
60 | 6.61k | bool region_is_2_bytes = fuzzed_data.ConsumeBool(); |
61 | 6.61k | std::string region = fuzzed_data.ConsumeBytesAsString(region_is_2_bytes ? 2 : 3); |
62 | | |
63 | | // setup fuzzed data for matchers |
64 | 6.61k | i18n::phonenumbers::PhoneNumberMatcher::Leniency leniency = |
65 | 6.61k | ConsumeLeniency(fuzzed_data); |
66 | 6.61k | int max_tries = fuzzed_data.ConsumeIntegralInRange(0, 500); |
67 | 6.61k | bool full_match = fuzzed_data.ConsumeBool(); |
68 | 6.61k | std::string regexp_string = fuzzed_data.ConsumeRandomLengthString(32); |
69 | | |
70 | | |
71 | | // initialize and fuzz the built-in matcher |
72 | 6.61k | i18n::phonenumbers::PhoneNumberMatcher matcher(*phone_util, text, region, |
73 | 6.61k | leniency, max_tries); |
74 | 11.7k | while (matcher.HasNext()) { |
75 | 5.11k | i18n::phonenumbers::PhoneNumberMatch match; |
76 | 5.11k | matcher.Next(&match); |
77 | 5.11k | } |
78 | | |
79 | | // fuzz the matching with the icu adapter |
80 | 6.61k | std::string matched_string; |
81 | 6.61k | i18n::phonenumbers::ICURegExpFactory factory; |
82 | 6.61k | std::unique_ptr<i18n::phonenumbers::RegExp> regexp( |
83 | 6.61k | factory.CreateRegExp(regexp_string)); |
84 | 6.61k | regexp->Match(text, full_match, &matched_string); |
85 | | |
86 | 6.61k | return 0; |
87 | 6.61k | } |