1 /******************************************************************************
2  *
3  * Copyright (C) 2020 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19  */
20 
21 #include <stdlib.h>
22 #include <algorithm>
23 
24 #include <pvmp3decoder_api.h>
25 
26 constexpr int kMaxFrameSamples = 4608;
27 constexpr int kMaxChannels = 2;
28 constexpr e_equalization kEqualizerTypes[] = {flat, bass_boost, rock, pop,
29                                               jazz, classical,  talk, flat_};
30 
parseMp3Header(uint32_t header,size_t * frame_size,uint32_t * out_sampling_rate=nullptr,uint32_t * out_channels=nullptr,uint32_t * out_bitrate=nullptr,uint32_t * out_num_samples=nullptr)31 static bool parseMp3Header(uint32_t header, size_t *frame_size,
32                            uint32_t *out_sampling_rate = nullptr, uint32_t *out_channels = nullptr,
33                            uint32_t *out_bitrate = nullptr, uint32_t *out_num_samples = nullptr) {
34   *frame_size = 0;
35   if (out_sampling_rate) *out_sampling_rate = 0;
36   if (out_channels) *out_channels = 0;
37   if (out_bitrate) *out_bitrate = 0;
38   if (out_num_samples) *out_num_samples = 0;
39 
40   if ((header & 0xffe00000) != 0xffe00000) {
41     return false;
42   }
43   unsigned version = (header >> 19) & 3;
44   if (version == 0x01) {
45     return false;
46   }
47   unsigned layer = (header >> 17) & 3;
48   if (layer == 0x00) {
49     return false;
50   }
51   unsigned bitrate_index = (header >> 12) & 0x0f;
52   if (bitrate_index == 0 || bitrate_index == 0x0f) {
53     return false;
54   }
55   unsigned sampling_rate_index = (header >> 10) & 3;
56   if (sampling_rate_index == 3) {
57     return false;
58   }
59   static const int kSamplingRateV1[] = {44100, 48000, 32000};
60   int sampling_rate = kSamplingRateV1[sampling_rate_index];
61   if (version == 2 /* V2 */) {
62     sampling_rate /= 2;
63   } else if (version == 0 /* V2.5 */) {
64     sampling_rate /= 4;
65   }
66 
67   unsigned padding = (header >> 9) & 1;
68 
69   if (layer == 3) {  // layer I
70     static const int kBitrateV1[] = {32,  64,  96,  128, 160, 192, 224,
71                                      256, 288, 320, 352, 384, 416, 448};
72     static const int kBitrateV2[] = {32,  48,  56,  64,  80,  96,  112,
73                                      128, 144, 160, 176, 192, 224, 256};
74 
75     int bitrate =
76         (version == 3 /* V1 */) ? kBitrateV1[bitrate_index - 1] : kBitrateV2[bitrate_index - 1];
77 
78     if (out_bitrate) {
79       *out_bitrate = bitrate;
80     }
81     *frame_size = (12000 * bitrate / sampling_rate + padding) * 4;
82     if (out_num_samples) {
83       *out_num_samples = 384;
84     }
85   } else {  // layer II or III
86     static const int kBitrateV1L2[] = {32,  48,  56,  64,  80,  96,  112,
87                                        128, 160, 192, 224, 256, 320, 384};
88     static const int kBitrateV1L3[] = {32,  40,  48,  56,  64,  80,  96,
89                                        112, 128, 160, 192, 224, 256, 320};
90     static const int kBitrateV2[] = {8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160};
91     int bitrate;
92     if (version == 3 /* V1 */) {
93       bitrate =
94           (layer == 2 /* L2 */) ? kBitrateV1L2[bitrate_index - 1] : kBitrateV1L3[bitrate_index - 1];
95 
96       if (out_num_samples) {
97         *out_num_samples = 1152;
98       }
99     } else {  // V2 (or 2.5)
100       bitrate = kBitrateV2[bitrate_index - 1];
101       if (out_num_samples) {
102         *out_num_samples = (layer == 1 /* L3 */) ? 576 : 1152;
103       }
104     }
105 
106     if (out_bitrate) {
107       *out_bitrate = bitrate;
108     }
109 
110     if (version == 3 /* V1 */) {
111       *frame_size = 144000 * bitrate / sampling_rate + padding;
112     } else {  // V2 or V2.5
113       size_t tmp = (layer == 1 /* L3 */) ? 72000 : 144000;
114       *frame_size = tmp * bitrate / sampling_rate + padding;
115     }
116   }
117 
118   if (out_sampling_rate) {
119     *out_sampling_rate = sampling_rate;
120   }
121 
122   if (out_channels) {
123     int channel_mode = (header >> 6) & 3;
124     *out_channels = (channel_mode == 3) ? 1 : 2;
125   }
126 
127   return true;
128 }
129 
U32_AT(const uint8_t * ptr)130 static uint32_t U32_AT(const uint8_t *ptr) {
131   return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
132 }
133 
checkHeader(uint8 * header,size_t inSize)134 static bool checkHeader(uint8 *header, size_t inSize) {
135   size_t frameSize;
136   size_t totalInSize = 0;
137   bool isValidBuffer = false;
138 
139   while (totalInSize + 4 < inSize) {
140     isValidBuffer = true;
141     uint32_t val = U32_AT(header + totalInSize);
142     if (!parseMp3Header(val, &frameSize, nullptr, nullptr, nullptr, nullptr)) {
143       return false;
144     }
145     totalInSize += frameSize;
146   }
147 
148   return (isValidBuffer);
149 }
150 
151 class Codec {
152  public:
153   Codec() = default;
~Codec()154   ~Codec() { deInitDecoder(); }
155 
156   bool initDecoder();
157   void decodeFrames(uint8_t *data, size_t size);
158   void deInitDecoder();
159 
160  private:
161   tPVMP3DecoderExternal *mConfig = nullptr;
162   void *mDecoderBuf = nullptr;
163 };
164 
initDecoder()165 bool Codec::initDecoder() {
166   mConfig = new tPVMP3DecoderExternal{};
167   if (!mConfig) {
168     return false;
169   }
170   size_t decoderBufSize = pvmp3_decoderMemRequirements();
171   mDecoderBuf = malloc(decoderBufSize);
172   if (!mDecoderBuf) {
173     return false;
174   }
175   memset(mDecoderBuf, 0x0, decoderBufSize);
176   pvmp3_InitDecoder(mConfig, mDecoderBuf);
177   return true;
178 }
179 
decodeFrames(uint8_t * data,size_t size)180 void Codec::decodeFrames(uint8_t *data, size_t size) {
181   uint8_t equalizerTypeValue = (data[0] & 0x7);
182   mConfig->equalizerType = kEqualizerTypes[equalizerTypeValue];
183   mConfig->crcEnabled = data[1] & 0x1;
184 
185   while (size > 0) {
186     bool status = checkHeader(data, size);
187     if (!status) {
188       size--;
189       data++;
190       continue;
191     }
192     size_t outBufSize = kMaxFrameSamples * kMaxChannels;
193     size_t usedBytes = 0;
194     int16_t outputBuf[outBufSize];
195     mConfig->inputBufferCurrentLength = size;
196     mConfig->inputBufferUsedLength = 0;
197     mConfig->inputBufferMaxLength = 0;
198     mConfig->pInputBuffer = data;
199     mConfig->pOutputBuffer = outputBuf;
200     mConfig->outputFrameSize = outBufSize / sizeof(int16_t);
201 
202     ERROR_CODE decoderErr;
203     decoderErr = pvmp3_framedecoder(mConfig, mDecoderBuf);
204     if (decoderErr != NO_DECODING_ERROR) {
205       size--;
206       data++;
207     } else {
208       usedBytes = std::min((int32_t)size, mConfig->inputBufferUsedLength);
209       size -= usedBytes;
210       data += usedBytes;
211     }
212   }
213 }
214 
deInitDecoder()215 void Codec::deInitDecoder() {
216   if (mDecoderBuf) {
217     free(mDecoderBuf);
218     mDecoderBuf = nullptr;
219   }
220   delete mConfig;
221   mConfig = nullptr;
222 }
223 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)224 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
225   if (size < 4) {
226     return 0;
227   }
228   Codec *codec = new Codec();
229   if (!codec) {
230     return 0;
231   }
232   if (codec->initDecoder()) {
233     codec->decodeFrames(const_cast<uint8_t *>(data), size);
234   }
235   delete codec;
236   return 0;
237 }
238