1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-01-24 13:56:33 +02:00

avformat/libgme: Fix memleaks on errors

Also free the gme_info_t structure immediately after its use.
This simplifies cleanup, because it might be unsafe to call
gme_free_info(NULL) (or even worse, gme_track_info() might even
on error set the pointer to the gme_info_t structure to something
else than NULL).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
This commit is contained in:
Andreas Rheinhardt 2021-03-24 04:41:58 +01:00
parent 3ec3370dea
commit 05457a3661

View File

@ -31,7 +31,6 @@
typedef struct GMEContext {
const AVClass *class;
Music_Emu *music_emu;
gme_info_t *info; ///< selected track
/* options */
int track_index;
@ -55,12 +54,16 @@ static void add_meta(AVFormatContext *s, const char *name, const char *value)
av_dict_set(&s->metadata, name, value, 0);
}
static int load_metadata(AVFormatContext *s)
static int load_metadata(AVFormatContext *s, int64_t *duration)
{
GMEContext *gme = s->priv_data;
gme_info_t *info = gme->info;
gme_info_t *info = NULL;
char buf[30];
if (gme_track_info(gme->music_emu, &info, gme->track_index))
return AVERROR_STREAM_NOT_FOUND;
*duration = info->length;
add_meta(s, "system", info->system);
add_meta(s, "game", info->game);
add_meta(s, "song", info->song);
@ -71,20 +74,30 @@ static int load_metadata(AVFormatContext *s)
snprintf(buf, sizeof(buf), "%d", (int)gme_track_count(gme->music_emu));
add_meta(s, "tracks", buf);
gme_free_info(info);
return 0;
}
#define AUDIO_PKT_SIZE 512
static int read_close_gme(AVFormatContext *s)
{
GMEContext *gme = s->priv_data;
gme_delete(gme->music_emu);
return 0;
}
static int read_header_gme(AVFormatContext *s)
{
AVStream *st;
AVIOContext *pb = s->pb;
GMEContext *gme = s->priv_data;
int64_t sz = avio_size(pb);
int64_t duration;
char *buf;
char dummy;
int ret;
if (sz < 0) {
av_log(s, AV_LOG_WARNING, "Could not determine file size\n");
@ -103,6 +116,7 @@ static int read_header_gme(AVFormatContext *s)
av_log(s, AV_LOG_ERROR, "File size is larger than max_size option "
"value %"PRIi64", consider increasing the max_size option\n",
gme->max_size);
av_freep(&buf);
return AVERROR_BUFFER_TOO_SMALL;
}
@ -112,20 +126,24 @@ static int read_header_gme(AVFormatContext *s)
}
av_freep(&buf);
if (gme_track_info(gme->music_emu, &gme->info, gme->track_index))
return AVERROR_STREAM_NOT_FOUND;
if (gme_start_track(gme->music_emu, gme->track_index))
ret = load_metadata(s, &duration);
if (ret < 0) {
read_close_gme(s);
return ret;
}
if (gme_start_track(gme->music_emu, gme->track_index)) {
read_close_gme(s);
return AVERROR_UNKNOWN;
load_metadata(s);
}
st = avformat_new_stream(s, NULL);
if (!st)
if (!st) {
read_close_gme(s);
return AVERROR(ENOMEM);
}
avpriv_set_pts_info(st, 64, 1, 1000);
if (st->duration > 0)
st->duration = gme->info->length;
st->duration = duration;
st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
st->codecpar->codec_id = AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE);
st->codecpar->channels = 2;
@ -153,14 +171,6 @@ static int read_packet_gme(AVFormatContext *s, AVPacket *pkt)
return 0;
}
static int read_close_gme(AVFormatContext *s)
{
GMEContext *gme = s->priv_data;
gme_free_info(gme->info);
gme_delete(gme->music_emu);
return 0;
}
static int read_seek_gme(AVFormatContext *s, int stream_idx, int64_t ts, int flags)
{
GMEContext *gme = s->priv_data;