Coverage Report

Created: 2026-11-12 07:13

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.5k
                   wuffs_base__image_decoder* dec) {
19
21.5k
  const char* ret = NULL;
20
21.5k
  wuffs_base__slice_u8 pixbuf = ((wuffs_base__slice_u8){});
21
21.5k
  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.5k
  {
26
21.5k
    wuffs_base__image_config ic = ((wuffs_base__image_config){});
27
21.5k
    wuffs_base__status status =
28
21.5k
        wuffs_base__image_decoder__decode_image_config(dec, &ic, src);
29
21.5k
    if (!wuffs_base__status__is_ok(&status)) {
30
5.89k
      ret = wuffs_base__status__message(&status);
31
5.89k
      goto exit;
32
5.89k
    }
33
15.6k
    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.6k
    if (hash & 1) {
40
8.44k
      wuffs_base__pixel_config__set(
41
8.44k
          &ic.pixcfg, WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL,
42
8.44k
          WUFFS_BASE__PIXEL_SUBSAMPLING__NONE,
43
8.44k
          wuffs_base__pixel_config__width(&ic.pixcfg),
44
8.44k
          wuffs_base__pixel_config__height(&ic.pixcfg));
45
8.44k
    }
46
15.6k
    hash >>= 1;
47
48
    // Wuffs allows either statically or dynamically allocated work buffers.
49
    // This program exercises dynamic allocation.
50
15.6k
    uint64_t n = wuffs_base__image_decoder__workbuf_len(dec).max_incl;
51
15.6k
    if (n > 64 * 1024 * 1024) {  // Don't allocate more than 64 MiB.
52
91
      ret = "image too large";
53
91
      goto exit;
54
91
    }
55
15.5k
    if (n > 0) {
56
11.2k
      workbuf = wuffs_base__malloc_slice_u8(malloc, n);
57
11.2k
      if (!workbuf.ptr) {
58
0
        ret = "out of memory";
59
0
        goto exit;
60
0
      }
61
11.2k
    }
62
63
15.5k
    n = wuffs_base__pixel_config__pixbuf_len(&ic.pixcfg);
64
15.5k
    if (n > 64 * 1024 * 1024) {  // Don't allocate more than 64 MiB.
65
138
      ret = "image too large";
66
138
      goto exit;
67
138
    }
68
15.4k
    if (n > 0) {
69
15.2k
      pixbuf = wuffs_base__malloc_slice_u8(malloc, n);
70
15.2k
      if (!pixbuf.ptr) {
71
0
        ret = "out of memory";
72
0
        goto exit;
73
0
      }
74
15.2k
    }
75
76
15.4k
    wuffs_base__pixel_buffer pb = ((wuffs_base__pixel_buffer){});
77
15.4k
    status = wuffs_base__pixel_buffer__set_from_slice(&pb, &ic.pixcfg, pixbuf);
78
15.4k
    if (!wuffs_base__status__is_ok(&status)) {
79
0
      ret = wuffs_base__status__message(&status);
80
0
      goto exit;
81
0
    }
82
83
15.4k
    bool seen_ok = false;
84
280k
    while (true) {
85
280k
      wuffs_base__frame_config fc = ((wuffs_base__frame_config){});
86
280k
      status = wuffs_base__image_decoder__decode_frame_config(dec, &fc, src);
87
280k
      if (!wuffs_base__status__is_ok(&status)) {
88
3.04k
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
89
726
          ret = wuffs_base__status__message(&status);
90
726
        }
91
3.04k
        goto exit;
92
3.04k
      }
93
94
277k
      status = wuffs_base__image_decoder__decode_frame(
95
277k
          dec, &pb, src, WUFFS_BASE__PIXEL_BLEND__SRC, workbuf, NULL);
96
97
277k
      wuffs_base__rect_ie_u32 frame_rect =
98
277k
          wuffs_base__frame_config__bounds(&fc);
99
277k
      wuffs_base__rect_ie_u32 dirty_rect =
100
277k
          wuffs_base__image_decoder__frame_dirty_rect(dec);
101
277k
      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
277k
      if (!wuffs_base__status__is_ok(&status)) {
107
12.3k
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
108
12.3k
          ret = wuffs_base__status__message(&status);
109
12.3k
        }
110
12.3k
        goto exit;
111
12.3k
      }
112
264k
      seen_ok = true;
113
114
264k
      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
264k
    }
