File libass-CVE-2020-26682.patch of Package libass.20681

Index: libass-0.14.0/libass/ass_outline.c
===================================================================
--- libass-0.14.0.orig/libass/ass_outline.c	2017-10-31 13:14:11.000000000 +0100
+++ libass-0.14.0/libass/ass_outline.c	2021-03-16 09:14:17.114485654 +0100
@@ -47,6 +47,11 @@ static void outline_clear(ASS_Outline *o
     outline->n_segments = outline->max_segments = 0;
 }
 
+static bool valid_point(const FT_Vector *pt)
+{
+    return abs(pt->x) <= OUTLINE_MAX && abs(pt->y) <= OUTLINE_MAX;
+}
+
 bool outline_convert(ASS_Outline *outline, const FT_Outline *source)
 {
     if (!source || !source->n_points) {
@@ -77,12 +82,16 @@ bool outline_convert(ASS_Outline *outlin
             continue;
         }
 
+        if (!valid_point(source->points + j))
+            goto fail;
         switch (FT_CURVE_TAG(source->tags[j])) {
         case FT_CURVE_TAG_ON:
             st = S_ON;
             break;
 
         case FT_CURVE_TAG_CONIC:
+            if (!valid_point(source->points + last))
+                goto fail;
             pt.x =  source->points[last].x;
             pt.y = -source->points[last].y;
             switch (FT_CURVE_TAG(source->tags[last])) {
@@ -110,6 +119,8 @@ bool outline_convert(ASS_Outline *outlin
         outline->points[outline->n_points++] = pt;
 
         for (j++; j <= last; j++) {
+            if (!valid_point(source->points + j))
+                goto fail;
             switch (FT_CURVE_TAG(source->tags[j])) {
             case FT_CURVE_TAG_ON:
                 switch (st) {
@@ -236,6 +247,9 @@ void outline_free(ASS_Outline *outline)
  */
 bool outline_add_point(ASS_Outline *outline, ASS_Vector pt, char segment)
 {
+    if(abs(pt.x) > OUTLINE_MAX || abs(pt.y) > OUTLINE_MAX)
+        return false;
+
     if (outline->n_points >= outline->max_points) {
         size_t new_size = 2 * outline->max_points;
         if (!ASS_REALLOC_ARRAY(outline->points, new_size))
@@ -1303,7 +1317,7 @@ bool outline_stroke(ASS_Outline *result,
 {
     const int dir = 3;
     int rad = FFMAX(xbord, ybord);
-    assert(rad >= eps);
+    assert(rad >= eps && rad <= OUTLINE_MAX);
 
     result->n_points = result->n_segments = 0;
     result1->n_points = result1->n_segments = 0;
@@ -1329,12 +1343,10 @@ bool outline_stroke(ASS_Outline *result,
     str.err_c = 390 * rel_err * rel_err;
     str.err_a = e;
 
-    for (size_t i = 0; i < path->n_points; i++) {
-        if (path->points[i].x < OUTLINE_MIN || path->points[i].x > OUTLINE_MAX)
-            return false;
-        if (path->points[i].y < OUTLINE_MIN || path->points[i].y > OUTLINE_MAX)
-            return false;
-    }
+#ifndef NDEBUG
+    for (size_t i = 0; i < path->n_points; i++)
+        assert(abs(path->points[i].x) <= OUTLINE_MAX && abs(path->points[i].y) <= OUTLINE_MAX);
+#endif
 
     ASS_Vector *start = path->points, *cur = start;
     for (size_t i = 0; i < path->n_segments; i++) {
Index: libass-0.14.0/libass/ass_outline.h
===================================================================
--- libass-0.14.0.orig/libass/ass_outline.h	2017-10-31 13:14:11.000000000 +0100
+++ libass-0.14.0/libass/ass_outline.h	2021-03-16 09:14:17.114485654 +0100
@@ -83,8 +83,9 @@ typedef struct {
     char *segments;
 } ASS_Outline;
 
-#define OUTLINE_MIN  (-((int32_t) 1 << 28))
+// ouline point coordinates should always be in [-OUTLINE_MAX, +OUTLINE_MAX] range
 #define OUTLINE_MAX  (((int32_t) 1 << 28) - 1)
+// cubic spline splitting requires 8 * OUTLINE_MAX + 4 <= INT32_MAX
 
 bool outline_alloc(ASS_Outline *outline, size_t n_points, size_t n_segments);
 bool outline_convert(ASS_Outline *outline, const FT_Outline *source);
Index: libass-0.14.0/libass/ass_rasterizer.c
===================================================================
--- libass-0.14.0.orig/libass/ass_rasterizer.c	2017-10-31 13:14:11.000000000 +0100
+++ libass-0.14.0/libass/ass_rasterizer.c	2021-03-16 09:14:17.114485654 +0100
@@ -269,12 +269,10 @@ bool rasterizer_set_outline(RasterizerDa
     }
     rst->size[0] = rst->n_first;
 
-    for (size_t i = 0; i < path->n_points; i++) {
-        if (path->points[i].x < OUTLINE_MIN || path->points[i].x > OUTLINE_MAX)
-            return false;
-        if (path->points[i].y < OUTLINE_MIN || path->points[i].y > OUTLINE_MAX)
-            return false;
-    }
+#ifndef NDEBUG
+    for (size_t i = 0; i < path->n_points; i++)
+        assert(abs(path->points[i].x) <= OUTLINE_MAX && abs(path->points[i].y) <= OUTLINE_MAX);
+#endif
 
     ASS_Vector *start = path->points, *cur = start;
     for (size_t i = 0; i < path->n_segments; i++) {
openSUSE Build Service is sponsored by