Merge "DO NOT MERGE codecs: check OMX buffer size before use in vorbisdec" into klp-dev
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index d7223d9..17293c8 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -51,7 +51,11 @@
         audio_source_t inputSource, uint32_t sampleRate, uint32_t channelCount)
     : mStarted(false),
       mSampleRate(sampleRate),
+      mTrackMaxAmplitude(false),
+      mStartTimeUs(0),
+      mMaxAmplitude(0),
       mPrevSampleTimeUs(0),
+      mInitialReadTimeUs(0),
       mNumFramesReceived(0),
       mNumClientOwnedBuffers(0) {
     ALOGV("sampleRate: %d, channelCount: %d", sampleRate, channelCount);
diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp
index 116f358..dfc3713 100644
--- a/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/SampleTable.cpp
@@ -288,6 +288,7 @@
     mDefaultSampleSize = U32_AT(&header[4]);
     mNumSampleSizes = U32_AT(&header[8]);
     if (mNumSampleSizes > (UINT32_MAX - 12) / 16) {
+        ALOGE("b/23247055, mNumSampleSizes(%u)", mNumSampleSizes);
         return ERROR_MALFORMED;
     }
 
@@ -507,6 +508,9 @@
     Mutex::Autolock autoLock(mLock);
 
     if (mSampleTimeEntries != NULL || mNumSampleSizes == 0) {
+        if (mNumSampleSizes == 0) {
+            ALOGE("b/23247055, mNumSampleSizes(%u)", mNumSampleSizes);
+        }
         return;
     }
 
diff --git a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
index b2ea98b..6fb59dd 100644
--- a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
+++ b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
@@ -306,13 +306,6 @@
         BufferInfo *inInfo = *inQueue.begin();
         OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
 
-        if (inHeader->nFilledLen == 0) {
-            inInfo->mOwnedByUs = false;
-            inQueue.erase(inQueue.begin());
-            notifyEmptyBufferDone(inHeader);
-            continue;
-        }
-
         BufferInfo *outInfo = *outQueue.begin();
         OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
 
@@ -330,6 +323,13 @@
             return;
         }
 
+        if (inHeader->nFilledLen == 0) {
+            inInfo->mOwnedByUs = false;
+            inQueue.erase(inQueue.begin());
+            notifyEmptyBufferDone(inHeader);
+            continue;
+        }
+
         if (inHeader->nOffset == 0) {
             mAnchorTimeUs = inHeader->nTimeStamp;
             mNumSamplesOutput = 0;
diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
index fb2a430..1a53c72 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
@@ -209,6 +209,14 @@
         int32_t bufferSize = inHeader->nFilledLen;
         int32_t tmp = bufferSize;
 
+        OMX_U32 frameSize = (mWidth * mHeight * 3) / 2;
+        if (outHeader->nAllocLen < frameSize) {
+            android_errorWriteLog(0x534e4554, "27833616");
+            ALOGE("Insufficient output buffer size");
+            notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+            mSignalledError = true;
+            return;
+        }
         // The PV decoder is lying to us, sometimes it'll claim to only have
         // consumed a subset of the buffer when it clearly consumed all of it.
         // ignore whatever it says...
@@ -250,7 +258,7 @@
         ++mInputBufferCount;
 
         outHeader->nOffset = 0;
-        outHeader->nFilledLen = (mWidth * mHeight * 3) / 2;
+        outHeader->nFilledLen = frameSize;
 
         List<BufferInfo *>::iterator it = outQueue.begin();
         while ((*it)->mHeader != outHeader) {
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
index c210455..139af11 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
@@ -273,6 +273,14 @@
         mConfig->inputBufferUsedLength = 0;
 
         mConfig->outputFrameSize = kOutputBufferSize / sizeof(int16_t);
+        if ((int32)outHeader->nAllocLen < mConfig->outputFrameSize) {
+            ALOGE("input buffer too small: got %lu, expected %u",
+                outHeader->nAllocLen, mConfig->outputFrameSize);
+            android_errorWriteLog(0x534e4554, "27793371");
+            notify(OMX_EventError, OMX_ErrorUndefined, OUTPUT_BUFFER_TOO_SMALL, NULL);
+            mSignalledError = true;
+            return;
+        }
 
         mConfig->pOutputBuffer =
             reinterpret_cast<int16_t *>(outHeader->pBuffer);
diff --git a/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp b/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp
index 7ddb13c..1f9f8d7 100644
--- a/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp
+++ b/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp
@@ -205,7 +205,12 @@
         }
 
         if (mFirstPicture && !outQueue.empty()) {
-            drainOneOutputBuffer(mFirstPictureId, mFirstPicture);
+            if (!drainOneOutputBuffer(mFirstPictureId, mFirstPicture)) {
+                ALOGE("Drain failed");
+                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                mSignalledError = true;
+                return;
+            }
             delete[] mFirstPicture;
             mFirstPicture = NULL;
             mFirstPictureId = -1;
@@ -255,11 +260,15 @@
     memcpy(mFirstPicture, data, mPictureSize);
 }
 
-void SoftAVC::drainOneOutputBuffer(int32_t picId, uint8_t* data) {
+bool SoftAVC::drainOneOutputBuffer(int32_t picId, uint8_t* data) {
     List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);
     BufferInfo *outInfo = *outQueue.begin();
-    outQueue.erase(outQueue.begin());
     OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+    if (outHeader->nAllocLen - outHeader->nOffset < mPictureSize) {
+        android_errorWriteLog(0x534e4554, "27833616");
+        return false;
+    }
+    outQueue.erase(outQueue.begin());
     OMX_BUFFERHEADERTYPE *header = mPicToHeaderMap.valueFor(picId);
     outHeader->nTimeStamp = header->nTimeStamp;
     outHeader->nFlags = header->nFlags;
@@ -270,6 +279,7 @@
     delete header;
     outInfo->mOwnedByUs = false;
     notifyFillBufferDone(outHeader);
+    return true;
 }
 
 void SoftAVC::drainAllOutputBuffers(bool eos) {
@@ -282,7 +292,12 @@
                     mHandle, &decodedPicture, eos /* flush */)) {
             int32_t picId = decodedPicture.picId;
             uint8_t *data = (uint8_t *) decodedPicture.pOutputPicture;
-            drainOneOutputBuffer(picId, data);
+            if (!drainOneOutputBuffer(picId, data)) {
+                ALOGE("Drain failed");
+                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                mSignalledError = true;
+                return;
+            }
         }
     }
 
diff --git a/media/libstagefright/codecs/on2/h264dec/SoftAVC.h b/media/libstagefright/codecs/on2/h264dec/SoftAVC.h
index ee69926..528ef1c 100644
--- a/media/libstagefright/codecs/on2/h264dec/SoftAVC.h
+++ b/media/libstagefright/codecs/on2/h264dec/SoftAVC.h
@@ -73,7 +73,7 @@
 
     status_t initDecoder();
     void drainAllOutputBuffers(bool eos);
-    void drainOneOutputBuffer(int32_t picId, uint8_t *data);
+    bool drainOneOutputBuffer(int32_t picId, uint8_t *data);
     void saveFirstOutputBuffer(int32_t pidId, uint8_t *data);
     bool handleCropRectEvent(const CropParams* crop);
     bool handlePortSettingChangeEvent(const H264SwDecInfo *info);