File CVE-2020-24994_2.patch of Package libass.19440

From 6835731c2fe4164a0c50bc91d12c43b2a2b4e799 Mon Sep 17 00:00:00 2001
From: Oleg Oshmyan <chortos@inbox.lv>
Date: Thu, 4 Jan 2018 02:42:09 +0200
Subject: [PATCH] parse_tags: don't recurse for nested \t()

This fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=4892
(stack overflow on deeply nested \t()).

This is possible because parentheses do not nest and the first ')'
terminates the whole tag. Thus something like \t(\t(\t(\t(\t() can be
read in a simple loop with no recursion required. Recursion is also
not required if the ')' is missing entirely and the outermost \t(...
never ends.

See https://github.com/libass/libass/pull/296 for more backstory.
---
 Changelog          |  3 +++
 libass/ass_parse.c | 12 +++++++++++-
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/libass/ass_parse.c b/libass/ass_parse.c
index b20ef664..652ffa97 100644
--- a/libass/ass_parse.c
+++ b/libass/ass_parse.c
@@ -650,7 +650,17 @@ char *parse_tags(ASS_Renderer *render_priv, char *p, char *end, double pwr)
                 k = pow(((double) (t - t1)) / delta_t, accel);
             }
             p = args[cnt].start;
-            p = parse_tags(render_priv, p, args[cnt].end, k);    // maybe k*pwr ? no, specs forbid nested \t's
+            if (args[cnt].end < end) {
+                p = parse_tags(render_priv, p, args[cnt].end, k);
+            } else {
+                assert(q == end);
+                // No other tags can possibly follow this \t tag,
+                // so we don't need to restore pwr after parsing \t.
+                // The recursive call is now essentially a tail call,
+                // so optimize it away.
+                pwr = k;
+                q = p;
+            }
         } else if (complex_tag("clip")) {
             if (nargs == 4) {
                 int x0, y0, x1, y1;
openSUSE Build Service is sponsored by