119
15.4k
  }
120
121
21.5k
exit:
122
21.5k
  free(workbuf.ptr);
123
21.5k
  free(pixbuf.ptr);
124
21.5k
  return ret;
125
15.4k
}
png_fuzzer.c:fuzz_image_decoder
Line
Count
Source
18
6.12k
                   wuffs_base__image_decoder* dec) {
19
6.12k
  const char* ret = NULL;
20
6.12k
  wuffs_base__slice_u8 pixbuf = ((wuffs_base__slice_u8){});
21
6.12k
  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.12k
  {
26
6.12k
    wuffs_base__image_config ic = ((wuffs_base__image_config){});
27
6.12k
    wuffs_base__status status =
28
6.12k
        wuffs_base__image_decoder__decode_image_config(dec, &ic, src);
29
6.12k
    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.29k
    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.29k
    if (hash & 1) {
40
2.18k
      wuffs_base__pixel_config__set(
41
2.18k
          &ic.pixcfg, WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL,
42
2.18k
          WUFFS_BASE__PIXEL_SUBSAMPLING__NONE,
43
2.18k
          wuffs_base__pixel_config__width(&ic.pixcfg),
44
2.18k
          wuffs_base__pixel_config__height(&ic.pixcfg));
45
2.18k
    }
46
4.29k
    hash >>= 1;
47
48
    // Wuffs allows either statically or dynamically allocated work buffers.
49
    // This program exercises dynamic allocation.
50
4.29k
    uint64_t n = wuffs_base__image_decoder__workbuf_len(dec).max_incl;
51
4.29k
    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.29k
    if (n > 0) {
56
4.29k
      workbuf = wuffs_base__malloc_slice_u8(malloc, n);
57
4.29k
      if (!workbuf.ptr) {
58
0
        ret = "out of memory";
59
0
        goto exit;
60
0
      }
61
4.29k
    }
62
63
4.29k
    n = wuffs_base__pixel_config__pixbuf_len(&ic.pixcfg);
64
4.29k
    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.29k
    if (n > 0) {
69
4.29k
      pixbuf = wuffs_base__malloc_slice_u8(malloc, n);
70
4.29k
      if (!pixbuf.ptr) {
71
0
        ret = "out of memory";
72
0
        goto exit;
73
0
      }
74
4.29k
    }
75
76
4.29k
    wuffs_base__pixel_buffer pb = ((wuffs_base__pixel_buffer){});
77
4.29k
    status = wuffs_base__pixel_buffer__set_from_slice(&pb, &ic.pixcfg, pixbuf);
78
4.29k
    if (!wuffs_base__status__is_ok(&status)) {
79
0
      ret = wuffs_base__status__message(&status);
80
0
      goto exit;
81
0
    }
82
83
4.29k
    bool seen_ok = false;
84
6.79k
    while (true) {
85
6.79k
      wuffs_base__frame_config fc = ((wuffs_base__frame_config){});
86
6.79k
      status = wuffs_base__image_decoder__decode_frame_config(dec, &fc, src);
87
6.79k
      if (!wuffs_base__status__is_ok(&status)) {
88
418
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
89
416
          ret = wuffs_base__status__message(&status);
90
416
        }
91
418
        goto exit;
92
418
      }
93
94
6.37k
      status = wuffs_base__image_decoder__decode_frame(
95
6.37k
          dec, &pb, src, WUFFS_BASE__PIXEL_BLEND__SRC, workbuf, NULL);
96
97
6.37k
      wuffs_base__rect_ie_u32 frame_rect =
98
6.37k
          wuffs_base__frame_config__bounds(&fc);
99
6.37k
      wuffs_base__rect_ie_u32 dirty_rect =
100
6.37k
          wuffs_base__image_decoder__frame_dirty_rect(dec);
101
6.37k
      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.37k
      if (!wuffs_base__status__is_ok(&status)) {
107
3.87k
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
108
3.87k
          ret = wuffs_base__status__message(&status);
109
3.87k
        }
110
3.87k
        goto exit;
111
3.87k
      }
112
2.50k
      seen_ok = true;
113
114
2.50k
      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.50k
    }
