Index: testing/libfuzzer/fuzzers/skia_color_space_fuzzer.cc |
diff --git a/testing/libfuzzer/fuzzers/skia_color_space_fuzzer.cc b/testing/libfuzzer/fuzzers/skia_color_space_fuzzer.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..3385d4eabfe20c1154094c48888b5443a815dcf1 |
--- /dev/null |
+++ b/testing/libfuzzer/fuzzers/skia_color_space_fuzzer.cc |
@@ -0,0 +1,100 @@ |
+// 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 <stddef.h> |
+#include <stdint.h> |
+ |
+#include "base/logging.h" |
+#include "base/macros.h" |
+#include "testing/libfuzzer/fuzzers/color_space_data.h" |
+#include "third_party/skia/include/core/SkColorSpace.h" |
+#include "third_party/skia/include/core/SkColorSpaceXform.h" |
+ |
+static constexpr unsigned kPixels = 2048 / 4; |
+ |
+static const char* RandomSource() { |
+ DCHECK_LT(kPixels * 4, arraysize(srgb_data)); |
+ // Use srgb_data as a source of kPixels * 4 read-only random data bytes. |
+ return srgb_data + arraysize(srgb_data) - kPixels * 4; |
+} |
+ |
+static sk_sp<SkColorSpace> test; |
+static sk_sp<SkColorSpace> srgb; |
+ |
+static void ColorTransform(size_t size, bool input) { |
+ DCHECK(test.get()); |
+ |
+ auto transform = input ? SkColorSpaceXform::New(test.get(), srgb.get()) |
+ : SkColorSpaceXform::New(srgb.get(), test.get()); |
+ if (!transform) |
+ return; |
+ |
+ uint32_t data[kPixels * 4]; |
Noel Gordon
2017/04/04 12:23:16
This is a fine source of random pixel data, and co
mmoroz
2017/04/04 13:43:06
I'm afraid that we cannot rely on this approach be
Noel Gordon
2017/04/05 14:14:07
IC, we can fix that ...
mmoroz
2017/04/06 08:26:37
Right, but something like:
if (size < 4 * kPixels)
|
+ if ((size & 7) == 7) |
+ memcpy(data, RandomSource(), kPixels * 4); |
+ |
+ const auto color = SkColorSpaceXform::ColorFormat(size & 7); |
+ const auto alpha = SkAlphaType(size & 3); |
+ |
+ transform->apply(color, data, color, data, kPixels, alpha); |
+} |
+ |
+template <typename T> |
+static T* FuzzyPointer(const uint8_t* data, size_t size) { |
+ constexpr size_t kAddress = 256; |
+ if (size < kAddress + sizeof(T) + 64) { |
+ static T object; |
+ return &object; |
+ } else { |
+ uintptr_t address = (uintptr_t)&data[kAddress]; |
+ return (T*)(address & ~31); // 32-bit aligned. |
mmoroz
2017/04/04 13:43:06
Coudl you please use c++ cast here?
Noel Gordon
2017/04/05 14:14:07
Removed all this.
|
+ } |
+} |
+ |
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
+ constexpr size_t kSizeLimit = 4 * 1024 * 1024; |
mmoroz
2017/04/04 13:43:06
As a follow-up to comment on line #33, |kSizeLimit
Noel Gordon
2017/04/05 14:14:08
The new "random" pixel generator is independent of
|
+ if (size > kSizeLimit) |
+ return 0; |
+ |
+ test = SkColorSpace::MakeICC(data, size); |
mmoroz
2017/04/04 13:43:06
As first |4 * kPixels| bytes of |data| will be use
Noel Gordon
2017/04/05 14:14:07
With the new design, I'm not sure any of this appl
mmoroz
2017/04/06 08:31:26
If the target creates internal structures with the
|
+ if (!test) |
+ return 0; |
+ |
+ switch (size & 7) { // Create profile to transform pixels to/from. |
mmoroz
2017/04/04 13:43:07
Nice trick, but it would be better to avoid relyin
Noel Gordon
2017/04/05 14:14:07
Not some a trick. The distribution of size & 7 ten
mmoroz
2017/04/06 08:26:37
The distribution of size & 7 doesn't matter becaus
|
+ case 0: |
+ srgb = SkColorSpace::MakeICC(adobe_data, arraysize(adobe_data)); |
+ break; |
+ case 1: |
+ srgb = SkColorSpace::MakeICC(srgb_para, arraysize(srgb_para)); |
+ break; |
+ case 2: |
+ srgb = SkColorSpace::MakeSRGBLinear(); |
+ break; |
+ case 3: |
+ srgb = SkColorSpace::MakeRGB( |
+ *FuzzyPointer<SkColorSpaceTransferFn>(data, size), |
+ SkColorSpace::Gamut::kAdobeRGB_Gamut); |
+ break; |
+ case 4: |
+ srgb = SkColorSpace::MakeRGB( |
+ SkColorSpace::RenderTargetGamma::kSRGB_RenderTargetGamma, |
+ *FuzzyPointer<SkMatrix44>(data, size)); |
+ break; |
+ case 5: |
+ srgb = SkColorSpace::MakeRGB( |
+ SkColorSpace::RenderTargetGamma::kSRGB_RenderTargetGamma, |
+ SkColorSpace::Gamut::kDCIP3_D65_Gamut); |
+ break; |
+ default: |
+ srgb = SkColorSpace::MakeICC(srgb_data, arraysize(srgb_data)); |
+ break; |
+ } |
+ |
+ ColorTransform(size, true); |
+ ColorTransform(size, false); |
+ |
+ test.reset(); |
+ srgb.reset(); |
+ return 0; |
+} |