@@ -15,34 +15,195 @@ limitations under the License.
1515#include " phonenumbers/phonenumbermatcher.h"
1616#include < string>
1717#include < vector>
18-
18+ # include < limits >
1919#include < unicode/unistr.h>
2020
2121#include " phonenumbers/base/basictypes.h"
2222#include " phonenumbers/base/memory/scoped_ptr.h"
2323#include " phonenumbers/base/memory/singleton.h"
2424#include " phonenumbers/default_logger.h"
2525#include " phonenumbers/phonenumber.h"
26- #include " phonenumbers/phonenumber.pb.h"
2726#include " phonenumbers/phonenumbermatch.h"
2827#include " phonenumbers/phonenumberutil.h"
2928#include " phonenumbers/stringutil.h"
30-
29+ #include " phonenumbers/asyoutypeformatter.h"
30+ #include " phonenumbers/shortnumberinfo.h"
3131#include < fuzzer/FuzzedDataProvider.h>
3232
33- extern " C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size)
34- {
35- FuzzedDataProvider fuzzed_data (data, size);
33+ using google::protobuf::RepeatedPtrField;
34+
35+ // consume PhoneNumberUtil::PhoneNumberType from libfuzzer data
36+ i18n::phonenumbers::PhoneNumberUtil::PhoneNumberType ConsumePhoneNumberType (
37+ FuzzedDataProvider& fuzzed_data) {
38+ switch (fuzzed_data.ConsumeIntegralInRange (0 , 11 )) {
39+ case 0 :
40+ return i18n::phonenumbers::PhoneNumberUtil::FIXED_LINE;
41+ case 1 :
42+ return i18n::phonenumbers::PhoneNumberUtil::MOBILE;
43+ case 2 :
44+ return i18n::phonenumbers::PhoneNumberUtil::FIXED_LINE_OR_MOBILE;
45+ case 3 :
46+ return i18n::phonenumbers::PhoneNumberUtil::TOLL_FREE;
47+ case 4 :
48+ return i18n::phonenumbers::PhoneNumberUtil::PREMIUM_RATE;
49+ case 5 :
50+ return i18n::phonenumbers::PhoneNumberUtil::SHARED_COST;
51+ case 6 :
52+ return i18n::phonenumbers::PhoneNumberUtil::VOIP;
53+ case 7 :
54+ return i18n::phonenumbers::PhoneNumberUtil::PERSONAL_NUMBER;
55+ case 8 :
56+ return i18n::phonenumbers::PhoneNumberUtil::PAGER;
57+ case 9 :
58+ return i18n::phonenumbers::PhoneNumberUtil::UAN;
59+ case 10 :
60+ return i18n::phonenumbers::PhoneNumberUtil::VOICEMAIL;
61+ default :
62+ return i18n::phonenumbers::PhoneNumberUtil::UNKNOWN;
63+ }
64+ }
65+
66+ // consume PhoneNumberUtil::PhoneNumberFormat from libfuzzer data
67+ i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat ConsumePhoneNumberFormat (
68+ FuzzedDataProvider& fuzzed_data) {
69+ switch (fuzzed_data.ConsumeIntegralInRange (0 , 3 )) {
70+ case 0 :
71+ return i18n::phonenumbers::PhoneNumberUtil::E164 ;
72+ case 1 :
73+ return i18n::phonenumbers::PhoneNumberUtil::INTERNATIONAL;
74+ case 2 :
75+ return i18n::phonenumbers::PhoneNumberUtil::NATIONAL;
76+ default :
77+ return i18n::phonenumbers::PhoneNumberUtil::RFC3966;
78+ }
79+ }
80+
81+ extern " C" int LLVMFuzzerTestOneInput (const uint8_t * data, size_t size) {
82+ // initialize the phone util
83+ i18n::phonenumbers::PhoneNumberUtil* phone_util =
84+ i18n::phonenumbers::PhoneNumberUtil::GetInstance ();
85+ FuzzedDataProvider fuzzed_data (data, size);
86+
87+ // initialize the first phone number, region and country calling code
88+ i18n::phonenumbers::PhoneNumber phone_number;
89+ bool region_is_2_bytes = fuzzed_data.ConsumeBool ();
90+ std::string region = fuzzed_data.ConsumeBytesAsString (region_is_2_bytes ? 2 : 3 );
91+ std::string number = fuzzed_data.ConsumeRandomLengthString (32 );
92+ int country_calling_code = fuzzed_data.ConsumeIntegral <int >();
93+
94+ // trigger either one of the public parse methods
95+ if (fuzzed_data.ConsumeBool ()) {
96+ phone_util->ParseAndKeepRawInput (number, region, &phone_number);
97+ } else {
98+ phone_util->Parse (number, region, &phone_number);
99+ }
100+
101+ // initialize the second phone number, this is used only for the
102+ // isNumberMatch* methods
103+ i18n::phonenumbers::PhoneNumber phone_number2;
104+ std::string number2 = fuzzed_data.ConsumeRandomLengthString (32 );
105+ if (fuzzed_data.ConsumeBool ()) {
106+ phone_util->ParseAndKeepRawInput (number2, region, &phone_number2);
107+ } else {
108+ phone_util->Parse (number2, region, &phone_number2);
109+ }
110+
111+ // randomly trigger the truncate method, this may affect state of the input
112+ // for the method calls that follow it
113+ if (fuzzed_data.ConsumeIntegralInRange (0 , 10 ) == 5 ) {
114+ phone_util->TruncateTooLongNumber (&phone_number);
115+ }
116+
117+ // fuzz public methods
118+ phone_util->IsAlphaNumber (number);
119+ phone_util->IsPossibleNumber (phone_number);
120+ phone_util->IsNumberMatch (phone_number, phone_number2);
121+ phone_util->IsNumberMatchWithOneString (phone_number, number2);
122+ phone_util->IsNumberMatchWithTwoStrings (number, number2);
123+ phone_util->CanBeInternationallyDialled (phone_number);
124+ phone_util->GetNumberType (phone_number);
125+ phone_util->GetLengthOfGeographicalAreaCode (phone_number);
126+ phone_util->GetLengthOfNationalDestinationCode (phone_number);
127+ phone_util->IsNANPACountry (region);
128+ phone_util->GetCountryCodeForRegion (region);
129+ phone_util->IsPossibleNumberForString (number, region);
130+ phone_util->IsNumberGeographical (phone_number);
131+ i18n::phonenumbers::PhoneNumberUtil::PhoneNumberType number_type =
132+ ConsumePhoneNumberType (fuzzed_data);
133+ phone_util->IsNumberGeographical (number_type, country_calling_code);
134+ phone_util->IsPossibleNumberForType (phone_number, number_type);
135+
136+ i18n::phonenumbers::PhoneNumber example_number;
137+ phone_util->GetExampleNumberForType (region, number_type, &example_number);
138+
139+ i18n::phonenumbers::PhoneNumber example_number_2;
140+ phone_util->GetExampleNumberForType (number_type, &example_number_2);
141+
142+ i18n::phonenumbers::PhoneNumber invalid_number;
143+ phone_util->GetInvalidExampleNumber (region, &invalid_number);
144+
145+ i18n::phonenumbers::PhoneNumber non_geo_number;
146+ phone_util->GetExampleNumberForNonGeoEntity (country_calling_code, &non_geo_number);
147+
148+ std::string output;
149+ phone_util->GetCountryMobileToken (country_calling_code, &output);
150+ output.clear ();
151+
152+ phone_util->GetRegionCodeForNumber (phone_number, &output);
153+ output.clear ();
154+
155+ phone_util->GetNddPrefixForRegion (region, fuzzed_data.ConsumeBool (), &output);
156+ output.clear ();
157+
158+ // Fuzz the methods which affect the input string, but not the PhoneNumber object
159+ std::string input = fuzzed_data.ConsumeRandomLengthString (32 );
160+ phone_util->ConvertAlphaCharactersInNumber (&input);
161+ input.clear ();
162+
163+ input = fuzzed_data.ConsumeRandomLengthString (32 );
164+ phone_util->NormalizeDigitsOnly (&input);
165+ input.clear ();
166+
167+ input = fuzzed_data.ConsumeRandomLengthString (32 );
168+ phone_util->NormalizeDiallableCharsOnly (&input);
169+ input.clear ();
170+
171+ // Fuzz the formatting methods
172+ i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat format = ConsumePhoneNumberFormat (fuzzed_data);
173+
174+ std::string formatted;
175+ phone_util->Format (phone_number, format, &formatted);
176+ formatted.clear ();
177+
178+ phone_util->FormatInOriginalFormat (phone_number, region, &formatted);
179+ formatted.clear ();
180+
181+ phone_util->FormatNumberForMobileDialing (phone_number, region,
182+ fuzzed_data.ConsumeBool (), &formatted);
183+ formatted.clear ();
184+
185+ phone_util->FormatNationalNumberWithPreferredCarrierCode (phone_number, region, &formatted);
186+ formatted.clear ();
187+
188+ phone_util->FormatOutOfCountryKeepingAlphaChars (phone_number, region, &formatted);
189+ formatted.clear ();
36190
37- std::string input = fuzzed_data.ConsumeRandomLengthString ();
38- std::string input2 = fuzzed_data.ConsumeRandomLengthString ();
191+ std::string carrier = fuzzed_data.ConsumeRandomLengthString (8 );
192+ phone_util->FormatNationalNumberWithCarrierCode (phone_number, carrier, &formatted);
193+ formatted.clear ();
39194
40- i18n::phonenumbers::PhoneNumberUtil *phone_util = i18n::phonenumbers::PhoneNumberUtil::GetInstance ();
41- i18n::phonenumbers::PhoneNumber parsed;
195+ // setup the parameters for FormatByPattern
196+ i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat number_format = ConsumePhoneNumberFormat (fuzzed_data);
197+ RepeatedPtrField<i18n::phonenumbers::NumberFormat> number_formats;
198+ i18n::phonenumbers::NumberFormat* temp_number_format = number_formats.Add ();
199+ std::string pattern = fuzzed_data.ConsumeRandomLengthString (16 );
200+ std::string format_string = fuzzed_data.ConsumeRandomLengthString (16 );
201+ temp_number_format->set_pattern (pattern);
202+ temp_number_format->set_format (format_string);
42203
43- phone_util-> Parse (input, input2, &parsed);
44- phone_util->IsValidNumber (parsed );
45- phone_util-> GetCountryCodeForRegion (input );
204+ // fuzz FormatByPattern
205+ phone_util->FormatByPattern (phone_number, number_format, number_formats, &formatted );
206+ formatted. clear ( );
46207
47- return 0 ;
208+ return 0 ;
48209}
0 commit comments