Coverage Report

Created: 2026-08-14 06:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wuffs/fuzz/c/fuzzlib/fuzzlib_image_decoder.c
Line
Count
Source
1
// Copyright 2020 The Wuffs Authors.
2
//
3
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6
// option. This file may not be copied, modified, or distributed
7
// except according to those terms.
8
//
9
// SPDX-License-Identifier: Apache-2.0 OR MIT
10
11
#ifndef WUFFS_INCLUDE_GUARD
12
#error "Wuffs' .h files need to be included before this file"
13
#endif
14
15
static const char*  //
16
fuzz_image_decoder(wuffs_base__io_buffer* src,
17
                   uint64_t hash,
18
21.3k
                   wuffs_base__image_decoder* dec) {
19
21.3k
  const char* ret = NULL;
20
21.3k
  wuffs_base__slice_u8 pixbuf = ((wuffs_base__slice_u8){});
21
21.3k
  wuffs_base__slice_u8 workbuf = ((wuffs_base__slice_u8){});
22
23
  // Use a {} code block so that "goto exit" doesn't trigger "jump bypasses
24
  // variable initialization" warnings.
25
21.3k
  {
26
21.3k
    wuffs_base__image_config ic = ((wuffs_base__image_config){});
27
21.3k
    wuffs_base__status status =
28
21.3k
        wuffs_base__image_decoder__decode_image_config(dec, &ic, src);
29
21.3k
    if (!wuffs_base__status__is_ok(&status)) {
30
5.85k
      ret = wuffs_base__status__message(&status);
31
5.85k
      goto exit;
32
5.85k
    }
33
15.5k
    if (!wuffs_base__image_config__is_valid(&ic)) {
34
0
      ret = "invalid image_config";
35
0
      goto exit;
36
0
    }
37
38
    // 50% of the time, choose BGRA_PREMUL instead of the native pixel config.
39
15.5k
    if (hash & 1) {
40
8.52k
      wuffs_base__pixel_config__set(
41
8.52k
          &ic.pixcfg, WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL,
42
8.52k
          WUFFS_BASE__PIXEL_SUBSAMPLING__NONE,
43
8.52k
          wuffs_base__pixel_config__width(&ic.pixcfg),
44
8.52k
          wuffs_base__pixel_config__height(&ic.pixcfg));
45
8.52k
    }
46
15.5k
    hash >>= 1;
47
48
    // Wuffs allows either statically or dynamically allocated work buffers.
49
    // This program exercises dynamic allocation.
50
15.5k
    uint64_t n = wuffs_base__image_decoder__workbuf_len(dec).max_incl;
51
15.5k
    if (n > 64 * 1024 * 1024) {  // Don't allocate more than 64 MiB.
52
77
      ret = "image too large";
53
77
      goto exit;
54
77
    }
55
15.4k
    if (n > 0) {
56
11.1k
      workbuf = wuffs_base__malloc_slice_u8(malloc, n);
57
11.1k
      if (!workbuf.ptr) {
58
0
        ret = "out of memory";
59
0
        goto exit;
60
0
      }
61
11.1k
    }
62
63
15.4k
    n = wuffs_base__pixel_config__pixbuf_len(&ic.pixcfg);
64
15.4k
    if (n > 64 * 1024 * 1024) {  // Don't allocate more than 64 MiB.
65
137
      ret = "image too large";
66
137
      goto exit;
67
137
    }
68
15.2k
    if (n > 0) {
69
15.0k
      pixbuf = wuffs_base__malloc_slice_u8(malloc, n);
70
15.0k
      if (!pixbuf.ptr) {
71
0
        ret = "out of memory";
72
0
        goto exit;
73
0
      }
74
15.0k
    }
75
76
15.2k
    wuffs_base__pixel_buffer pb = ((wuffs_base__pixel_buffer){});
77
15.2k
    status = wuffs_base__pixel_buffer__set_from_slice(&pb, &ic.pixcfg, pixbuf);
78
15.2k
    if (!wuffs_base__status__is_ok(&status)) {
79
0
      ret = wuffs_base__status__message(&status);
80
0
      goto exit;
81
0
    }
82
83
15.2k
    bool seen_ok = false;
84
310k
    while (true) {
85
310k
      wuffs_base__frame_config fc = ((wuffs_base__frame_config){});
86
310k
      status = wuffs_base__image_decoder__decode_frame_config(dec, &fc, src);
87
310k
      if (!wuffs_base__status__is_ok(&status)) {
88
3.03k
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
89
710
          ret = wuffs_base__status__message(&status);
90
710
        }
91
3.03k
        goto exit;
92
3.03k
      }
93
94
307k
      status = wuffs_base__image_decoder__decode_frame(
95
307k
          dec, &pb, src, WUFFS_BASE__PIXEL_BLEND__SRC, workbuf, NULL);
96
97
307k
      wuffs_base__rect_ie_u32 frame_rect =
98
307k
          wuffs_base__frame_config__bounds(&fc);
99
307k
      wuffs_base__rect_ie_u32 dirty_rect =
100
307k
          wuffs_base__image_decoder__frame_dirty_rect(dec);
101
307k
      if (!wuffs_base__rect_ie_u32__contains_rect(&frame_rect, dirty_rect)) {
102
0
        ret = "internal error: frame_rect does not contain dirty_rect";
103
0
        goto exit;
104
0
      }
105
106
307k
      if (!wuffs_base__status__is_ok(&status)) {
107
12.2k
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
108
12.2k
          ret = wuffs_base__status__message(&status);
109
12.2k
        }
110
12.2k
        goto exit;
111
12.2k
      }
112
295k
      seen_ok = true;
113
114
295k
      if (!wuffs_base__rect_ie_u32__equals(&frame_rect, dirty_rect)) {
115
0
        ret = "internal error: frame_rect does not equal dirty_rect";
116
0
        goto exit;
117
0
      }
118
295k
    }
