mirror of https://git.ffmpeg.org/ffmpeg.git
avformat/mxfdec: store parition score instead of partition pointer in metadata
Partition struct may be reallocated, so let's store the score directly in order to avoid use-after-free. Also mxf->current_partition might be null when reading some local tags. Signed-off-by: Marton Balint <cus@passwd.hu>
This commit is contained in:
parent
f852490f72
commit
f0d4077c53
|
@ -108,7 +108,7 @@ typedef struct MXFPartition {
|
||||||
|
|
||||||
typedef struct MXFMetadataSet {
|
typedef struct MXFMetadataSet {
|
||||||
UID uid;
|
UID uid;
|
||||||
MXFPartition *partition;
|
uint64_t partition_score;
|
||||||
enum MXFMetadataSetType type;
|
enum MXFMetadataSetType type;
|
||||||
} MXFMetadataSet;
|
} MXFMetadataSet;
|
||||||
|
|
||||||
|
@ -831,21 +831,25 @@ static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int partition_score(MXFPartition *p)
|
static uint64_t partition_score(MXFPartition *p)
|
||||||
{
|
{
|
||||||
|
uint64_t score;
|
||||||
|
if (!p)
|
||||||
|
return 0;
|
||||||
if (p->type == Footer)
|
if (p->type == Footer)
|
||||||
return 5;
|
score = 5;
|
||||||
if (p->complete)
|
else if (p->complete)
|
||||||
return 4;
|
score = 4;
|
||||||
if (p->closed)
|
else if (p->closed)
|
||||||
return 3;
|
score = 3;
|
||||||
return 1;
|
else
|
||||||
|
score = 1;
|
||||||
|
return (score << 60) | ((uint64_t)p->this_partition >> 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mxf_add_metadata_set(MXFContext *mxf, MXFMetadataSet **metadata_set)
|
static int mxf_add_metadata_set(MXFContext *mxf, MXFMetadataSet **metadata_set)
|
||||||
{
|
{
|
||||||
MXFMetadataSet **tmp;
|
MXFMetadataSet **tmp;
|
||||||
MXFPartition *new_p = (*metadata_set)->partition;
|
|
||||||
enum MXFMetadataSetType type = (*metadata_set)->type;
|
enum MXFMetadataSetType type = (*metadata_set)->type;
|
||||||
|
|
||||||
// Index Table is special because it might be added manually without
|
// Index Table is special because it might be added manually without
|
||||||
|
@ -854,10 +858,9 @@ static int mxf_add_metadata_set(MXFContext *mxf, MXFMetadataSet **metadata_set)
|
||||||
if (type != IndexTableSegment) {
|
if (type != IndexTableSegment) {
|
||||||
for (int i = 0; i < mxf->metadata_sets_count; i++) {
|
for (int i = 0; i < mxf->metadata_sets_count; i++) {
|
||||||
if (!memcmp((*metadata_set)->uid, mxf->metadata_sets[i]->uid, 16) && type == mxf->metadata_sets[i]->type) {
|
if (!memcmp((*metadata_set)->uid, mxf->metadata_sets[i]->uid, 16) && type == mxf->metadata_sets[i]->type) {
|
||||||
MXFPartition *old_p = mxf->metadata_sets[i]->partition;
|
uint64_t old_s = mxf->metadata_sets[i]->partition_score;
|
||||||
int old_s = partition_score(old_p);
|
uint64_t new_s = (*metadata_set)->partition_score;
|
||||||
int new_s = partition_score(new_p);
|
if (old_s > new_s) {
|
||||||
if (old_s > new_s || old_s == new_s && old_p->this_partition > new_p->this_partition) {
|
|
||||||
mxf_free_metadataset(metadata_set, 1);
|
mxf_free_metadataset(metadata_set, 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2894,7 +2897,7 @@ static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = {
|
||||||
static int mxf_metadataset_init(MXFMetadataSet *ctx, enum MXFMetadataSetType type, MXFPartition *partition)
|
static int mxf_metadataset_init(MXFMetadataSet *ctx, enum MXFMetadataSetType type, MXFPartition *partition)
|
||||||
{
|
{
|
||||||
ctx->type = type;
|
ctx->type = type;
|
||||||
ctx->partition = partition;
|
ctx->partition_score = partition_score(partition);
|
||||||
switch (type){
|
switch (type){
|
||||||
case MultipleDescriptor:
|
case MultipleDescriptor:
|
||||||
case Descriptor:
|
case Descriptor:
|
||||||
|
|
Loading…
Reference in New Issue