/** * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // This PoC is written using aac_dec_fuzzer.cpp as reference. #include "aacdecoder_lib.h" #include constexpr uint8_t kNumberOfLayers = 1; constexpr uint8_t kMaxChannelCount = 8; constexpr uint8_t kConfigBytes = 92; constexpr uint32_t kMaxOutBufferSize = 2048 * kMaxChannelCount; class Codec { public: Codec() = default; ~Codec() { deInitDecoder(); } bool initDecoder(); void decodeFrames(UCHAR *data, UINT size); void deInitDecoder(); private: HANDLE_AACDECODER mAacDecoderHandle = nullptr; AAC_DECODER_ERROR mErrorCode = AAC_DEC_OK; bool mConfigFlag = false; }; bool Codec::initDecoder() { mAacDecoderHandle = aacDecoder_Open(TT_MP4_ADIF, kNumberOfLayers); if (!mAacDecoderHandle) { return false; } return true; } void Codec::deInitDecoder() { aacDecoder_Close(mAacDecoderHandle); mAacDecoderHandle = nullptr; } void Codec::decodeFrames(UCHAR *data, UINT size) { while (size > 0) { UINT inputSize = size; UINT valid = size; if (!mConfigFlag) { inputSize = kConfigBytes; aacDecoder_ConfigRaw(mAacDecoderHandle, &data, &inputSize); data += kConfigBytes; size -= kConfigBytes; mConfigFlag = true; continue; } aacDecoder_Fill(mAacDecoderHandle, &data, &inputSize, &valid); INT_PCM outputBuf[kMaxOutBufferSize]; do { mErrorCode = aacDecoder_DecodeFrame(mAacDecoderHandle, outputBuf, kMaxOutBufferSize, 0); } while (mErrorCode == AAC_DEC_OK); UINT offset = inputSize - valid; data += offset; size = valid; } } int main(int argc, char *argv[]) { if (argc != 2) { return EXIT_FAILURE; } FILE *fp = fopen(argv[1], "rb"); if (!fp) { return EXIT_FAILURE; } fseek(fp, 0, SEEK_END); UINT size = ftell(fp); fseek(fp, 0, SEEK_SET); UCHAR *data = new UCHAR[size]; fread(data, sizeof(UCHAR), size, fp); fclose(fp); fp = nullptr; Codec *codec = new Codec(); if (!codec) { delete[] data; return EXIT_FAILURE; } if (codec->initDecoder()) { codec->decodeFrames((UCHAR *)(data), static_cast(size)); } delete codec; delete[] data; return EXIT_SUCCESS; }