119
15.2k
  }
120
121
21.3k
exit:
122
21.3k
  free(workbuf.ptr);
123
21.3k
  free(pixbuf.ptr);
124
21.3k
  return ret;
125
15.2k
}
png_fuzzer.c:fuzz_image_decoder
Line
Count
Source
18
6.04k
                   wuffs_base__image_decoder* dec) {
19
6.04k
  const char* ret = NULL;
20
6.04k
  wuffs_base__slice_u8 pixbuf = ((wuffs_base__slice_u8){});
21
6.04k
  wuffs_base__slice_u8 workbuf = ((wuffs_base__slice_u8){});
22
23
  // Use a {} code block so that "goto exit" doesn't trigger "jump bypasses
24
  // variable initialization" warnings.
25
6.04k
  {
26
6.04k
    wuffs_base__image_config ic = ((wuffs_base__image_config){});
27
6.04k
    wuffs_base__status status =
28
6.04k
        wuffs_base__image_decoder__decode_image_config(dec, &ic, src);
29
6.04k
    if (!wuffs_base__status__is_ok(&status)) {
30
1.82k
      ret = wuffs_base__status__message(&status);
31
1.82k
      goto exit;
32
1.82k
    }
33
4.21k
    if (!wuffs_base__image_config__is_valid(&ic)) {
34
0
      ret = "invalid image_config";
35
0
      goto exit;
36
0
    }
37
38
    // 50% of the time, choose BGRA_PREMUL instead of the native pixel config.
39
4.21k
    if (hash & 1) {
40
2.12k
      wuffs_base__pixel_config__set(
41
2.12k
          &ic.pixcfg, WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL,
42
2.12k
          WUFFS_BASE__PIXEL_SUBSAMPLING__NONE,
43
2.12k
          wuffs_base__pixel_config__width(&ic.pixcfg),
44
2.12k
          wuffs_base__pixel_config__height(&ic.pixcfg));
45
2.12k
    }
46
4.21k
    hash >>= 1;
47
48
    // Wuffs allows either statically or dynamically allocated work buffers.
49
    // This program exercises dynamic allocation.
50
4.21k
    uint64_t n = wuffs_base__image_decoder__workbuf_len(dec).max_incl;
51
4.21k
    if (n > 64 * 1024 * 1024) {  // Don't allocate more than 64 MiB.
52
6
      ret = "image too large";
53
6
      goto exit;
54
6
    }
55
4.21k
    if (n > 0) {
56
4.21k
      workbuf = wuffs_base__malloc_slice_u8(malloc, n);
57
4.21k
      if (!workbuf.ptr) {
58
0
        ret = "out of memory";
59
0
        goto exit;
60
0
      }
61
4.21k
    }
62
63
4.21k
    n = wuffs_base__pixel_config__pixbuf_len(&ic.pixcfg);
64
4.21k
    if (n > 64 * 1024 * 1024) {  // Don't allocate more than 64 MiB.
65
1
      ret = "image too large";
66
1
      goto exit;
67
1
    }
68
4.21k
    if (n > 0) {
69
4.21k
      pixbuf = wuffs_base__malloc_slice_u8(malloc, n);
70
4.21k
      if (!pixbuf.ptr) {
71
0
        ret = "out of memory";
72
0
        goto exit;
73
0
      }
74
4.21k
    }
75
76
4.21k
    wuffs_base__pixel_buffer pb = ((wuffs_base__pixel_buffer){});
77
4.21k
    status = wuffs_base__pixel_buffer__set_from_slice(&pb, &ic.pixcfg, pixbuf);
78
4.21k
    if (!wuffs_base__status__is_ok(&status)) {
79
0
      ret = wuffs_base__status__message(&status);
80
0
      goto exit;
81
0
    }
82
83
4.21k
    bool seen_ok = false;
84
6.80k
    while (true) {
85
6.80k
      wuffs_base__frame_config fc = ((wuffs_base__frame_config){});
86
6.80k
      status = wuffs_base__image_decoder__decode_frame_config(dec, &fc, src);
87
6.80k
      if (!wuffs_base__status__is_ok(&status)) {
88
415
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
89
412
          ret = wuffs_base__status__message(&status);
90
412
        }
91
415
        goto exit;
92
415
      }
93
94
6.39k
      status = wuffs_base__image_decoder__decode_frame(
95
6.39k
          dec, &pb, src, WUFFS_BASE__PIXEL_BLEND__SRC, workbuf, NULL);
96
97
6.39k
      wuffs_base__rect_ie_u32 frame_rect =
98
6.39k
          wuffs_base__frame_config__bounds(&fc);
99
6.39k
      wuffs_base__rect_ie_u32 dirty_rect =
100
6.39k
          wuffs_base__image_decoder__frame_dirty_rect(dec);
101
6.39k
      if (!wuffs_base__rect_ie_u32__contains_rect(&frame_rect, dirty_rect)) {
102
0
        ret = "internal error: frame_rect does not contain dirty_rect";
103
0
        goto exit;
104
0
      }
105
106
6.39k
      if (!wuffs_base__status__is_ok(&status)) {
107
3.79k
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
108
3.79k
          ret = wuffs_base__status__message(&status);
109
3.79k
        }
110
3.79k
        goto exit;
111
3.79k
      }
112
2.59k
      seen_ok = true;
113
114
2.59k
      if (!wuffs_base__rect_ie_u32__equals(&frame_rect, dirty_rect)) {
115
0
        ret = "internal error: frame_rect does not equal dirty_rect";
116
0
        goto exit;
117
0
      }
118
2.59k
    }
