Loading media/libmediaplayerservice/MediaPlayerService.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -237,7 +237,8 @@ void unmarshallAudioAttributes(const Parcel& parcel, audio_attributes_t *attribu // copying array size -1, array for tags was calloc'd, no need to NULL-terminate it size_t tagSize = realTagSize > AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 ? AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 : realTagSize; utf16_to_utf8(tags.string(), tagSize, attributes->tags); utf16_to_utf8(tags.string(), tagSize, attributes->tags, sizeof(attributes->tags) / sizeof(attributes->tags[0])); } } else { ALOGE("unmarshallAudioAttributes() received unflattened tags, ignoring tag values"); Loading media/libstagefright/OMXCodec.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -1637,7 +1637,9 @@ status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) { for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) { sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize); CHECK(mem.get() != NULL); if (mem == NULL || mem->pointer() == NULL) { return NO_MEMORY; } BufferInfo info; info.mData = NULL; Loading media/libstagefright/SampleTable.cpp +137 −35 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ //#define LOG_NDEBUG 0 #include <utils/Log.h> #include <limits> #include "include/SampleTable.h" #include "include/SampleIterator.h" Loading @@ -27,11 +29,6 @@ #include <media/stagefright/DataSource.h> #include <media/stagefright/Utils.h> /* TODO: remove after being merged into other branches */ #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif namespace android { // static Loading @@ -45,6 +42,8 @@ const uint32_t SampleTable::kSampleSizeTypeCompact = FOURCC('s', 't', 'z', '2'); //////////////////////////////////////////////////////////////////////////////// const off64_t kMaxOffset = std::numeric_limits<off64_t>::max(); struct SampleTable::CompositionDeltaLookup { CompositionDeltaLookup(); Loading Loading @@ -123,7 +122,7 @@ SampleTable::SampleTable(const sp<DataSource> &source) mNumSampleSizes(0), mHasTimeToSample(false), mTimeToSampleCount(0), mTimeToSample(), mTimeToSample(NULL), mSampleTimeEntries(NULL), mCompositionTimeDeltaEntries(NULL), mNumCompositionTimeDeltaEntries(0), Loading @@ -132,7 +131,8 @@ SampleTable::SampleTable(const sp<DataSource> &source) mNumSyncSamples(0), mSyncSamples(NULL), mLastSyncSampleIndex(0), mSampleToChunkEntries(NULL) { mSampleToChunkEntries(NULL), mTotalSize(0) { mSampleIterator = new SampleIterator(this); } Loading @@ -143,6 +143,9 @@ SampleTable::~SampleTable() { delete[] mSyncSamples; mSyncSamples = NULL; delete[] mTimeToSample; mTimeToSample = NULL; delete mCompositionDeltaLookup; mCompositionDeltaLookup = NULL; Loading Loading @@ -234,32 +237,67 @@ status_t SampleTable::setSampleToChunkParams( mNumSampleToChunkOffsets = U32_AT(&header[4]); if ((data_size - 8) / 12 < mNumSampleToChunkOffsets) { if ((data_size - 8) / sizeof(SampleToChunkEntry) < mNumSampleToChunkOffsets) { return ERROR_MALFORMED; } if (SIZE_MAX / sizeof(SampleToChunkEntry) <= (size_t)mNumSampleToChunkOffsets) if ((uint64_t)kMaxTotalSize / sizeof(SampleToChunkEntry) <= (uint64_t)mNumSampleToChunkOffsets) { ALOGE("Sample-to-chunk table size too large."); return ERROR_OUT_OF_RANGE; } mTotalSize += (uint64_t)mNumSampleToChunkOffsets * sizeof(SampleToChunkEntry); if (mTotalSize > kMaxTotalSize) { ALOGE("Sample-to-chunk table size would make sample table too large.\n" " Requested sample-to-chunk table size = %llu\n" " Eventual sample table size >= %llu\n" " Allowed sample table size = %llu\n", (unsigned long long)mNumSampleToChunkOffsets * sizeof(SampleToChunkEntry), (unsigned long long)mTotalSize, (unsigned long long)kMaxTotalSize); return ERROR_OUT_OF_RANGE; } mSampleToChunkEntries = new (std::nothrow) SampleToChunkEntry[mNumSampleToChunkOffsets]; if (!mSampleToChunkEntries) if (!mSampleToChunkEntries) { ALOGE("Cannot allocate sample-to-chunk table with %llu entries.", (unsigned long long)mNumSampleToChunkOffsets); return ERROR_OUT_OF_RANGE; } if (mNumSampleToChunkOffsets == 0) { return OK; } if ((off64_t)(kMaxOffset - 8 - ((mNumSampleToChunkOffsets - 1) * sizeof(SampleToChunkEntry))) < mSampleToChunkOffset) { return ERROR_MALFORMED; } for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) { uint8_t buffer[12]; uint8_t buffer[sizeof(SampleToChunkEntry)]; if ((SIZE_MAX - 8 - (i * 12)) < (size_t)mSampleToChunkOffset) { return ERROR_MALFORMED; } if (mDataSource->readAt( mSampleToChunkOffset + 8 + i * 12, buffer, sizeof(buffer)) mSampleToChunkOffset + 8 + i * sizeof(SampleToChunkEntry), buffer, sizeof(buffer)) != (ssize_t)sizeof(buffer)) { return ERROR_IO; } CHECK(U32_AT(buffer) >= 1); // chunk index is 1 based in the spec. // chunk index is 1 based in the spec. if (U32_AT(buffer) < 1) { ALOGE("b/23534160"); return ERROR_OUT_OF_RANGE; } // We want the chunk index to be 0-based. mSampleToChunkEntries[i].startChunk = U32_AT(buffer) - 1; Loading Loading @@ -351,29 +389,48 @@ status_t SampleTable::setTimeToSampleParams( } mTimeToSampleCount = U32_AT(&header[4]); if ((uint64_t)mTimeToSampleCount > (uint64_t)UINT32_MAX / (2 * sizeof(uint32_t))) { if (mTimeToSampleCount > UINT32_MAX / (2 * sizeof(uint32_t))) { // Choose this bound because // 1) 2 * sizeof(uint32_t) is the amount of memory needed for one // time-to-sample entry in the time-to-sample table. // 2) mTimeToSampleCount is the number of entries of the time-to-sample // table. // 3) We hope that the table size does not exceed UINT32_MAX. ALOGE(" Error: Time-to-sample table size too large."); ALOGE("Time-to-sample table size too large."); return ERROR_OUT_OF_RANGE; } // Note: At this point, we know that mTimeToSampleCount * 2 will not // overflow because of the above condition. if (!mDataSource->getVector(data_offset + 8, &mTimeToSample, mTimeToSampleCount * 2)) { ALOGE(" Error: Incomplete data read for time-to-sample table."); uint64_t allocSize = (uint64_t)mTimeToSampleCount * 2 * sizeof(uint32_t); mTotalSize += allocSize; if (mTotalSize > kMaxTotalSize) { ALOGE("Time-to-sample table size would make sample table too large.\n" " Requested time-to-sample table size = %llu\n" " Eventual sample table size >= %llu\n" " Allowed sample table size = %llu\n", (unsigned long long)allocSize, (unsigned long long)mTotalSize, (unsigned long long)kMaxTotalSize); return ERROR_OUT_OF_RANGE; } mTimeToSample = new (std::nothrow) uint32_t[mTimeToSampleCount * 2]; if (!mTimeToSample) { ALOGE("Cannot allocate time-to-sample table with %llu entries.", (unsigned long long)mTimeToSampleCount); return ERROR_OUT_OF_RANGE; } if (mDataSource->readAt(data_offset + 8, mTimeToSample, (size_t)allocSize) < (ssize_t)allocSize) { ALOGE("Incomplete data read for time-to-sample table."); return ERROR_IO; } for (size_t i = 0; i < mTimeToSample.size(); ++i) { mTimeToSample.editItemAt(i) = ntohl(mTimeToSample[i]); for (size_t i = 0; i < mTimeToSampleCount * 2; ++i) { mTimeToSample[i] = ntohl(mTimeToSample[i]); } mHasTimeToSample = true; Loading Loading @@ -408,17 +465,32 @@ status_t SampleTable::setCompositionTimeToSampleParams( mNumCompositionTimeDeltaEntries = numEntries; uint64_t allocSize = (uint64_t)numEntries * 2 * sizeof(uint32_t); if (allocSize > UINT32_MAX) { if (allocSize > kMaxTotalSize) { ALOGE("Composition-time-to-sample table size too large."); return ERROR_OUT_OF_RANGE; } mTotalSize += allocSize; if (mTotalSize > kMaxTotalSize) { ALOGE("Composition-time-to-sample table would make sample table too large.\n" " Requested composition-time-to-sample table size = %llu\n" " Eventual sample table size >= %llu\n" " Allowed sample table size = %llu\n", (unsigned long long)allocSize, (unsigned long long)mTotalSize, (unsigned long long)kMaxTotalSize); return ERROR_OUT_OF_RANGE; } mCompositionTimeDeltaEntries = new (std::nothrow) uint32_t[2 * numEntries]; if (!mCompositionTimeDeltaEntries) if (!mCompositionTimeDeltaEntries) { ALOGE("Cannot allocate composition-time-to-sample table with %llu " "entries.", (unsigned long long)numEntries); return ERROR_OUT_OF_RANGE; } if (mDataSource->readAt( data_offset + 8, mCompositionTimeDeltaEntries, numEntries * 8) < (ssize_t)numEntries * 8) { if (mDataSource->readAt(data_offset + 8, mCompositionTimeDeltaEntries, (size_t)allocSize) < (ssize_t)allocSize) { delete[] mCompositionTimeDeltaEntries; mCompositionTimeDeltaEntries = NULL; Loading Loading @@ -459,18 +531,33 @@ status_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) ALOGV("Table of sync samples is empty or has only a single entry!"); } uint64_t allocSize = mNumSyncSamples * (uint64_t)sizeof(uint32_t); if (allocSize > SIZE_MAX) { uint64_t allocSize = (uint64_t)mNumSyncSamples * sizeof(uint32_t); if (allocSize > kMaxTotalSize) { ALOGE("Sync sample table size too large."); return ERROR_OUT_OF_RANGE; } mTotalSize += allocSize; if (mTotalSize > kMaxTotalSize) { ALOGE("Sync sample table size would make sample table too large.\n" " Requested sync sample table size = %llu\n" " Eventual sample table size >= %llu\n" " Allowed sample table size = %llu\n", (unsigned long long)allocSize, (unsigned long long)mTotalSize, (unsigned long long)kMaxTotalSize); return ERROR_OUT_OF_RANGE; } mSyncSamples = new (std::nothrow) uint32_t[mNumSyncSamples]; if (!mSyncSamples) if (!mSyncSamples) { ALOGE("Cannot allocate sync sample table with %llu entries.", (unsigned long long)mNumSyncSamples); return ERROR_OUT_OF_RANGE; } size_t size = mNumSyncSamples * sizeof(uint32_t); if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, size) != (ssize_t)size) { if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, (size_t)allocSize) != (ssize_t)allocSize) { return ERROR_IO; } Loading Loading @@ -535,9 +622,24 @@ void SampleTable::buildSampleEntriesTable() { return; } mTotalSize += (uint64_t)mNumSampleSizes * sizeof(SampleTimeEntry); if (mTotalSize > kMaxTotalSize) { ALOGE("Sample entry table size would make sample table too large.\n" " Requested sample entry table size = %llu\n" " Eventual sample table size >= %llu\n" " Allowed sample table size = %llu\n", (unsigned long long)mNumSampleSizes * sizeof(SampleTimeEntry), (unsigned long long)mTotalSize, (unsigned long long)kMaxTotalSize); return; } mSampleTimeEntries = new (std::nothrow) SampleTimeEntry[mNumSampleSizes]; if (!mSampleTimeEntries) if (!mSampleTimeEntries) { ALOGE("Cannot allocate sample entry table with %llu entries.", (unsigned long long)mNumSampleSizes); return; } uint32_t sampleIndex = 0; uint32_t sampleTime = 0; Loading media/libstagefright/Utils.cpp +19 −11 Original line number Diff line number Diff line Loading @@ -694,22 +694,30 @@ void convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) { // reassemble the csd data into its original form sp<ABuffer> csd0; if (msg->findBuffer("csd-0", &csd0)) { int csd0size = csd0->size(); if (mime == MEDIA_MIMETYPE_VIDEO_AVC) { sp<ABuffer> csd1; if (msg->findBuffer("csd-1", &csd1)) { char avcc[1024]; // that oughta be enough, right? size_t outsize = reassembleAVCC(csd0, csd1, avcc); meta->setData(kKeyAVCC, kKeyAVCC, avcc, outsize); Vector<char> avcc; int avccSize = csd0size + csd1->size() + 1024; if (avcc.resize(avccSize) < 0) { ALOGE("error allocating avcc (size %d); abort setting avcc.", avccSize); } else { size_t outsize = reassembleAVCC(csd0, csd1, avcc.editArray()); meta->setData(kKeyAVCC, kKeyAVCC, avcc.array(), outsize); } } } else if (mime == MEDIA_MIMETYPE_AUDIO_AAC || mime == MEDIA_MIMETYPE_VIDEO_MPEG4) { int csd0size = csd0->size(); char esds[csd0size + 31]; Vector<char> esds; int esdsSize = csd0size + 31; if (esds.resize(esdsSize) < 0) { ALOGE("error allocating esds (size %d); abort setting esds.", esdsSize); } else { // The written ESDS is actually for an audio stream, but it's enough // for transporting the CSD to muxers. reassembleESDS(csd0, esds); meta->setData(kKeyESDS, kKeyESDS, esds, sizeof(esds)); } else { AVUtils::get()->HEVCMuxerUtils().reassembleHEVCCSD(mime, csd0, meta); reassembleESDS(csd0, esds.editArray()); meta->setData(kKeyESDS, kKeyESDS, esds.array(), esds.size()); } } } Loading media/libstagefright/codecs/mp3dec/SoftMP3.cpp +18 −4 Original line number Diff line number Diff line Loading @@ -122,6 +122,17 @@ void SoftMP3::initDecoder() { mIsFirst = true; } void *SoftMP3::memsetSafe(OMX_BUFFERHEADERTYPE *outHeader, int c, size_t len) { if (len > outHeader->nAllocLen) { ALOGE("memset buffer too small: got %u, expected %zu", outHeader->nAllocLen, len); android_errorWriteLog(0x534e4554, "29422022"); notify(OMX_EventError, OMX_ErrorUndefined, OUTPUT_BUFFER_TOO_SMALL, NULL); mSignalledError = true; return NULL; } return memset(outHeader->pBuffer, c, len); } OMX_ERRORTYPE SoftMP3::internalGetParameter( OMX_INDEXTYPE index, OMX_PTR params) { switch (index) { Loading Loading @@ -318,7 +329,10 @@ void SoftMP3::onQueueFilled(OMX_U32 /* portIndex */) { outHeader->nOffset = 0; outHeader->nFilledLen = kPVMP3DecoderDelay * mNumChannels * sizeof(int16_t); memset(outHeader->pBuffer, 0, outHeader->nFilledLen); if (!memsetSafe(outHeader, 0, outHeader->nFilledLen)) { return; } } outHeader->nFlags = OMX_BUFFERFLAG_EOS; mSignalledOutputEos = true; Loading @@ -330,9 +344,9 @@ void SoftMP3::onQueueFilled(OMX_U32 /* portIndex */) { // if mIsFirst is true as we may not have a valid // mConfig->samplingRate and mConfig->num_channels? ALOGV_IF(mIsFirst, "insufficient data for first frame, sending silence"); memset(outHeader->pBuffer, 0, mConfig->outputFrameSize * sizeof(int16_t)); if (!memsetSafe(outHeader, 0, mConfig->outputFrameSize * sizeof(int16_t))) { return; } if (inHeader) { mConfig->inputBufferUsedLength = inHeader->nFilledLen; Loading Loading
media/libmediaplayerservice/MediaPlayerService.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -237,7 +237,8 @@ void unmarshallAudioAttributes(const Parcel& parcel, audio_attributes_t *attribu // copying array size -1, array for tags was calloc'd, no need to NULL-terminate it size_t tagSize = realTagSize > AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 ? AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 : realTagSize; utf16_to_utf8(tags.string(), tagSize, attributes->tags); utf16_to_utf8(tags.string(), tagSize, attributes->tags, sizeof(attributes->tags) / sizeof(attributes->tags[0])); } } else { ALOGE("unmarshallAudioAttributes() received unflattened tags, ignoring tag values"); Loading
media/libstagefright/OMXCodec.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -1637,7 +1637,9 @@ status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) { for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) { sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize); CHECK(mem.get() != NULL); if (mem == NULL || mem->pointer() == NULL) { return NO_MEMORY; } BufferInfo info; info.mData = NULL; Loading
media/libstagefright/SampleTable.cpp +137 −35 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ //#define LOG_NDEBUG 0 #include <utils/Log.h> #include <limits> #include "include/SampleTable.h" #include "include/SampleIterator.h" Loading @@ -27,11 +29,6 @@ #include <media/stagefright/DataSource.h> #include <media/stagefright/Utils.h> /* TODO: remove after being merged into other branches */ #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif namespace android { // static Loading @@ -45,6 +42,8 @@ const uint32_t SampleTable::kSampleSizeTypeCompact = FOURCC('s', 't', 'z', '2'); //////////////////////////////////////////////////////////////////////////////// const off64_t kMaxOffset = std::numeric_limits<off64_t>::max(); struct SampleTable::CompositionDeltaLookup { CompositionDeltaLookup(); Loading Loading @@ -123,7 +122,7 @@ SampleTable::SampleTable(const sp<DataSource> &source) mNumSampleSizes(0), mHasTimeToSample(false), mTimeToSampleCount(0), mTimeToSample(), mTimeToSample(NULL), mSampleTimeEntries(NULL), mCompositionTimeDeltaEntries(NULL), mNumCompositionTimeDeltaEntries(0), Loading @@ -132,7 +131,8 @@ SampleTable::SampleTable(const sp<DataSource> &source) mNumSyncSamples(0), mSyncSamples(NULL), mLastSyncSampleIndex(0), mSampleToChunkEntries(NULL) { mSampleToChunkEntries(NULL), mTotalSize(0) { mSampleIterator = new SampleIterator(this); } Loading @@ -143,6 +143,9 @@ SampleTable::~SampleTable() { delete[] mSyncSamples; mSyncSamples = NULL; delete[] mTimeToSample; mTimeToSample = NULL; delete mCompositionDeltaLookup; mCompositionDeltaLookup = NULL; Loading Loading @@ -234,32 +237,67 @@ status_t SampleTable::setSampleToChunkParams( mNumSampleToChunkOffsets = U32_AT(&header[4]); if ((data_size - 8) / 12 < mNumSampleToChunkOffsets) { if ((data_size - 8) / sizeof(SampleToChunkEntry) < mNumSampleToChunkOffsets) { return ERROR_MALFORMED; } if (SIZE_MAX / sizeof(SampleToChunkEntry) <= (size_t)mNumSampleToChunkOffsets) if ((uint64_t)kMaxTotalSize / sizeof(SampleToChunkEntry) <= (uint64_t)mNumSampleToChunkOffsets) { ALOGE("Sample-to-chunk table size too large."); return ERROR_OUT_OF_RANGE; } mTotalSize += (uint64_t)mNumSampleToChunkOffsets * sizeof(SampleToChunkEntry); if (mTotalSize > kMaxTotalSize) { ALOGE("Sample-to-chunk table size would make sample table too large.\n" " Requested sample-to-chunk table size = %llu\n" " Eventual sample table size >= %llu\n" " Allowed sample table size = %llu\n", (unsigned long long)mNumSampleToChunkOffsets * sizeof(SampleToChunkEntry), (unsigned long long)mTotalSize, (unsigned long long)kMaxTotalSize); return ERROR_OUT_OF_RANGE; } mSampleToChunkEntries = new (std::nothrow) SampleToChunkEntry[mNumSampleToChunkOffsets]; if (!mSampleToChunkEntries) if (!mSampleToChunkEntries) { ALOGE("Cannot allocate sample-to-chunk table with %llu entries.", (unsigned long long)mNumSampleToChunkOffsets); return ERROR_OUT_OF_RANGE; } if (mNumSampleToChunkOffsets == 0) { return OK; } if ((off64_t)(kMaxOffset - 8 - ((mNumSampleToChunkOffsets - 1) * sizeof(SampleToChunkEntry))) < mSampleToChunkOffset) { return ERROR_MALFORMED; } for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) { uint8_t buffer[12]; uint8_t buffer[sizeof(SampleToChunkEntry)]; if ((SIZE_MAX - 8 - (i * 12)) < (size_t)mSampleToChunkOffset) { return ERROR_MALFORMED; } if (mDataSource->readAt( mSampleToChunkOffset + 8 + i * 12, buffer, sizeof(buffer)) mSampleToChunkOffset + 8 + i * sizeof(SampleToChunkEntry), buffer, sizeof(buffer)) != (ssize_t)sizeof(buffer)) { return ERROR_IO; } CHECK(U32_AT(buffer) >= 1); // chunk index is 1 based in the spec. // chunk index is 1 based in the spec. if (U32_AT(buffer) < 1) { ALOGE("b/23534160"); return ERROR_OUT_OF_RANGE; } // We want the chunk index to be 0-based. mSampleToChunkEntries[i].startChunk = U32_AT(buffer) - 1; Loading Loading @@ -351,29 +389,48 @@ status_t SampleTable::setTimeToSampleParams( } mTimeToSampleCount = U32_AT(&header[4]); if ((uint64_t)mTimeToSampleCount > (uint64_t)UINT32_MAX / (2 * sizeof(uint32_t))) { if (mTimeToSampleCount > UINT32_MAX / (2 * sizeof(uint32_t))) { // Choose this bound because // 1) 2 * sizeof(uint32_t) is the amount of memory needed for one // time-to-sample entry in the time-to-sample table. // 2) mTimeToSampleCount is the number of entries of the time-to-sample // table. // 3) We hope that the table size does not exceed UINT32_MAX. ALOGE(" Error: Time-to-sample table size too large."); ALOGE("Time-to-sample table size too large."); return ERROR_OUT_OF_RANGE; } // Note: At this point, we know that mTimeToSampleCount * 2 will not // overflow because of the above condition. if (!mDataSource->getVector(data_offset + 8, &mTimeToSample, mTimeToSampleCount * 2)) { ALOGE(" Error: Incomplete data read for time-to-sample table."); uint64_t allocSize = (uint64_t)mTimeToSampleCount * 2 * sizeof(uint32_t); mTotalSize += allocSize; if (mTotalSize > kMaxTotalSize) { ALOGE("Time-to-sample table size would make sample table too large.\n" " Requested time-to-sample table size = %llu\n" " Eventual sample table size >= %llu\n" " Allowed sample table size = %llu\n", (unsigned long long)allocSize, (unsigned long long)mTotalSize, (unsigned long long)kMaxTotalSize); return ERROR_OUT_OF_RANGE; } mTimeToSample = new (std::nothrow) uint32_t[mTimeToSampleCount * 2]; if (!mTimeToSample) { ALOGE("Cannot allocate time-to-sample table with %llu entries.", (unsigned long long)mTimeToSampleCount); return ERROR_OUT_OF_RANGE; } if (mDataSource->readAt(data_offset + 8, mTimeToSample, (size_t)allocSize) < (ssize_t)allocSize) { ALOGE("Incomplete data read for time-to-sample table."); return ERROR_IO; } for (size_t i = 0; i < mTimeToSample.size(); ++i) { mTimeToSample.editItemAt(i) = ntohl(mTimeToSample[i]); for (size_t i = 0; i < mTimeToSampleCount * 2; ++i) { mTimeToSample[i] = ntohl(mTimeToSample[i]); } mHasTimeToSample = true; Loading Loading @@ -408,17 +465,32 @@ status_t SampleTable::setCompositionTimeToSampleParams( mNumCompositionTimeDeltaEntries = numEntries; uint64_t allocSize = (uint64_t)numEntries * 2 * sizeof(uint32_t); if (allocSize > UINT32_MAX) { if (allocSize > kMaxTotalSize) { ALOGE("Composition-time-to-sample table size too large."); return ERROR_OUT_OF_RANGE; } mTotalSize += allocSize; if (mTotalSize > kMaxTotalSize) { ALOGE("Composition-time-to-sample table would make sample table too large.\n" " Requested composition-time-to-sample table size = %llu\n" " Eventual sample table size >= %llu\n" " Allowed sample table size = %llu\n", (unsigned long long)allocSize, (unsigned long long)mTotalSize, (unsigned long long)kMaxTotalSize); return ERROR_OUT_OF_RANGE; } mCompositionTimeDeltaEntries = new (std::nothrow) uint32_t[2 * numEntries]; if (!mCompositionTimeDeltaEntries) if (!mCompositionTimeDeltaEntries) { ALOGE("Cannot allocate composition-time-to-sample table with %llu " "entries.", (unsigned long long)numEntries); return ERROR_OUT_OF_RANGE; } if (mDataSource->readAt( data_offset + 8, mCompositionTimeDeltaEntries, numEntries * 8) < (ssize_t)numEntries * 8) { if (mDataSource->readAt(data_offset + 8, mCompositionTimeDeltaEntries, (size_t)allocSize) < (ssize_t)allocSize) { delete[] mCompositionTimeDeltaEntries; mCompositionTimeDeltaEntries = NULL; Loading Loading @@ -459,18 +531,33 @@ status_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) ALOGV("Table of sync samples is empty or has only a single entry!"); } uint64_t allocSize = mNumSyncSamples * (uint64_t)sizeof(uint32_t); if (allocSize > SIZE_MAX) { uint64_t allocSize = (uint64_t)mNumSyncSamples * sizeof(uint32_t); if (allocSize > kMaxTotalSize) { ALOGE("Sync sample table size too large."); return ERROR_OUT_OF_RANGE; } mTotalSize += allocSize; if (mTotalSize > kMaxTotalSize) { ALOGE("Sync sample table size would make sample table too large.\n" " Requested sync sample table size = %llu\n" " Eventual sample table size >= %llu\n" " Allowed sample table size = %llu\n", (unsigned long long)allocSize, (unsigned long long)mTotalSize, (unsigned long long)kMaxTotalSize); return ERROR_OUT_OF_RANGE; } mSyncSamples = new (std::nothrow) uint32_t[mNumSyncSamples]; if (!mSyncSamples) if (!mSyncSamples) { ALOGE("Cannot allocate sync sample table with %llu entries.", (unsigned long long)mNumSyncSamples); return ERROR_OUT_OF_RANGE; } size_t size = mNumSyncSamples * sizeof(uint32_t); if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, size) != (ssize_t)size) { if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, (size_t)allocSize) != (ssize_t)allocSize) { return ERROR_IO; } Loading Loading @@ -535,9 +622,24 @@ void SampleTable::buildSampleEntriesTable() { return; } mTotalSize += (uint64_t)mNumSampleSizes * sizeof(SampleTimeEntry); if (mTotalSize > kMaxTotalSize) { ALOGE("Sample entry table size would make sample table too large.\n" " Requested sample entry table size = %llu\n" " Eventual sample table size >= %llu\n" " Allowed sample table size = %llu\n", (unsigned long long)mNumSampleSizes * sizeof(SampleTimeEntry), (unsigned long long)mTotalSize, (unsigned long long)kMaxTotalSize); return; } mSampleTimeEntries = new (std::nothrow) SampleTimeEntry[mNumSampleSizes]; if (!mSampleTimeEntries) if (!mSampleTimeEntries) { ALOGE("Cannot allocate sample entry table with %llu entries.", (unsigned long long)mNumSampleSizes); return; } uint32_t sampleIndex = 0; uint32_t sampleTime = 0; Loading
media/libstagefright/Utils.cpp +19 −11 Original line number Diff line number Diff line Loading @@ -694,22 +694,30 @@ void convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) { // reassemble the csd data into its original form sp<ABuffer> csd0; if (msg->findBuffer("csd-0", &csd0)) { int csd0size = csd0->size(); if (mime == MEDIA_MIMETYPE_VIDEO_AVC) { sp<ABuffer> csd1; if (msg->findBuffer("csd-1", &csd1)) { char avcc[1024]; // that oughta be enough, right? size_t outsize = reassembleAVCC(csd0, csd1, avcc); meta->setData(kKeyAVCC, kKeyAVCC, avcc, outsize); Vector<char> avcc; int avccSize = csd0size + csd1->size() + 1024; if (avcc.resize(avccSize) < 0) { ALOGE("error allocating avcc (size %d); abort setting avcc.", avccSize); } else { size_t outsize = reassembleAVCC(csd0, csd1, avcc.editArray()); meta->setData(kKeyAVCC, kKeyAVCC, avcc.array(), outsize); } } } else if (mime == MEDIA_MIMETYPE_AUDIO_AAC || mime == MEDIA_MIMETYPE_VIDEO_MPEG4) { int csd0size = csd0->size(); char esds[csd0size + 31]; Vector<char> esds; int esdsSize = csd0size + 31; if (esds.resize(esdsSize) < 0) { ALOGE("error allocating esds (size %d); abort setting esds.", esdsSize); } else { // The written ESDS is actually for an audio stream, but it's enough // for transporting the CSD to muxers. reassembleESDS(csd0, esds); meta->setData(kKeyESDS, kKeyESDS, esds, sizeof(esds)); } else { AVUtils::get()->HEVCMuxerUtils().reassembleHEVCCSD(mime, csd0, meta); reassembleESDS(csd0, esds.editArray()); meta->setData(kKeyESDS, kKeyESDS, esds.array(), esds.size()); } } } Loading
media/libstagefright/codecs/mp3dec/SoftMP3.cpp +18 −4 Original line number Diff line number Diff line Loading @@ -122,6 +122,17 @@ void SoftMP3::initDecoder() { mIsFirst = true; } void *SoftMP3::memsetSafe(OMX_BUFFERHEADERTYPE *outHeader, int c, size_t len) { if (len > outHeader->nAllocLen) { ALOGE("memset buffer too small: got %u, expected %zu", outHeader->nAllocLen, len); android_errorWriteLog(0x534e4554, "29422022"); notify(OMX_EventError, OMX_ErrorUndefined, OUTPUT_BUFFER_TOO_SMALL, NULL); mSignalledError = true; return NULL; } return memset(outHeader->pBuffer, c, len); } OMX_ERRORTYPE SoftMP3::internalGetParameter( OMX_INDEXTYPE index, OMX_PTR params) { switch (index) { Loading Loading @@ -318,7 +329,10 @@ void SoftMP3::onQueueFilled(OMX_U32 /* portIndex */) { outHeader->nOffset = 0; outHeader->nFilledLen = kPVMP3DecoderDelay * mNumChannels * sizeof(int16_t); memset(outHeader->pBuffer, 0, outHeader->nFilledLen); if (!memsetSafe(outHeader, 0, outHeader->nFilledLen)) { return; } } outHeader->nFlags = OMX_BUFFERFLAG_EOS; mSignalledOutputEos = true; Loading @@ -330,9 +344,9 @@ void SoftMP3::onQueueFilled(OMX_U32 /* portIndex */) { // if mIsFirst is true as we may not have a valid // mConfig->samplingRate and mConfig->num_channels? ALOGV_IF(mIsFirst, "insufficient data for first frame, sending silence"); memset(outHeader->pBuffer, 0, mConfig->outputFrameSize * sizeof(int16_t)); if (!memsetSafe(outHeader, 0, mConfig->outputFrameSize * sizeof(int16_t))) { return; } if (inHeader) { mConfig->inputBufferUsedLength = inHeader->nFilledLen; Loading