/src/mozilla-central/gfx/qcms/fuzztest/qcms_fuzzer.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #ifdef BUILD_FOR_OSSFUZZ |
8 | | #define TESTFUNC_TYPE extern "C" int |
9 | | #define MOZ_FUZZING_INTERFACE_RAW(initFunc, testFunc, moduleName) |
10 | | #else |
11 | | #include "FuzzingInterface.h" |
12 | | #define TESTFUNC_TYPE static int |
13 | | #endif |
14 | | |
15 | | #include <stdint.h> |
16 | | #include <stdlib.h> |
17 | | |
18 | | #include "qcms.h" |
19 | | |
20 | | static void |
21 | | transform(qcms_profile* src_profile, qcms_profile* dst_profile, size_t size) |
22 | 0 | { |
23 | 0 | // qcms supports GRAY and RGB profiles as input, and RGB as output. |
24 | 0 |
|
25 | 0 | uint32_t src_color_space = qcms_profile_get_color_space(src_profile); |
26 | 0 | qcms_data_type src_type = size & 1 ? QCMS_DATA_RGBA_8 : QCMS_DATA_RGB_8; |
27 | 0 | if (src_color_space == icSigGrayData) { |
28 | 0 | src_type = size & 1 ? QCMS_DATA_GRAYA_8 : QCMS_DATA_GRAY_8; |
29 | 0 | } else if (src_color_space != icSigRgbData) { |
30 | 0 | return; |
31 | 0 | } |
32 | 0 | |
33 | 0 | uint32_t dst_color_space = qcms_profile_get_color_space(dst_profile); |
34 | 0 | if (dst_color_space != icSigRgbData) { |
35 | 0 | return; |
36 | 0 | } |
37 | 0 | qcms_data_type dst_type = size & 2 ? QCMS_DATA_RGBA_8 : QCMS_DATA_RGB_8; |
38 | 0 |
|
39 | 0 | qcms_intent intent = qcms_profile_get_rendering_intent(src_profile); |
40 | 0 | // Firefox calls this on the display profile to increase performance. |
41 | 0 | // Skip with low probability to increase coverage. |
42 | 0 | if (size % 0x10) { |
43 | 0 | qcms_profile_precache_output_transform(dst_profile); |
44 | 0 | } |
45 | 0 |
|
46 | 0 | qcms_transform* transform = |
47 | 0 | qcms_transform_create(src_profile, src_type, dst_profile, dst_type, intent); |
48 | 0 | if (!transform) { |
49 | 0 | return; |
50 | 0 | } |
51 | 0 | |
52 | 0 | static uint8_t src[] = { |
53 | 0 | 0x7F, 0x7F, 0x7F, 0x00, 0x00, 0x7F, 0x7F, 0xFF, 0x7F, 0x10, 0x20, 0x30, |
54 | 0 | }; |
55 | 0 | static uint8_t dst[sizeof(src) * 4]; // 4x in case of GRAY to RGBA |
56 | 0 |
|
57 | 0 | int src_bytes_per_pixel = 4; // QCMS_DATA_RGBA_8 |
58 | 0 | if (src_type == QCMS_DATA_RGB_8) { |
59 | 0 | src_bytes_per_pixel = 3; |
60 | 0 | } else if (src_type == QCMS_DATA_GRAYA_8) { |
61 | 0 | src_bytes_per_pixel = 2; |
62 | 0 | } else if (src_type == QCMS_DATA_GRAY_8) { |
63 | 0 | src_bytes_per_pixel = 1; |
64 | 0 | } |
65 | 0 |
|
66 | 0 | qcms_transform_data(transform, src, dst, sizeof(src) / src_bytes_per_pixel); |
67 | 0 | qcms_transform_release(transform); |
68 | 0 | } |
69 | | |
70 | | TESTFUNC_TYPE |
71 | | LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) |
72 | 0 | { |
73 | 0 | qcms_enable_iccv4(); |
74 | 0 |
|
75 | 0 | qcms_profile* profile = qcms_profile_from_memory(data, size); |
76 | 0 | if (!profile) { |
77 | 0 | return 0; |
78 | 0 | } |
79 | 0 | |
80 | 0 | qcms_profile* srgb_profile = qcms_profile_sRGB(); |
81 | 0 | if (!srgb_profile) { |
82 | 0 | qcms_profile_release(profile); |
83 | 0 | return 0; |
84 | 0 | } |
85 | 0 | |
86 | 0 | transform(profile, srgb_profile, size); |
87 | 0 |
|
88 | 0 | // Firefox only checks the display (destination) profile. |
89 | 0 | if (qcms_profile_is_bogus(profile)) { |
90 | 0 | goto release_profiles; |
91 | 0 | }; |
92 | 0 |
|
93 | 0 | transform(srgb_profile, profile, size); |
94 | 0 |
|
95 | 0 | release_profiles: |
96 | 0 | qcms_profile_release(profile); |
97 | 0 | qcms_profile_release(srgb_profile); |
98 | 0 |
|
99 | 0 | return 0; |
100 | 0 | } |
101 | | |
102 | | MOZ_FUZZING_INTERFACE_RAW(nullptr, LLVMFuzzerTestOneInput, Qcms); |