119
4.21k
  }
120
121
6.04k
exit:
122
6.04k
  free(workbuf.ptr);
123
6.04k
  free(pixbuf.ptr);
124
6.04k
  return ret;
125
4.21k
}
gif_fuzzer.c:fuzz_image_decoder
Line
Count
Source
18
2.27k
                   wuffs_base__image_decoder* dec) {
19
2.27k
  const char* ret = NULL;
20
2.27k
  wuffs_base__slice_u8 pixbuf = ((wuffs_base__slice_u8){});
21
2.27k
  wuffs_base__slice_u8 workbuf = ((wuffs_base__slice_u8){});
22
23
  // Use a {} code block so that "goto exit" doesn't trigger "jump bypasses
24
  // variable initialization" warnings.
25
2.27k
  {
26
2.27k
    wuffs_base__image_config ic = ((wuffs_base__image_config){});
27
2.27k
    wuffs_base__status status =
28
2.27k
        wuffs_base__image_decoder__decode_image_config(dec, &ic, src);
29
2.27k
    if (!wuffs_base__status__is_ok(&status)) {
30
686
      ret = wuffs_base__status__message(&status);
31
686
      goto exit;
32
686
    }
33
1.59k
    if (!wuffs_base__image_config__is_valid(&ic)) {
34
0
      ret = "invalid image_config";
35
0
      goto exit;
36
0
    }
37
38
    // 50% of the time, choose BGRA_PREMUL instead of the native pixel config.
39
1.59k
    if (hash & 1) {
40
788
      wuffs_base__pixel_config__set(
41
788
          &ic.pixcfg, WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL,
42
788
          WUFFS_BASE__PIXEL_SUBSAMPLING__NONE,
43
788
          wuffs_base__pixel_config__width(&ic.pixcfg),
44
788
          wuffs_base__pixel_config__height(&ic.pixcfg));
45
788
    }
46
1.59k
    hash >>= 1;
47
48
    // Wuffs allows either statically or dynamically allocated work buffers.
49
    // This program exercises dynamic allocation.
50
1.59k
    uint64_t n = wuffs_base__image_decoder__workbuf_len(dec).max_incl;
51
1.59k
    if (n > 64 * 1024 * 1024) {  // Don't allocate more than 64 MiB.
52
0
      ret = "image too large";
53
0
      goto exit;
54
0
    }
55
1.59k
    if (n > 0) {
56
0
      workbuf = wuffs_base__malloc_slice_u8(malloc, n);
57
0
      if (!workbuf.ptr) {
58
0
        ret = "out of memory";
59
0
        goto exit;
60
0
      }
61
0
    }
62
63
1.59k
    n = wuffs_base__pixel_config__pixbuf_len(&ic.pixcfg);
64
1.59k
    if (n > 64 * 1024 * 1024) {  // Don't allocate more than 64 MiB.
65
67
      ret = "image too large";
66
67
      goto exit;
67
67
    }
68
1.52k
    if (n > 0) {
69
1.33k
      pixbuf = wuffs_base__malloc_slice_u8(malloc, n);
70
1.33k
      if (!pixbuf.ptr) {
71
0
        ret = "out of memory";
72
0
        goto exit;
73
0
      }
74
1.33k
    }
75
76
1.52k
    wuffs_base__pixel_buffer pb = ((wuffs_base__pixel_buffer){});
77
1.52k
    status = wuffs_base__pixel_buffer__set_from_slice(&pb, &ic.pixcfg, pixbuf);
78
1.52k
    if (!wuffs_base__status__is_ok(&status)) {
79
0
      ret = wuffs_base__status__message(&status);
80
0
      goto exit;
81
0
    }
82
83
1.52k
    bool seen_ok = false;
84
291k
    while (true) {
85
291k
      wuffs_base__frame_config fc = ((wuffs_base__frame_config){});
86
291k
      status = wuffs_base__image_decoder__decode_frame_config(dec, &fc, src);
87
291k
      if (!wuffs_base__status__is_ok(&status)) {
88
372
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
89
298
          ret = wuffs_base__status__message(&status);
90
298
        }
91
372
        goto exit;
92
372
      }
93
94
291k
      status = wuffs_base__image_decoder__decode_frame(
95
291k
          dec, &pb, src, WUFFS_BASE__PIXEL_BLEND__SRC, workbuf, NULL);
96
97
291k
      wuffs_base__rect_ie_u32 frame_rect =
98
291k
          wuffs_base__frame_config__bounds(&fc);
99
291k
      wuffs_base__rect_ie_u32 dirty_rect =
100
291k
          wuffs_base__image_decoder__frame_dirty_rect(dec);
101
291k
      if (!wuffs_base__rect_ie_u32__contains_rect(&frame_rect, dirty_rect)) {
102
0
        ret = "internal error: frame_rect does not contain dirty_rect";
103
0
        goto exit;
104
0
      }
105
106
291k
      if (!wuffs_base__status__is_ok(&status)) {
107
1.15k
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
108
1.15k
          ret = wuffs_base__status__message(&status);
109
1.15k
        }
110
1.15k
        goto exit;
111
1.15k
      }
112
290k
      seen_ok = true;
113
114
290k
      if (!wuffs_base__rect_ie_u32__equals(&frame_rect, dirty_rect)) {
115
0
        ret = "internal error: frame_rect does not equal dirty_rect";
116
0
        goto exit;
117
0
      }
118
290k
    }
