This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 1bfb91609d921d1df949b111edfb43a378ca072e Author: Romain Beauxis <[email protected]> AuthorDate: Wed Oct 28 16:33:52 2026 -0500 Commit: Romain Beauxis <[email protected]> CommitDate: Fri Oct 30 13:57:55 2026 +0000 avformat/oggparsevorbis: prevent out of order or missing chained headers Header packets of a chained stream are only buffered in identification, comment, setup order. A misplaced packet discards the buffered set with a warning, so a missing or misordered header no longer mixes headers from different chains into the new extradata. A misplaced comment header is skipped without applying its metadata. Reserved packet types are ignored, as required by Vorbis I section 1.3.2, and leave a buffered header set intact. --- libavformat/oggparsevorbis.c | 72 ++++++++++++++++++++-- .../ref/fate/ogg-vorbis-chained-misplaced-headers | 34 +++++----- 2 files changed, 85 insertions(+), 21 deletions(-) diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c index d4df9e234b..4ecc5bd8aa 100644 --- a/libavformat/oggparsevorbis.c +++ b/libavformat/oggparsevorbis.c @@ -209,9 +209,18 @@ int ff_vorbis_comment(AVFormatContext *as, AVDictionary **m, * [framing_flag] = read one bit | Not Used */ +enum VorbisPacketType { + VORBIS_PACKET_DATA, + VORBIS_PACKET_ID, + VORBIS_PACKET_COMMENT, + VORBIS_PACKET_SETUP, + VORBIS_PACKET_RESERVED, +}; + struct oggvorbis_private { unsigned int len[3]; unsigned char *packet[3]; + enum VorbisPacketType last_packet; ///< type of the last packet seen by vorbis_packet() AVVorbisParseContext *vp; int64_t bos_page_pos; int ts_offset; @@ -445,6 +454,56 @@ static int vorbis_header(AVFormatContext *s, int idx) return 1; } +/** + * Check that a packet follows the identification, comment, setup order of a + * chained stream's headers, and record it as the last packet. + * + * An identification header starts a new set. A misplaced packet discards the + * buffered headers, so an incomplete or misordered set is never packed. + * Reserved packet types are ignored, per Vorbis I ยง1.3.2. + * + * @return 0 if the packet is in order, AVERROR_INVALIDDATA otherwise + */ +static int vorbis_check_packet_order(AVFormatContext *s, + struct oggvorbis_private *priv, + enum VorbisPacketType type) +{ + enum VorbisPacketType last = priv->last_packet; + const char *error = NULL; + + switch (type) { + case VORBIS_PACKET_RESERVED: + return 0; + case VORBIS_PACKET_DATA: + if (last == VORBIS_PACKET_ID || last == VORBIS_PACKET_COMMENT) + error = "data packet before the setup header"; + break; + case VORBIS_PACKET_ID: + if (last == VORBIS_PACKET_ID || last == VORBIS_PACKET_COMMENT) + error = "identification header before the setup header"; + break; + case VORBIS_PACKET_COMMENT: + if (last != VORBIS_PACKET_ID) + error = "comment header without identification header"; + break; + case VORBIS_PACKET_SETUP: + if (last != VORBIS_PACKET_COMMENT) + error = "setup header without comment header"; + break; + } + + if (error) + av_log(s, AV_LOG_WARNING, + "Invalid chained stream headers: %s, discarding them\n", error); + + if (error || type == VORBIS_PACKET_ID) + for (int i = 0; i < 3; i++) + av_freep(&priv->packet[i]); + + priv->last_packet = error && type != VORBIS_PACKET_ID ? VORBIS_PACKET_DATA : type; + return error ? AVERROR_INVALIDDATA : 0; +} + static int vorbis_packet(AVFormatContext *s, int idx) { struct ogg *ogg = s->priv_data; @@ -553,6 +612,8 @@ static int vorbis_packet(AVFormatContext *s, int idx) * skipped; the headers are buffered and attached as extradata to the * first data packet that follows. */ if (flags & VORBIS_FLAG_HEADER) { + vorbis_check_packet_order(s, priv, VORBIS_PACKET_ID); + ret = vorbis_parse_header(s, s->streams[idx], os->buf + os->pstart, os->psize); if (ret < 0) return ret; @@ -568,11 +629,8 @@ static int vorbis_packet(AVFormatContext *s, int idx) } if (flags & VORBIS_FLAG_COMMENT) { - if (!priv->packet[0]) { - av_log(s, AV_LOG_WARNING, - "Comment header without identification header, ignoring it\n"); + if (vorbis_check_packet_order(s, priv, VORBIS_PACKET_COMMENT) < 0) return 1; - } ret = vorbis_update_metadata(s, idx); if (ret < 0) @@ -590,6 +648,9 @@ static int vorbis_packet(AVFormatContext *s, int idx) } if (flags & VORBIS_FLAG_SETUP) { + if (vorbis_check_packet_order(s, priv, VORBIS_PACKET_SETUP) < 0) + return 1; + ret = av_reallocp(&priv->packet[2], os->psize); if (ret < 0) return ret; @@ -600,6 +661,9 @@ static int vorbis_packet(AVFormatContext *s, int idx) skip_packet = 1; } + if (!skip_packet) + vorbis_check_packet_order(s, priv, os->buf[os->pstart] & 1 ? + VORBIS_PACKET_RESERVED : VORBIS_PACKET_DATA); /* All three headers for the new chained stream have been collected; * pack them into new extradata to be attached to the next data packet. */ diff --git a/tests/ref/fate/ogg-vorbis-chained-misplaced-headers b/tests/ref/fate/ogg-vorbis-chained-misplaced-headers index e8cc320427..664b7214cf 100644 --- a/tests/ref/fate/ogg-vorbis-chained-misplaced-headers +++ b/tests/ref/fate/ogg-vorbis-chained-misplaced-headers @@ -144,26 +144,26 @@ packet|pts=66496 packet|pts=67520 packet|pts=68544 packet|pts=69568 -packet|pts=70016|tag:title=Ziggy Stardust|tag:artist=The Moog Cookbook|tag:album=The Moog Cookbook Plays The Classic Rock Hits|tag:track=4|side_datum/strings_metadata:side_data_type=Strings Metadata|side_datum/new_extradata:side_data_type=New Extradata packet|pts=70144 -packet|pts=70720 -packet|pts=71744 -packet|pts=72768 -packet|pts=73792 -packet|pts=74368 +packet|pts=70272 +packet|pts=70848 +packet|pts=71872 +packet|pts=72896 +packet|pts=73920 packet|pts=74496 packet|pts=74624 -packet|pts=75200 -packet|pts=76224 -packet|pts=77248 -packet|pts=78272 -packet|pts=79296 -packet|pts=80320 -packet|pts=81344 -packet|pts=82368 -packet|pts=83392 -packet|pts=84416 -packet|pts=85440 +packet|pts=74752 +packet|pts=75328 +packet|pts=76352 +packet|pts=77376 +packet|pts=78400 +packet|pts=79424 +packet|pts=80448 +packet|pts=81472 +packet|pts=82496 +packet|pts=83520 +packet|pts=84544 +packet|pts=85568 packet|pts=16320 packet|pts=17344 packet|pts=18368 -- To stop receiving notification emails like this one, please contact [email protected]. _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
