avformat/vorbiscomment: fix writing huge chapter numbers and time offets to vorbiscomment

Previous code truncated chapter numbers more than 999 and and time offsets more
than 99 hours.

The Vorbis comment format only allows 1000 chapters, so cap the number of
written chapters there.

This also fixes the GCC warnings for truncated strings.

Signed-off-by: Marton Balint <cus@passwd.hu>
This commit is contained in:
Marton Balint
2025-12-25 19:20:51 +01:00
parent b2e077ad69
commit 96e8f3b8cc

View File

@@ -65,6 +65,9 @@ int ff_vorbiscomment_write(AVIOContext *pb, const AVDictionary *m,
int cm_count = 0;
avio_wl32(pb, vendor_string_length);
avio_write(pb, vendor_string, vendor_string_length);
/* Vorbis comment only supports 1000 chapters */
if (nb_chapters > 1000)
nb_chapters = 1000;
if (chapters && nb_chapters) {
for (int i = 0; i < nb_chapters; i++) {
cm_count += av_dict_count(chapters[i]->metadata) + 1;
@@ -86,22 +89,17 @@ int ff_vorbiscomment_write(AVIOContext *pb, const AVDictionary *m,
}
for (int i = 0; i < nb_chapters; i++) {
AVChapter *chp = chapters[i];
char chapter_time[13];
char chapter_number[4];
int h, m, s, ms;
char chapter_time[64];
int h, m, s, ms, len;
s = av_rescale(chp->start, chp->time_base.num, chp->time_base.den);
h = s / 3600;
m = (s / 60) % 60;
ms = av_rescale_q(chp->start, chp->time_base, av_make_q( 1, 1000)) % 1000;
s = s % 60;
snprintf(chapter_number, sizeof(chapter_number), "%03d", i);
snprintf(chapter_time, sizeof(chapter_time), "%02d:%02d:%02d.%03d", h, m, s, ms);
avio_wl32(pb, 10 + 1 + 12);
avio_write(pb, "CHAPTER", 7);
avio_write(pb, chapter_number, 3);
avio_w8(pb, '=');
avio_write(pb, chapter_time, 12);
len = snprintf(chapter_time, sizeof(chapter_time), "CHAPTER%03d=%02d:%02d:%02d.%03d", i, h, m, s, ms);
avio_wl32(pb, len);
avio_write(pb, chapter_time, len);
tag = NULL;
while ((tag = av_dict_iterate(chapters[i]->metadata, tag))) {
@@ -110,8 +108,7 @@ int ff_vorbiscomment_write(AVIOContext *pb, const AVDictionary *m,
if (len1+1+len2+10 > UINT32_MAX)
return AVERROR(EINVAL);
avio_wl32(pb, 10 + len1 + 1 + len2);
avio_write(pb, "CHAPTER", 7);
avio_write(pb, chapter_number, 3);
avio_write(pb, chapter_time, 10);
if (!strcmp(tag->key, "title"))
avio_write(pb, "NAME", 4);
else