Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f35ff157 authored by Joshua J. Drake's avatar Joshua J. Drake Committed by Nick Kralevich
Browse files

MPEG4Extractor: still more NULL dereference fixes

When processing various FourCC values within MP4 media, mLastTrack is accessed
without first ensuring that a track has been encoutered. Check for NULL and
bail out instead of crashing.

Bug: 20139950
Change-Id: Ie16687024d17348f576a0e13bd60bd4d6898de91
parent e41b5f31
Loading
Loading
Loading
Loading
+56 −0
Original line number Diff line number Diff line
@@ -874,6 +874,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
                    }
                }

                if (mLastTrack == NULL)
                    return ERROR_MALFORMED;

                mLastTrack->sampleTable = new SampleTable(mDataSource);
            }

@@ -1028,6 +1031,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
            }
            original_fourcc = ntohl(original_fourcc);
            ALOGV("read original format: %d", original_fourcc);

            if (mLastTrack == NULL)
                return ERROR_MALFORMED;

            mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(original_fourcc));
            uint32_t num_channels = 0;
            uint32_t sample_rate = 0;
@@ -1083,6 +1090,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
                return ERROR_IO;
            }

            if (mLastTrack == NULL)
                return ERROR_MALFORMED;

            mLastTrack->meta->setInt32(kKeyCryptoMode, defaultAlgorithmId);
            mLastTrack->meta->setInt32(kKeyCryptoDefaultIVSize, defaultIVSize);
            mLastTrack->meta->setData(kKeyCryptoKey, 'tenc', defaultKeyId, 16);
@@ -1257,6 +1267,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
                // display the timed text.
                // For encrypted files, there may also be more than one entry.
                const char *mime;

                if (mLastTrack == NULL)
                    return ERROR_MALFORMED;

                CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
                if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) &&
                        strcasecmp(mime, "application/octet-stream")) {
@@ -1303,6 +1317,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
            uint16_t sample_size = U16_AT(&buffer[18]);
            uint32_t sample_rate = U32_AT(&buffer[24]) >> 16;

            if (mLastTrack == NULL)
                return ERROR_MALFORMED;

            if (chunk_type != FOURCC('e', 'n', 'c', 'a')) {
                // if the chunk type is enca, we'll get the type from the sinf/frma box later
                mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
@@ -1364,6 +1381,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
            // printf("*** coding='%s' width=%d height=%d\n",
            //        chunk, width, height);

            if (mLastTrack == NULL)
                return ERROR_MALFORMED;

            if (chunk_type != FOURCC('e', 'n', 'c', 'v')) {
                // if the chunk type is encv, we'll get the type from the sinf/frma box later
                mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
@@ -1591,6 +1611,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
                return ERROR_MALFORMED;
            }

            if (mLastTrack == NULL)
                return ERROR_MALFORMED;

            mLastTrack->meta->setData(
                    kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4);

@@ -1623,6 +1646,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
                return ERROR_IO;
            }

            if (mLastTrack == NULL)
                return ERROR_MALFORMED;

            mLastTrack->meta->setData(
                    kKeyAVCC, kTypeAVCC, buffer->data(), chunk_data_size);

@@ -1637,6 +1663,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
                return ERROR_IO;
            }

            if (mLastTrack == NULL)
                return ERROR_MALFORMED;

            mLastTrack->meta->setData(
                    kKeyHVCC, kTypeHVCC, buffer->data(), chunk_data_size);

@@ -1670,6 +1699,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
                return ERROR_IO;
            }

            if (mLastTrack == NULL)
                return ERROR_MALFORMED;

            mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size);

            break;
@@ -1851,6 +1883,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
                return ERROR_IO;
            }

            if (mLastTrack == NULL)
                return ERROR_MALFORMED;

            uint32_t type = ntohl(buffer);
            // For the 3GPP file format, the handler-type within the 'hdlr' box
            // shall be 'text'. We also want to support 'sbtl' handler type
@@ -1883,6 +1918,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {

        case FOURCC('t', 'x', '3', 'g'):
        {
            if (mLastTrack == NULL)
                return ERROR_MALFORMED;

            uint32_t type;
            const void *data;
            size_t size = 0;
@@ -2107,6 +2145,9 @@ status_t MPEG4Extractor::parseSegmentIndex(off64_t offset, size_t size) {

    uint64_t sidxDuration = total_duration * 1000000 / timeScale;

    if (mLastTrack == NULL)
        return ERROR_MALFORMED;

    int64_t metaDuration;
    if (!mLastTrack->meta->findInt64(kKeyDuration, &metaDuration) || metaDuration == 0) {
        mLastTrack->meta->setInt64(kKeyDuration, sidxDuration);
@@ -2157,6 +2198,9 @@ status_t MPEG4Extractor::parseTrackHeader(
        return ERROR_UNSUPPORTED;
    }

    if (mLastTrack == NULL)
        return ERROR_MALFORMED;

    mLastTrack->meta->setInt32(kKeyTrackID, id);

    size_t matrixOffset = dynSize + 16;
@@ -2339,6 +2383,9 @@ status_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) {
                    int32_t delay, padding;
                    if (sscanf(mLastCommentData,
                               " %*x %x %x %*x", &delay, &padding) == 2) {
                        if (mLastTrack == NULL)
                            return ERROR_MALFORMED;

                        mLastTrack->meta->setInt32(kKeyEncoderDelay, delay);
                        mLastTrack->meta->setInt32(kKeyEncoderPadding, padding);
                    }
@@ -2701,6 +2748,9 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(

    if (objectTypeIndication == 0xe1) {
        // This isn't MPEG4 audio at all, it's QCELP 14k...
        if (mLastTrack == NULL)
            return ERROR_MALFORMED;

        mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP);
        return OK;
    }
@@ -2749,6 +2799,9 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
        objectType = 32 + br.getBits(6);
    }

    if (mLastTrack == NULL)
        return ERROR_MALFORMED;

    //keep AOT type
    mLastTrack->meta->setInt32(kKeyAACAOT, objectType);

@@ -2919,6 +2972,9 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
        return ERROR_UNSUPPORTED;
    }

    if (mLastTrack == NULL)
        return ERROR_MALFORMED;

    int32_t prevSampleRate;
    CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate));