Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2020 Google Inc. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | #include <cstddef> |
16 | | #include <cstdint> |
17 | | |
18 | | #include <opencv2/opencv.hpp> |
19 | | #include <fuzzer/FuzzedDataProvider.h> |
20 | | |
21 | | namespace { |
22 | | |
23 | | bool GetCVImage(const std::string& image_string, const int max_pixels, |
24 | 3.56k | cv::Mat* original_image) { |
25 | 3.56k | if (image_string.empty()) return false; |
26 | 3.56k | std::vector<uchar> raw_data(image_string.size()); |
27 | 3.56k | const char* ptr = image_string.data(); |
28 | 3.56k | std::copy(ptr, ptr + image_string.size(), raw_data.data()); |
29 | 3.56k | try { |
30 | 3.56k | *original_image = cv::imdecode(raw_data, cv::IMREAD_UNCHANGED); |
31 | 3.56k | } catch (cv::Exception e) {} |
32 | 3.56k | return !original_image->empty(); |
33 | 3.56k | } |
34 | | |
35 | 0 | void TestExternalMethods(const cv::Mat& mat) { |
36 | 0 | try{ |
37 | 0 | cv::sum(mat); |
38 | 0 | } catch (cv::Exception e) {} |
39 | 0 | try { |
40 | 0 | cv::mean(mat); |
41 | 0 | } catch (cv::Exception e) {} |
42 | 0 | try { |
43 | 0 | cv::trace(mat); |
44 | 0 | } catch (cv::Exception e) {} |
45 | 0 | } |
46 | | |
47 | 3.56k | void TestInternalMethods(const cv::Mat& mat) { |
48 | 3.56k | try { |
49 | 3.56k | mat.t(); |
50 | 3.56k | } catch (cv::Exception e) {} |
51 | 3.56k | try { |
52 | 3.56k | mat.inv(); |
53 | 3.56k | } catch (cv::Exception e) {} |
54 | 3.56k | try { |
55 | 3.56k | mat.diag(); |
56 | 3.56k | } catch (cv::Exception e) {} |
57 | 3.56k | } |
58 | | |
59 | 3.56k | void TestSplitAndMerge(const cv::Mat& image) { |
60 | 3.56k | std::vector<cv::Mat> split_image(image.channels()); |
61 | 3.56k | cv::split(image, split_image); |
62 | 3.56k | if (!split_image.empty()) { |
63 | 3.56k | cv::Mat new_image; |
64 | 3.56k | cv::merge(split_image, new_image); |
65 | 3.56k | } |
66 | 3.56k | } |
67 | | |
68 | | } // namespace |
69 | | |
70 | 3.56k | extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
71 | | // Prepares a backup image we will use if we cannot successfully get an image |
72 | | // by decoding the string. |
73 | 3.56k | std::vector<uint8_t> image_data = {data, data + size}; |
74 | 3.56k | cv::Mat backup_image = |
75 | 3.56k | cv::Mat(1, image_data.size(), CV_8UC1, image_data.data()); |
76 | | |
77 | 3.56k | FuzzedDataProvider fuzzed_data_provider(data, size); |
78 | 3.56k | const int max_pixels = fuzzed_data_provider.ConsumeIntegral<int>(); |
79 | 3.56k | const std::string image_string = |
80 | 3.56k | fuzzed_data_provider.ConsumeRemainingBytesAsString(); |
81 | 3.56k | cv::Mat original_image; |
82 | | // Tests the clone method. |
83 | 3.56k | cv::Mat cloned_image = GetCVImage(image_string, max_pixels, &original_image) |
84 | 3.56k | ? original_image.clone() |
85 | 3.56k | : backup_image.clone(); |
86 | | |
87 | | // TODO: enabling the following crashes right away. |
88 | | // TestExternalMethods(cloned_image); |
89 | 3.56k | TestInternalMethods(cloned_image); |
90 | 3.56k | TestSplitAndMerge(cloned_image); |
91 | 3.56k | return 0; |
92 | 3.56k | } |