Skip to content

Commit

Permalink
[demuxers/Mp4] Factorize, safeguard against reading past array end, r…
Browse files Browse the repository at this point in the history
…emove some asserts where we can fail safely
  • Loading branch information
eumagga0x2a committed Dec 29, 2022
1 parent 108a74b commit cb31334
Showing 1 changed file with 79 additions and 39 deletions.
118 changes: 79 additions & 39 deletions avidemux_plugins/ADM_demuxers/Mp4/ADM_mp4Analyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,62 @@ uint8_t MP4Header::parseEdts(void *ztom,uint32_t trackType)
tom->skipAtom();
return 1;
}

/*
\fn avcCDump
\brief Print some info about given AVC extradata
*/
static void avcCDump(uint8_t *data, int size)
{
int len,offset;

#define MKD8(x) data[x]
#define MKD16(x) ((MKD8(x)<<8)+MKD8(x+1))
/* #define MKD32(x) ((MKD16(x)<<16)+MKD16(x+2)) */

printf("avcC size : %d\n", size);
printf("avcC Revision : 0x%x\n", MKD8(0));
printf("avcC AVCProfileIndication : 0x%x\n", MKD8(1));
printf("avcC profile_compatibility : 0x%x\n", MKD8(2));
printf("avcC AVCLevelIndication : 0x%x\n", MKD8(3));
printf("avcC NAL length : %d\n", (MKD8(4) & 3) + 1);

offset = 5;
int numPs = MKD8(offset++) & 0x1F;
printf("avcC NumSequenceParSets : %d\n", numPs);

for(int i=0; i < numPs; i++)
{
len = MKD16(offset);
offset += 2;
printf("avcC SPS (%d) len : %d\n", i, len);
if(offset + len > size)
{
printf(" SPS length out of bounds, invalid data!\n");
return;
}
mixDump(data + offset, len);
offset += len;
}

numPs = MKD8(offset++) & 0x1F;
printf("avcC numOfPictureParSets : %d\n", numPs);

for(int i=0; i < numPs; i++)
{
len = MKD16(offset);
offset += 2;
printf("avcC PPS (%d) len : %d\n", i, len);
if(offset + len > size)
{
printf(" PPS length out of bounds, invalid data!\n");
return;
}
mixDump(data + offset, len);
offset += len;
}
}

/**
\fn parseStbl
\brief parse sample table. this is the most important function.
Expand Down Expand Up @@ -1167,7 +1223,12 @@ uint8_t MP4Header::parseStbl(void *ztom,uint32_t trackType,uint32_t trackScale)
continue;
}
printf("Reading %s, got hvcC of size %" PRId64"\n", hevc, remaining);
ADM_assert(remaining >= 0 && remaining <= 0xffffffff);
if(remaining < 0 || remaining > 0xffffffff)
{
ADM_warning("Invalid data encountered reading hvcC atom.\n");
ADM_dealloc(hevc);
return 0;
}
VDEO.extraDataSize = remaining;
ADM_info("Found %d bytes of extradata \n",VDEO.extraDataSize);
VDEO.extraData=new uint8_t [VDEO.extraDataSize];
Expand All @@ -1188,53 +1249,31 @@ uint8_t MP4Header::parseStbl(void *ztom,uint32_t trackType,uint32_t trackScale)
commonPart(H264);
// There is a avcC atom just after
// configuration data for h264
char *avcName = ADM_strdup(fourCC::tostringBE(entryName));
while(!son.isDone())
{
adm_atom avcc(&son);
printf("Reading avcC, got %s\n",fourCC::tostringBE(avcc.getFCC()));
if(avcc.getFCC()!=MKFCCR('a','v','c','C'))
int64_t remaining = avcc.getRemainingSize();
uint32_t fcc = avcc.getFCC();
if(fcc != MKFCCR('a','v','c','C'))
{
printf("Reading %s, skipping %s of size %" PRId64"\n", avcName, fourCC::tostringBE(fcc), remaining);
avcc.skipAtom();
continue;
}

int len,offset;
VDEO.extraDataSize=avcc.getRemainingSize();
VDEO.extraData=new uint8_t [VDEO.extraDataSize];
avcc.readPayload(VDEO.extraData,VDEO.extraDataSize);
printf("avcC size : %d\n",VDEO.extraDataSize);
// Dump some info
#define MKD8(x) VDEO.extraData[x]
#define MKD16(x) ((MKD8(x)<<8)+MKD8(x+1))
#define MKD32(x) ((MKD16(x)<<16)+MKD16(x+2))

printf("avcC Revision : 0x%x\n", MKD8(0));
printf("avcC AVCProfileIndication : 0x%x\n", MKD8(1));
printf("avcC profile_compatibility : 0x%x\n", MKD8(2));
printf("avcC AVCLevelIndication : 0x%x\n", MKD8(3));

printf("avcC NAL length : %d\n", (MKD8(4) & 3) + 1);
offset = 5;
int numPs = MKD8(offset++) & 0x1F;
printf("avcC NumSequenceParSets : %d\n", numPs);
for(int i=0; i < numPs; i++)
{
len = MKD16(offset);
offset += 2;
printf("avcC SPS (%d) len : %d\n", i, len);
mixDump(VDEO.extraData + offset, len);
offset += len;
}
numPs = MKD8(offset++) & 0x1F;
printf("avcC numOfPictureParSets : %d\n", numPs);
for(int i=0; i < numPs; i++)
printf("Reading %s, got avcC of size %" PRId64"\n", avcName, remaining);
if(remaining < 7 || remaining > 0xffffffff) // FIXME
{
len = MKD16(offset);
offset += 2;
printf("avcC PPS (%d) len : %d\n", i, len);
mixDump(VDEO.extraData + offset, len);
offset += len;
ADM_warning("Invalid data encountered reading avcC atom.\n");
ADM_dealloc(avcName);
return 0;
}
VDEO.extraDataSize = remaining;
VDEO.extraData=new uint8_t [VDEO.extraDataSize];
avcc.readPayload(VDEO.extraData,VDEO.extraDataSize);

avcCDump(VDEO.extraData, VDEO.extraDataSize);

// Verify width and height, the values from the container may be wrong.
ADM_SPSInfo sps;
if(false==extractSPSInfo(VDEO.extraData,VDEO.extraDataSize,&sps))
Expand Down Expand Up @@ -1271,6 +1310,7 @@ uint8_t MP4Header::parseStbl(void *ztom,uint32_t trackType,uint32_t trackScale)
}
break;
} // while
ADM_dealloc(avcName);
son.skipAtom();
left=0;

Expand Down

0 comments on commit cb31334

Please sign in to comment.