libstagefright: Fix crash in convertMetaDataToMessage

- The ABuffer used for the Message has a preset value of 1024, if
  flattening the meta data exceeds this value, a check fails hence
  the crash.
- This change creates a new ABuffer if the buffer size would exceed
  the buffer capacity.

Bug: 22771132

CRs-Fixed: 857850

(cherry picked from commit 9c170c076382096b9e767da0e3f9f37dafa76546)

Change-Id: I056ade2f95bc8d82dfe092de7ecddba588cc5b72
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 25afc5b..d86be6e 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -70,6 +70,23 @@
     return ((uint64_t)htonl(x & 0xffffffff) << 32) | htonl(x >> 32);
 }
 
+static status_t copyNALUToABuffer(sp<ABuffer> *buffer, const uint8_t *ptr, size_t length) {
+    if (((*buffer)->size() + 4 + length) > ((*buffer)->capacity() - (*buffer)->offset())) {
+        sp<ABuffer> tmpBuffer = new (std::nothrow) ABuffer((*buffer)->size() + 4 + length + 1024);
+        if (tmpBuffer.get() == NULL || tmpBuffer->base() == NULL) {
+            return NO_MEMORY;
+        }
+        memcpy(tmpBuffer->data(), (*buffer)->data(), (*buffer)->size());
+        tmpBuffer->setRange(0, (*buffer)->size());
+        (*buffer) = tmpBuffer;
+    }
+
+    memcpy((*buffer)->data() + (*buffer)->size(), "\x00\x00\x00\x01", 4);
+    memcpy((*buffer)->data() + (*buffer)->size() + 4, ptr, length);
+    (*buffer)->setRange((*buffer)->offset(), (*buffer)->size() + 4 + length);
+    return OK;
+}
+
 status_t convertMetaDataToMessage(
         const sp<MetaData> &meta, sp<AMessage> *format) {
     format->clear();
@@ -199,7 +216,10 @@
         ptr += 6;
         size -= 6;
 
-        sp<ABuffer> buffer = new ABuffer(1024);
+        sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
+        if (buffer.get() == NULL || buffer->base() == NULL) {
+            return NO_MEMORY;
+        }
         buffer->setRange(0, 0);
 
         for (size_t i = 0; i < numSeqParameterSets; ++i) {
@@ -209,11 +229,13 @@
             ptr += 2;
             size -= 2;
 
-            CHECK(size >= length);
-
-            memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
-            memcpy(buffer->data() + buffer->size() + 4, ptr, length);
-            buffer->setRange(0, buffer->size() + 4 + length);
+            if (size < length) {
+                return BAD_VALUE;
+            }
+            status_t err = copyNALUToABuffer(&buffer, ptr, length);
+            if (err != OK) {
+                return err;
+            }
 
             ptr += length;
             size -= length;
@@ -224,7 +246,10 @@
 
         msg->setBuffer("csd-0", buffer);
 
-        buffer = new ABuffer(1024);
+        buffer = new (std::nothrow) ABuffer(1024);
+        if (buffer.get() == NULL || buffer->base() == NULL) {
+            return NO_MEMORY;
+        }
         buffer->setRange(0, 0);
 
         CHECK(size >= 1);
@@ -239,11 +264,13 @@
             ptr += 2;
             size -= 2;
 
-            CHECK(size >= length);
-
-            memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
-            memcpy(buffer->data() + buffer->size() + 4, ptr, length);
-            buffer->setRange(0, buffer->size() + 4 + length);
+            if (size < length) {
+                return BAD_VALUE;
+            }
+            status_t err = copyNALUToABuffer(&buffer, ptr, length);
+            if (err != OK) {
+                return err;
+            }
 
             ptr += length;
             size -= length;
@@ -268,7 +295,10 @@
         size -= 1;
         size_t j = 0, i = 0;
 
-        sp<ABuffer> buffer = new ABuffer(1024);
+        sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
+        if (buffer.get() == NULL || buffer->base() == NULL) {
+            return NO_MEMORY;
+        }
         buffer->setRange(0, 0);
 
         for (i = 0; i < numofArrays; i++) {
@@ -288,11 +318,13 @@
                 ptr += 2;
                 size -= 2;
 
-                CHECK(size >= length);
-
-                memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
-                memcpy(buffer->data() + buffer->size() + 4, ptr, length);
-                buffer->setRange(0, buffer->size() + 4 + length);
+                if (size < length) {
+                    return BAD_VALUE;
+                }
+                status_t err = copyNALUToABuffer(&buffer, ptr, length);
+                if (err != OK) {
+                    return err;
+                }
 
                 ptr += length;
                 size -= length;
@@ -311,7 +343,10 @@
         esds.getCodecSpecificInfo(
                 &codec_specific_data, &codec_specific_data_size);
 
-        sp<ABuffer> buffer = new ABuffer(codec_specific_data_size);
+        sp<ABuffer> buffer = new (std::nothrow) ABuffer(codec_specific_data_size);
+        if (buffer.get() == NULL || buffer->base() == NULL) {
+            return NO_MEMORY;
+        }
 
         memcpy(buffer->data(), codec_specific_data,
                codec_specific_data_size);
@@ -320,7 +355,10 @@
         buffer->meta()->setInt64("timeUs", 0);
         msg->setBuffer("csd-0", buffer);
     } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
-        sp<ABuffer> buffer = new ABuffer(size);
+        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
+        if (buffer.get() == NULL || buffer->base() == NULL) {
+            return NO_MEMORY;
+        }
         memcpy(buffer->data(), data, size);
 
         buffer->meta()->setInt32("csd", true);
@@ -331,14 +369,20 @@
             return -EINVAL;
         }
 
-        buffer = new ABuffer(size);
+        buffer = new (std::nothrow) ABuffer(size);
+        if (buffer.get() == NULL || buffer->base() == NULL) {
+            return NO_MEMORY;
+        }
         memcpy(buffer->data(), data, size);
 
         buffer->meta()->setInt32("csd", true);
         buffer->meta()->setInt64("timeUs", 0);
         msg->setBuffer("csd-1", buffer);
     } else if (meta->findData(kKeyOpusHeader, &type, &data, &size)) {
-        sp<ABuffer> buffer = new ABuffer(size);
+        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
+        if (buffer.get() == NULL || buffer->base() == NULL) {
+            return NO_MEMORY;
+        }
         memcpy(buffer->data(), data, size);
 
         buffer->meta()->setInt32("csd", true);