diff options
-rw-r--r-- | drm/common/IDrmManagerService.cpp | 16 | ||||
-rw-r--r-- | media/libmedia/IAudioFlinger.cpp | 54 | ||||
-rw-r--r-- | media/libmedia/IAudioPolicyService.cpp | 26 | ||||
-rw-r--r-- | media/libmedia/ICrypto.cpp | 20 | ||||
-rw-r--r-- | media/libmedia/IEffect.cpp | 27 | ||||
-rw-r--r-- | media/libmedia/IMediaPlayer.cpp | 4 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/GenericSource.cpp | 31 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/GenericSource.h | 1 | ||||
-rw-r--r-- | media/libstagefright/OggExtractor.cpp | 93 | ||||
-rw-r--r-- | media/libstagefright/StagefrightMetadataRetriever.cpp | 5 | ||||
-rw-r--r-- | media/libstagefright/Utils.cpp | 36 | ||||
-rw-r--r-- | media/libstagefright/foundation/base64.cpp | 11 | ||||
-rw-r--r-- | media/libstagefright/timedtext/TextDescriptions.cpp | 627 | ||||
-rw-r--r-- | media/libstagefright/timedtext/TextDescriptions.h | 4 |
14 files changed, 551 insertions, 404 deletions
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp index b90da1b..f2e14b6 100644 --- a/drm/common/IDrmManagerService.cpp +++ b/drm/common/IDrmManagerService.cpp @@ -742,9 +742,11 @@ status_t BpDrmManagerService::decrypt( const status_t status = reply.readInt32(); ALOGV("Return value of decrypt() is %d", status); - const int size = reply.readInt32(); - (*decBuffer)->length = size; - reply.read((void *)(*decBuffer)->data, size); + if (status == NO_ERROR) { + const int size = reply.readInt32(); + (*decBuffer)->length = size; + reply.read((void *)(*decBuffer)->data, size); + } return status; } @@ -1470,9 +1472,11 @@ status_t BnDrmManagerService::onTransact( reply->writeInt32(status); - const int size = decBuffer->length; - reply->writeInt32(size); - reply->write(decBuffer->data, size); + if (status == NO_ERROR) { + const int size = decBuffer->length; + reply->writeInt32(size); + reply->write(decBuffer->data, size); + } clearDecryptHandle(&handle); delete encBuffer; encBuffer = NULL; diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp index a3f014b..0bf503a 100644 --- a/media/libmedia/IAudioFlinger.cpp +++ b/media/libmedia/IAudioFlinger.cpp @@ -937,7 +937,7 @@ status_t BnAudioFlinger::onTransact( pid_t tid = (pid_t) data.readInt32(); int sessionId = data.readInt32(); int clientUid = data.readInt32(); - status_t status; + status_t status = NO_ERROR; sp<IAudioTrack> track; if ((haveSharedBuffer && (buffer == 0)) || ((buffer != 0) && (buffer->pointer() == NULL))) { @@ -972,7 +972,7 @@ status_t BnAudioFlinger::onTransact( size_t notificationFrames = data.readInt64(); sp<IMemory> cblk; sp<IMemory> buffers; - status_t status; + status_t status = NO_ERROR; sp<IAudioRecord> record = openRecord(input, sampleRate, format, channelMask, opPackageName, &frameCount, &flags, tid, clientUid, &sessionId, ¬ificationFrames, cblk, buffers, &status); @@ -1104,13 +1104,15 @@ status_t BnAudioFlinger::onTransact( case OPEN_OUTPUT: { CHECK_INTERFACE(IAudioFlinger, data, reply); audio_module_handle_t module = (audio_module_handle_t)data.readInt32(); - audio_config_t config; - data.read(&config, sizeof(audio_config_t)); + audio_config_t config = {}; + if (data.read(&config, sizeof(audio_config_t)) != NO_ERROR) { + ALOGE("b/23905951"); + } audio_devices_t devices = (audio_devices_t)data.readInt32(); String8 address(data.readString8()); audio_output_flags_t flags = (audio_output_flags_t) data.readInt32(); - uint32_t latencyMs; - audio_io_handle_t output; + uint32_t latencyMs = 0; + audio_io_handle_t output = AUDIO_IO_HANDLE_NONE; status_t status = openOutput(module, &output, &config, &devices, address, &latencyMs, flags); ALOGV("OPEN_OUTPUT output, %d", output); @@ -1149,8 +1151,10 @@ status_t BnAudioFlinger::onTransact( CHECK_INTERFACE(IAudioFlinger, data, reply); audio_module_handle_t module = (audio_module_handle_t)data.readInt32(); audio_io_handle_t input = (audio_io_handle_t)data.readInt32(); - audio_config_t config; - data.read(&config, sizeof(audio_config_t)); + audio_config_t config = {}; + if (data.read(&config, sizeof(audio_config_t)) != NO_ERROR) { + ALOGE("b/23905951"); + } audio_devices_t device = (audio_devices_t)data.readInt32(); String8 address(data.readString8()); audio_source_t source = (audio_source_t)data.readInt32(); @@ -1186,8 +1190,8 @@ status_t BnAudioFlinger::onTransact( case GET_RENDER_POSITION: { CHECK_INTERFACE(IAudioFlinger, data, reply); audio_io_handle_t output = (audio_io_handle_t) data.readInt32(); - uint32_t halFrames; - uint32_t dspFrames; + uint32_t halFrames = 0; + uint32_t dspFrames = 0; status_t status = getRenderPosition(&halFrames, &dspFrames, output); reply->writeInt32(status); if (status == NO_ERROR) { @@ -1223,7 +1227,7 @@ status_t BnAudioFlinger::onTransact( } break; case QUERY_NUM_EFFECTS: { CHECK_INTERFACE(IAudioFlinger, data, reply); - uint32_t numEffects; + uint32_t numEffects = 0; status_t status = queryNumberEffects(&numEffects); reply->writeInt32(status); if (status == NO_ERROR) { @@ -1233,7 +1237,7 @@ status_t BnAudioFlinger::onTransact( } case QUERY_EFFECT: { CHECK_INTERFACE(IAudioFlinger, data, reply); - effect_descriptor_t desc; + effect_descriptor_t desc = {}; status_t status = queryEffect(data.readInt32(), &desc); reply->writeInt32(status); if (status == NO_ERROR) { @@ -1245,7 +1249,7 @@ status_t BnAudioFlinger::onTransact( CHECK_INTERFACE(IAudioFlinger, data, reply); effect_uuid_t uuid; data.read(&uuid, sizeof(effect_uuid_t)); - effect_descriptor_t desc; + effect_descriptor_t desc = {}; status_t status = getEffectDescriptor(&uuid, &desc); reply->writeInt32(status); if (status == NO_ERROR) { @@ -1255,16 +1259,18 @@ status_t BnAudioFlinger::onTransact( } case CREATE_EFFECT: { CHECK_INTERFACE(IAudioFlinger, data, reply); - effect_descriptor_t desc; - data.read(&desc, sizeof(effect_descriptor_t)); + effect_descriptor_t desc = {}; + if (data.read(&desc, sizeof(effect_descriptor_t)) != NO_ERROR) { + ALOGE("b/23905951"); + } sp<IEffectClient> client = interface_cast<IEffectClient>(data.readStrongBinder()); int32_t priority = data.readInt32(); audio_io_handle_t output = (audio_io_handle_t) data.readInt32(); int sessionId = data.readInt32(); const String16 opPackageName = data.readString16(); - status_t status; - int id; - int enabled; + status_t status = NO_ERROR; + int id = 0; + int enabled = 0; sp<IEffect> effect = createEffect(&desc, client, priority, output, sessionId, opPackageName, &status, &id, &enabled); @@ -1333,8 +1339,10 @@ status_t BnAudioFlinger::onTransact( } break; case GET_AUDIO_PORT: { CHECK_INTERFACE(IAudioFlinger, data, reply); - struct audio_port port; - data.read(&port, sizeof(struct audio_port)); + struct audio_port port = {}; + if (data.read(&port, sizeof(struct audio_port)) != NO_ERROR) { + ALOGE("b/23905951"); + } status_t status = getAudioPort(&port); reply->writeInt32(status); if (status == NO_ERROR) { @@ -1346,8 +1354,10 @@ status_t BnAudioFlinger::onTransact( CHECK_INTERFACE(IAudioFlinger, data, reply); struct audio_patch patch; data.read(&patch, sizeof(struct audio_patch)); - audio_patch_handle_t handle; - data.read(&handle, sizeof(audio_patch_handle_t)); + audio_patch_handle_t handle = {}; + if (data.read(&handle, sizeof(audio_patch_handle_t)) != NO_ERROR) { + ALOGE("b/23905951"); + } status_t status = createAudioPatch(&patch, &handle); reply->writeInt32(status); if (status == NO_ERROR) { diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp index 3348441..76b5924 100644 --- a/media/libmedia/IAudioPolicyService.cpp +++ b/media/libmedia/IAudioPolicyService.cpp @@ -877,7 +877,7 @@ status_t BnAudioPolicyService::onTransact( if (hasOffloadInfo) { data.read(&offloadInfo, sizeof(audio_offload_info_t)); } - audio_io_handle_t output; + audio_io_handle_t output = 0; status_t status = getOutputForAttr(hasAttributes ? &attr : NULL, &output, session, &stream, uid, samplingRate, format, channelMask, @@ -932,7 +932,7 @@ status_t BnAudioPolicyService::onTransact( audio_channel_mask_t channelMask = data.readInt32(); audio_input_flags_t flags = (audio_input_flags_t) data.readInt32(); audio_port_handle_t selectedDeviceId = (audio_port_handle_t) data.readInt32(); - audio_io_handle_t input; + audio_io_handle_t input = {}; status_t status = getInputForAttr(&attr, &input, session, uid, samplingRate, format, channelMask, flags, selectedDeviceId); @@ -994,7 +994,7 @@ status_t BnAudioPolicyService::onTransact( audio_stream_type_t stream = static_cast <audio_stream_type_t>(data.readInt32()); audio_devices_t device = static_cast <audio_devices_t>(data.readInt32()); - int index; + int index = 0; status_t status = getStreamVolumeIndex(stream, &index, device); reply->writeInt32(index); reply->writeInt32(static_cast <uint32_t>(status)); @@ -1148,8 +1148,10 @@ status_t BnAudioPolicyService::onTransact( case GET_AUDIO_PORT: { CHECK_INTERFACE(IAudioPolicyService, data, reply); - struct audio_port port; - data.read(&port, sizeof(struct audio_port)); + struct audio_port port = {}; + if (data.read(&port, sizeof(struct audio_port)) != NO_ERROR) { + ALOGE("b/23912202"); + } status_t status = getAudioPort(&port); reply->writeInt32(status); if (status == NO_ERROR) { @@ -1162,8 +1164,10 @@ status_t BnAudioPolicyService::onTransact( CHECK_INTERFACE(IAudioPolicyService, data, reply); struct audio_patch patch; data.read(&patch, sizeof(struct audio_patch)); - audio_patch_handle_t handle; - data.read(&handle, sizeof(audio_patch_handle_t)); + audio_patch_handle_t handle = {}; + if (data.read(&handle, sizeof(audio_patch_handle_t)) != NO_ERROR) { + ALOGE("b/23912202"); + } status_t status = createAudioPatch(&patch, &handle); reply->writeInt32(status); if (status == NO_ERROR) { @@ -1238,9 +1242,9 @@ status_t BnAudioPolicyService::onTransact( CHECK_INTERFACE(IAudioPolicyService, data, reply); sp<IAudioPolicyServiceClient> client = interface_cast<IAudioPolicyServiceClient>( data.readStrongBinder()); - audio_session_t session; - audio_io_handle_t ioHandle; - audio_devices_t device; + audio_session_t session = {}; + audio_io_handle_t ioHandle = {}; + audio_devices_t device = {}; status_t status = acquireSoundTriggerSession(&session, &ioHandle, &device); reply->writeInt32(status); if (status == NO_ERROR) { @@ -1292,7 +1296,7 @@ status_t BnAudioPolicyService::onTransact( data.read(&source, sizeof(struct audio_port_config)); audio_attributes_t attributes; data.read(&attributes, sizeof(audio_attributes_t)); - audio_io_handle_t handle; + audio_io_handle_t handle = {}; status_t status = startAudioSource(&source, &attributes, &handle); reply->writeInt32(status); reply->writeInt32(handle); diff --git a/media/libmedia/ICrypto.cpp b/media/libmedia/ICrypto.cpp index 8f05936..53b105d 100644 --- a/media/libmedia/ICrypto.cpp +++ b/media/libmedia/ICrypto.cpp @@ -308,7 +308,25 @@ status_t BnCrypto::onTransact( AString errorDetailMsg; ssize_t result; - if (offset + totalSize > sharedBuffer->size()) { + size_t sumSubsampleSizes = 0; + bool overflow = false; + for (int32_t i = 0; i < numSubSamples; ++i) { + CryptoPlugin::SubSample &ss = subSamples[i]; + if (sumSubsampleSizes <= SIZE_MAX - ss.mNumBytesOfEncryptedData) { + sumSubsampleSizes += ss.mNumBytesOfEncryptedData; + } else { + overflow = true; + } + if (sumSubsampleSizes <= SIZE_MAX - ss.mNumBytesOfClearData) { + sumSubsampleSizes += ss.mNumBytesOfClearData; + } else { + overflow = true; + } + } + + if (overflow || sumSubsampleSizes != totalSize) { + result = -EINVAL; + } else if (offset + totalSize > sharedBuffer->size()) { result = -EINVAL; } else { result = decrypt( diff --git a/media/libmedia/IEffect.cpp b/media/libmedia/IEffect.cpp index 761b243..faf5795 100644 --- a/media/libmedia/IEffect.cpp +++ b/media/libmedia/IEffect.cpp @@ -85,13 +85,15 @@ public: data.writeInt32(size); status_t status = remote()->transact(COMMAND, data, &reply); + if (status == NO_ERROR) { + status = reply.readInt32(); + } if (status != NO_ERROR) { if (pReplySize != NULL) *pReplySize = 0; return status; } - status = reply.readInt32(); size = reply.readInt32(); if (size != 0 && pReplyData != NULL && pReplySize != NULL) { reply.read(pReplyData, size); @@ -155,6 +157,10 @@ status_t BnEffect::onTransact( char *cmd = NULL; if (cmdSize) { cmd = (char *)calloc(cmdSize, 1); + if (cmd == NULL) { + reply->writeInt32(NO_MEMORY); + return NO_ERROR; + } data.read(cmd, cmdSize); } uint32_t replySize = data.readInt32(); @@ -162,15 +168,22 @@ status_t BnEffect::onTransact( char *resp = NULL; if (replySize) { resp = (char *)calloc(replySize, 1); + if (resp == NULL) { + free(cmd); + reply->writeInt32(NO_MEMORY); + return NO_ERROR; + } } status_t status = command(cmdCode, cmdSize, cmd, &replySz, resp); reply->writeInt32(status); - if (replySz < replySize) { - replySize = replySz; - } - reply->writeInt32(replySize); - if (replySize) { - reply->write(resp, replySize); + if (status == NO_ERROR) { + if (replySz < replySize) { + replySize = replySz; + } + reply->writeInt32(replySize); + if (replySize) { + reply->write(resp, replySize); + } } if (cmd) { free(cmd); diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp index 7387a79..942aec3 100644 --- a/media/libmedia/IMediaPlayer.cpp +++ b/media/libmedia/IMediaPlayer.cpp @@ -566,7 +566,7 @@ status_t BnMediaPlayer::onTransact( } break; case GET_CURRENT_POSITION: { CHECK_INTERFACE(IMediaPlayer, data, reply); - int msec; + int msec = 0; status_t ret = getCurrentPosition(&msec); reply->writeInt32(msec); reply->writeInt32(ret); @@ -574,7 +574,7 @@ status_t BnMediaPlayer::onTransact( } break; case GET_DURATION: { CHECK_INTERFACE(IMediaPlayer, data, reply); - int msec; + int msec = 0; status_t ret = getDuration(&msec); reply->writeInt32(msec); reply->writeInt32(ret); diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp index 6957a90..21befd3 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp +++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp @@ -468,9 +468,17 @@ void NuPlayer::GenericSource::finishPrepareAsync() { void NuPlayer::GenericSource::notifyPreparedAndCleanup(status_t err) { if (err != OK) { - mDataSource.clear(); - mCachedSource.clear(); - mHttpSource.clear(); + { + sp<DataSource> dataSource = mDataSource; + sp<NuCachedSource2> cachedSource = mCachedSource; + sp<DataSource> httpSource = mHttpSource; + { + Mutex::Autolock _l(mDisconnectLock); + mDataSource.clear(); + mCachedSource.clear(); + mHttpSource.clear(); + } + } mBitrate = -1; cancelPollBuffering(); @@ -523,13 +531,20 @@ void NuPlayer::GenericSource::resume() { } void NuPlayer::GenericSource::disconnect() { - if (mDataSource != NULL) { + sp<DataSource> dataSource, httpSource; + { + Mutex::Autolock _l(mDisconnectLock); + dataSource = mDataSource; + httpSource = mHttpSource; + } + + if (dataSource != NULL) { // disconnect data source - if (mDataSource->flags() & DataSource::kIsCachingDataSource) { - static_cast<NuCachedSource2 *>(mDataSource.get())->disconnect(); + if (dataSource->flags() & DataSource::kIsCachingDataSource) { + static_cast<NuCachedSource2 *>(dataSource.get())->disconnect(); } - } else if (mHttpSource != NULL) { - static_cast<HTTPBase *>(mHttpSource.get())->disconnect(); + } else if (httpSource != NULL) { + static_cast<HTTPBase *>(httpSource.get())->disconnect(); } } diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h index 0181947..d7467c2 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.h +++ b/media/libmediaplayerservice/nuplayer/GenericSource.h @@ -153,6 +153,7 @@ protected: int32_t mPrevBufferPercentage; mutable Mutex mReadBufferLock; + mutable Mutex mDisconnectLock; sp<ALooper> mLooper; diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp index c438d3c..578171f 100644 --- a/media/libstagefright/OggExtractor.cpp +++ b/media/libstagefright/OggExtractor.cpp @@ -23,6 +23,7 @@ #include <cutils/properties.h> #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> +#include <media/stagefright/foundation/base64.h> #include <media/stagefright/DataSource.h> #include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MediaBufferGroup.h> @@ -1202,84 +1203,18 @@ void parseVorbisComment( } -// The returned buffer should be free()d. -static uint8_t *DecodeBase64(const char *s, size_t size, size_t *outSize) { - *outSize = 0; - - if ((size % 4) != 0) { - return NULL; - } - - size_t n = size; - size_t padding = 0; - if (n >= 1 && s[n - 1] == '=') { - padding = 1; - - if (n >= 2 && s[n - 2] == '=') { - padding = 2; - } - } - - size_t outLen = 3 * size / 4 - padding; - - *outSize = outLen; - - void *buffer = malloc(outLen); - CHECK(buffer != NULL); - - uint8_t *out = (uint8_t *)buffer; - size_t j = 0; - uint32_t accum = 0; - for (size_t i = 0; i < n; ++i) { - char c = s[i]; - unsigned value; - if (c >= 'A' && c <= 'Z') { - value = c - 'A'; - } else if (c >= 'a' && c <= 'z') { - value = 26 + c - 'a'; - } else if (c >= '0' && c <= '9') { - value = 52 + c - '0'; - } else if (c == '+') { - value = 62; - } else if (c == '/') { - value = 63; - } else if (c != '=') { - return NULL; - } else { - if (i < n - padding) { - return NULL; - } - - value = 0; - } - - accum = (accum << 6) | value; - - if (((i + 1) % 4) == 0) { - out[j++] = (accum >> 16); - - if (j < outLen) { out[j++] = (accum >> 8) & 0xff; } - if (j < outLen) { out[j++] = accum & 0xff; } - - accum = 0; - } - } - - return (uint8_t *)buffer; -} - static void extractAlbumArt( const sp<MetaData> &fileMeta, const void *data, size_t size) { ALOGV("extractAlbumArt from '%s'", (const char *)data); - size_t flacSize; - uint8_t *flac = DecodeBase64((const char *)data, size, &flacSize); - - if (flac == NULL) { + sp<ABuffer> flacBuffer = decodeBase64(AString((const char *)data, size)); + if (flacBuffer == NULL) { ALOGE("malformed base64 encoded data."); return; } + size_t flacSize = flacBuffer->size(); + uint8_t *flac = flacBuffer->data(); ALOGV("got flac of size %zu", flacSize); uint32_t picType; @@ -1289,24 +1224,24 @@ static void extractAlbumArt( char type[128]; if (flacSize < 8) { - goto exit; + return; } picType = U32_AT(flac); if (picType != 3) { // This is not a front cover. - goto exit; + return; } typeLen = U32_AT(&flac[4]); if (typeLen > sizeof(type) - 1) { - goto exit; + return; } // we've already checked above that flacSize >= 8 if (flacSize - 8 < typeLen) { - goto exit; + return; } memcpy(type, &flac[8], typeLen); @@ -1316,7 +1251,7 @@ static void extractAlbumArt( if (!strcmp(type, "-->")) { // This is not inline cover art, but an external url instead. - goto exit; + return; } descLen = U32_AT(&flac[8 + typeLen]); @@ -1324,7 +1259,7 @@ static void extractAlbumArt( if (flacSize < 32 || flacSize - 32 < typeLen || flacSize - 32 - typeLen < descLen) { - goto exit; + return; } dataLen = U32_AT(&flac[8 + typeLen + 4 + descLen + 16]); @@ -1332,7 +1267,7 @@ static void extractAlbumArt( // we've already checked above that (flacSize - 32 - typeLen - descLen) >= 0 if (flacSize - 32 - typeLen - descLen < dataLen) { - goto exit; + return; } ALOGV("got image data, %zu trailing bytes", @@ -1342,10 +1277,6 @@ static void extractAlbumArt( kKeyAlbumArt, 0, &flac[8 + typeLen + 4 + descLen + 20], dataLen); fileMeta->setCString(kKeyAlbumArtMIME, type); - -exit: - free(flac); - flac = NULL; } //////////////////////////////////////////////////////////////////////////////// diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp index 28f9557..c3adac4 100644 --- a/media/libstagefright/StagefrightMetadataRetriever.cpp +++ b/media/libstagefright/StagefrightMetadataRetriever.cpp @@ -156,7 +156,10 @@ static VideoFrame *extractVideoFrame( sp<MetaData> format = source->getFormat(); sp<AMessage> videoFormat; - convertMetaDataToMessage(trackMeta, &videoFormat); + if (convertMetaDataToMessage(trackMeta, &videoFormat) != OK) { + ALOGW("Failed to convert meta data to message"); + return NULL; + } // TODO: Use Flexible color instead videoFormat->setInt32("color-format", OMX_COLOR_FormatYUV420Planar); diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp index d7b0bad..a29885f 100644 --- a/media/libstagefright/Utils.cpp +++ b/media/libstagefright/Utils.cpp @@ -219,8 +219,10 @@ status_t convertMetaDataToMessage( const uint8_t *ptr = (const uint8_t *)data; - CHECK(size >= 7); - CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 + if (size < 7 || ptr[0] != 1) { // configurationVersion == 1 + ALOGE("b/23680780"); + return BAD_VALUE; + } uint8_t profile __unused = ptr[1]; uint8_t level __unused = ptr[3]; @@ -246,7 +248,10 @@ status_t convertMetaDataToMessage( buffer->setRange(0, 0); for (size_t i = 0; i < numSeqParameterSets; ++i) { - CHECK(size >= 2); + if (size < 2) { + ALOGE("b/23680780"); + return BAD_VALUE; + } size_t length = U16_AT(ptr); ptr += 2; @@ -275,13 +280,19 @@ status_t convertMetaDataToMessage( } buffer->setRange(0, 0); - CHECK(size >= 1); + if (size < 1) { + ALOGE("b/23680780"); + return BAD_VALUE; + } size_t numPictureParameterSets = *ptr; ++ptr; --size; for (size_t i = 0; i < numPictureParameterSets; ++i) { - CHECK(size >= 2); + if (size < 2) { + ALOGE("b/23680780"); + return BAD_VALUE; + } size_t length = U16_AT(ptr); ptr += 2; @@ -305,8 +316,10 @@ status_t convertMetaDataToMessage( } else if (meta->findData(kKeyHVCC, &type, &data, &size)) { const uint8_t *ptr = (const uint8_t *)data; - CHECK(size >= 7); - //CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 + if (size < 23 || ptr[0] != 1) { // configurationVersion == 1 + ALOGE("b/23680780"); + return BAD_VALUE; + } uint8_t profile __unused = ptr[1] & 31; uint8_t level __unused = ptr[12]; ptr += 22; @@ -325,6 +338,10 @@ status_t convertMetaDataToMessage( buffer->setRange(0, 0); for (i = 0; i < numofArrays; i++) { + if (size < 3) { + ALOGE("b/23680780"); + return BAD_VALUE; + } ptr += 1; size -= 1; @@ -335,7 +352,10 @@ status_t convertMetaDataToMessage( size -= 2; for (j = 0; j < numofNals; j++) { - CHECK(size >= 2); + if (size < 2) { + ALOGE("b/23680780"); + return BAD_VALUE; + } size_t length = U16_AT(ptr); ptr += 2; diff --git a/media/libstagefright/foundation/base64.cpp b/media/libstagefright/foundation/base64.cpp index dcf5bef..7da7db9 100644 --- a/media/libstagefright/foundation/base64.cpp +++ b/media/libstagefright/foundation/base64.cpp @@ -22,11 +22,11 @@ namespace android { sp<ABuffer> decodeBase64(const AString &s) { - if ((s.size() % 4) != 0) { + size_t n = s.size(); + if ((n % 4) != 0) { return NULL; } - size_t n = s.size(); size_t padding = 0; if (n >= 1 && s.c_str()[n - 1] == '=') { padding = 1; @@ -40,11 +40,16 @@ sp<ABuffer> decodeBase64(const AString &s) { } } - size_t outLen = 3 * s.size() / 4 - padding; + // We divide first to avoid overflow. It's OK to do this because we + // already made sure that n % 4 == 0. + size_t outLen = (n / 4) * 3 - padding; sp<ABuffer> buffer = new ABuffer(outLen); uint8_t *out = buffer->data(); + if (out == NULL || buffer->size() < outLen) { + return NULL; + } size_t j = 0; uint32_t accum = 0; for (size_t i = 0; i < n; ++i) { diff --git a/media/libstagefright/timedtext/TextDescriptions.cpp b/media/libstagefright/timedtext/TextDescriptions.cpp index f9c1fe0..c762a74 100644 --- a/media/libstagefright/timedtext/TextDescriptions.cpp +++ b/media/libstagefright/timedtext/TextDescriptions.cpp @@ -30,9 +30,9 @@ status_t TextDescriptions::getParcelOfDescriptions( if (flags & IN_BAND_TEXT_3GPP) { if (flags & GLOBAL_DESCRIPTIONS) { - return extract3GPPGlobalDescriptions(data, size, parcel, 0); + return extract3GPPGlobalDescriptions(data, size, parcel); } else if (flags & LOCAL_DESCRIPTIONS) { - return extract3GPPLocalDescriptions(data, size, timeMs, parcel, 0); + return extract3GPPLocalDescriptions(data, size, timeMs, parcel); } } else if (flags & OUT_OF_BAND_TEXT_SRT) { if (flags & LOCAL_DESCRIPTIONS) { @@ -69,314 +69,437 @@ status_t TextDescriptions::extractSRTLocalDescriptions( // styles, and 'krok' box contains karaoke timing and positions. status_t TextDescriptions::extract3GPPLocalDescriptions( const uint8_t *data, ssize_t size, - int timeMs, Parcel *parcel, int depth) { - if (depth == 0) { - parcel->writeInt32(KEY_LOCAL_SETTING); - - // write start time to display this text sample - parcel->writeInt32(KEY_START_TIME); - parcel->writeInt32(timeMs); - - ssize_t textLen = (*data) << 8 | (*(data + 1)); - - // write text sample length and text sample itself - parcel->writeInt32(KEY_STRUCT_TEXT); - parcel->writeInt32(textLen); - parcel->writeInt32(textLen); - parcel->write(data + 2, textLen); - - if (size > textLen) { - data += (textLen + 2); - size -= (textLen + 2); - } else { - return OK; - } + int timeMs, Parcel *parcel) { + + parcel->writeInt32(KEY_LOCAL_SETTING); + + // write start time to display this text sample + parcel->writeInt32(KEY_START_TIME); + parcel->writeInt32(timeMs); + + if (size < 2) { + return OK; } + ssize_t textLen = (*data) << 8 | (*(data + 1)); - const uint8_t *tmpData = data; - ssize_t chunkSize = U32_AT(tmpData); - uint32_t chunkType = U32_AT(tmpData + 4); + if (size < textLen + 2) { + return OK; + } - if (chunkSize <= 0) { + // write text sample length and text sample itself + parcel->writeInt32(KEY_STRUCT_TEXT); + parcel->writeInt32(textLen); + parcel->writeInt32(textLen); + parcel->write(data + 2, textLen); + + if (size > textLen + 2) { + data += (textLen + 2); + size -= (textLen + 2); + } else { return OK; } - tmpData += 8; + while (size >= 8) { + const uint8_t *tmpData = data; + ssize_t chunkSize = U32_AT(tmpData); // size includes size and type + uint32_t chunkType = U32_AT(tmpData + 4); - switch(chunkType) { - // 'styl' box specifies the style of the text. - case FOURCC('s', 't', 'y', 'l'): - { - uint16_t count = U16_AT(tmpData); + if (chunkSize <= 8 || chunkSize > size) { + return OK; + } - tmpData += 2; + size_t remaining = chunkSize - 8; - for (int i = 0; i < count; i++) { - parcel->writeInt32(KEY_STRUCT_STYLE_LIST); - parcel->writeInt32(KEY_START_CHAR); - parcel->writeInt32(U16_AT(tmpData)); + tmpData += 8; - parcel->writeInt32(KEY_END_CHAR); - parcel->writeInt32(U16_AT(tmpData + 2)); + switch(chunkType) { + // 'styl' box specifies the style of the text. + case FOURCC('s', 't', 'y', 'l'): + { + if (remaining < 2) { + return OK; + } + size_t dataPos = parcel->dataPosition(); + uint16_t count = U16_AT(tmpData); - parcel->writeInt32(KEY_FONT_ID); - parcel->writeInt32(U16_AT(tmpData + 4)); + tmpData += 2; + remaining -= 2; - parcel->writeInt32(KEY_STYLE_FLAGS); - parcel->writeInt32(*(tmpData + 6)); + for (int i = 0; i < count; i++) { + if (remaining < 12) { + // roll back + parcel->setDataPosition(dataPos); + return OK; + } + parcel->writeInt32(KEY_STRUCT_STYLE_LIST); + parcel->writeInt32(KEY_START_CHAR); + parcel->writeInt32(U16_AT(tmpData)); - parcel->writeInt32(KEY_FONT_SIZE); - parcel->writeInt32(*(tmpData + 7)); + parcel->writeInt32(KEY_END_CHAR); + parcel->writeInt32(U16_AT(tmpData + 2)); - parcel->writeInt32(KEY_TEXT_COLOR_RGBA); - uint32_t rgba = *(tmpData + 8) << 24 | *(tmpData + 9) << 16 - | *(tmpData + 10) << 8 | *(tmpData + 11); - parcel->writeInt32(rgba); + parcel->writeInt32(KEY_FONT_ID); + parcel->writeInt32(U16_AT(tmpData + 4)); - tmpData += 12; + parcel->writeInt32(KEY_STYLE_FLAGS); + parcel->writeInt32(*(tmpData + 6)); + + parcel->writeInt32(KEY_FONT_SIZE); + parcel->writeInt32(*(tmpData + 7)); + + parcel->writeInt32(KEY_TEXT_COLOR_RGBA); + uint32_t rgba = *(tmpData + 8) << 24 | *(tmpData + 9) << 16 + | *(tmpData + 10) << 8 | *(tmpData + 11); + parcel->writeInt32(rgba); + + tmpData += 12; + remaining -= 12; + } + + break; + } + // 'krok' box. The number of highlight events is specified, and each + // event is specified by a starting and ending char offset and an end + // time for the event. + case FOURCC('k', 'r', 'o', 'k'): + { + if (remaining < 6) { + return OK; + } + size_t dataPos = parcel->dataPosition(); + + parcel->writeInt32(KEY_STRUCT_KARAOKE_LIST); + + int startTime = U32_AT(tmpData); + uint16_t count = U16_AT(tmpData + 4); + parcel->writeInt32(count); + + tmpData += 6; + remaining -= 6; + int lastEndTime = 0; + + for (int i = 0; i < count; i++) { + if (remaining < 8) { + // roll back + parcel->setDataPosition(dataPos); + return OK; + } + parcel->writeInt32(startTime + lastEndTime); + + lastEndTime = U32_AT(tmpData); + parcel->writeInt32(lastEndTime); + + parcel->writeInt32(U16_AT(tmpData + 4)); + parcel->writeInt32(U16_AT(tmpData + 6)); + + tmpData += 8; + remaining -= 8; + } + + break; } + // 'hlit' box specifies highlighted text + case FOURCC('h', 'l', 'i', 't'): + { + if (remaining < 4) { + return OK; + } - break; - } - // 'krok' box. The number of highlight events is specified, and each - // event is specified by a starting and ending char offset and an end - // time for the event. - case FOURCC('k', 'r', 'o', 'k'): - { + parcel->writeInt32(KEY_STRUCT_HIGHLIGHT_LIST); - parcel->writeInt32(KEY_STRUCT_KARAOKE_LIST); + // the start char offset to highlight + parcel->writeInt32(U16_AT(tmpData)); + // the last char offset to highlight + parcel->writeInt32(U16_AT(tmpData + 2)); - int startTime = U32_AT(tmpData); - uint16_t count = U16_AT(tmpData + 4); - parcel->writeInt32(count); + tmpData += 4; + remaining -= 4; + break; + } + // 'hclr' box specifies the RGBA color: 8 bits each of + // red, green, blue, and an alpha(transparency) value + case FOURCC('h', 'c', 'l', 'r'): + { + if (remaining < 4) { + return OK; + } + parcel->writeInt32(KEY_HIGHLIGHT_COLOR_RGBA); + + uint32_t rgba = *(tmpData) << 24 | *(tmpData + 1) << 16 + | *(tmpData + 2) << 8 | *(tmpData + 3); + parcel->writeInt32(rgba); + + tmpData += 4; + remaining -= 4; + break; + } + // 'dlay' box specifies a delay after a scroll in and/or + // before scroll out. + case FOURCC('d', 'l', 'a', 'y'): + { + if (remaining < 4) { + return OK; + } + parcel->writeInt32(KEY_SCROLL_DELAY); + + uint32_t delay = *(tmpData) << 24 | *(tmpData + 1) << 16 + | *(tmpData + 2) << 8 | *(tmpData + 3); + parcel->writeInt32(delay); + + tmpData += 4; + remaining -= 4; + break; + } + // 'href' box for hyper text link + case FOURCC('h', 'r', 'e', 'f'): + { + if (remaining < 5) { + return OK; + } - tmpData += 6; - int lastEndTime = 0; + size_t dataPos = parcel->dataPosition(); - for (int i = 0; i < count; i++) { - parcel->writeInt32(startTime + lastEndTime); + parcel->writeInt32(KEY_STRUCT_HYPER_TEXT_LIST); - lastEndTime = U32_AT(tmpData); - parcel->writeInt32(lastEndTime); + // the start offset of the text to be linked + parcel->writeInt32(U16_AT(tmpData)); + // the end offset of the text + parcel->writeInt32(U16_AT(tmpData + 2)); + // the number of bytes in the following URL + size_t len = *(tmpData + 4); + parcel->writeInt32(len); + + remaining -= 5; + + if (remaining < len) { + parcel->setDataPosition(dataPos); + return OK; + } + // the linked-to URL + parcel->writeInt32(len); + parcel->write(tmpData + 5, len); + + tmpData += (5 + len); + remaining -= len; + + if (remaining < 1) { + parcel->setDataPosition(dataPos); + return OK; + } + + // the number of bytes in the following "alt" string + len = *tmpData; + parcel->writeInt32(len); + + tmpData += 1; + remaining -= 1; + if (remaining < len) { + parcel->setDataPosition(dataPos); + return OK; + } + + // an "alt" string for user display + parcel->writeInt32(len); + parcel->write(tmpData, len); + + tmpData += 1; + remaining -= 1; + break; + } + // 'tbox' box to indicate the position of the text with values + // of top, left, bottom and right + case FOURCC('t', 'b', 'o', 'x'): + { + if (remaining < 8) { + return OK; + } + parcel->writeInt32(KEY_STRUCT_TEXT_POS); + parcel->writeInt32(U16_AT(tmpData)); + parcel->writeInt32(U16_AT(tmpData + 2)); parcel->writeInt32(U16_AT(tmpData + 4)); parcel->writeInt32(U16_AT(tmpData + 6)); tmpData += 8; + remaining -= 8; + break; } + // 'blnk' to specify the char range to be blinked + case FOURCC('b', 'l', 'n', 'k'): + { + if (remaining < 4) { + return OK; + } - break; - } - // 'hlit' box specifies highlighted text - case FOURCC('h', 'l', 'i', 't'): - { - parcel->writeInt32(KEY_STRUCT_HIGHLIGHT_LIST); + parcel->writeInt32(KEY_STRUCT_BLINKING_TEXT_LIST); - // the start char offset to highlight - parcel->writeInt32(U16_AT(tmpData)); - // the last char offset to highlight - parcel->writeInt32(U16_AT(tmpData + 2)); + // start char offset + parcel->writeInt32(U16_AT(tmpData)); + // end char offset + parcel->writeInt32(U16_AT(tmpData + 2)); - break; + tmpData += 4; + remaining -= 4; + break; + } + // 'twrp' box specifies text wrap behavior. If the value if 0x00, + // then no wrap. If it's 0x01, then automatic 'soft' wrap is enabled. + // 0x02-0xff are reserved. + case FOURCC('t', 'w', 'r', 'p'): + { + if (remaining < 1) { + return OK; + } + parcel->writeInt32(KEY_WRAP_TEXT); + parcel->writeInt32(*tmpData); + + tmpData += 1; + remaining -= 1; + break; + } + default: + { + break; + } } - // 'hclr' box specifies the RGBA color: 8 bits each of - // red, green, blue, and an alpha(transparency) value - case FOURCC('h', 'c', 'l', 'r'): - { - parcel->writeInt32(KEY_HIGHLIGHT_COLOR_RGBA); - uint32_t rgba = *(tmpData) << 24 | *(tmpData + 1) << 16 - | *(tmpData + 2) << 8 | *(tmpData + 3); - parcel->writeInt32(rgba); + data += chunkSize; + size -= chunkSize; + } + + return OK; +} - break; - } - // 'dlay' box specifies a delay after a scroll in and/or - // before scroll out. - case FOURCC('d', 'l', 'a', 'y'): - { - parcel->writeInt32(KEY_SCROLL_DELAY); +// To extract box 'tx3g' defined in 3GPP TS 26.245, and store it in a Parcel +status_t TextDescriptions::extract3GPPGlobalDescriptions( + const uint8_t *data, ssize_t size, Parcel *parcel) { + + parcel->writeInt32(KEY_GLOBAL_SETTING); - uint32_t delay = *(tmpData) << 24 | *(tmpData + 1) << 16 - | *(tmpData + 2) << 8 | *(tmpData + 3); - parcel->writeInt32(delay); + while (size >= 8) { + ssize_t chunkSize = U32_AT(data); + uint32_t chunkType = U32_AT(data + 4); + const uint8_t *tmpData = data; + tmpData += 8; + size_t remaining = size - 8; - break; + if (size < chunkSize) { + return OK; } - // 'href' box for hyper text link - case FOURCC('h', 'r', 'e', 'f'): - { - parcel->writeInt32(KEY_STRUCT_HYPER_TEXT_LIST); + switch(chunkType) { + case FOURCC('t', 'x', '3', 'g'): + { + if (remaining < 18) { // 8 just below, and another 10 a little further down + return OK; + } + tmpData += 8; // skip the first 8 bytes + remaining -=8; + parcel->writeInt32(KEY_DISPLAY_FLAGS); + parcel->writeInt32(U32_AT(tmpData)); + + parcel->writeInt32(KEY_STRUCT_JUSTIFICATION); + parcel->writeInt32(tmpData[4]); + parcel->writeInt32(tmpData[5]); + + parcel->writeInt32(KEY_BACKGROUND_COLOR_RGBA); + uint32_t rgba = *(tmpData + 6) << 24 | *(tmpData + 7) << 16 + | *(tmpData + 8) << 8 | *(tmpData + 9); + parcel->writeInt32(rgba); - // the start offset of the text to be linked - parcel->writeInt32(U16_AT(tmpData)); - // the end offset of the text - parcel->writeInt32(U16_AT(tmpData + 2)); + tmpData += 10; + remaining -= 10; - // the number of bytes in the following URL - int len = *(tmpData + 4); - parcel->writeInt32(len); + if (remaining < 8) { + return OK; + } + parcel->writeInt32(KEY_STRUCT_TEXT_POS); + parcel->writeInt32(U16_AT(tmpData)); + parcel->writeInt32(U16_AT(tmpData + 2)); + parcel->writeInt32(U16_AT(tmpData + 4)); + parcel->writeInt32(U16_AT(tmpData + 6)); - // the linked-to URL - parcel->writeInt32(len); - parcel->write(tmpData + 5, len); + tmpData += 8; + remaining -= 8; - tmpData += (5 + len); + if (remaining < 12) { + return OK; + } + parcel->writeInt32(KEY_STRUCT_STYLE_LIST); + parcel->writeInt32(KEY_START_CHAR); + parcel->writeInt32(U16_AT(tmpData)); - // the number of bytes in the following "alt" string - len = *tmpData; - parcel->writeInt32(len); + parcel->writeInt32(KEY_END_CHAR); + parcel->writeInt32(U16_AT(tmpData + 2)); - // an "alt" string for user display - parcel->writeInt32(len); - parcel->write(tmpData + 1, len); + parcel->writeInt32(KEY_FONT_ID); + parcel->writeInt32(U16_AT(tmpData + 4)); - break; - } - // 'tbox' box to indicate the position of the text with values - // of top, left, bottom and right - case FOURCC('t', 'b', 'o', 'x'): - { - parcel->writeInt32(KEY_STRUCT_TEXT_POS); - parcel->writeInt32(U16_AT(tmpData)); - parcel->writeInt32(U16_AT(tmpData + 2)); - parcel->writeInt32(U16_AT(tmpData + 4)); - parcel->writeInt32(U16_AT(tmpData + 6)); - - break; - } - // 'blnk' to specify the char range to be blinked - case FOURCC('b', 'l', 'n', 'k'): - { - parcel->writeInt32(KEY_STRUCT_BLINKING_TEXT_LIST); + parcel->writeInt32(KEY_STYLE_FLAGS); + parcel->writeInt32(*(tmpData + 6)); - // start char offset - parcel->writeInt32(U16_AT(tmpData)); - // end char offset - parcel->writeInt32(U16_AT(tmpData + 2)); + parcel->writeInt32(KEY_FONT_SIZE); + parcel->writeInt32(*(tmpData + 7)); - break; - } - // 'twrp' box specifies text wrap behavior. If the value if 0x00, - // then no wrap. If it's 0x01, then automatic 'soft' wrap is enabled. - // 0x02-0xff are reserved. - case FOURCC('t', 'w', 'r', 'p'): - { - parcel->writeInt32(KEY_WRAP_TEXT); - parcel->writeInt32(*tmpData); - - break; - } - default: - { - break; - } - } + parcel->writeInt32(KEY_TEXT_COLOR_RGBA); + rgba = *(tmpData + 8) << 24 | *(tmpData + 9) << 16 + | *(tmpData + 10) << 8 | *(tmpData + 11); + parcel->writeInt32(rgba); - if (size > chunkSize) { - data += chunkSize; - size -= chunkSize; - // continue to parse next box - return extract3GPPLocalDescriptions(data, size, 0, parcel, 1); - } + tmpData += 12; + remaining -= 12; - return OK; -} + if (remaining < 2) { + return OK; + } -// To extract box 'tx3g' defined in 3GPP TS 26.245, and store it in a Parcel -status_t TextDescriptions::extract3GPPGlobalDescriptions( - const uint8_t *data, ssize_t size, Parcel *parcel, int depth) { + size_t dataPos = parcel->dataPosition(); - ssize_t chunkSize = U32_AT(data); - uint32_t chunkType = U32_AT(data + 4); - const uint8_t *tmpData = data; - tmpData += 8; + parcel->writeInt32(KEY_STRUCT_FONT_LIST); + uint16_t count = U16_AT(tmpData); + parcel->writeInt32(count); - if (size < chunkSize) { - return OK; - } + tmpData += 2; + remaining -= 2; - if (depth == 0) { - parcel->writeInt32(KEY_GLOBAL_SETTING); - } - switch(chunkType) { - case FOURCC('t', 'x', '3', 'g'): - { - tmpData += 8; // skip the first 8 bytes - parcel->writeInt32(KEY_DISPLAY_FLAGS); - parcel->writeInt32(U32_AT(tmpData)); - - parcel->writeInt32(KEY_STRUCT_JUSTIFICATION); - parcel->writeInt32(tmpData[4]); - parcel->writeInt32(tmpData[5]); - - parcel->writeInt32(KEY_BACKGROUND_COLOR_RGBA); - uint32_t rgba = *(tmpData + 6) << 24 | *(tmpData + 7) << 16 - | *(tmpData + 8) << 8 | *(tmpData + 9); - parcel->writeInt32(rgba); - - tmpData += 10; - parcel->writeInt32(KEY_STRUCT_TEXT_POS); - parcel->writeInt32(U16_AT(tmpData)); - parcel->writeInt32(U16_AT(tmpData + 2)); - parcel->writeInt32(U16_AT(tmpData + 4)); - parcel->writeInt32(U16_AT(tmpData + 6)); - - tmpData += 8; - parcel->writeInt32(KEY_STRUCT_STYLE_LIST); - parcel->writeInt32(KEY_START_CHAR); - parcel->writeInt32(U16_AT(tmpData)); - - parcel->writeInt32(KEY_END_CHAR); - parcel->writeInt32(U16_AT(tmpData + 2)); - - parcel->writeInt32(KEY_FONT_ID); - parcel->writeInt32(U16_AT(tmpData + 4)); - - parcel->writeInt32(KEY_STYLE_FLAGS); - parcel->writeInt32(*(tmpData + 6)); - - parcel->writeInt32(KEY_FONT_SIZE); - parcel->writeInt32(*(tmpData + 7)); - - parcel->writeInt32(KEY_TEXT_COLOR_RGBA); - rgba = *(tmpData + 8) << 24 | *(tmpData + 9) << 16 - | *(tmpData + 10) << 8 | *(tmpData + 11); - parcel->writeInt32(rgba); - - tmpData += 12; - parcel->writeInt32(KEY_STRUCT_FONT_LIST); - uint16_t count = U16_AT(tmpData); - parcel->writeInt32(count); - - tmpData += 2; - for (int i = 0; i < count; i++) { - // font ID - parcel->writeInt32(U16_AT(tmpData)); + for (int i = 0; i < count; i++) { + if (remaining < 3) { + // roll back + parcel->setDataPosition(dataPos); + return OK; + } + // font ID + parcel->writeInt32(U16_AT(tmpData)); - // font name length - parcel->writeInt32(*(tmpData + 2)); + // font name length + parcel->writeInt32(*(tmpData + 2)); - int len = *(tmpData + 2); + size_t len = *(tmpData + 2); - parcel->write(tmpData + 3, len); - tmpData += 3 + len; - } + tmpData += 3; + remaining -= 3; - break; - } - default: - { - break; - } - } + if (remaining < len) { + // roll back + parcel->setDataPosition(dataPos); + return OK; + } - data += chunkSize; - size -= chunkSize; + parcel->write(tmpData, len); + tmpData += len; + remaining -= len; + } - if (size > 0) { - // continue to extract next 'tx3g' - return extract3GPPGlobalDescriptions(data, size, parcel, 1); + // there is a "DisparityBox" after this according to the spec, but we ignore it + break; + } + default: + { + break; + } + } + + data += chunkSize; + size -= chunkSize; } return OK; diff --git a/media/libstagefright/timedtext/TextDescriptions.h b/media/libstagefright/timedtext/TextDescriptions.h index 0144917..bf67f3f 100644 --- a/media/libstagefright/timedtext/TextDescriptions.h +++ b/media/libstagefright/timedtext/TextDescriptions.h @@ -72,10 +72,10 @@ private: int timeMs, Parcel *parcel); static status_t extract3GPPGlobalDescriptions( const uint8_t *data, ssize_t size, - Parcel *parcel, int depth); + Parcel *parcel); static status_t extract3GPPLocalDescriptions( const uint8_t *data, ssize_t size, - int timeMs, Parcel *parcel, int depth); + int timeMs, Parcel *parcel); DISALLOW_EVIL_CONSTRUCTORS(TextDescriptions); }; |