summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOneric <oneric@oneric.stub>2022-09-29 19:06:15 +0200
committerOneric <oneric@oneric.stub>2022-09-29 23:33:47 +0200
commit44f6532daf5eb13cb1aa95f5449a77b5df1dd85b (patch)
tree9ffc944c3629b57750cac26f0ae568e8673928e9
parentabd7cd51d86d299b72d5827332352bfdbeb359db (diff)
downloadlibass-44f6532daf5eb13cb1aa95f5449a77b5df1dd85b.tar.bz2
libass-44f6532daf5eb13cb1aa95f5449a77b5df1dd85b.tar.xz
ass: discard invalid events early
They cannot possibly produce any rendering output, so there's no benefit in keeping them around. On the contrary, keeping them around can significantly slow down processing of fuzzing samples as discovered by OSS-Fuzz. For its sample, there's one valid event with a large Text entry (516503 bytes) and 9786 invalid events. Processing just the one valid events takes a few seconds, which isn't fast but still bearable and given the large amount of text being parsed, shaped and rendered not too surprising. If now the invalid events are kept around, processing the sample still wasn't finished after 5 minutes. While processing of invalid events ends early in ass_render_event and they won't create any output themselves, their time overlaps with the costly, valid event. Meaning this costly event now get's rendered thousands of times and processing cost is amplified via just a few bytes being added by the fuzzing engine. We already do a similar discarding for Styles in process_style(). Unlike the former, process_event_tail() doesn't allocate the new event itself, so discarding is instead done by its callers. Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=47952
-rw-r--r--libass/ass.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/libass/ass.c b/libass/ass.c
index 5ec8a95..19cc460 100644
--- a/libass/ass.c
+++ b/libass/ass.c
@@ -822,7 +822,13 @@ static int process_events_line(ASS_Track *track, char *str)
return -1;
event = track->events + eid;
- return process_event_tail(track, event, str, 0);
+ int ret = process_event_tail(track, event, str, 0);
+ if (!ret)
+ return 0;
+ // If something went wrong, discard the useless Event
+ ass_free_event(track, eid);
+ track->n_events--;
+ return ret;
} else {
ass_msg(track->library, MSGL_V, "Not understood: '%.30s'", str);
}
@@ -1125,7 +1131,8 @@ void ass_process_chunk(ASS_Track *track, char *data, int size,
NEXT(p, token);
event->Layer = atoi(token);
- process_event_tail(track, event, p, 3);
+ if (process_event_tail(track, event, p, 3))
+ break;
event->Start = timecode;
event->Duration = duration;