Coverage Report

Created: 2026-02-14 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.75k
    FuzzedDataProvider& fuzzed_data) {
38
6.75k
  switch (fuzzed_data.ConsumeIntegralInRange(0, 3)) {
39
2.34k
    case 0:
40
2.34k
      return i18n::phonenumbers::PhoneNumberMatcher::Leniency::POSSIBLE;
41
1.19k
    case 1:
42
1.19k
      return i18n::phonenumbers::PhoneNumberMatcher::Leniency::VALID;
43
1.59k
    case 2:
44
1.59k
      return i18n::phonenumbers::PhoneNumberMatcher::Leniency::STRICT_GROUPING;
45
1.63k
    default:
46
1.63k
      return i18n::phonenumbers::PhoneNumberMatcher::Leniency::EXACT_GROUPING;
47
6.75k
  }
48
6.75k
}
49
50
6.75k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
51
  // Setup the data provider and util
52
6.75k
  FuzzedDataProvider fuzzed_data(data, size);
53
6.75k
  i18n::phonenumbers::PhoneNumberUtil* phone_util = 
54
6.75k
      i18n::phonenumbers::PhoneNumberUtil::GetInstance();
55
56
  // this should be enought to get at least 2 matches
57
6.75k
  std::string text = fuzzed_data.ConsumeBytesAsString(128);
58
59
  // the region is either 2 or 3 characters long
60
6.75k
  bool region_is_2_bytes = fuzzed_data.ConsumeBool();
61
6.75k
  std::string region = fuzzed_data.ConsumeBytesAsString(region_is_2_bytes ? 2 : 3);
62
63
  // setup fuzzed data for matchers
64
6.75k
  i18n::phonenumbers::PhoneNumberMatcher::Leniency leniency = 
65
6.75k
    ConsumeLeniency(fuzzed_data);
66
6.75k
  int max_tries = fuzzed_data.ConsumeIntegralInRange(0, 500);
67
6.75k
  bool full_match = fuzzed_data.ConsumeBool();
68
6.75k
  std::string regexp_string = fuzzed_data.ConsumeRandomLengthString(32);
69
70
71
  // initialize and fuzz the built-in matcher
72
6.75k
  i18n::phonenumbers::PhoneNumberMatcher matcher(*phone_util, text, region, 
73
6.75k
      leniency, max_tries);
74
11.3k
  while (matcher.HasNext()) {
75
4.60k
    i18n::phonenumbers::PhoneNumberMatch match;
76
4.60k
    matcher.Next(&match);
77
4.60k
  }
78
79
  // fuzz the matching with the icu adapter
80
6.75k
  std::string matched_string;
81
6.75k
  i18n::phonenumbers::ICURegExpFactory factory;
82
6.75k
  std::unique_ptr<i18n::phonenumbers::RegExp> regexp(
83
6.75k
    factory.CreateRegExp(regexp_string));
84
6.75k
  regexp->Match(text, full_match, &matched_string);
85
86
6.75k
  return 0;
87
6.75k
}