Coverage Report

Created: 2026-06-10 06:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libavif/tests/gtest/avif_fuzztest_properties.cc
Line
Count
Source
1
// Copyright 2024 Google LLC
2
// SPDX-License-Identifier: BSD-2-Clause
3
4
#include <array>
5
#include <cstdint>
6
#include <cstring>
7
#include <memory>
8
#include <vector>
9
10
#include "avif/avif.h"
11
#include "avif/internal.h"
12
#include "avif_fuzztest_helpers.h"
13
#include "aviftest_helpers.h"
14
#include "fuzztest/fuzztest.h"
15
#include "gtest/gtest.h"
16
17
namespace avif {
18
namespace testutil {
19
namespace {
20
21
struct TestProp {
22
  std::array<uint8_t, 4> fourcc;
23
  std::array<uint8_t, 16> uuid;
24
  std::vector<uint8_t> body;
25
};
26
27
void EncodeDecode(ImagePtr image, EncoderPtr encoder, DecoderPtr decoder,
28
13.7k
                  const std::vector<TestProp>& test_props) {
29
13.7k
  ImagePtr decoded_image(avifImageCreateEmpty());
30
13.7k
  ASSERT_NE(image.get(), nullptr);
31
13.7k
  ASSERT_NE(encoder.get(), nullptr);
32
13.7k
  ASSERT_NE(decoder.get(), nullptr);
33
13.7k
  ASSERT_NE(decoded_image.get(), nullptr);
34
35
13.7k
  std::vector<TestProp> valid_test_properties;
36
13.7k
  for (const TestProp& testProp : test_props) {
37
3.74k
    if (testProp.fourcc == std::array<uint8_t, 4>{'u', 'u', 'i', 'd'}) {
38
2.49k
      const avifResult result =
39
2.49k
          avifImageAddUUIDProperty(image.get(), testProp.uuid.data(),
40
2.49k
                                   testProp.body.data(), testProp.body.size());
41
2.49k
      if (avifIsValidUUID(testProp.uuid.data())) {
42
1.44k
        valid_test_properties.push_back(testProp);
43
1.44k
        ASSERT_EQ(result, AVIF_RESULT_OK);
44
1.44k
      } else {
45
1.04k
        ASSERT_EQ(result, AVIF_RESULT_INVALID_ARGUMENT);
46
1.04k
      }
47
2.49k
    } else {
48
1.25k
      const avifResult result = avifImageAddOpaqueProperty(
49
1.25k
          image.get(), testProp.fourcc.data(), testProp.body.data(),
50
1.25k
          testProp.body.size());
51
1.25k
      if (avifIsKnownPropertyType(testProp.fourcc.data())) {
52
0
        ASSERT_EQ(result, AVIF_RESULT_INVALID_ARGUMENT);
53
1.25k
      } else {
54
1.25k
        valid_test_properties.push_back(testProp);
55
1.25k
        ASSERT_EQ(result, AVIF_RESULT_OK);
56
1.25k
      }
57
1.25k
    }
58
3.74k
  }
59
60
13.7k
  AvifRwData encoded_data;
61
13.7k
  const avifResult encoder_result =
62
13.7k
      avifEncoderWrite(encoder.get(), image.get(), &encoded_data);
63
27.5k
  ASSERT_EQ(encoder_result, AVIF_RESULT_OK)
64
27.5k
      << avifResultToString(encoder_result);
65
66
13.7k
  const avifResult decoder_result = avifDecoderReadMemory(
67
13.7k
      decoder.get(), decoded_image.get(), encoded_data.data, encoded_data.size);
68
27.5k
  ASSERT_EQ(decoder_result, AVIF_RESULT_OK)
69
27.5k
      << avifResultToString(decoder_result);
70
71
13.7k
  ASSERT_EQ(decoder->image->numProperties, valid_test_properties.size());
72
16.4k
  for (size_t i = 0; i < valid_test_properties.size(); i++) {
73
2.69k
    const TestProp& testProp = valid_test_properties[i];
74
2.69k
    const avifImageItemProperty& decodeProp = decoder->image->properties[i];
75
2.69k
    EXPECT_EQ(std::string(decodeProp.boxtype, decodeProp.boxtype + 4),
76
2.69k
              std::string(testProp.fourcc.data(), testProp.fourcc.data() + 4));
77
2.69k
    EXPECT_EQ(std::vector<uint8_t>(
78
2.69k
                  decodeProp.boxPayload.data,
79
2.69k
                  decodeProp.boxPayload.data + decodeProp.boxPayload.size),
80
2.69k
              testProp.body);
81
2.69k
  }
82
13.7k
}
83
84
2
inline auto ArbitraryProp() {
85
2
  auto fourcc = fuzztest::Arbitrary<std::array<uint8_t, 4>>();
86
2
  auto uuid = fuzztest::Arbitrary<std::array<uint8_t, 16>>();  // ignored
87
2
  auto body = fuzztest::Arbitrary<std::vector<uint8_t>>();
88
2
  return fuzztest::StructOf<TestProp>(fourcc, uuid, body);
89
2
}
90
91
2
inline auto ArbitraryUUIDProp() {
92
2
  auto fourcc = fuzztest::Just(std::array<uint8_t, 4>{'u', 'u', 'i', 'd'});
93
2
  auto uuid = fuzztest::Arbitrary<std::array<uint8_t, 16>>();
94
2
  auto body = fuzztest::Arbitrary<std::vector<uint8_t>>();
95
2
  return fuzztest::StructOf<TestProp>(fourcc, uuid, body);
96
2
}
97
98
2
inline auto ArbitraryProps() {
99
2
  return fuzztest::VectorOf(
100
2
             fuzztest::OneOf(ArbitraryProp(), ArbitraryUUIDProp()))
101
2
      .WithMaxSize(
102
2
          /*maximum unique property count for an avifEncoder instance*/ 127 -
103
2
          /*maximum unique property count used by libavif*/ 16);
104
2
}
105
106
FUZZ_TEST(PropertiesAvifFuzzTest, EncodeDecode)
107
    .WithDomains(ArbitraryAvifImage(), ArbitraryAvifEncoder(),
108
                 ArbitraryAvifDecoder(), ArbitraryProps());
109
110
}  // namespace
111
}  // namespace testutil
112
}  // namespace avif