extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Odd sizes are handled in various ways, depending how they arrive. // Let's not worry about that case here. if (size % sizeof(UChar)) return 0; // Used to control what kind of extra data is provided to the deserializer. unsigned hash = StringHasher::hashMemory(data, size); // If message ports are requested, make some. MessagePortArray* messagePorts = nullptr; if (hash & kFuzzMessagePorts) { messagePorts = new MessagePortArray(3); std::generate(messagePorts->begin(), messagePorts->end(), []() { WebMessagePortChannelUniquePtr channel(new WebMessagePortChannelImpl()); MessagePort* port = MessagePort::create(pageHolder->document()); port->entangle(std::move(channel)); return port; }); } // If blobs are requested, supply blob info. const auto* blobs = (hash & kFuzzBlobInfo) ? blobInfoArray : nullptr; // Set up. ScriptState* scriptState = ScriptState::forMainWorld(&pageHolder->frame()); v8::Isolate* isolate = scriptState->isolate(); ScriptState::Scope scope(scriptState); v8::TryCatch tryCatch(isolate); // Deserialize. RefPtr<SerializedScriptValue> serializedScriptValue = SerializedScriptValue::create(reinterpret_cast<const char*>(data), size); serializedScriptValue->deserialize(isolate, messagePorts, blobs); CHECK(!tryCatch.HasCaught()) << "deserialize() should return null rather than throwing an exception."; // Clean up. We have to periodically run pending tasks so that scheduled // Oilpan GC occurs. static int iterations = 0; if (iterations++ == 2048) { testing::runPendingTasks(); iterations = 0; } return 0; }