Skip to content

Commit

Permalink
subviewer: sanitize packets.
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
ubitux committed Jan 3, 2013
1 parent 52334f5 commit 3fa642d
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 20 deletions.
15 changes: 10 additions & 5 deletions libavcodec/subviewerdec.c
Original file line number Diff line number Diff line change
Expand Up @@ -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++;
}
Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion libavcodec/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -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, \
Expand Down
35 changes: 23 additions & 12 deletions libavformat/subviewerdec.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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? */
Expand All @@ -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);
Expand All @@ -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;
}
}

Expand Down
2 changes: 1 addition & 1 deletion libavformat/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -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, \
Expand Down
2 changes: 1 addition & 1 deletion tests/ref/fate/sub-subviewer
Original file line number Diff line number Diff line change
@@ -1 +1 @@
303c25863d2283928c19db58a53c93e2
aef995d49af4517b40589b72cfa918f7

0 comments on commit 3fa642d

Please sign in to comment.