119
1.52k
  }
120
121
2.27k
exit:
122
2.27k
  free(workbuf.ptr);
123
2.27k
  free(pixbuf.ptr);
124
2.27k
  return ret;
125
1.52k
}
jpeg_fuzzer.c:fuzz_image_decoder
Line
Count
Source
18
3.86k
                   wuffs_base__image_decoder* dec) {
19
3.86k
  const char* ret = NULL;
20
3.86k
  wuffs_base__slice_u8 pixbuf = ((wuffs_base__slice_u8){});
21
3.86k
  wuffs_base__slice_u8 workbuf = ((wuffs_base__slice_u8){});
22
23
  // Use a {} code block so that "goto exit" doesn't trigger "jump bypasses
24
  // variable initialization" warnings.
25
3.86k
  {
26
3.86k
    wuffs_base__image_config ic = ((wuffs_base__image_config){});
27
3.86k
    wuffs_base__status status =
28
3.86k
        wuffs_base__image_decoder__decode_image_config(dec, &ic, src);
29
3.86k
    if (!wuffs_base__status__is_ok(&status)) {
30
1.03k
      ret = wuffs_base__status__message(&status);
31
1.03k
      goto exit;
32
1.03k
    }
33
2.83k
    if (!wuffs_base__image_config__is_valid(&ic)) {
34
0
      ret = "invalid image_config";
35
0
      goto exit;
36
0
    }
37
38
    // 50% of the time, choose BGRA_PREMUL instead of the native pixel config.
39
2.83k
    if (hash & 1) {
40
1.49k
      wuffs_base__pixel_config__set(
41
1.49k
          &ic.pixcfg, WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL,
42
1.49k
          WUFFS_BASE__PIXEL_SUBSAMPLING__NONE,
43
1.49k
          wuffs_base__pixel_config__width(&ic.pixcfg),
44
1.49k
          wuffs_base__pixel_config__height(&ic.pixcfg));
45
1.49k
    }
46
2.83k
    hash >>= 1;
47
48
    // Wuffs allows either statically or dynamically allocated work buffers.
49
    // This program exercises dynamic allocation.
50
2.83k
    uint64_t n = wuffs_base__image_decoder__workbuf_len(dec).max_incl;
51
2.83k
    if (n > 64 * 1024 * 1024) {  // Don't allocate more than 64 MiB.
52
18
      ret = "image too large";
53
18
      goto exit;
54
18
    }
55
2.81k
    if (n > 0) {
56
2.81k
      workbuf = wuffs_base__malloc_slice_u8(malloc, n);
57
2.81k
      if (!workbuf.ptr) {
58
0
        ret = "out of memory";
59
0
        goto exit;
60
0
      }
61
2.81k
    }
62
63
2.81k
    n = wuffs_base__pixel_config__pixbuf_len(&ic.pixcfg);
64
2.81k
    if (n > 64 * 1024 * 1024) {  // Don't allocate more than 64 MiB.
65
4
      ret = "image too large";
66
4
      goto exit;
67
4
    }
68
2.81k
    if (n > 0) {
69
2.81k
      pixbuf = wuffs_base__malloc_slice_u8(malloc, n);
70
2.81k
      if (!pixbuf.ptr) {
71
0
        ret = "out of memory";
72
0
        goto exit;
73
0
      }
74
2.81k
    }
75
76
2.81k
    wuffs_base__pixel_buffer pb = ((wuffs_base__pixel_buffer){});
77
2.81k
    status = wuffs_base__pixel_buffer__set_from_slice(&pb, &ic.pixcfg, pixbuf);
78
2.81k
    if (!wuffs_base__status__is_ok(&status)) {
79
0
      ret = wuffs_base__status__message(&status);
80
0
      goto exit;
81
0
    }
82
83
2.81k
    bool seen_ok = false;
84
2.81k
    while (true) {
85
2.81k
      wuffs_base__frame_config fc = ((wuffs_base__frame_config){});
86
2.81k
      status = wuffs_base__image_decoder__decode_frame_config(dec, &fc, src);
87
2.81k
      if (!wuffs_base__status__is_ok(&status)) {
88
4
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
89
0
          ret = wuffs_base__status__message(&status);
90
0
        }
91
4
        goto exit;
92
4
      }
93
94
2.81k
      status = wuffs_base__image_decoder__decode_frame(
95
2.81k
          dec, &pb, src, WUFFS_BASE__PIXEL_BLEND__SRC, workbuf, NULL);
96
97
2.81k
      wuffs_base__rect_ie_u32 frame_rect =
98
2.81k
          wuffs_base__frame_config__bounds(&fc);
99
2.81k
      wuffs_base__rect_ie_u32 dirty_rect =
100
2.81k
          wuffs_base__image_decoder__frame_dirty_rect(dec);
101
2.81k
      if (!wuffs_base__rect_ie_u32__contains_rect(&frame_rect, dirty_rect)) {
102
0
        ret = "internal error: frame_rect does not contain dirty_rect";
103
0
        goto exit;
104
0
      }
105
106
2.81k
      if (!wuffs_base__status__is_ok(&status)) {
107
2.80k
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
108
2.80k
          ret = wuffs_base__status__message(&status);
109
2.80k
        }
110
2.80k
        goto exit;
111
2.80k
      }
112
4
      seen_ok = true;
113
114
4
      if (!wuffs_base__rect_ie_u32__equals(&frame_rect, dirty_rect)) {
115
0
        ret = "internal error: frame_rect does not equal dirty_rect";
116
0
        goto exit;
117
0
      }
118
4
    }
