summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRockchip2015-10-08 14:42:26 +0800
committerRockchip2015-10-08 14:42:26 +0800
commitff61f8466424d2dfcb99f5f186e82b5d1b1f0fde (patch)
tree35b65e0d6df65779445b0623bd3255794f5663a3
parentf2703036fad96331e7c81f641dc7099539d11e7d (diff)
stagefright:merge google secure patch bulletin-2015-15
-rw-r--r--drm/common/IDrmManagerService.cpp16
-rwxr-xr-xmedia/libmedia/IAudioFlinger.cpp54
-rw-r--r--media/libmedia/IAudioPolicyService.cpp20
-rw-r--r--media/libmedia/ICrypto.cpp24
-rw-r--r--media/libmedia/IEffect.cpp31
-rw-r--r--media/libmedia/IMediaPlayer.cpp2
-rw-r--r--media/libmediaplayerservice/nuplayer/GenericSource.cpp31
-rw-r--r--media/libmediaplayerservice/nuplayer/GenericSource.h1
-rwxr-xr-xmedia/libstagefright/ACodec.cpp8
-rw-r--r--media/libstagefright/OggExtractor.cpp93
-rw-r--r--media/libstagefright/Utils.cpp36
-rw-r--r--media/libstagefright/foundation/base64.cpp11
-rwxr-xr-x[-rw-r--r--]media/libstagefright/timedtext/TextDescriptions.cpp637
-rw-r--r--media/libstagefright/timedtext/TextDescriptions.h4
14 files changed, 561 insertions, 407 deletions
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp
index db41e0b..c235201 100644
--- a/drm/common/IDrmManagerService.cpp
+++ b/drm/common/IDrmManagerService.cpp
@@ -741,9 +741,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;
}
@@ -1438,9 +1440,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 d7ca425..ac2d1c9 100755
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -924,7 +924,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))) {
@@ -957,7 +957,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, &frameCount, &flags, tid, &sessionId,
&notificationFrames,
@@ -1090,13 +1090,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);
@@ -1135,8 +1137,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();
@@ -1172,8 +1176,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) {
@@ -1209,7 +1213,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) {
@@ -1219,7 +1223,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) {
@@ -1231,7 +1235,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) {
@@ -1241,15 +1245,17 @@ 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();
- 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,
&status, &id, &enabled);
@@ -1318,8 +1324,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) {
@@ -1331,8 +1339,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 12efa8a..80f8516 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -816,7 +816,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,
samplingRate, format, channelMask,
@@ -1085,8 +1085,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) {
@@ -1099,8 +1101,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) {
@@ -1169,9 +1173,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) {
diff --git a/media/libmedia/ICrypto.cpp b/media/libmedia/ICrypto.cpp
index f7d8bc6..2abb3ac 100644
--- a/media/libmedia/ICrypto.cpp
+++ b/media/libmedia/ICrypto.cpp
@@ -265,7 +265,28 @@ status_t BnCrypto::onTransact(
}
AString errorDetailMsg;
- ssize_t result = decrypt(
+ ssize_t result;
+
+ 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 {
+ result = decrypt(
secure,
key,
iv,
@@ -274,6 +295,7 @@ status_t BnCrypto::onTransact(
subSamples, numSubSamples,
secure ? secureBufferId : dstPtr,
&errorDetailMsg);
+ }
reply->writeInt32(result);
diff --git a/media/libmedia/IEffect.cpp b/media/libmedia/IEffect.cpp
index b94012a..8cd158d 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);
@@ -154,23 +156,34 @@ status_t BnEffect::onTransact(
uint32_t cmdSize = data.readInt32();
char *cmd = NULL;
if (cmdSize) {
- cmd = (char *)malloc(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();
uint32_t replySz = replySize;
char *resp = NULL;
if (replySize) {
- resp = (char *)malloc(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 d778d05..aa22b58 100644
--- a/media/libmedia/IMediaPlayer.cpp
+++ b/media/libmedia/IMediaPlayer.cpp
@@ -525,6 +525,7 @@ status_t BnMediaPlayer::onTransact(
CHECK_INTERFACE(IMediaPlayer, data, reply);
struct sockaddr_in endpoint;
+ memset(&endpoint, 0, sizeof(endpoint));
int amt = data.readInt32();
if (amt == sizeof(endpoint)) {
data.read(&endpoint, sizeof(struct sockaddr_in));
@@ -539,6 +540,7 @@ status_t BnMediaPlayer::onTransact(
CHECK_INTERFACE(IMediaPlayer, data, reply);
struct sockaddr_in endpoint;
+ memset(&endpoint, 0, sizeof(endpoint));
status_t res = getRetransmitEndpoint(&endpoint);
reply->writeInt32(res);
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 1b2fc5e..e4cd338 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -468,9 +468,17 @@ void NuPlayer::GenericSource::notifyPreparedAndCleanup(status_t err) {
mMetaDataSize = -1ll;
mContentType = "";
mSniffedMIME = "";
- 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();
@@ -593,13 +601,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 2d73ea9..5527448 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.h
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.h
@@ -149,6 +149,7 @@ private:
bool mBuffering;
bool mPrepareBuffering;
mutable Mutex mReadBufferLock;
+ mutable Mutex mDisconnectLock;
sp<ALooper> mLooper;
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index b455f9e..fc7fe65 100755
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -554,7 +554,9 @@ status_t ACodec::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.mStatus = BufferInfo::OWNED_BY_US;
@@ -898,7 +900,9 @@ status_t ACodec::allocateOutputMetaDataBuffers() {
sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
sizeof(struct VideoDecoderOutputMetaData));
- CHECK(mem.get() != NULL);
+ if (mem == NULL || mem->pointer() == NULL) {
+ return NO_MEMORY;
+ }
info.mData = new ABuffer(mem->pointer(), mem->size());
// we use useBuffer for metadata regardless of quirks
diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp
index f502959..c441603 100644
--- a/media/libstagefright/OggExtractor.cpp
+++ b/media/libstagefright/OggExtractor.cpp
@@ -21,7 +21,9 @@
#include "include/OggExtractor.h"
#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>
@@ -875,83 +877,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);
-
- 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;
@@ -961,24 +898,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);
@@ -988,7 +925,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]);
@@ -996,7 +933,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]);
@@ -1004,7 +941,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",
@@ -1014,10 +951,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/Utils.cpp b/media/libstagefright/Utils.cpp
index d86be6e..214e2fc 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -196,8 +196,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 = ptr[1];
uint8_t level = ptr[3];
@@ -223,7 +225,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;
@@ -252,13 +257,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;
@@ -282,8 +293,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 = ptr[1] & 31;
uint8_t level = ptr[12];
ptr += 22;
@@ -302,6 +315,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;
@@ -312,7 +329,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 3d61723..9d53499 100644..100755
--- 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) {
@@ -71,215 +71,301 @@ 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) {
- const uint8_t *tmpData = data;
- ssize_t chunkSize = U32_AT(tmpData);
- uint32_t chunkType = U32_AT(tmpData + 4);
+ parcel->writeInt32(KEY_LOCAL_SETTING);
+
+ // write start time to display this text sample
+ parcel->writeInt32(KEY_START_TIME);
+ parcel->writeInt32(timeMs);
- if (chunkSize <= 0) {
+ if (size < 2) {
return OK;
}
+ ssize_t textLen = (*data) << 8 | (*(data + 1));
- tmpData += 8;
-
- switch(chunkType) {
- // 'styl' box specifies the style of the text.
- case FOURCC('s', 't', 'y', 'l'):
- {
- uint16_t count = U16_AT(tmpData);
-
- tmpData += 2;
+ if (size < textLen + 2) {
+ return OK;
+ }
- for (int i = 0; i < count; i++) {
- parcel->writeInt32(KEY_STRUCT_STYLE_LIST);
- parcel->writeInt32(KEY_START_CHAR);
- parcel->writeInt32(U16_AT(tmpData));
+ // 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;
+ }
- parcel->writeInt32(KEY_END_CHAR);
- parcel->writeInt32(U16_AT(tmpData + 2));
+ 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);
- parcel->writeInt32(KEY_FONT_ID);
- parcel->writeInt32(U16_AT(tmpData + 4));
+ if (chunkSize <= 8 || chunkSize > size) {
+ return OK;
+ }
- parcel->writeInt32(KEY_STYLE_FLAGS);
- parcel->writeInt32(*(tmpData + 6));
+ size_t remaining = chunkSize - 8;
- parcel->writeInt32(KEY_FONT_SIZE);
- parcel->writeInt32(*(tmpData + 7));
+ tmpData += 8;
- parcel->writeInt32(KEY_TEXT_COLOR_RGBA);
- uint32_t rgba = *(tmpData + 8) << 24 | *(tmpData + 9) << 16
- | *(tmpData + 10) << 8 | *(tmpData + 11);
- parcel->writeInt32(rgba);
+ 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);
- tmpData += 12;
- }
+ tmpData += 2;
+ remaining -= 2;
- 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'):
- {
+ 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_STRUCT_KARAOKE_LIST);
+ parcel->writeInt32(KEY_END_CHAR);
+ parcel->writeInt32(U16_AT(tmpData + 2));
- int startTime = U32_AT(tmpData);
- uint16_t count = U16_AT(tmpData + 4);
- parcel->writeInt32(count);
+ parcel->writeInt32(KEY_FONT_ID);
+ parcel->writeInt32(U16_AT(tmpData + 4));
- tmpData += 6;
- int lastEndTime = 0;
+ parcel->writeInt32(KEY_STYLE_FLAGS);
+ parcel->writeInt32(*(tmpData + 6));
- for (int i = 0; i < count; i++) {
- parcel->writeInt32(startTime + lastEndTime);
+ parcel->writeInt32(KEY_FONT_SIZE);
+ parcel->writeInt32(*(tmpData + 7));
- lastEndTime = U32_AT(tmpData);
- parcel->writeInt32(lastEndTime);
+ 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(U16_AT(tmpData + 4));
- parcel->writeInt32(U16_AT(tmpData + 6));
+ tmpData += 12;
+ remaining -= 12;
+ }
- tmpData += 8;
+ 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;
- }
- // 'hlit' box specifies highlighted text
- case FOURCC('h', 'l', 'i', 't'):
- {
- parcel->writeInt32(KEY_STRUCT_HIGHLIGHT_LIST);
-
- // the start char offset to highlight
- parcel->writeInt32(U16_AT(tmpData));
- // the last char offset to highlight
- parcel->writeInt32(U16_AT(tmpData + 2));
-
- 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);
-
- 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);
+ parcel->writeInt32(KEY_STRUCT_HIGHLIGHT_LIST);
- uint32_t delay = *(tmpData) << 24 | *(tmpData + 1) << 16
- | *(tmpData + 2) << 8 | *(tmpData + 3);
- parcel->writeInt32(delay);
+ // the start char offset to highlight
+ parcel->writeInt32(U16_AT(tmpData));
+ // the last char offset to highlight
+ parcel->writeInt32(U16_AT(tmpData + 2));
- break;
- }
- // 'href' box for hyper text link
- case FOURCC('h', 'r', 'e', 'f'):
- {
- parcel->writeInt32(KEY_STRUCT_HYPER_TEXT_LIST);
+ 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);
- // 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 += 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;
+ }
- // the number of bytes in the following URL
- int len = *(tmpData + 4);
- parcel->writeInt32(len);
+ size_t dataPos = parcel->dataPosition();
- // the linked-to URL
- parcel->writeInt32(len);
- parcel->write(tmpData + 5, len);
+ parcel->writeInt32(KEY_STRUCT_HYPER_TEXT_LIST);
- tmpData += (5 + len);
+ // 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 "alt" string
- len = *tmpData;
- parcel->writeInt32(len);
+ // 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));
- // an "alt" string for user display
- parcel->writeInt32(len);
- parcel->write(tmpData + 1, len);
+ 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;
- }
- // '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_STRUCT_BLINKING_TEXT_LIST);
- // start char offset
- parcel->writeInt32(U16_AT(tmpData));
- // end char offset
- parcel->writeInt32(U16_AT(tmpData + 2));
+ // start char offset
+ parcel->writeInt32(U16_AT(tmpData));
+ // end char offset
+ parcel->writeInt32(U16_AT(tmpData + 2));
- 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;
+ 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;
+ }
}
- }
-
- if (size > chunkSize) {
data += chunkSize;
size -= chunkSize;
- // continue to parse next box
- return extract3GPPLocalDescriptions(data, size, 0, parcel, 1);
}
return OK;
@@ -287,100 +373,135 @@ status_t TextDescriptions::extract3GPPLocalDescriptions(
// 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) {
+ const uint8_t *data, ssize_t size, Parcel *parcel) {
- ssize_t chunkSize = U32_AT(data);
- uint32_t chunkType = U32_AT(data + 4);
- const uint8_t *tmpData = data;
- tmpData += 8;
+ parcel->writeInt32(KEY_GLOBAL_SETTING);
- if (size < chunkSize) {
- return OK;
- }
+ 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;
- 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
+ if (size < chunkSize) {
+ return OK;
+ }
+ 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);
+
+ tmpData += 10;
+ remaining -= 10;
+
+ 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));
- // font name length
- parcel->writeInt32(*(tmpData + 2));
+ tmpData += 8;
+ remaining -= 8;
- int len = *(tmpData + 2);
+ if (remaining < 12) {
+ return OK;
+ }
+ parcel->writeInt32(KEY_STRUCT_STYLE_LIST);
+ parcel->writeInt32(KEY_START_CHAR);
+ parcel->writeInt32(U16_AT(tmpData));
- parcel->write(tmpData + 3, len);
- tmpData += 3 + len;
- }
+ parcel->writeInt32(KEY_END_CHAR);
+ parcel->writeInt32(U16_AT(tmpData + 2));
- break;
- }
- default:
- {
- break;
- }
- }
+ parcel->writeInt32(KEY_FONT_ID);
+ parcel->writeInt32(U16_AT(tmpData + 4));
- data += chunkSize;
- size -= chunkSize;
+ parcel->writeInt32(KEY_STYLE_FLAGS);
+ parcel->writeInt32(*(tmpData + 6));
- if (size > 0) {
- // continue to extract next 'tx3g'
- return extract3GPPGlobalDescriptions(data, size, parcel, 1);
- }
+ 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;
+ remaining -= 12;
+
+ if (remaining < 2) {
+ return OK;
+ }
+
+ size_t dataPos = parcel->dataPosition();
+
+ parcel->writeInt32(KEY_STRUCT_FONT_LIST);
+ uint16_t count = U16_AT(tmpData);
+ parcel->writeInt32(count);
+
+ tmpData += 2;
+ remaining -= 2;
+ 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));
+
+ size_t len = *(tmpData + 2);
+
+ tmpData += 3;
+ remaining -= 3;
+
+ if (remaining < len) {
+ // roll back
+ parcel->setDataPosition(dataPos);
+ return OK;
+ }
+
+ parcel->write(tmpData, len);
+ tmpData += len;
+ remaining -= len;
+ }
+
+ // 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 dff8b92..903cd00 100644
--- a/media/libstagefright/timedtext/TextDescriptions.h
+++ b/media/libstagefright/timedtext/TextDescriptions.h
@@ -73,10 +73,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);
static status_t extractMatroskaLocalDescriptions(
const uint8_t *data, ssize_t size,
int timeMs, Parcel *parcel);