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