xref: /aosp_15_r20/external/flac/fuzzer/flac_dec_fuzzer.cpp (revision 600f14f40d737144c998e2ec7a483122d3776fbc)
1*600f14f4SXin Li /******************************************************************************
2*600f14f4SXin Li  *
3*600f14f4SXin Li  * Copyright (C) 2020 The Android Open Source Project
4*600f14f4SXin Li  *
5*600f14f4SXin Li  * Licensed under the Apache License, Version 2.0 (the "License");
6*600f14f4SXin Li  * you may not use this file except in compliance with the License.
7*600f14f4SXin Li  * You may obtain a copy of the License at:
8*600f14f4SXin Li  *
9*600f14f4SXin Li  * http://www.apache.org/licenses/LICENSE-2.0
10*600f14f4SXin Li  *
11*600f14f4SXin Li  * Unless required by applicable law or agreed to in writing, software
12*600f14f4SXin Li  * distributed under the License is distributed on an "AS IS" BASIS,
13*600f14f4SXin Li  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*600f14f4SXin Li  * See the License for the specific language governing permissions and
15*600f14f4SXin Li  * limitations under the License.
16*600f14f4SXin Li  *
17*600f14f4SXin Li  *****************************************************************************
18*600f14f4SXin Li  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*600f14f4SXin Li  */
20*600f14f4SXin Li 
21*600f14f4SXin Li #include <fuzzer/FuzzedDataProvider.h>
22*600f14f4SXin Li #include <stdlib.h>
23*600f14f4SXin Li #include <utils/String8.h>
24*600f14f4SXin Li #include "FLAC/stream_decoder.h"
25*600f14f4SXin Li 
26*600f14f4SXin Li constexpr FLAC__MetadataType kMetadataTypes[8] = {
27*600f14f4SXin Li   FLAC__METADATA_TYPE_PICTURE,
28*600f14f4SXin Li   FLAC__METADATA_TYPE_STREAMINFO,
29*600f14f4SXin Li   FLAC__METADATA_TYPE_PADDING,
30*600f14f4SXin Li   FLAC__METADATA_TYPE_APPLICATION,
31*600f14f4SXin Li   FLAC__METADATA_TYPE_SEEKTABLE,
32*600f14f4SXin Li   FLAC__METADATA_TYPE_VORBIS_COMMENT,
33*600f14f4SXin Li   FLAC__METADATA_TYPE_CUESHEET,
34*600f14f4SXin Li   FLAC__METADATA_TYPE_UNDEFINED,
35*600f14f4SXin Li };
36*600f14f4SXin Li 
37*600f14f4SXin Li const char *kMetadataIDs[3] = {
38*600f14f4SXin Li   "aiff",
39*600f14f4SXin Li   "riff",
40*600f14f4SXin Li   "w64",
41*600f14f4SXin Li };
42*600f14f4SXin Li 
43*600f14f4SXin Li // First four bytes are always "fLaC" in ASCII format.
44*600f14f4SXin Li #define FIRST_ENCODED_BYTE_OFFSET 4
45*600f14f4SXin Li 
46*600f14f4SXin Li class Codec {
47*600f14f4SXin Li  public:
Codec(const uint8_t * data,size_t size)48*600f14f4SXin Li   Codec(const uint8_t* data, size_t size) : mFdp(data, size) {
49*600f14f4SXin Li     mBuffer = data;
50*600f14f4SXin Li     mBufferLen = size;
51*600f14f4SXin Li   };
~Codec()52*600f14f4SXin Li   ~Codec() { deInitDecoder(); }
53*600f14f4SXin Li   bool initDecoder();
54*600f14f4SXin Li   void decodeFrames();
55*600f14f4SXin Li   void deInitDecoder();
56*600f14f4SXin Li 
57*600f14f4SXin Li  private:
58*600f14f4SXin Li   FLAC__StreamDecoder *mDecoder = nullptr;
59*600f14f4SXin Li   const uint8_t *mBuffer = nullptr;
60*600f14f4SXin Li   size_t mBufferLen = 0;
61*600f14f4SXin Li   size_t mBufferPos = 0;
62*600f14f4SXin Li   FLAC__StreamDecoderReadStatus readCallback(FLAC__byte buffer[], size_t *bytes);
63*600f14f4SXin Li   FLAC__StreamDecoderWriteStatus writeCallback(const FLAC__Frame *frame,
64*600f14f4SXin Li                                                const FLAC__int32 *const buffer[]);
65*600f14f4SXin Li   void errorCallback(FLAC__StreamDecoderErrorStatus status);
66*600f14f4SXin Li   void metadataCallback(const FLAC__StreamMetadata *metadata);
67*600f14f4SXin Li   FuzzedDataProvider mFdp;
68*600f14f4SXin Li };
69*600f14f4SXin Li 
initDecoder()70*600f14f4SXin Li bool Codec::initDecoder() {
71*600f14f4SXin Li   mDecoder = FLAC__stream_decoder_new();
72*600f14f4SXin Li   if (!mDecoder) {
73*600f14f4SXin Li     return false;
74*600f14f4SXin Li   }
75*600f14f4SXin Li   FLAC__stream_decoder_set_metadata_ignore_all(mDecoder);
76*600f14f4SXin Li   FLAC__stream_decoder_set_md5_checking(mDecoder, true);
77*600f14f4SXin Li   // read_callback, write_callback, error_callback and metadata_callback cannot be nullptrs
78*600f14f4SXin Li 
79*600f14f4SXin Li   static auto read_callback = [](const FLAC__StreamDecoder *, FLAC__byte buffer[], size_t *bytes,
80*600f14f4SXin Li                                  void *client_data) -> FLAC__StreamDecoderReadStatus {
81*600f14f4SXin Li     Codec *client = reinterpret_cast<Codec *>(client_data);
82*600f14f4SXin Li     return client->readCallback(buffer, bytes);
83*600f14f4SXin Li   };
84*600f14f4SXin Li   static auto write_callback = [](const FLAC__StreamDecoder *, const FLAC__Frame *frame,
85*600f14f4SXin Li                                   const FLAC__int32 *const buffer[],
86*600f14f4SXin Li                                   void *client_data) -> FLAC__StreamDecoderWriteStatus {
87*600f14f4SXin Li     Codec *client = reinterpret_cast<Codec *>(client_data);
88*600f14f4SXin Li     return client->writeCallback(frame, buffer);
89*600f14f4SXin Li   };
90*600f14f4SXin Li   static auto error_callback = [](const FLAC__StreamDecoder *,
91*600f14f4SXin Li                                   FLAC__StreamDecoderErrorStatus status, void *client_data) {
92*600f14f4SXin Li     Codec *client = reinterpret_cast<Codec *>(client_data);
93*600f14f4SXin Li     client->errorCallback(status);
94*600f14f4SXin Li   };
95*600f14f4SXin Li 
96*600f14f4SXin Li   if (mFdp.ConsumeBool()) {
97*600f14f4SXin Li     FLAC__stream_decoder_set_metadata_ignore(mDecoder, mFdp.PickValueInArray(kMetadataTypes));
98*600f14f4SXin Li   }
99*600f14f4SXin Li   if (mFdp.ConsumeBool()) {
100*600f14f4SXin Li     FLAC__stream_decoder_skip_single_frame(mDecoder);
101*600f14f4SXin Li   }
102*600f14f4SXin Li 
103*600f14f4SXin Li   if (mFdp.ConsumeBool()) {
104*600f14f4SXin Li     FLAC__MetadataType metadataType = mFdp.PickValueInArray(kMetadataTypes);
105*600f14f4SXin Li     FLAC__stream_decoder_set_metadata_respond(mDecoder, metadataType);
106*600f14f4SXin Li   }
107*600f14f4SXin Li   else {
108*600f14f4SXin Li     FLAC__byte* metadataIgnoreID = (FLAC__byte*)mFdp.PickValueInArray(kMetadataIDs);
109*600f14f4SXin Li     FLAC__byte* metadataRespondID = (FLAC__byte*)mFdp.PickValueInArray(kMetadataIDs);
110*600f14f4SXin Li     FLAC__stream_decoder_set_metadata_ignore_application(mDecoder, metadataIgnoreID);
111*600f14f4SXin Li     FLAC__stream_decoder_set_metadata_respond_application(mDecoder, metadataRespondID);
112*600f14f4SXin Li   }
113*600f14f4SXin Li 
114*600f14f4SXin Li   static auto metadata_callback = [](const FLAC__StreamDecoder *,
115*600f14f4SXin Li                                      const FLAC__StreamMetadata *metadata, void *client_data) {
116*600f14f4SXin Li     Codec *client = reinterpret_cast<Codec *>(client_data);
117*600f14f4SXin Li     client->metadataCallback(metadata);
118*600f14f4SXin Li   };
119*600f14f4SXin Li   void *client_data = reinterpret_cast<void *>(this);
120*600f14f4SXin Li   FLAC__StreamDecoderInitStatus initStatus = FLAC__stream_decoder_init_stream(
121*600f14f4SXin Li       mDecoder, read_callback, nullptr, nullptr, nullptr, nullptr, write_callback,
122*600f14f4SXin Li       metadata_callback, error_callback, client_data);
123*600f14f4SXin Li   if (initStatus != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
124*600f14f4SXin Li     return false;
125*600f14f4SXin Li   }
126*600f14f4SXin Li   if (mFdp.ConsumeBool()) {
127*600f14f4SXin Li     FLAC__stream_decoder_set_metadata_respond_all(mDecoder);
128*600f14f4SXin Li   }
129*600f14f4SXin Li   if (mFdp.ConsumeBool()) {
130*600f14f4SXin Li     FLAC__stream_decoder_seek_absolute(mDecoder, (FLAC__uint64)mFdp.ConsumeIntegral<uint64_t>());
131*600f14f4SXin Li   }
132*600f14f4SXin Li   return true;
133*600f14f4SXin Li }
134*600f14f4SXin Li 
readCallback(FLAC__byte buffer[],size_t * bytes)135*600f14f4SXin Li FLAC__StreamDecoderReadStatus Codec::readCallback(FLAC__byte buffer[], size_t *bytes) {
136*600f14f4SXin Li   if (!mBuffer || mBufferLen == 0) {
137*600f14f4SXin Li     *bytes = 0;
138*600f14f4SXin Li     return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
139*600f14f4SXin Li   }
140*600f14f4SXin Li   size_t bytesRequested = *bytes;
141*600f14f4SXin Li   if (bytesRequested > mBufferLen - mBufferPos) {
142*600f14f4SXin Li     bytesRequested = mBufferLen - mBufferPos;
143*600f14f4SXin Li   }
144*600f14f4SXin Li   memcpy(buffer, mBuffer + mBufferPos, bytesRequested);
145*600f14f4SXin Li   mBufferPos += bytesRequested;
146*600f14f4SXin Li   *bytes = bytesRequested;
147*600f14f4SXin Li   return (bytesRequested == 0 ? FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM
148*600f14f4SXin Li                               : FLAC__STREAM_DECODER_READ_STATUS_CONTINUE);
149*600f14f4SXin Li }
150*600f14f4SXin Li 
writeCallback(const FLAC__Frame * frame,const FLAC__int32 * const buffer[])151*600f14f4SXin Li FLAC__StreamDecoderWriteStatus Codec::writeCallback(const FLAC__Frame *frame,
152*600f14f4SXin Li                                                     const FLAC__int32 *const buffer[]) {
153*600f14f4SXin Li   (void)frame;
154*600f14f4SXin Li   (void)buffer;
155*600f14f4SXin Li   return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
156*600f14f4SXin Li }
157*600f14f4SXin Li 
errorCallback(FLAC__StreamDecoderErrorStatus status)158*600f14f4SXin Li void Codec::errorCallback(FLAC__StreamDecoderErrorStatus status) {
159*600f14f4SXin Li   (void)status;
160*600f14f4SXin Li   return;
161*600f14f4SXin Li }
162*600f14f4SXin Li 
metadataCallback(const FLAC__StreamMetadata * metadata)163*600f14f4SXin Li void Codec::metadataCallback(const FLAC__StreamMetadata *metadata) {
164*600f14f4SXin Li   (void)metadata;
165*600f14f4SXin Li   return;
166*600f14f4SXin Li }
167*600f14f4SXin Li 
decodeFrames()168*600f14f4SXin Li void Codec::decodeFrames() {
169*600f14f4SXin Li   if (mFdp.ConsumeBool()) {
170*600f14f4SXin Li     if (!FLAC__stream_decoder_process_until_end_of_metadata(mDecoder)) {
171*600f14f4SXin Li       return;
172*600f14f4SXin Li     }
173*600f14f4SXin Li     while(mBufferPos <= mBufferLen) {
174*600f14f4SXin Li       FLAC__stream_decoder_process_single(mDecoder);
175*600f14f4SXin Li       if (FLAC__STREAM_DECODER_END_OF_STREAM == FLAC__stream_decoder_get_state(mDecoder)) {
176*600f14f4SXin Li         return;
177*600f14f4SXin Li       }
178*600f14f4SXin Li     }
179*600f14f4SXin Li   } else {
180*600f14f4SXin Li     FLAC__stream_decoder_process_until_end_of_stream(mDecoder);
181*600f14f4SXin Li   }
182*600f14f4SXin Li   FLAC__stream_decoder_finish(mDecoder);
183*600f14f4SXin Li }
184*600f14f4SXin Li 
deInitDecoder()185*600f14f4SXin Li void Codec::deInitDecoder() {
186*600f14f4SXin Li   if (mDecoder != nullptr) {
187*600f14f4SXin Li     FLAC__stream_decoder_delete(mDecoder);
188*600f14f4SXin Li   }
189*600f14f4SXin Li }
190*600f14f4SXin Li 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)191*600f14f4SXin Li extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
192*600f14f4SXin Li   if (size == 0) {
193*600f14f4SXin Li     return 0;
194*600f14f4SXin Li   }
195*600f14f4SXin Li   auto codec = std::make_unique<Codec>(data, size);
196*600f14f4SXin Li   if (codec->initDecoder()) {
197*600f14f4SXin Li     codec->decodeFrames();
198*600f14f4SXin Li   }
199*600f14f4SXin Li   return 0;
200*600f14f4SXin Li }
201