blob: a4313919eb75e877b50c22fcc165eb24427a9f3c [file] [log] [blame]
#include <fuzzer/FuzzedDataProvider.h>
#include <array>
#include <string>
#include "base/commandlineflags.h"
#include "devtools/build/runtime/get_runfiles_dir.h"
#include "third_party/absl/strings/str_cat.h"
#include "third_party/absl/strings/string_view.h"
#include "third_party/hunspell/src/hunspell/hunspell.hxx"
DEFINE_string(hunspell_dicts_dir,
"_dictionaries/unsorted",
"Directory containing the dictionary for the specified language");
// Note: moved English first to make the conversion of existing crash samples
// easier.
static const char *kLanguages[] = {
"en", "af", "an", "ar", "bg", "ca", "cs", "da", "de", "el", "eo",
"es", "et", "eu", "fa", "fi", "fo", "fr", "ga", "gd", "gl", "gv",
"he", "hr", "hu", "hy", "it", "kk", "ko", "ku", "lt", "lv", "ml",
"nb", "ne", "nl", "nn", "no", "pl", "pt", "ro", "ru", "se", "sh",
"sk", "sl", "sr", "sv", "sw", "th", "tl", "uz", "vi"};
static Hunspell *CreateHunspell(absl::string_view language) {
std::string common_path =
absl::StrCat(devtools_build::GetRunfilesDir(), "/",
FLAGS_hunspell_dicts_dir, "/", language);
std::string affix_filepath(common_path + ".aff");
std::string dic_filepath(common_path + ".dic");
fprintf(stderr, "Hunspell(%s,%s)\n", affix_filepath.c_str(),
dic_filepath.c_str());
return new Hunspell(affix_filepath.c_str(), dic_filepath.c_str());
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
FuzzedDataProvider fdp(data, size);
static Hunspell *hunspell = CreateHunspell(fdp.PickValueInArray(kLanguages));
std::string s = fdp.ConsumeRemainingBytesAsString();
hunspell->spell(s.c_str());
// Search suggestions
char **suggestions = nullptr;
int suggestions_len = hunspell->suggest(&suggestions, s.c_str());
hunspell->free_list(&suggestions, suggestions_len);
// Morphological analysis
char **results = nullptr;
suggestions_len = hunspell->analyze(&suggestions, s.c_str());
int results_len = hunspell->stem(&results, suggestions, suggestions_len);
hunspell->free_list(&suggestions, suggestions_len);
hunspell->free_list(&results, results_len);
return 0;
}