119
2.81k
  }
120
121
3.86k
exit:
122
3.86k
  free(workbuf.ptr);
123
3.86k
  free(pixbuf.ptr);
124
3.86k
  return ret;
125
2.81k
}
bmp_fuzzer.c:fuzz_image_decoder
Line
Count
Source
18
3.14k
                   wuffs_base__image_decoder* dec) {
19
3.14k
  const char* ret = NULL;
20
3.14k
  wuffs_base__slice_u8 pixbuf = ((wuffs_base__slice_u8){});
21
3.14k
  wuffs_base__slice_u8 workbuf = ((wuffs_base__slice_u8){});
22
23
  // Use a {} code block so that "goto exit" doesn't trigger "jump bypasses
24
  // variable initialization" warnings.
25
3.14k
  {
26
3.14k
    wuffs_base__image_config ic = ((wuffs_base__image_config){});
27
3.14k
    wuffs_base__status status =
28
3.14k
        wuffs_base__image_decoder__decode_image_config(dec, &ic, src);
29
3.14k
    if (!wuffs_base__status__is_ok(&status)) {
30
1.34k
      ret = wuffs_base__status__message(&status);
31
1.34k
      goto exit;
32
1.34k
    }
33
1.79k
    if (!wuffs_base__image_config__is_valid(&ic)) {
34
0
      ret = "invalid image_config";
35
0
      goto exit;
36
0
    }
37
38
    // 50% of the time, choose BGRA_PREMUL instead of the native pixel config.
39
1.79k
    if (hash & 1) {
40
1.38k
      wuffs_base__pixel_config__set(
41
1.38k
          &ic.pixcfg, WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL,
42
1.38k
          WUFFS_BASE__PIXEL_SUBSAMPLING__NONE,
43
1.38k
          wuffs_base__pixel_config__width(&ic.pixcfg),
44
1.38k
          wuffs_base__pixel_config__height(&ic.pixcfg));
45
1.38k
    }
46
1.79k
    hash >>= 1;
47
48
    // Wuffs allows either statically or dynamically allocated work buffers.
49
    // This program exercises dynamic allocation.
50
1.79k
    uint64_t n = wuffs_base__image_decoder__workbuf_len(dec).max_incl;
51
1.79k
    if (n > 64 * 1024 * 1024) {  // Don't allocate more than 64 MiB.
52
0
      ret = "image too large";
53
0
      goto exit;
54
0
    }
55
1.79k
    if (n > 0) {
56
0
      workbuf = wuffs_base__malloc_slice_u8(malloc, n);
57
0
      if (!workbuf.ptr) {
58
0
        ret = "out of memory";
59
0
        goto exit;
60
0
      }
61
0
    }
62
63
1.79k
    n = wuffs_base__pixel_config__pixbuf_len(&ic.pixcfg);
64
1.79k
    if (n > 64 * 1024 * 1024) {  // Don't allocate more than 64 MiB.
65
40
      ret = "image too large";
66
40
      goto exit;
67
40
    }
68
1.75k
    if (n > 0) {
69
1.74k
      pixbuf = wuffs_base__malloc_slice_u8(malloc, n);
70
1.74k
      if (!pixbuf.ptr) {
71
0
        ret = "out of memory";
72
0
        goto exit;
73
0
      }
74
1.74k
    }
75
76
1.75k
    wuffs_base__pixel_buffer pb = ((wuffs_base__pixel_buffer){});
77
1.75k
    status = wuffs_base__pixel_buffer__set_from_slice(&pb, &ic.pixcfg, pixbuf);
78
1.75k
    if (!wuffs_base__status__is_ok(&status)) {
79
0
      ret = wuffs_base__status__message(&status);
80
0
      goto exit;
81
0
    }
82
83
1.75k
    bool seen_ok = false;
84
1.87k
    while (true) {
85
1.87k
      wuffs_base__frame_config fc = ((wuffs_base__frame_config){});
86
1.87k
      status = wuffs_base__image_decoder__decode_frame_config(dec, &fc, src);
87
1.87k
      if (!wuffs_base__status__is_ok(&status)) {
88
125
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
89
0
          ret = wuffs_base__status__message(&status);
90
0
        }
91
125
        goto exit;
92
125
      }
93
94
1.75k
      status = wuffs_base__image_decoder__decode_frame(
95
1.75k
          dec, &pb, src, WUFFS_BASE__PIXEL_BLEND__SRC, workbuf, NULL);
96
97
1.75k
      wuffs_base__rect_ie_u32 frame_rect =
98
1.75k
          wuffs_base__frame_config__bounds(&fc);
99
1.75k
      wuffs_base__rect_ie_u32 dirty_rect =
100
1.75k
          wuffs_base__image_decoder__frame_dirty_rect(dec);
101
1.75k
      if (!wuffs_base__rect_ie_u32__contains_rect(&frame_rect, dirty_rect)) {
102
0
        ret = "internal error: frame_rect does not contain dirty_rect";
103
0
        goto exit;
104
0
      }
105
106
1.75k
      if (!wuffs_base__status__is_ok(&status)) {
107
1.62k
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
108
1.62k
          ret = wuffs_base__status__message(&status);
109
1.62k
        }
110
1.62k
        goto exit;
111
1.62k
      }
112
125
      seen_ok = true;
113
114
125
      if (!wuffs_base__rect_ie_u32__equals(&frame_rect, dirty_rect)) {
115
0
        ret = "internal error: frame_rect does not equal dirty_rect";
116
0
        goto exit;
117
0
      }
118
125
    }
