diff options
-rw-r--r-- | Changelog | 1 | ||||
-rw-r--r-- | libass/ass_parse.c | 15 | ||||
-rw-r--r-- | libass/ass_parse.h | 3 | ||||
-rw-r--r-- | libass/ass_render.c | 2 |
4 files changed, 14 insertions, 7 deletions
@@ -1,4 +1,5 @@ libass (unreleased) + * Treat invalid nested \t tags like VSFilter * Fix stack overflow on deeply nested \t tags libass (0.14.0) diff --git a/libass/ass_parse.c b/libass/ass_parse.c index 652ffa9..3ccf556 100644 --- a/libass/ass_parse.c +++ b/libass/ass_parse.c @@ -230,7 +230,8 @@ static int parse_vector_clip(ASS_Renderer *render_priv, * of a number of spaces immediately preceding '}' or ')' * \param pwr multiplier for some tag effects (comes from \t tags) */ -char *parse_tags(ASS_Renderer *render_priv, char *p, char *end, double pwr) +char *parse_tags(ASS_Renderer *render_priv, char *p, char *end, double pwr, + bool nested) { for (char *q; p < end; p = q) { while (*p != '\\' && p != end) @@ -630,12 +631,11 @@ char *parse_tags(ASS_Renderer *render_priv, char *p, char *end, double pwr) t1 = 0; t2 = 0; accel = argtod(args[0]); - } else if (cnt == 0) { + } else { t1 = 0; t2 = 0; accel = 1.; - } else - continue; + } render_priv->state.detect_collisions = 0; if (t2 == 0) t2 = render_priv->state.event->Duration; @@ -649,9 +649,13 @@ char *parse_tags(ASS_Renderer *render_priv, char *p, char *end, double pwr) assert(delta_t != 0.); k = pow(((double) (t - t1)) / delta_t, accel); } + if (nested) + pwr = k; + if (cnt < 0 || cnt > 3) + continue; p = args[cnt].start; if (args[cnt].end < end) { - p = parse_tags(render_priv, p, args[cnt].end, k); + p = parse_tags(render_priv, p, args[cnt].end, k, true); } else { assert(q == end); // No other tags can possibly follow this \t tag, @@ -659,6 +663,7 @@ char *parse_tags(ASS_Renderer *render_priv, char *p, char *end, double pwr) // The recursive call is now essentially a tail call, // so optimize it away. pwr = k; + nested = true; q = p; } } else if (complex_tag("clip")) { diff --git a/libass/ass_parse.h b/libass/ass_parse.h index 1b1b131..bf72b78 100644 --- a/libass/ass_parse.h +++ b/libass/ass_parse.h @@ -31,7 +31,8 @@ double ensure_font_size(ASS_Renderer *priv, double size); void apply_transition_effects(ASS_Renderer *render_priv, ASS_Event *event); void process_karaoke_effects(ASS_Renderer *render_priv); unsigned get_next_char(ASS_Renderer *render_priv, char **str); -char *parse_tags(ASS_Renderer *render_priv, char *p, char *end, double pwr); +char *parse_tags(ASS_Renderer *render_priv, char *p, char *end, double pwr, + bool nested); int event_has_hard_overrides(char *str); extern void change_alpha(uint32_t *var, int32_t new, double pwr); extern uint32_t mult_alpha(uint32_t a, uint32_t b); diff --git a/libass/ass_render.c b/libass/ass_render.c index d5f881f..9ba3884 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -1712,7 +1712,7 @@ static int parse_events(ASS_Renderer *render_priv, ASS_Event *event) code = 0; while (*p) { if ((*p == '{') && (q = strchr(p, '}'))) { - p = parse_tags(render_priv, p, q, 1.); + p = parse_tags(render_priv, p, q, 1., false); assert(*p == '}'); p++; } else if (render_priv->state.drawing_scale) { |