summaryrefslogtreecommitdiff
path: root/libavcodec/ass_split.c
diff options
context:
space:
mode:
authorClément Bœsch <u@pkh.me>2014-10-11 16:12:51 +0200
committerClément Bœsch <u@pkh.me>2014-10-15 19:25:06 +0200
commit3e86ead383c189d4eb41b3e4b33798eecf51a759 (patch)
tree14eda7fd7a4d5c6bdefdc84211886464dbc48608 /libavcodec/ass_split.c
parentd9f272fe33063350127d1d6632804f4f0fd8dd9c (diff)
downloadffmpeg-3e86ead383c189d4eb41b3e4b33798eecf51a759.tar.gz
avcodec/ass_split: assume default order when "Format:" line is not found
Fixes the decoding of the ASS stream in a mkv from a fansub release from Coalgirls.
Diffstat (limited to 'libavcodec/ass_split.c')
-rw-r--r--libavcodec/ass_split.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/libavcodec/ass_split.c b/libavcodec/ass_split.c
index fea38e719e..bd7db93e65 100644
--- a/libavcodec/ass_split.c
+++ b/libavcodec/ass_split.c
@@ -229,6 +229,20 @@ static inline const char *skip_space(const char *buf)
return buf;
}
+static int *get_default_field_orders(const ASSSection *section)
+{
+ int i;
+ int *order = av_malloc(FF_ARRAY_ELEMS(section->fields) * sizeof(*order));
+
+ if (!order)
+ return NULL;
+ for (i = 0; section->fields[i].name; i++)
+ order[i] = i;
+ while (i < FF_ARRAY_ELEMS(section->fields))
+ order[i] = -1;
+ return order;
+}
+
static const char *ass_split_section(ASSSplitContext *ctx, const char *buf)
{
const ASSSection *section = &ass_sections[ctx->current_section];
@@ -246,7 +260,7 @@ static const char *ass_split_section(ASSSplitContext *ctx, const char *buf)
} else if (section->format_header && !order) {
len = strlen(section->format_header);
if (strncmp(buf, section->format_header, len) || buf[len] != ':')
- return NULL;
+ goto next_line;
buf += len + 1;
while (!is_eol(*buf)) {
buf = skip_space(buf);
@@ -269,6 +283,15 @@ static const char *ass_split_section(ASSSplitContext *ctx, const char *buf)
if (!strncmp(buf, section->fields_header, len) && buf[len] == ':') {
uint8_t *ptr, *struct_ptr = realloc_section_array(ctx);
if (!struct_ptr) return NULL;
+
+ /* No format header line found so far, assume default */
+ if (!order) {
+ order = get_default_field_orders(section);
+ if (!order)
+ return NULL;
+ ctx->field_order[ctx->current_section] = order;
+ }
+
buf += len + 1;
for (i=0; !is_eol(*buf) && i < *number; i++) {
int last = i == *number - 1;
@@ -298,6 +321,7 @@ static const char *ass_split_section(ASSSplitContext *ctx, const char *buf)
}
}
}
+next_line:
buf += strcspn(buf, "\n");
buf += !!*buf;
}