Index: third_party/WebKit/Source/bindings/core/v8/serialization/SerializedScriptValueFuzzer.cpp |
diff --git a/third_party/WebKit/Source/bindings/core/v8/serialization/SerializedScriptValueFuzzer.cpp b/third_party/WebKit/Source/bindings/core/v8/serialization/SerializedScriptValueFuzzer.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..814474534d404cf6e5f41067e2ef1a304ce893d1 |
--- /dev/null |
+++ b/third_party/WebKit/Source/bindings/core/v8/serialization/SerializedScriptValueFuzzer.cpp |
@@ -0,0 +1,101 @@ |
+// Copyright 2016 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 "bindings/core/v8/SerializedScriptValue.h" |
+ |
+#include "bindings/core/v8/ScriptState.h" |
+#include "core/dom/MessagePort.h" |
+#include "core/frame/Settings.h" |
+#include "core/testing/DummyPageHolder.h" |
+#include "platform/RuntimeEnabledFeatures.h" |
+#include "platform/testing/BlinkFuzzerTestSupport.h" |
+#include "public/platform/WebBlobInfo.h" |
+#include "public/platform/WebMessagePortChannel.h" |
+#include "wtf/StringHasher.h" |
+ |
+#include <algorithm> |
+#include <cstddef> |
+#include <cstdint> |
+#include <v8.h> |
+ |
+using namespace blink; |
+ |
+namespace { |
+ |
+// Intentionally leaked during fuzzing. |
+// See testing/libfuzzer/efficient_fuzzer.md. |
+DummyPageHolder* pageHolder = nullptr; |
+WebBlobInfoArray* blobInfoArray = nullptr; |
+ |
+enum : uint32_t { |
+ kFuzzMessagePorts = 1 << 0, |
+ kFuzzBlobInfo = 1 << 1, |
+}; |
+ |
+class WebMessagePortChannelImpl final : public WebMessagePortChannel { |
+ public: |
+ // WebMessagePortChannel |
+ void setClient(WebMessagePortChannelClient* client) override {} |
+ void destroy() override { delete this; } |
+ void postMessage(const WebString&, WebMessagePortChannelArray*) { |
+ NOTIMPLEMENTED(); |
+ } |
+ bool tryGetMessage(WebString*, WebMessagePortChannelArray&) { return false; } |
+}; |
+ |
+} // namespace |
+ |
+extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) { |
+ InitializeBlinkFuzzTest(argc, argv); |
+ RuntimeEnabledFeatures::setV8BasedStructuredCloneEnabled(true); |
+ pageHolder = DummyPageHolder::create().release(); |
+ pageHolder->frame().settings()->setScriptEnabled(true); |
+ blobInfoArray = new WebBlobInfoArray(); |
+ blobInfoArray->emplaceAppend("d875dfc2-4505-461b-98fe-0cf6cc5eaf44", |
+ "text/plain", 12); |
+ blobInfoArray->emplaceAppend("d875dfc2-4505-461b-98fe-0cf6cc5eaf44", |
+ "/native/path", "path", "text/plain"); |
esprehn
2016/10/07 22:02:17
what's with the magic hashes? can you add a commen
|
+ return 0; |
+} |
+ |
+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); |
+ |
+ // Clean up. |
+ CHECK(!tryCatch.HasCaught()) |
+ << "deserialize() should return null rather than throwing an exception."; |
+ return 0; |
+} |