blob: 7d5ee25257687cc4a0047b95a1b4bf8684b517e8 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <objbase.h>
#include "build/build_config.h"
#include "content/public/browser/tts_platform.h"
namespace content {
// Entry point for LibFuzzer.
extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size) {
int utterance_id = 0;
std::string utterance;
std::string lang;
VoiceData voice;
UtteranceContinuousParameters params;
params.pitch = 1.0;
params.rate = 1.0;
params.volume = 0.1;
#if defined(OS_WIN)
static bool initialized = false;
if (!initialized) {
initialized = true;
CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
}
#endif
// First byte gives us the utterance ID.
size_t i = 0;
if (i < size)
utterance_id = data[i++];
// Decide whether we want to fuzz the language, rate, pitch,
// voice name, and all that. Half the time we'll just leave
// those empty and fuzz only the utterance, otherwise it's
// possible the fuzzer would never spend any effort fuzzing
// utteranes.
if (i < size && (data[i++] % 2 == 0)) {
// The next few bytes determine the language. Ensure that
// we frequently get some common real languages but allow
// arbitrary strings up to 10 characters.
if (i < size) {
int lang_choice = data[i++];
switch (lang_choice) {
case 0:
lang = "";
break;
case 1:
lang = "en";
break;
case 2:
lang = "fr";
break;
case 3:
lang = "es";
break;
default:
int lang_len = 1 + (lang_choice - 4) % 10;
for (int j = 0; j < lang_len; j++) {
if (i < size)
lang.append(1, data[i++]);
}
}
}
// Set native_voice_identifier
if (i < size) {
int voice_len = data[i++] % 10;
for (int j = 0; j < voice_len; j++) {
if (i < size)
voice.native_voice_identifier.append(1, data[i++]);
}
}
// Set rate, pitch.
if (i + 4 <= size) {
params.rate = *reinterpret_cast<const float*>(&data[i]);
i += 4;
}
if (i + 4 <= size) {
params.pitch = *reinterpret_cast<const float*>(&data[i]);
i += 4;
}
}
// The rest of the data becomes the utterance.
while (i < size)
utterance.append(1, data[i++]);
TtsPlatform* tts = TtsPlatform::GetInstance();
CHECK(tts->PlatformImplAvailable());
VLOG(1) << "id=" << utterance_id << " lang='" << lang << "'"
<< " voice='" << voice.native_voice_identifier << "'"
<< " pitch=" << params.pitch << " rate=" << params.rate
<< " volume=" << params.volume << " utterance='" << utterance << "'";
tts->StopSpeaking();
tts->Speak(utterance_id, utterance, lang, voice, params);
return 0;
}
} // namespace content