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