aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClément Bœsch <ubitux@gmail.com>2013-01-03 07:25:45 +0100
committerClément Bœsch <ubitux@gmail.com>2013-01-03 07:25:47 +0100
commit3fa642d60f428a36413498a191eb2ee319fe4445 (patch)
treebb52e50a620674614da7f43ff3c33e15134c4dca
parent52334f5be2ef31a5c836f689f3ab95b25bad026a (diff)
downloadffmpeg-3fa642d60f428a36413498a191eb2ee319fe4445.tar.gz
subviewer: sanitize packets.
The data does not contain timing or trailing line breaks anymore. In addition to being less idiotic, it is consistent with other codecs and thus allows more switches between formats and codecs. It also fixes the issue of the trailing line returns being simple \n instead of CRLF in the ASS rectangle dialogue (this is the reason of the FATE update).
-rw-r--r--libavcodec/subviewerdec.c15
-rw-r--r--libavcodec/version.h2
-rw-r--r--libavformat/subviewerdec.c35
-rw-r--r--libavformat/version.h2
-rw-r--r--tests/ref/fate/sub-subviewer2
5 files changed, 36 insertions, 20 deletions
diff --git a/libavcodec/subviewerdec.c b/libavcodec/subviewerdec.c
index 0e8be90e78..7580cbe679 100644
--- a/libavcodec/subviewerdec.c
+++ b/libavcodec/subviewerdec.c
@@ -31,17 +31,13 @@
static int subviewer_event_to_ass(AVBPrint *buf, const char *p)
{
while (*p) {
- char c;
-
- if (sscanf(p, "%*u:%*u:%*u.%*u,%*u:%*u:%*u.%*u%c", &c) == 1)
- p += strcspn(p, "\n") + 1;
if (!strncmp(p, "[br]", 4)) {
av_bprintf(buf, "\\N");
p += 4;
} else {
if (p[0] == '\n' && p[1])
av_bprintf(buf, "\\N");
- else if (*p != '\r')
+ else if (*p != '\n' && *p != '\r')
av_bprint_chars(buf, *p, 1);
p++;
}
@@ -54,10 +50,19 @@ static int subviewer_event_to_ass(AVBPrint *buf, const char *p)
static int subviewer_decode_frame(AVCodecContext *avctx,
void *data, int *got_sub_ptr, AVPacket *avpkt)
{
+ char c;
AVSubtitle *sub = data;
const char *ptr = avpkt->data;
AVBPrint buf;
+ /* To be removed later */
+ if (sscanf(ptr, "%*u:%*u:%*u.%*u,%*u:%*u:%*u.%*u%c", &c) == 1) {
+ av_log(avctx, AV_LOG_ERROR, "AVPacket is not clean (contains timing "
+ "information). You need to upgrade your libavformat or "
+ "sanitize your packet.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
// note: no need to rescale pts & duration since they are in the same
// timebase as ASS (1/100)
diff --git a/libavcodec/version.h b/libavcodec/version.h
index b4608a2cb0..670a875964 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -30,7 +30,7 @@
#define LIBAVCODEC_VERSION_MAJOR 54
#define LIBAVCODEC_VERSION_MINOR 85
-#define LIBAVCODEC_VERSION_MICRO 100
+#define LIBAVCODEC_VERSION_MICRO 101
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \
diff --git a/libavformat/subviewerdec.c b/libavformat/subviewerdec.c
index 439f5e76dc..7cacd973db 100644
--- a/libavformat/subviewerdec.c
+++ b/libavformat/subviewerdec.c
@@ -71,7 +71,10 @@ static int subviewer_read_header(AVFormatContext *s)
SubViewerContext *subviewer = s->priv_data;
AVStream *st = avformat_new_stream(s, NULL);
AVBPrint header;
- int res = 0;
+ int res = 0, new_event = 1;
+ int64_t pts_start = AV_NOPTS_VALUE;
+ int duration = -1;
+ AVPacket *sub = NULL;
if (!st)
return AVERROR(ENOMEM);
@@ -83,12 +86,14 @@ static int subviewer_read_header(AVFormatContext *s)
while (!url_feof(s->pb)) {
char line[2048];
- const int64_t pos = avio_tell(s->pb);
+ int64_t pos = 0;
int len = ff_get_line(s->pb, line, sizeof(line));
if (!len)
break;
+ line[strcspn(line, "\r\n")] = 0;
+
if (line[0] == '[' && strncmp(line, "[br]", 4)) {
/* ignore event style, XXX: add to side_data? */
@@ -97,7 +102,7 @@ static int subviewer_read_header(AVFormatContext *s)
continue;
if (!st->codec->extradata) { // header not finalized yet
- av_bprintf(&header, "%s", line);
+ av_bprintf(&header, "%s\n", line);
if (!strncmp(line, "[END INFORMATION]", 17) || !strncmp(line, "[SUBTITLE]", 10)) {
/* end of header */
res = avpriv_bprint_to_extradata(st->codec, &header);
@@ -116,29 +121,35 @@ static int subviewer_read_header(AVFormatContext *s)
i++;
while (line[i] == ' ')
i++;
- while (j < sizeof(value) - 1 && line[i] && !strchr("]\r\n", line[i]))
+ while (j < sizeof(value) - 1 && line[i] && line[i] != ']')
value[j++] = line[i++];
value[j] = 0;
av_dict_set(&s->metadata, key, value, 0);
}
}
- } else {
- int64_t pts_start = AV_NOPTS_VALUE;
- int duration = -1;
- int timed_line = !read_ts(line, &pts_start, &duration);
- AVPacket *sub;
-
- sub = ff_subtitles_queue_insert(&subviewer->q, line, len, !timed_line);
+ } else if (read_ts(line, &pts_start, &duration) >= 0) {
+ new_event = 1;
+ pos = avio_tell(s->pb);
+ } else if (*line) {
+ if (!new_event) {
+ sub = ff_subtitles_queue_insert(&subviewer->q, "\n", 1, 1);
+ if (!sub) {
+ res = AVERROR(ENOMEM);
+ goto end;
+ }
+ }
+ sub = ff_subtitles_queue_insert(&subviewer->q, line, strlen(line), !new_event);
if (!sub) {
res = AVERROR(ENOMEM);
goto end;
}
- if (timed_line) {
+ if (new_event) {
sub->pos = pos;
sub->pts = pts_start;
sub->duration = duration;
}
+ new_event = 0;
}
}
diff --git a/libavformat/version.h b/libavformat/version.h
index 1759ed3e95..f20354b580 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -31,7 +31,7 @@
#define LIBAVFORMAT_VERSION_MAJOR 54
#define LIBAVFORMAT_VERSION_MINOR 59
-#define LIBAVFORMAT_VERSION_MICRO 100
+#define LIBAVFORMAT_VERSION_MICRO 101
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, \
diff --git a/tests/ref/fate/sub-subviewer b/tests/ref/fate/sub-subviewer
index 3b5327f67b..abae1f7bb5 100644
--- a/tests/ref/fate/sub-subviewer
+++ b/tests/ref/fate/sub-subviewer
@@ -1 +1 @@
-303c25863d2283928c19db58a53c93e2
+aef995d49af4517b40589b72cfa918f7