summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog1
-rw-r--r--libass/ass_parse.c15
-rw-r--r--libass/ass_parse.h3
-rw-r--r--libass/ass_render.c2
4 files changed, 14 insertions, 7 deletions
diff --git a/Changelog b/Changelog
index ba8f6f5..6968a53 100644
--- a/Changelog
+++ b/Changelog
@@ -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) {