Skip to content

Commit 0ba8660

Browse files
committed
Report a runtime error instead of asserting on malformed avc configuration data.
Change-Id: Ibcd9c3fb5b6532eba843ed80ecdcdacaf50d8845 related-to-bug: 5641069
1 parent dea90a0 commit 0ba8660

File tree

2 files changed

+91
-57
lines changed

2 files changed

+91
-57
lines changed

include/media/stagefright/OMXCodec.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,10 @@ struct OMXCodec : public MediaSource,
336336

337337
int64_t retrieveDecodingTimeUs(bool isCodecSpecific);
338338

339+
status_t parseAVCCodecSpecificData(
340+
const void *data, size_t size,
341+
unsigned *profile, unsigned *level);
342+
339343
OMXCodec(const OMXCodec &);
340344
OMXCodec &operator=(const OMXCodec &);
341345
};

media/libstagefright/OMXCodec.cpp

Lines changed: 87 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,85 @@ sp<MediaSource> OMXCodec::Create(
520520
return NULL;
521521
}
522522

523+
status_t OMXCodec::parseAVCCodecSpecificData(
524+
const void *data, size_t size,
525+
unsigned *profile, unsigned *level) {
526+
const uint8_t *ptr = (const uint8_t *)data;
527+
528+
// verify minimum size and configurationVersion == 1.
529+
if (size < 7 || ptr[0] != 1) {
530+
return ERROR_MALFORMED;
531+
}
532+
533+
*profile = ptr[1];
534+
*level = ptr[3];
535+
536+
// There is decodable content out there that fails the following
537+
// assertion, let's be lenient for now...
538+
// CHECK((ptr[4] >> 2) == 0x3f); // reserved
539+
540+
size_t lengthSize = 1 + (ptr[4] & 3);
541+
542+
// commented out check below as H264_QVGA_500_NO_AUDIO.3gp
543+
// violates it...
544+
// CHECK((ptr[5] >> 5) == 7); // reserved
545+
546+
size_t numSeqParameterSets = ptr[5] & 31;
547+
548+
ptr += 6;
549+
size -= 6;
550+
551+
for (size_t i = 0; i < numSeqParameterSets; ++i) {
552+
if (size < 2) {
553+
return ERROR_MALFORMED;
554+
}
555+
556+
size_t length = U16_AT(ptr);
557+
558+
ptr += 2;
559+
size -= 2;
560+
561+
if (size < length) {
562+
return ERROR_MALFORMED;
563+
}
564+
565+
addCodecSpecificData(ptr, length);
566+
567+
ptr += length;
568+
size -= length;
569+
}
570+
571+
if (size < 1) {
572+
return ERROR_MALFORMED;
573+
}
574+
575+
size_t numPictureParameterSets = *ptr;
576+
++ptr;
577+
--size;
578+
579+
for (size_t i = 0; i < numPictureParameterSets; ++i) {
580+
if (size < 2) {
581+
return ERROR_MALFORMED;
582+
}
583+
584+
size_t length = U16_AT(ptr);
585+
586+
ptr += 2;
587+
size -= 2;
588+
589+
if (size < length) {
590+
return ERROR_MALFORMED;
591+
}
592+
593+
addCodecSpecificData(ptr, length);
594+
595+
ptr += length;
596+
size -= length;
597+
}
598+
599+
return OK;
600+
}
601+
523602
status_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
524603
LOGV("configureCodec protected=%d",
525604
(mFlags & kEnableGrallocUsageProtected) ? 1 : 0);
@@ -542,66 +621,17 @@ status_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
542621
} else if (meta->findData(kKeyAVCC, &type, &data, &size)) {
543622
// Parse the AVCDecoderConfigurationRecord
544623

545-
const uint8_t *ptr = (const uint8_t *)data;
546-
547-
CHECK(size >= 7);
548-
CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1
549-
uint8_t profile = ptr[1];
550-
uint8_t level = ptr[3];
551-
552-
// There is decodable content out there that fails the following
553-
// assertion, let's be lenient for now...
554-
// CHECK((ptr[4] >> 2) == 0x3f); // reserved
555-
556-
size_t lengthSize = 1 + (ptr[4] & 3);
557-
558-
// commented out check below as H264_QVGA_500_NO_AUDIO.3gp
559-
// violates it...
560-
// CHECK((ptr[5] >> 5) == 7); // reserved
561-
562-
size_t numSeqParameterSets = ptr[5] & 31;
563-
564-
ptr += 6;
565-
size -= 6;
566-
567-
for (size_t i = 0; i < numSeqParameterSets; ++i) {
568-
CHECK(size >= 2);
569-
size_t length = U16_AT(ptr);
570-
571-
ptr += 2;
572-
size -= 2;
573-
574-
CHECK(size >= length);
575-
576-
addCodecSpecificData(ptr, length);
577-
578-
ptr += length;
579-
size -= length;
580-
}
581-
582-
CHECK(size >= 1);
583-
size_t numPictureParameterSets = *ptr;
584-
++ptr;
585-
--size;
586-
587-
for (size_t i = 0; i < numPictureParameterSets; ++i) {
588-
CHECK(size >= 2);
589-
size_t length = U16_AT(ptr);
590-
591-
ptr += 2;
592-
size -= 2;
593-
594-
CHECK(size >= length);
595-
596-
addCodecSpecificData(ptr, length);
597-
598-
ptr += length;
599-
size -= length;
624+
unsigned profile, level;
625+
status_t err;
626+
if ((err = parseAVCCodecSpecificData(
627+
data, size, &profile, &level)) != OK) {
628+
LOGE("Malformed AVC codec specific data.");
629+
return err;
600630
}
601631

602632
CODEC_LOGI(
603-
"AVC profile = %d (%s), level = %d",
604-
(int)profile, AVCProfileToString(profile), level);
633+
"AVC profile = %u (%s), level = %u",
634+
profile, AVCProfileToString(profile), level);
605635

606636
if (!strcmp(mComponentName, "OMX.TI.Video.Decoder")
607637
&& (profile != kAVCProfileBaseline || level > 30)) {

0 commit comments

Comments
 (0)