Coverage Report

Created: 2025-11-16 06:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}