blob: 067af0556b7480ac5a0f50eba476cfd2f4713a7a [file] [log] [blame]
Erik de Castro Lopoe0f7e0e2019-11-17 16:15:51 +11001#include <cstddef>
2#include <cstdint>
3#include <limits>
4
5#include <fuzzing/datasource/datasource.hpp>
6#include <fuzzing/memory.hpp>
7
8#include "FLAC++/encoder.h"
9
10#define SAMPLE_VALUE_LIMIT (1024*1024*10)
11
12static_assert(SAMPLE_VALUE_LIMIT <= std::numeric_limits<FLAC__int32>::max(), "Invalid SAMPLE_VALUE_LIMIT");
13static_assert(-SAMPLE_VALUE_LIMIT >= std::numeric_limits<FLAC__int32>::min(), "Invalid SAMPLE_VALUE_LIMIT");
14
15namespace FLAC {
16 namespace Encoder {
17 class FuzzerStream : public Stream {
18 private:
19 // fuzzing::datasource::Datasource& ds;
20 public:
21 FuzzerStream(fuzzing::datasource::Datasource&) :
22 Stream() { }
23
24 ::FLAC__StreamEncoderWriteStatus write_callback(const FLAC__byte buffer[], size_t bytes, uint32_t /* samples */, uint32_t /* current_frame */) override {
25 fuzzing::memory::memory_test(buffer, bytes);
26#if 0
27 try {
28 if ( ds.Get<bool>() == true ) {
29 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
30 }
31 } catch ( ... ) { }
32#endif
33 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
34 }
35 };
36 }
37}
38
39extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
40 fuzzing::datasource::Datasource ds(data, size);
41 FLAC::Encoder::FuzzerStream encoder(ds);
42
43 const int channels = 2;
44 encoder.set_channels(channels);
45 encoder.set_bits_per_sample(16);
46
47 try {
48 ::FLAC__StreamEncoderInitStatus ret;
49
50 if ( ds.Get<bool>() ) {
51 ret = encoder.init();
52 } else {
53 ret = encoder.init_ogg();
54 }
55
56 if ( ret != FLAC__STREAM_ENCODER_INIT_STATUS_OK ) {
57 goto end;
58 }
59
60 {
61 const bool res = encoder.set_streamable_subset(ds.Get<bool>());
62 fuzzing::memory::memory_test(res);
63 }
64 {
65 const bool res = encoder.set_ogg_serial_number(ds.Get<long>());
66 fuzzing::memory::memory_test(res);
67 }
68 {
69 const bool res = encoder.set_verify(ds.Get<bool>());
70 fuzzing::memory::memory_test(res);
71 }
72 {
73 const bool res = encoder.set_compression_level(ds.Get<uint8_t>());
74 fuzzing::memory::memory_test(res);
75 }
76 {
77 const bool res = encoder.set_do_exhaustive_model_search(ds.Get<bool>());
78 fuzzing::memory::memory_test(res);
79 }
80 {
81 const bool res = encoder.set_do_mid_side_stereo(ds.Get<bool>());
82 fuzzing::memory::memory_test(res);
83 }
84 {
85 const bool res = encoder.set_loose_mid_side_stereo(ds.Get<bool>());
86 fuzzing::memory::memory_test(res);
87 }
88 {
89 const auto s = ds.Get<std::string>();
90 const bool res = encoder.set_apodization(s.data());
91 fuzzing::memory::memory_test(res);
92 }
93 {
94 const bool res = encoder.set_max_lpc_order(ds.Get<uint8_t>());
95 fuzzing::memory::memory_test(res);
96 }
97 {
98 const bool res = encoder.set_qlp_coeff_precision(ds.Get<uint32_t>());
99 fuzzing::memory::memory_test(res);
100 }
101 {
102 const bool res = encoder.set_do_qlp_coeff_prec_search(ds.Get<bool>());
103 fuzzing::memory::memory_test(res);
104 }
105 {
106 const bool res = encoder.set_do_escape_coding(ds.Get<bool>());
107 fuzzing::memory::memory_test(res);
108 }
109 {
110 const bool res = encoder.set_min_residual_partition_order(ds.Get<uint32_t>());
111 fuzzing::memory::memory_test(res);
112 }
113 {
114 const bool res = encoder.set_max_residual_partition_order(ds.Get<uint32_t>());
115 fuzzing::memory::memory_test(res);
116 }
117 {
118 const bool res = encoder.set_rice_parameter_search_dist(ds.Get<uint32_t>());
119 fuzzing::memory::memory_test(res);
120 }
121 {
122 const bool res = encoder.set_total_samples_estimate(ds.Get<uint64_t>());
123 fuzzing::memory::memory_test(res);
124 }
125
126 while ( ds.Get<bool>() ) {
127 {
128 auto dat = ds.GetVector<FLAC__int32>();
129 for (size_t i = 0; i < dat.size(); i++) {
130 if ( SAMPLE_VALUE_LIMIT != 0 ) {
131 if ( dat[i] < -SAMPLE_VALUE_LIMIT ) {
132 dat[i] = -SAMPLE_VALUE_LIMIT;
133 } else if ( dat[i] > SAMPLE_VALUE_LIMIT ) {
134 dat[i] = SAMPLE_VALUE_LIMIT;
135 }
136 }
137 }
138 const uint32_t samples = dat.size() / 2;
139 if ( samples > 0 ) {
140 const int32_t* ptr = dat.data();
141 const bool res = encoder.process_interleaved(ptr, samples);
142 fuzzing::memory::memory_test(res);
143 }
144 }
145 }
146 } catch ( ... ) { }
147
148end:
149 {
150 const bool res = encoder.finish();
151 fuzzing::memory::memory_test(res);
152 }
153 return 0;
154}