• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 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 ////////////////////////////////////////////////////////////////////////////////
16 
17 // Fuzzing of libwebp's image readers
18 
19 #include <cstddef>
20 #include <cstdint>
21 #include <cstdlib>
22 #include <iostream>
23 #include <string_view>
24 
25 #include "imageio/image_dec.h"
26 #include "imageio/metadata.h"
27 #include "src/webp/encode.h"
28 #include "tests/fuzzer/fuzz_utils.h"
29 
30 namespace {
31 
TestReader(const uint8_t * data,size_t size,WebPImageReader reader,bool keep_alpha,bool use_argb)32 void TestReader(const uint8_t *data, size_t size, WebPImageReader reader,
33                 bool keep_alpha, bool use_argb) {
34   WebPPicture pic;
35   if (!WebPPictureInit(&pic)) {
36     std::cerr << "WebPPictureInit failed" << std::endl;
37     abort();
38   }
39   Metadata metadata;
40   MetadataInit(&metadata);
41   pic.use_argb = use_argb ? 1 : 0;
42 
43   if (!fuzz_utils::IsImageTooBig(data, size)) {
44     (void)(*reader)(data, size, &pic, keep_alpha ? 1 : 0, &metadata);
45   }
46   WebPPictureFree(&pic);
47   MetadataFree(&metadata);
48 }
49 
50 constexpr WebPInputFileFormat kUnknown = WEBP_UNSUPPORTED_FORMAT;
51 
Decode(std::string_view arbitrary_bytes,WebPInputFileFormat format,bool keep_alpha,bool use_argb)52 void Decode(std::string_view arbitrary_bytes, WebPInputFileFormat format,
53             bool keep_alpha, bool use_argb) {
54   const uint8_t *data =
55       reinterpret_cast<const uint8_t *>(arbitrary_bytes.data());
56   const size_t size = arbitrary_bytes.size();
57   if (format == kUnknown) {
58     (void)WebPGuessImageType(data, size);  // shouldn't fail
59     TestReader(data, size, WebPGuessImageReader(data, size), keep_alpha,
60                use_argb);
61   } else {
62     TestReader(data, size, WebPGetImageReader(format), keep_alpha, use_argb);
63   }
64 }
65 
66 FUZZ_TEST(ImageIOSuite, Decode)
67     .WithDomains(
68         fuzztest::String()
69             .WithMaxSize(fuzz_utils::kMaxWebPFileSize + 1),
70         fuzztest::ElementOf<WebPInputFileFormat>(
71             {WEBP_PNG_FORMAT, WEBP_JPEG_FORMAT, WEBP_TIFF_FORMAT,
72              WEBP_WEBP_FORMAT, WEBP_PNM_FORMAT, kUnknown}),
73         /*keep_alpha=*/fuzztest::Arbitrary<bool>(),
74         /*use_argb=*/fuzztest::Arbitrary<bool>());
75 
76 }  // namespace
77