119
4.29k
  }
120
121
6.12k
exit:
122
6.12k
  free(workbuf.ptr);
123
6.12k
  free(pixbuf.ptr);
124
6.12k
  return ret;
125
4.29k
}
gif_fuzzer.c:fuzz_image_decoder
Line
Count
Source
18
2.31k
                   wuffs_base__image_decoder* dec) {
19
2.31k
  const char* ret = NULL;
20
2.31k
  wuffs_base__slice_u8 pixbuf = ((wuffs_base__slice_u8){});
21
2.31k
  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.31k
  {
26
2.31k
    wuffs_base__image_config ic = ((wuffs_base__image_config){});
27
2.31k
    wuffs_base__status status =
28
2.31k
        wuffs_base__image_decoder__decode_image_config(dec, &ic, src);
29
2.31k
    if (!wuffs_base__status__is_ok(&status)) {
30
686
      ret = wuffs_base__status__message(&status);
31
686
      goto exit;
32
686
    }
33
1.63k
    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.63k
    if (hash & 1) {
40
799
      wuffs_base__pixel_config__set(
41
799
          &ic.pixcfg, WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL,
42
799
          WUFFS_BASE__PIXEL_SUBSAMPLING__NONE,
43
799
          wuffs_base__pixel_config__width(&ic.pixcfg),
44
799
          wuffs_base__pixel_config__height(&ic.pixcfg));
45
799
    }
46
1.63k
    hash >>= 1;
47
48
    // Wuffs allows either statically or dynamically allocated work buffers.
49
    // This program exercises dynamic allocation.
50
1.63k
    uint64_t n = wuffs_base__image_decoder__workbuf_len(dec).max_incl;
51
1.63k
    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.63k
    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.63k
    n = wuffs_base__pixel_config__pixbuf_len(&ic.pixcfg);
64
1.63k
    if (n > 64 * 1024 * 1024) {  // Don't allocate more than 64 MiB.
65
63
      ret = "image too large";
66
63
      goto exit;
67
63
    }
68
1.56k
    if (n > 0) {
69
1.40k
      pixbuf = wuffs_base__malloc_slice_u8(malloc, n);
70
1.40k
      if (!pixbuf.ptr) {
71
0
        ret = "out of memory";
72
0
        goto exit;
73
0
      }
74
1.40k
    }
75
76
1.56k
    wuffs_base__pixel_buffer pb = ((wuffs_base__pixel_buffer){});
77
1.56k
    status = wuffs_base__pixel_buffer__set_from_slice(&pb, &ic.pixcfg, pixbuf);
78
1.56k
    if (!wuffs_base__status__is_ok(&status)) {
79
0
      ret = wuffs_base__status__message(&status);
80
0
      goto exit;
81
0
    }
82
83
1.56k
    bool seen_ok = false;
84
261k
    while (true) {
85
261k
      wuffs_base__frame_config fc = ((wuffs_base__frame_config){});
86
261k
      status = wuffs_base__image_decoder__decode_frame_config(dec, &fc, src);
87
261k
      if (!wuffs_base__status__is_ok(&status)) {
88
380
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
89
310
          ret = wuffs_base__status__message(&status);
90
310
        }
91
380
        goto exit;
92
380
      }
93
94
261k
      status = wuffs_base__image_decoder__decode_frame(
95
261k
          dec, &pb, src, WUFFS_BASE__PIXEL_BLEND__SRC, workbuf, NULL);
96
97
261k
      wuffs_base__rect_ie_u32 frame_rect =
98
261k
          wuffs_base__frame_config__bounds(&fc);
99
261k
      wuffs_base__rect_ie_u32 dirty_rect =
100
261k
          wuffs_base__image_decoder__frame_dirty_rect(dec);
101
261k
      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
261k
      if (!wuffs_base__status__is_ok(&status)) {
107
1.18k
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
108
1.18k
          ret = wuffs_base__status__message(&status);
109
1.18k
        }
110
1.18k
        goto exit;
111
1.18k
      }
112
260k
      seen_ok = true;
113
114
260k
      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
260k
    }
