File: locale_morph_fuzzer.cpp

package info (click to toggle)
icu 76.1-4
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 121,296 kB
  • sloc: cpp: 522,712; ansic: 113,387; sh: 4,983; makefile: 4,709; perl: 3,198; python: 2,847; xml: 2,652; sed: 36; lisp: 12
file content (109 lines) | stat: -rw-r--r-- 3,580 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// © 2019 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html

// Fuzzer for ICU Locales.

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <set>
#include <string>
#include <vector>

#include "unicode/locid.h"
#include "unicode/localpointer.h"
#include "unicode/stringpiece.h"

#include "locale_util.h"

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
    if (size < 1) return 0;
    icu::StringPiece fuzzData(reinterpret_cast<const char *>(data), size);
    uint8_t rnd = *fuzzData.data();
    fuzzData.remove_prefix(1);
    const std::string input = MakeZeroTerminatedInput(
        (const uint8_t*)(fuzzData.data()), fuzzData.length());

    icu::Locale locale(input.c_str());
    UErrorCode status = U_ZERO_ERROR;
    switch(rnd % 8) {
        case 0:
            locale.addLikelySubtags(status);
            break;
        case 1:
            locale.minimizeSubtags(status);
            break;
        case 2:
            locale.canonicalize(status);
            break;
        case 3:
            {
                icu::LocalPointer<icu::StringEnumeration> senum(
                    locale.createKeywords(status), status);
                while (U_SUCCESS(status) &&
                       (senum->next(nullptr, status)) != nullptr) {
                    // noop
                }
            }
            break;
        case 4:
            {
                icu::LocalPointer<icu::StringEnumeration> senum(
                    locale.createUnicodeKeywords(status), status);
                while (U_SUCCESS(status) &&
                       (senum->next(nullptr, status)) != nullptr) {
                    // noop
                }
            }
            break;
        case 5:
            {
                char buf[256];
                icu::CheckedArrayByteSink sink(buf, rnd);
                locale.toLanguageTag(sink, status);
            }
            break;
        case 6:
            {
                std::set<std::string> keys;
                locale.getKeywords<std::string>(
                    std::insert_iterator<decltype(keys)>(keys, keys.begin()),
                    status);
                if (U_SUCCESS(status)) {
                    char buf[256];
                    icu::CheckedArrayByteSink sink(buf, rnd);
                    for (std::set<std::string>::iterator it=keys.begin();
                         it!=keys.end();
                         ++it) {
                        locale.getKeywordValue(
                            icu::StringPiece(it->c_str(), it->length()), sink,
                            status);
                    }
                }
            }
            break;
        case 7:
            {
                std::set<std::string> keys;
                locale.getUnicodeKeywords<std::string>(
                    std::insert_iterator<decltype(keys)>(keys, keys.begin()),
                    status);
                if (U_SUCCESS(status)) {
                    char buf[256];
                    icu::CheckedArrayByteSink sink(buf, rnd);
                    for (std::set<std::string>::iterator it=keys.begin();
                         it!=keys.end();
                         ++it) {
                        locale.getUnicodeKeywordValue(
                            icu::StringPiece(it->c_str(), it->length()), sink,
                            status);
                    }
                }
            }
            break;
        default:
          break;
    }
    return EXIT_SUCCESS;
}