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