119
1.56k
  }
120
121
2.31k
exit:
122
2.31k
  free(workbuf.ptr);
123
2.31k
  free(pixbuf.ptr);
124
2.31k
  return ret;
125
1.56k
}
jpeg_fuzzer.c:fuzz_image_decoder
Line
Count
Source
18
3.91k
                   wuffs_base__image_decoder* dec) {
19
3.91k
  const char* ret = NULL;
20
3.91k
  wuffs_base__slice_u8 pixbuf = ((wuffs_base__slice_u8){});
21
3.91k
  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.91k
  {
26
3.91k
    wuffs_base__image_config ic = ((wuffs_base__image_config){});
27
3.91k
    wuffs_base__status status =
28
3.91k
        wuffs_base__image_decoder__decode_image_config(dec, &ic, src);
29
3.91k
    if (!wuffs_base__status__is_ok(&status)) {
30
1.04k
      ret = wuffs_base__status__message(&status);
31
1.04k
      goto exit;
32
1.04k
    }
33
2.86k
    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.86k
    if (hash & 1) {
40
1.46k
      wuffs_base__pixel_config__set(
41
1.46k
          &ic.pixcfg, WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL,
42
1.46k
          WUFFS_BASE__PIXEL_SUBSAMPLING__NONE,
43
1.46k
          wuffs_base__pixel_config__width(&ic.pixcfg),
44
1.46k
          wuffs_base__pixel_config__height(&ic.pixcfg));
45
1.46k
    }
46
2.86k
    hash >>= 1;
47
48
    // Wuffs allows either statically or dynamically allocated work buffers.
49
    // This program exercises dynamic allocation.
50
2.86k
    uint64_t n = wuffs_base__image_decoder__workbuf_len(dec).max_incl;
51
2.86k
    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.84k
    if (n > 0) {
56
2.84k
      workbuf = wuffs_base__malloc_slice_u8(malloc, n);
57
2.84k
      if (!workbuf.ptr) {
58
0
        ret = "out of memory";
59
0
        goto exit;
60
0
      }
61
2.84k
    }
62
63
2.84k
    n = wuffs_base__pixel_config__pixbuf_len(&ic.pixcfg);
64
2.84k
    if (n > 64 * 1024 * 1024) {  // Don't allocate more than 64 MiB.
65
8
      ret = "image too large";
66
8
      goto exit;
67
8
    }
68
2.83k
    if (n > 0) {
69
2.83k
      pixbuf = wuffs_base__malloc_slice_u8(malloc, n);
70
2.83k
      if (!pixbuf.ptr) {
71
0
        ret = "out of memory";
72
0
        goto exit;
73
0
      }
74
2.83k
    }
75
76
2.83k
    wuffs_base__pixel_buffer pb = ((wuffs_base__pixel_buffer){});
77
2.83k
    status = wuffs_base__pixel_buffer__set_from_slice(&pb, &ic.pixcfg, pixbuf);
78
2.83k
    if (!wuffs_base__status__is_ok(&status)) {
79
0
      ret = wuffs_base__status__message(&status);
80
0
      goto exit;
81
0
    }
82
83
2.83k
    bool seen_ok = false;
84
2.84k
    while (true) {
85
2.84k
      wuffs_base__frame_config fc = ((wuffs_base__frame_config){});
86
2.84k
      status = wuffs_base__image_decoder__decode_frame_config(dec, &fc, src);
87
2.84k
      if (!wuffs_base__status__is_ok(&status)) {
88
8
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
89
0
          ret = wuffs_base__status__message(&status);
90
0
        }
91
8
        goto exit;
92
8
      }
93
94
2.83k
      status = wuffs_base__image_decoder__decode_frame(
95
2.83k
          dec, &pb, src, WUFFS_BASE__PIXEL_BLEND__SRC, workbuf, NULL);
96
97
2.83k
      wuffs_base__rect_ie_u32 frame_rect =
98
2.83k
          wuffs_base__frame_config__bounds(&fc);
99
2.83k
      wuffs_base__rect_ie_u32 dirty_rect =
100
2.83k
          wuffs_base__image_decoder__frame_dirty_rect(dec);
101
2.83k
      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.83k
      if (!wuffs_base__status__is_ok(&status)) {
107
2.82k
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
108
2.82k
          ret = wuffs_base__status__message(&status);
109
2.82k
        }
110
2.82k
        goto exit;
111
2.82k
      }
112
8
      seen_ok = true;
113
114
8
      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
8
    }
