1 /**
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 // This PoC is written using aac_dec_fuzzer.cpp as reference.
18 #include "aacdecoder_lib.h"
19 #include <stdlib.h>
20 
21 constexpr uint8_t kNumberOfLayers = 1;
22 constexpr uint8_t kMaxChannelCount = 8;
23 constexpr uint8_t kConfigBytes = 92;
24 constexpr uint32_t kMaxOutBufferSize = 2048 * kMaxChannelCount;
25 
26 class Codec {
27 public:
28   Codec() = default;
~Codec()29   ~Codec() { deInitDecoder(); }
30   bool initDecoder();
31   void decodeFrames(UCHAR *data, UINT size);
32   void deInitDecoder();
33 
34 private:
35   HANDLE_AACDECODER mAacDecoderHandle = nullptr;
36   AAC_DECODER_ERROR mErrorCode = AAC_DEC_OK;
37   bool mConfigFlag = false;
38 };
39 
initDecoder()40 bool Codec::initDecoder() {
41   mAacDecoderHandle = aacDecoder_Open(TT_MP4_ADIF, kNumberOfLayers);
42   if (!mAacDecoderHandle) {
43     return false;
44   }
45   return true;
46 }
47 
deInitDecoder()48 void Codec::deInitDecoder() {
49   aacDecoder_Close(mAacDecoderHandle);
50   mAacDecoderHandle = nullptr;
51 }
52 
decodeFrames(UCHAR * data,UINT size)53 void Codec::decodeFrames(UCHAR *data, UINT size) {
54   while (size > 0) {
55     UINT inputSize = size;
56     UINT valid = size;
57 
58     if (!mConfigFlag) {
59       inputSize = kConfigBytes;
60       aacDecoder_ConfigRaw(mAacDecoderHandle, &data, &inputSize);
61       data += kConfigBytes;
62       size -= kConfigBytes;
63       mConfigFlag = true;
64       continue;
65     }
66 
67     aacDecoder_Fill(mAacDecoderHandle, &data, &inputSize, &valid);
68     INT_PCM outputBuf[kMaxOutBufferSize];
69     do {
70         mErrorCode = aacDecoder_DecodeFrame(mAacDecoderHandle, outputBuf, kMaxOutBufferSize, 0);
71     } while (mErrorCode == AAC_DEC_OK);
72     UINT offset = inputSize - valid;
73     data += offset;
74     size = valid;
75   }
76 }
77 
main(int argc,char * argv[])78 int main(int argc, char *argv[]) {
79   if (argc != 2) {
80     return EXIT_FAILURE;
81   }
82 
83   FILE *fp = fopen(argv[1], "rb");
84   if (!fp) {
85     return EXIT_FAILURE;
86   }
87 
88   fseek(fp, 0, SEEK_END);
89   UINT size = ftell(fp);
90   fseek(fp, 0, SEEK_SET);
91   UCHAR *data = new UCHAR[size];
92   fread(data, sizeof(UCHAR), size, fp);
93   fclose(fp);
94   fp = nullptr;
95 
96   Codec *codec = new Codec();
97   if (!codec) {
98     delete[] data;
99     return EXIT_FAILURE;
100   }
101 
102   if (codec->initDecoder()) {
103     codec->decodeFrames((UCHAR *)(data), static_cast<UINT>(size));
104   }
105 
106   delete codec;
107   delete[] data;
108   return EXIT_SUCCESS;
109 }
110