Index: third_party/qcms/qcms_color_space_fuzzer.cc |
diff --git a/third_party/qcms/qcms_color_space_fuzzer.cc b/third_party/qcms/qcms_color_space_fuzzer.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c14b170d2e71a61d67f48f3cb5840c0e91b02c3b |
--- /dev/null |
+++ b/third_party/qcms/qcms_color_space_fuzzer.cc |
@@ -0,0 +1,84 @@ |
+// Copyright 2017 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 <cstddef> |
+#include <cstdint> |
+#include <random> |
+ |
+#include "base/logging.h" |
+#include "base/strings/string_piece.h" |
+#include "testing/libfuzzer/fuzzers/color_space_data.h" |
+#include "third_party/qcms/src/qcms.h" |
+ |
+static constexpr size_t kPixels = 2048 / 4; |
+ |
+static uint32_t pixels[kPixels]; |
+ |
+static void GeneratePixels(size_t hash) { |
+ static std::uniform_int_distribution<uint32_t> uniform(0u, ~0u); |
+ |
+ std::mt19937_64 random(hash); |
+ for (size_t i = 0; i < arraysize(pixels); ++i) |
+ pixels[i] = uniform(random); |
+} |
+ |
+static qcms_profile* test; |
+static qcms_profile* srgb; |
+ |
+static void ColorTransform(bool input) { |
+ if (!test) |
+ return; |
+ |
+ const qcms_intent intent = QCMS_INTENT_DEFAULT; |
+ const qcms_data_type format = QCMS_DATA_RGBA_8; |
+ |
+ auto transform = |
dcheng
2017/04/12 07:19:23
Nit: auto*
Noel Gordon
2017/04/12 12:09:47
Done.
|
+ input ? qcms_transform_create(test, format, srgb, format, intent) |
+ : qcms_transform_create(srgb, format, test, format, intent); |
+ if (!transform) |
+ return; |
+ |
+ static uint32_t output[kPixels]; |
+ |
+ qcms_transform_data(transform, pixels, output, kPixels); |
+ qcms_transform_release(transform); |
+} |
+ |
+static qcms_profile* SelectProfile(size_t hash) { |
+ static qcms_profile* profiles[4] = { |
+ qcms_profile_from_memory(kSRGBData, arraysize(kSRGBData)), |
+ qcms_profile_from_memory(kSRGBPara, arraysize(kSRGBPara)), |
+ qcms_profile_from_memory(kAdobeData, arraysize(kAdobeData)), |
+ qcms_profile_sRGB(), |
+ }; |
+ |
+ return profiles[hash & 3]; |
+} |
+ |
+inline size_t Hash(const char* data, size_t size) { |
+ return base::StringPieceHash()(base::StringPiece(data, size)); |
+} |
+ |
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
+ constexpr size_t kSizeLimit = 4 * 1024 * 1024; |
+ if (size < 128 || size > kSizeLimit) |
+ return 0; |
+ |
+ test = qcms_profile_from_memory(data, size); |
+ if (!test) |
+ return 0; |
+ |
+ const size_t hash = Hash(reinterpret_cast<const char*>(data), size); |
dcheng
2017/04/12 07:19:23
How about just running this through base::SHA1Hash
Noel Gordon
2017/04/12 12:09:47
Too slow: need a good and fast hash.
dcheng
2017/04/12 20:21:10
Hmm... how about just use one byte of the test inp
|
+ srgb = SelectProfile(hash); |
+ GeneratePixels(hash); |
+ |
+ qcms_profile_precache_output_transform(srgb); |
+ ColorTransform(true); |
+ |
+ qcms_profile_precache_output_transform(test); |
+ ColorTransform(false); |
+ |
+ qcms_profile_release(test); |
+ return 0; |
+} |