119
2.83k
  }
120
121
3.91k
exit:
122
3.91k
  free(workbuf.ptr);
123
3.91k
  free(pixbuf.ptr);
124
3.91k
  return ret;
125
2.83k
}
bmp_fuzzer.c:fuzz_image_decoder
Line
Count
Source
18
3.16k
                   wuffs_base__image_decoder* dec) {
19
3.16k
  const char* ret = NULL;
20
3.16k
  wuffs_base__slice_u8 pixbuf = ((wuffs_base__slice_u8){});
21
3.16k
  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.16k
  {
26
3.16k
    wuffs_base__image_config ic = ((wuffs_base__image_config){});
27
3.16k
    wuffs_base__status status =
28
3.16k
        wuffs_base__image_decoder__decode_image_config(dec, &ic, src);
29
3.16k
    if (!wuffs_base__status__is_ok(&status)) {
30
1.38k
      ret = wuffs_base__status__message(&status);
31
1.38k
      goto exit;
32
1.38k
    }
33
1.77k
    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.77k
    if (hash & 1) {
40
1.35k
      wuffs_base__pixel_config__set(
41
1.35k
          &ic.pixcfg, WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL,
42
1.35k
          WUFFS_BASE__PIXEL_SUBSAMPLING__NONE,
43
1.35k
          wuffs_base__pixel_config__width(&ic.pixcfg),
44
1.35k
          wuffs_base__pixel_config__height(&ic.pixcfg));
45
1.35k
    }
46
1.77k
    hash >>= 1;
47
48
    // Wuffs allows either statically or dynamically allocated work buffers.
49
    // This program exercises dynamic allocation.
50
1.77k
    uint64_t n = wuffs_base__image_decoder__workbuf_len(dec).max_incl;
51
1.77k
    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.77k
    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.77k
    n = wuffs_base__pixel_config__pixbuf_len(&ic.pixcfg);
64
1.77k
    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.73k
    if (n > 0) {
69
1.72k
      pixbuf = wuffs_base__malloc_slice_u8(malloc, n);
70
1.72k
      if (!pixbuf.ptr) {
71
0
        ret = "out of memory";
72
0
        goto exit;
73
0
      }
74
1.72k
    }
75
76
1.73k
    wuffs_base__pixel_buffer pb = ((wuffs_base__pixel_buffer){});
77
1.73k
    status = wuffs_base__pixel_buffer__set_from_slice(&pb, &ic.pixcfg, pixbuf);
78
1.73k
    if (!wuffs_base__status__is_ok(&status)) {
79
0
      ret = wuffs_base__status__message(&status);
80
0
      goto exit;
81
0
    }
82
83
1.73k
    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
135
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
89
0
          ret = wuffs_base__status__message(&status);
90
0
        }
91
135
        goto exit;
92
135
      }
93
94
1.73k
      status = wuffs_base__image_decoder__decode_frame(
95
1.73k
          dec, &pb, src, WUFFS_BASE__PIXEL_BLEND__SRC, workbuf, NULL);
96
97
1.73k
      wuffs_base__rect_ie_u32 frame_rect =
98
1.73k
          wuffs_base__frame_config__bounds(&fc);
99
1.73k
      wuffs_base__rect_ie_u32 dirty_rect =
100
1.73k
          wuffs_base__image_decoder__frame_dirty_rect(dec);
101
1.73k
      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.73k
      if (!wuffs_base__status__is_ok(&status)) {
107
1.60k
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
108
1.60k
          ret = wuffs_base__status__message(&status);
109
1.60k
        }
110
1.60k
        goto exit;
111
1.60k
      }
112
135
      seen_ok = true;