119
1.75k
  }
120
121
3.14k
exit:
122
3.14k
  free(workbuf.ptr);
123
3.14k
  free(pixbuf.ptr);
124
3.14k
  return ret;
125
1.75k
}
targa_fuzzer.c:fuzz_image_decoder
Line
Count
Source
18
1.17k
                   wuffs_base__image_decoder* dec) {
19
1.17k
  const char* ret = NULL;
20
1.17k
  wuffs_base__slice_u8 pixbuf = ((wuffs_base__slice_u8){});
21
1.17k
  wuffs_base__slice_u8 workbuf = ((wuffs_base__slice_u8){});
22
23
  // Use a {} code block so that "goto exit" doesn't trigger "jump bypasses
24
  // variable initialization" warnings.
25
1.17k
  {
26
1.17k
    wuffs_base__image_config ic = ((wuffs_base__image_config){});
27
1.17k
    wuffs_base__status status =
28
1.17k
        wuffs_base__image_decoder__decode_image_config(dec, &ic, src);
29
1.17k
    if (!wuffs_base__status__is_ok(&status)) {
30
262
      ret = wuffs_base__status__message(&status);
31
262
      goto exit;
32
262
    }
33
912
    if (!wuffs_base__image_config__is_valid(&ic)) {
34
0
      ret = "invalid image_config";
35
0
      goto exit;
36
0
    }
37
38
    // 50% of the time, choose BGRA_PREMUL instead of the native pixel config.
39
912
    if (hash & 1) {
40
522
      wuffs_base__pixel_config__set(
41
522
          &ic.pixcfg, WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL,
42
522
          WUFFS_BASE__PIXEL_SUBSAMPLING__NONE,
43
522
          wuffs_base__pixel_config__width(&ic.pixcfg),
44
522
          wuffs_base__pixel_config__height(&ic.pixcfg));
45
522
    }
46
912
    hash >>= 1;
47
48
    // Wuffs allows either statically or dynamically allocated work buffers.
49
    // This program exercises dynamic allocation.
50
912
    uint64_t n = wuffs_base__image_decoder__workbuf_len(dec).max_incl;
51
912
    if (n > 64 * 1024 * 1024) {  // Don't allocate more than 64 MiB.
52
0
      ret = "image too large";
53
0
      goto exit;
54
0
    }
55
912
    if (n > 0) {
56
0
      workbuf = wuffs_base__malloc_slice_u8(malloc, n);
57
0
      if (!workbuf.ptr) {
58
0
        ret = "out of memory";
59
0
        goto exit;
60
0
      }
61
0
    }
62
63
912
    n = wuffs_base__pixel_config__pixbuf_len(&ic.pixcfg);
64
912
    if (n > 64 * 1024 * 1024) {  // Don't allocate more than 64 MiB.
65
23
      ret = "image too large";
66
23
      goto exit;
67
23
    }
68
889
    if (n > 0) {
69
863
      pixbuf = wuffs_base__malloc_slice_u8(malloc, n);
70
863
      if (!pixbuf.ptr) {
71
0
        ret = "out of memory";
72
0
        goto exit;
73
0
      }
74
863
    }
75
76
889
    wuffs_base__pixel_buffer pb = ((wuffs_base__pixel_buffer){});
77
889
    status = wuffs_base__pixel_buffer__set_from_slice(&pb, &ic.pixcfg, pixbuf);
78
889
    if (!wuffs_base__status__is_ok(&status)) {
79
0
      ret = wuffs_base__status__message(&status);
80
0
      goto exit;
81
0
    }
82
83
889
    bool seen_ok = false;
84
933
    while (true) {
85
933
      wuffs_base__frame_config fc = ((wuffs_base__frame_config){});
86
933
      status = wuffs_base__image_decoder__decode_frame_config(dec, &fc, src);
87
933
      if (!wuffs_base__status__is_ok(&status)) {
88
44
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
89
0
          ret = wuffs_base__status__message(&status);
90
0
        }
91
44
        goto exit;
92
44
      }
93
94
889
      status = wuffs_base__image_decoder__decode_frame(
95
889
          dec, &pb, src, WUFFS_BASE__PIXEL_BLEND__SRC, workbuf, NULL);
96
97
889
      wuffs_base__rect_ie_u32 frame_rect =
98
889
          wuffs_base__frame_config__bounds(&fc);
99
889
      wuffs_base__rect_ie_u32 dirty_rect =
100
889
          wuffs_base__image_decoder__frame_dirty_rect(dec);
101
889
      if (!wuffs_base__rect_ie_u32__contains_rect(&frame_rect, dirty_rect)) {
102
0
        ret = "internal error: frame_rect does not contain dirty_rect";
103
0
        goto exit;
104
0
      }
105
106
889
      if (!wuffs_base__status__is_ok(&status)) {
107
845
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
108
845
          ret = wuffs_base__status__message(&status);
109
845
        }
110
845
        goto exit;
111
845
      }
112
44
      seen_ok = true;
113
114
44
      if (!wuffs_base__rect_ie_u32__equals(&frame_rect, dirty_rect)) {
115
0
        ret = "internal error: frame_rect does not equal dirty_rect";
116
0
        goto exit;
117
0
      }
118
44
    }
