• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GetCVImage(const std::string & image_string,const int max_pixels,cv::Mat * original_image)23 bool GetCVImage(const std::string& image_string, const int max_pixels,
24                 cv::Mat* original_image) {
25   if (image_string.empty()) return false;
26   std::vector<uchar> raw_data(image_string.size());
27   const char* ptr = image_string.data();
28   std::copy(ptr, ptr + image_string.size(), raw_data.data());
29   try {
30     *original_image = cv::imdecode(raw_data, cv::IMREAD_UNCHANGED);
31   } catch (cv::Exception e) {}
32   return !original_image->empty();
33 }
34 
TestExternalMethods(const cv::Mat & mat)35 void TestExternalMethods(const cv::Mat& mat) {
36   try{
37     cv::sum(mat);
38   } catch (cv::Exception e) {}
39   try {
40     cv::mean(mat);
41   } catch (cv::Exception e) {}
42   try {
43     cv::trace(mat);
44   } catch (cv::Exception e) {}
45 }
46 
TestInternalMethods(const cv::Mat & mat)47 void TestInternalMethods(const cv::Mat& mat) {
48   try {
49     mat.t();
50   } catch (cv::Exception e) {}
51   try {
52     mat.inv();
53   } catch (cv::Exception e) {}
54   try {
55     mat.diag();
56   } catch (cv::Exception e) {}
57 }
58 
TestSplitAndMerge(const cv::Mat & image)59 void TestSplitAndMerge(const cv::Mat& image) {
60   std::vector<cv::Mat> split_image(image.channels());
61   cv::split(image, split_image);
62   if (!split_image.empty()) {
63     cv::Mat new_image;
64     cv::merge(split_image, new_image);
65   }
66 }
67 
68 }  // namespace
69 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)70 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   std::vector<uint8_t> image_data = {data, data + size};
74   cv::Mat backup_image =
75       cv::Mat(1, image_data.size(), CV_8UC1, image_data.data());
76 
77   FuzzedDataProvider fuzzed_data_provider(data, size);
78   const int max_pixels = fuzzed_data_provider.ConsumeIntegral<int>();
79   const std::string image_string =
80       fuzzed_data_provider.ConsumeRemainingBytesAsString();
81   cv::Mat original_image;
82   // Tests the clone method.
83   cv::Mat cloned_image = GetCVImage(image_string, max_pixels, &original_image)
84                              ? original_image.clone()
85                              : backup_image.clone();
86 
87   // TODO: enabling the following crashes right away.
88   // TestExternalMethods(cloned_image);
89   TestInternalMethods(cloned_image);
90   TestSplitAndMerge(cloned_image);
91   return 0;
92 }
93