113
114
135
      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
135
    }
119
1.73k
  }
120
121
3.16k
exit:
122
3.16k
  free(workbuf.ptr);
123
3.16k
  free(pixbuf.ptr);
124
3.16k
  return ret;
125
1.73k
}
targa_fuzzer.c:fuzz_image_decoder
Line
Count
Source
18
1.16k
                   wuffs_base__image_decoder* dec) {
19
1.16k
  const char* ret = NULL;
20
1.16k
  wuffs_base__slice_u8 pixbuf = ((wuffs_base__slice_u8){});
21
1.16k
  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.16k
  {
26
1.16k
    wuffs_base__image_config ic = ((wuffs_base__image_config){});
27
1.16k
    wuffs_base__status status =
28
1.16k
        wuffs_base__image_decoder__decode_image_config(dec, &ic, src);
29
1.16k
    if (!wuffs_base__status__is_ok(&status)) {
30
258
      ret = wuffs_base__status__message(&status);
31
258
      goto exit;
32
258
    }
33
902
    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
902
    if (hash & 1) {
40
519
      wuffs_base__pixel_config__set(
41
519
          &ic.pixcfg, WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL,
42
519
          WUFFS_BASE__PIXEL_SUBSAMPLING__NONE,
43
519
          wuffs_base__pixel_config__width(&ic.pixcfg),
44
519
          wuffs_base__pixel_config__height(&ic.pixcfg));
45
519
    }
46
902
    hash >>= 1;
47
48
    // Wuffs allows either statically or dynamically allocated work buffers.
49
    // This program exercises dynamic allocation.
50
902
    uint64_t n = wuffs_base__image_decoder__workbuf_len(dec).max_incl;
51
902
    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
902
    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
902
    n = wuffs_base__pixel_config__pixbuf_len(&ic.pixcfg);
64
902
    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
879
    if (n > 0) {
69
846
      pixbuf = wuffs_base__malloc_slice_u8(malloc, n);
70
846
      if (!pixbuf.ptr) {
71
0
        ret = "out of memory";
72
0
        goto exit;
73
0
      }
74
846
    }
75
76
879
    wuffs_base__pixel_buffer pb = ((wuffs_base__pixel_buffer){});
77
879
    status = wuffs_base__pixel_buffer__set_from_slice(&pb, &ic.pixcfg, pixbuf);
78
879
    if (!wuffs_base__status__is_ok(&status)) {
79
0
      ret = wuffs_base__status__message(&status);
80
0
      goto exit;
81
0
    }
82
83
879
    bool seen_ok = false;
84
929
    while (true) {
85
929
      wuffs_base__frame_config fc = ((wuffs_base__frame_config){});
86
929
      status = wuffs_base__image_decoder__decode_frame_config(dec, &fc, src);
87
929
      if (!wuffs_base__status__is_ok(&status)) {
88
50
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
89
0
          ret = wuffs_base__status__message(&status);
90
0
        }
91
50
        goto exit;
92
50
      }
93
94
879
      status = wuffs_base__image_decoder__decode_frame(
95
879
          dec, &pb, src, WUFFS_BASE__PIXEL_BLEND__SRC, workbuf, NULL);
96
97
879
      wuffs_base__rect_ie_u32 frame_rect =
98
879
          wuffs_base__frame_config__bounds(&fc);
99
879
      wuffs_base__rect_ie_u32 dirty_rect =
100
879
          wuffs_base__image_decoder__frame_dirty_rect(dec);
101
879
      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
879
      if (!wuffs_base__status__is_ok(&status)) {
107
829
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
108
829
          ret = wuffs_base__status__message(&status);
109
829
        }
110
829
        goto exit;
111
829
      }
112
50
      seen_ok = true;
113
114
50
      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
50
    }
119
879
  }
120
121
1.16k
exit:
122
1.16k
  free(workbuf.ptr);
123
1.16k
  free(pixbuf.ptr);
124
1.16k
  return ret;