119
889
  }
120
121
1.17k
exit:
122
1.17k
  free(workbuf.ptr);
123
1.17k
  free(pixbuf.ptr);
124
1.17k
  return ret;
125
889
}
webp_fuzzer.c:fuzz_image_decoder
Line
Count
Source
18
4.85k
                   wuffs_base__image_decoder* dec) {
19
4.85k
  const char* ret = NULL;
20
4.85k
  wuffs_base__slice_u8 pixbuf = ((wuffs_base__slice_u8){});
21
4.85k
  wuffs_base__slice_u8 workbuf = ((wuffs_base__slice_u8){});
22
23
  // Use a {} code block so that "goto exit" doesn't trigger "jump bypasses
24
  // variable initialization" warnings.
25
4.85k
  {
26
4.85k
    wuffs_base__image_config ic = ((wuffs_base__image_config){});
27
4.85k
    wuffs_base__status status =
28
4.85k
        wuffs_base__image_decoder__decode_image_config(dec, &ic, src);
29
4.85k
    if (!wuffs_base__status__is_ok(&status)) {
30
699
      ret = wuffs_base__status__message(&status);
31
699
      goto exit;
32
699
    }
33
4.15k
    if (!wuffs_base__image_config__is_valid(&ic)) {
34
0
      ret = "invalid image_config";
35
0
      goto exit;
36
0
    }
37
38
    // 50% of the time, choose BGRA_PREMUL instead of the native pixel config.
39
4.15k
    if (hash & 1) {
40
2.21k
      wuffs_base__pixel_config__set(
41
2.21k
          &ic.pixcfg, WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL,
42
2.21k
          WUFFS_BASE__PIXEL_SUBSAMPLING__NONE,
43
2.21k
          wuffs_base__pixel_config__width(&ic.pixcfg),
44
2.21k
          wuffs_base__pixel_config__height(&ic.pixcfg));
45
2.21k
    }
46
4.15k
    hash >>= 1;
47
48
    // Wuffs allows either statically or dynamically allocated work buffers.
49
    // This program exercises dynamic allocation.
50
4.15k
    uint64_t n = wuffs_base__image_decoder__workbuf_len(dec).max_incl;
51
4.15k
    if (n > 64 * 1024 * 1024) {  // Don't allocate more than 64 MiB.
52
53
      ret = "image too large";
53
53
      goto exit;
54
53
    }
55
4.10k
    if (n > 0) {
56
4.10k
      workbuf = wuffs_base__malloc_slice_u8(malloc, n);
57
4.10k
      if (!workbuf.ptr) {
58
0
        ret = "out of memory";
59
0
        goto exit;
60
0
      }
61
4.10k
    }
62
63
4.10k
    n = wuffs_base__pixel_config__pixbuf_len(&ic.pixcfg);
64
4.10k
    if (n > 64 * 1024 * 1024) {  // Don't allocate more than 64 MiB.
65
2
      ret = "image too large";
66
2
      goto exit;
67
2
    }
68
4.10k
    if (n > 0) {
69
4.10k
      pixbuf = wuffs_base__malloc_slice_u8(malloc, n);
70
4.10k
      if (!pixbuf.ptr) {
71
0
        ret = "out of memory";
72
0
        goto exit;
73
0
      }
74
4.10k
    }
75
76
4.10k
    wuffs_base__pixel_buffer pb = ((wuffs_base__pixel_buffer){});
77
4.10k
    status = wuffs_base__pixel_buffer__set_from_slice(&pb, &ic.pixcfg, pixbuf);
78
4.10k
    if (!wuffs_base__status__is_ok(&status)) {
79
0
      ret = wuffs_base__status__message(&status);
80
0
      goto exit;
81
0
    }
82
83
4.10k
    bool seen_ok = false;
84
6.17k
    while (true) {
85
6.17k
      wuffs_base__frame_config fc = ((wuffs_base__frame_config){});
86
6.17k
      status = wuffs_base__image_decoder__decode_frame_config(dec, &fc, src);
87
6.17k
      if (!wuffs_base__status__is_ok(&status)) {
88
2.07k
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
89
0
          ret = wuffs_base__status__message(&status);
90
0
        }
91
2.07k
        goto exit;
92
2.07k
      }
93
94
4.10k
      status = wuffs_base__image_decoder__decode_frame(
95
4.10k
          dec, &pb, src, WUFFS_BASE__PIXEL_BLEND__SRC, workbuf, NULL);
96
97
4.10k
      wuffs_base__rect_ie_u32 frame_rect =
98
4.10k
          wuffs_base__frame_config__bounds(&fc);
99
4.10k
      wuffs_base__rect_ie_u32 dirty_rect =
100
4.10k
          wuffs_base__image_decoder__frame_dirty_rect(dec);
101
4.10k
      if (!wuffs_base__rect_ie_u32__contains_rect(&frame_rect, dirty_rect)) {
102
0
        ret = "internal error: frame_rect does not contain dirty_rect";
103
0
        goto exit;
104
0
      }
105
106
4.10k
      if (!wuffs_base__status__is_ok(&status)) {
107
2.02k
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
108
2.02k
          ret = wuffs_base__status__message(&status);
109
2.02k
        }
110
2.02k
        goto exit;
111
2.02k
      }
112
2.07k
      seen_ok = true;
113
114
2.07k
      if (!wuffs_base__rect_ie_u32__equals(&frame_rect, dirty_rect)) {
115
0
        ret = "internal error: frame_rect does not equal dirty_rect";
116
0
        goto exit;
117
0
      }
118
2.07k
    }
119
4.10k
  }
120
121
4.85k
exit:
122
4.85k
  free(workbuf.ptr);
123
4.85k
  free(pixbuf.ptr);
124
4.85k
  return ret;
125
4.10k
}