summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Karasik <dmitry.karasik@teliacompany.com>2021-08-07 09:36:03 +0200
committerAlan Coopersmith <alan.coopersmith@oracle.com>2022-07-18 00:46:25 +0000
commit3b888fdf89b4d8f4712c28b340c28604c8ff0b7e (patch)
tree2998d594e0da2f03b4940bfba9239b8cff3b07bc
parente314946813bcb96e8baedc1a290c48a2aa6ef162 (diff)
downloadxorg-lib-libXrender-3b888fdf89b4d8f4712c28b340c28604c8ff0b7e.tar.gz
fix coredumps in XRenderComputeTrapezoids (issue #1)
Rationale: I don't have enough expertise to judge on how the tessellation algorithm is broken in XRenderComputeTrapezoids but I do trust Keith Packard that it is. However using cairo for proper tessellation, as he suggests, is too heavyweight, and here I propose to alter the code to at least do not cause coredumps. Even if/when the function will be marked as obsolete, I believe it is pretty much capable of rendering relatively simple shapes, and still retains some value.
-rw-r--r--src/Poly.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/src/Poly.c b/src/Poly.c
index 5c4185f..69a2da6 100644
--- a/src/Poly.c
+++ b/src/Poly.c
@@ -81,6 +81,8 @@ XRenderComputeIntersect (XLineFixed *l1, XLineFixed *l2)
double m2 = XRenderComputeInverseSlope (l2);
double b2 = XRenderComputeXIntercept (l2, m2);
+ if ( m1 == m2 ) return XDoubleToFixed(32766); /* lines don't intersect */
+
return XDoubleToFixed ((b2 - b1) / (m1 - m2));
}
@@ -88,16 +90,18 @@ static int
XRenderComputeTrapezoids (Edge *edges,
int nedges,
int winding,
- XTrapezoid *traps)
+ XTrapezoid *traps,
+ int *ntraps,
+ int maxtraps)
{
- int ntraps = 0;
- int inactive;
+ int ok = 1, inactive;
Edge *active;
Edge *e, *en, *next;
XFixed y, next_y, intersect;
qsort (edges, nedges, sizeof (Edge), CompareEdge);
+ *ntraps = 0;
y = edges[0].edge.p1.y;
active = NULL;
inactive = 0;
@@ -182,7 +186,7 @@ XRenderComputeTrapezoids (Edge *edges,
intersect = XRenderComputeIntersect (&e->edge, &e->next->edge);
/* make sure this point is below the actual intersection */
intersect = intersect + 1;
- if (intersect < next_y)
+ if (intersect < next_y && intersect > y)
next_y = intersect;
}
}
@@ -198,7 +202,11 @@ XRenderComputeTrapezoids (Edge *edges,
traps->left = e->edge;
traps->right = en->edge;
traps++;
- ntraps++;
+ (*ntraps)++;
+ if ( --maxtraps <= 0 ) {
+ ok = 0;
+ break;
+ }
}
y = next_y;
@@ -218,7 +226,7 @@ XRenderComputeTrapezoids (Edge *edges,
}
}
}
- return ntraps;
+ return ok;
}
void
@@ -295,8 +303,9 @@ XRenderCompositeDoublePoly (Display *dpy,
prevx = x;
prevy = y;
}
- ntraps = XRenderComputeTrapezoids (edges, nedges, winding, traps);
- /* XXX adjust xSrc/xDst */
- XRenderCompositeTrapezoids (dpy, op, src, dst, maskFormat, xSrc, ySrc, traps, ntraps);
+ if ( XRenderComputeTrapezoids (edges, nedges, winding, traps, &ntraps, npoints * npoints )) {
+ /* XXX adjust xSrc/xDst */
+ XRenderCompositeTrapezoids (dpy, op, src, dst, maskFormat, xSrc, ySrc, traps, ntraps);
+ }
Xfree (edges);
}