125
879
}
webp_fuzzer.c:fuzz_image_decoder
Line
Count
Source
18
4.89k
                   wuffs_base__image_decoder* dec) {
19
4.89k
  const char* ret = NULL;
20
4.89k
  wuffs_base__slice_u8 pixbuf = ((wuffs_base__slice_u8){});
21
4.89k
  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.89k
  {
26
4.89k
    wuffs_base__image_config ic = ((wuffs_base__image_config){});
27
4.89k
    wuffs_base__status status =
28
4.89k
        wuffs_base__image_decoder__decode_image_config(dec, &ic, src);
29
4.89k
    if (!wuffs_base__status__is_ok(&status)) {
30
691
      ret = wuffs_base__status__message(&status);
31
691
      goto exit;
32
691
    }
33
4.20k
    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.20k
    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.20k
    hash >>= 1;
47
48
    // Wuffs allows either statically or dynamically allocated work buffers.
49
    // This program exercises dynamic allocation.
50
4.20k
    uint64_t n = wuffs_base__image_decoder__workbuf_len(dec).max_incl;
51
4.20k
    if (n > 64 * 1024 * 1024) {  // Don't allocate more than 64 MiB.
52
67
      ret = "image too large";
53
67
      goto exit;
54
67
    }
55
4.13k
    if (n > 0) {
56
4.13k
      workbuf = wuffs_base__malloc_slice_u8(malloc, n);
57
4.13k
      if (!workbuf.ptr) {
58
0
        ret = "out of memory";
59
0
        goto exit;
60
0
      }
61
4.13k
    }
62
63
4.13k
    n = wuffs_base__pixel_config__pixbuf_len(&ic.pixcfg);
64
4.13k
    if (n > 64 * 1024 * 1024) {  // Don't allocate more than 64 MiB.
65
3
      ret = "image too large";
66
3
      goto exit;
67
3
    }
68
4.13k
    if (n > 0) {
69
4.13k
      pixbuf = wuffs_base__malloc_slice_u8(malloc, n);
70
4.13k
      if (!pixbuf.ptr) {
71
0
        ret = "out of memory";
72
0
        goto exit;
73
0
      }
74
4.13k
    }
75
76
4.13k
    wuffs_base__pixel_buffer pb = ((wuffs_base__pixel_buffer){});
77
4.13k
    status = wuffs_base__pixel_buffer__set_from_slice(&pb, &ic.pixcfg, pixbuf);
78
4.13k
    if (!wuffs_base__status__is_ok(&status)) {
79
0
      ret = wuffs_base__status__message(&status);
80
0
      goto exit;
81
0
    }
82
83
4.13k
    bool seen_ok = false;
84
6.18k
    while (true) {
85
6.18k
      wuffs_base__frame_config fc = ((wuffs_base__frame_config){});
86
6.18k
      status = wuffs_base__image_decoder__decode_frame_config(dec, &fc, src);
87
6.18k
      if (!wuffs_base__status__is_ok(&status)) {
88
2.05k
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
89
0
          ret = wuffs_base__status__message(&status);
90
0
        }
91
2.05k
        goto exit;
92
2.05k
      }
93
94
4.13k
      status = wuffs_base__image_decoder__decode_frame(
95
4.13k
          dec, &pb, src, WUFFS_BASE__PIXEL_BLEND__SRC, workbuf, NULL);
96
97
4.13k
      wuffs_base__rect_ie_u32 frame_rect =
98
4.13k
          wuffs_base__frame_config__bounds(&fc);
99
4.13k
      wuffs_base__rect_ie_u32 dirty_rect =
100
4.13k
          wuffs_base__image_decoder__frame_dirty_rect(dec);
101
4.13k
      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.13k
      if (!wuffs_base__status__is_ok(&status)) {
107
2.07k
        if ((status.repr != wuffs_base__note__end_of_data) || !seen_ok) {
108
2.07k
          ret = wuffs_base__status__message(&status);
109
2.07k
        }
110
2.07k
        goto exit;
111
2.07k
      }
112
2.05k
      seen_ok = true;
113
114
2.05k
      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.05k
    }
119
4.13k
  }
120
121
4.89k
exit:
122
4.89k
  free(workbuf.ptr);
123
4.89k
  free(pixbuf.ptr);
124
4.89k
  return ret;
125
4.13k
}