From 2ec68c51e4599b8493a2e103793f571451d872d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20H=C3=A4rdin?= Date: Thu, 28 Mar 2024 20:30:37 +0100 Subject: [PATCH 1/2] lavf/subtitles: Add ff_text_peek_r16(), only accept \r, \n, \r\n and \r\r\n line endings --- libavformat/subtitles.c | 53 +++++++++++++++++++++++++++++++++++++---- libavformat/subtitles.h | 5 ++++ 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/libavformat/subtitles.c b/libavformat/subtitles.c index 3413763c7b..01187df6ab 100644 --- a/libavformat/subtitles.c +++ b/libavformat/subtitles.c @@ -22,6 +22,7 @@ #include "subtitles.h" #include "avio_internal.h" #include "libavutil/avstring.h" +#include "libavutil/intreadwrite.h" void ff_text_init_avio(void *s, FFTextReader *r, AVIOContext *pb) { @@ -106,6 +107,42 @@ int ff_text_peek_r8(FFTextReader *r) return c; } +int ff_text_peek_r16(FFTextReader *r) +{ + int c1, c2; + if (r->buf_pos < r->buf_len - 1) + return AV_RB16(&r->buf[r->buf_pos]); + + // missing one or two bytes + c1 = ff_text_r8(r); + if (avio_feof(r->pb)) + return 0; + + if (r->buf_pos == r->buf_len - 1) { + // missing one byte + r->buf[0] = r->buf[r->buf_pos]; + r->buf[1] = c1; + r->buf_pos = 0; + r->buf_len = 2; + return AV_RB16(r->buf); + } + + // missing two bytes + c2 = ff_text_r8(r); + if (avio_feof(r->pb)) { + r->buf[0] = c1; + r->buf_pos = 0; + r->buf_len = 1; + return 0; + } + + r->buf[0] = c1; + r->buf[1] = c2; + r->buf_pos = 0; + r->buf_len = 2; + return AV_RB16(r->buf); +} + AVPacket *ff_subtitles_queue_insert(FFDemuxSubtitlesQueue *q, const uint8_t *event, size_t len, int merge) { @@ -446,11 +483,12 @@ int ff_subtitles_read_chunk(AVIOContext *pb, AVBPrint *buf) ptrdiff_t ff_subtitles_read_line(FFTextReader *tr, char *buf, size_t size) { size_t cur = 0; + unsigned char c; if (!size) return 0; buf[0] = '\0'; while (cur + 1 < size) { - unsigned char c = ff_text_r8(tr); + c = ff_text_r8(tr); if (!c) return ff_text_eof(tr) ? cur : AVERROR_INVALIDDATA; if (c == '\r' || c == '\n') @@ -458,9 +496,14 @@ ptrdiff_t ff_subtitles_read_line(FFTextReader *tr, char *buf, size_t size) buf[cur++] = c; buf[cur] = '\0'; } - while (ff_text_peek_r8(tr) == '\r') - ff_text_r8(tr); - if (ff_text_peek_r8(tr) == '\n') - ff_text_r8(tr); + if (c == '\r') { + if (ff_text_peek_r8(tr) == '\n') + ff_text_r8(tr); + else if (ff_text_peek_r16(tr) == AV_RB16("\r\n")) { + // ticket5032-rrn.srt has \r\r\n + ff_text_r8(tr); + ff_text_r8(tr); + } + } return cur; } diff --git a/libavformat/subtitles.h b/libavformat/subtitles.h index 88665663c5..2a92044976 100644 --- a/libavformat/subtitles.h +++ b/libavformat/subtitles.h @@ -94,6 +94,11 @@ int ff_text_eof(FFTextReader *r); */ int ff_text_peek_r8(FFTextReader *r); +/** + * Like ff_text_peek_r8(), but peek two bytes and return them as a big-endian number. + */ +int ff_text_peek_r16(FFTextReader *r); + /** * Read the given number of bytes (in UTF-8). On error or EOF, \0 bytes are * written. -- 2.39.2