mirror of
https://mirror.skon.top/https://github.com/FFmpeg/FFmpeg
synced 2026-04-20 21:00:41 +08:00
avformat/vorbiscomment: use null buf to calculate vorbis comment length
Also check possible failures when calculating length, and change return type to int as bigger return values are no longer possible.
This commit is contained in:
@@ -64,11 +64,13 @@ static int flac_write_block_comment(AVIOContext *pb, AVDictionary **m,
|
||||
int last_block, int bitexact)
|
||||
{
|
||||
const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT;
|
||||
int64_t len;
|
||||
int len;
|
||||
|
||||
ff_metadata_conv(m, ff_vorbiscomment_metadata_conv, NULL);
|
||||
|
||||
len = ff_vorbiscomment_length(*m, vendor, NULL, 0);
|
||||
if (len < 0)
|
||||
return len;
|
||||
if (len >= ((1<<24) - 4))
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
|
||||
@@ -1061,12 +1061,14 @@ static int put_flac_codecpriv(AVFormatContext *s, AVIOContext *pb,
|
||||
"Lavf" : LIBAVFORMAT_IDENT;
|
||||
AVDictionary *dict = NULL;
|
||||
uint8_t buf[32];
|
||||
int64_t len;
|
||||
int len;
|
||||
|
||||
snprintf(buf, sizeof(buf), "0x%"PRIx64, par->ch_layout.u.mask);
|
||||
av_dict_set(&dict, "WAVEFORMATEXTENSIBLE_CHANNEL_MASK", buf, 0);
|
||||
|
||||
len = ff_vorbiscomment_length(dict, vendor, NULL, 0);
|
||||
if (len < 0)
|
||||
return len;
|
||||
av_assert1(len < (1 << 24) - 4);
|
||||
|
||||
avio_w8(pb, 0x84);
|
||||
|
||||
@@ -295,7 +295,10 @@ static uint8_t *ogg_write_vorbiscomment(int64_t offset, int bitexact,
|
||||
|
||||
ff_metadata_conv(m, ff_vorbiscomment_metadata_conv, NULL);
|
||||
|
||||
size = offset + ff_vorbiscomment_length(*m, vendor, chapters, nb_chapters) + framing_bit;
|
||||
size = ff_vorbiscomment_length(*m, vendor, chapters, nb_chapters);
|
||||
if (size < 0)
|
||||
return NULL;
|
||||
size += offset + framing_bit;
|
||||
if (size > INT_MAX)
|
||||
return NULL;
|
||||
p = av_mallocz(size);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "avio.h"
|
||||
#include "avio_internal.h"
|
||||
#include "avformat.h"
|
||||
#include "metadata.h"
|
||||
#include "vorbiscomment.h"
|
||||
@@ -38,27 +39,21 @@ const AVMetadataConv ff_vorbiscomment_metadata_conv[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
int64_t ff_vorbiscomment_length(const AVDictionary *m, const char *vendor_string,
|
||||
AVChapter **chapters, unsigned int nb_chapters)
|
||||
int ff_vorbiscomment_length(const AVDictionary *m, const char *vendor_string,
|
||||
AVChapter **chapters, unsigned int nb_chapters)
|
||||
{
|
||||
int64_t len = 8;
|
||||
len += strlen(vendor_string);
|
||||
if (chapters && nb_chapters) {
|
||||
for (int i = 0; i < nb_chapters; i++) {
|
||||
const AVDictionaryEntry *tag = NULL;
|
||||
len += 4 + 12 + 1 + 10;
|
||||
while ((tag = av_dict_iterate(chapters[i]->metadata, tag))) {
|
||||
int64_t len1 = !strcmp(tag->key, "title") ? 4 : strlen(tag->key);
|
||||
len += 4 + 10 + len1 + 1 + strlen(tag->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m) {
|
||||
const AVDictionaryEntry *tag = NULL;
|
||||
while ((tag = av_dict_iterate(m, tag))) {
|
||||
len += 4 +strlen(tag->key) + 1 + strlen(tag->value);
|
||||
}
|
||||
}
|
||||
AVIOContext *avio_buf;
|
||||
int ret, len;
|
||||
|
||||
ret = ffio_open_null_buf(&avio_buf);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ff_vorbiscomment_write(avio_buf, m, vendor_string, chapters, nb_chapters);
|
||||
len = ffio_close_null_buf(avio_buf);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
* For no string, set to an empty string.
|
||||
* @return The length in bytes.
|
||||
*/
|
||||
int64_t ff_vorbiscomment_length(const AVDictionary *m, const char *vendor_string,
|
||||
AVChapter **chapters, unsigned int nb_chapters);
|
||||
int ff_vorbiscomment_length(const AVDictionary *m, const char *vendor_string,
|
||||
AVChapter **chapters, unsigned int nb_chapters);
|
||||
|
||||
/**
|
||||
* Write a VorbisComment into an AVIOContext. The output size can be obtained
|
||||
|
||||
Reference in New Issue
Block a user