mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 05:33:36 +00:00
sw_engine: Fix buffer overflow in texture mapping rasterizer
Fix heap buffer overflow in texture mapping rasterizer by adding proper bounds checking for texture coordinates. This prevents accessing memory outside of the allocated image buffer during texture sampling and interpolation. Co-Authored-By: Hermet Park <hermet@lottiefiles.com> issue: https://github.com/thorvg/thorvg/issues/3102
This commit is contained in:
parent
12b9c5fc53
commit
c64624c8c8
1 changed files with 29 additions and 39 deletions
|
@ -87,9 +87,8 @@ static void _rasterBlendingPolygonImageSegment(SwSurface* surface, const SwImage
|
||||||
float _xa = xa, _xb = xb, _ua = ua, _va = va;
|
float _xa = xa, _xb = xb, _ua = ua, _va = va;
|
||||||
auto sbuf = image->buf32;
|
auto sbuf = image->buf32;
|
||||||
auto dbuf = surface->buf32;
|
auto dbuf = surface->buf32;
|
||||||
int32_t sw = static_cast<int32_t>(image->stride);
|
int32_t sw = static_cast<int32_t>(image->w);
|
||||||
int32_t sh = image->h;
|
int32_t sh = static_cast<int32_t>(image->h);
|
||||||
int32_t dw = surface->stride;
|
|
||||||
int32_t x1, x2, x, y, ar, ab, iru, irv, px, ay;
|
int32_t x1, x2, x, y, ar, ab, iru, irv, px, ay;
|
||||||
int32_t vv = 0, uu = 0;
|
int32_t vv = 0, uu = 0;
|
||||||
int32_t minx = INT32_MAX, maxx = 0;
|
int32_t minx = INT32_MAX, maxx = 0;
|
||||||
|
@ -146,7 +145,7 @@ static void _rasterBlendingPolygonImageSegment(SwSurface* surface, const SwImage
|
||||||
u = _ua + dx * _dudx;
|
u = _ua + dx * _dudx;
|
||||||
v = _va + dx * _dvdx;
|
v = _va + dx * _dvdx;
|
||||||
|
|
||||||
buf = dbuf + ((y * dw) + x1);
|
buf = dbuf + ((y * surface->stride) + x1);
|
||||||
|
|
||||||
x = x1;
|
x = x1;
|
||||||
|
|
||||||
|
@ -154,32 +153,32 @@ static void _rasterBlendingPolygonImageSegment(SwSurface* surface, const SwImage
|
||||||
//Draw horizontal line
|
//Draw horizontal line
|
||||||
while (x++ < x2) {
|
while (x++ < x2) {
|
||||||
uu = (int) u;
|
uu = (int) u;
|
||||||
if (uu >= sw) continue;
|
|
||||||
vv = (int) v;
|
vv = (int) v;
|
||||||
if (vv >= sh) continue;
|
|
||||||
|
if ((uint32_t) uu >= image->w || (uint32_t) vv >= image->h) continue;
|
||||||
|
|
||||||
ar = (int)(255 * (1 - modff(u, &iptr)));
|
ar = (int)(255 * (1 - modff(u, &iptr)));
|
||||||
ab = (int)(255 * (1 - modff(v, &iptr)));
|
ab = (int)(255 * (1 - modff(v, &iptr)));
|
||||||
iru = uu + 1;
|
iru = uu + 1;
|
||||||
irv = vv + 1;
|
irv = vv + 1;
|
||||||
|
|
||||||
px = *(sbuf + (vv * sw) + uu);
|
px = *(sbuf + (vv * image->stride) + uu);
|
||||||
|
|
||||||
/* horizontal interpolate */
|
/* horizontal interpolate */
|
||||||
if (iru < sw) {
|
if (iru < sw) {
|
||||||
/* right pixel */
|
/* right pixel */
|
||||||
int px2 = *(sbuf + (vv * sw) + iru);
|
int px2 = *(sbuf + (vv * image->stride) + iru);
|
||||||
px = INTERPOLATE(px, px2, ar);
|
px = INTERPOLATE(px, px2, ar);
|
||||||
}
|
}
|
||||||
/* vertical interpolate */
|
/* vertical interpolate */
|
||||||
if (irv < sh) {
|
if (irv < sh) {
|
||||||
/* bottom pixel */
|
/* bottom pixel */
|
||||||
int px2 = *(sbuf + (irv * sw) + uu);
|
int px2 = *(sbuf + (irv * image->stride) + uu);
|
||||||
|
|
||||||
/* horizontal interpolate */
|
/* horizontal interpolate */
|
||||||
if (iru < sw) {
|
if (iru < sw) {
|
||||||
/* bottom right pixel */
|
/* bottom right pixel */
|
||||||
int px3 = *(sbuf + (irv * sw) + iru);
|
int px3 = *(sbuf + (irv * image->stride) + iru);
|
||||||
px2 = INTERPOLATE(px2, px3, ar);
|
px2 = INTERPOLATE(px2, px3, ar);
|
||||||
}
|
}
|
||||||
px = INTERPOLATE(px, px2, ab);
|
px = INTERPOLATE(px, px2, ab);
|
||||||
|
@ -190,39 +189,37 @@ static void _rasterBlendingPolygonImageSegment(SwSurface* surface, const SwImage
|
||||||
//Step UV horizontally
|
//Step UV horizontally
|
||||||
u += _dudx;
|
u += _dudx;
|
||||||
v += _dvdx;
|
v += _dvdx;
|
||||||
//range over?
|
|
||||||
if ((uint32_t)(int32_t)v >= image->h) break;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//Draw horizontal line
|
//Draw horizontal line
|
||||||
while (x++ < x2) {
|
while (x++ < x2) {
|
||||||
uu = (int) u;
|
uu = (int) u;
|
||||||
if (uu >= sw) continue;
|
|
||||||
vv = (int) v;
|
vv = (int) v;
|
||||||
if (vv >= sh) continue;
|
|
||||||
|
if ((uint32_t) uu >= image->w || (uint32_t) vv >= image->h) continue;
|
||||||
|
|
||||||
ar = (int)(255 * (1 - modff(u, &iptr)));
|
ar = (int)(255 * (1 - modff(u, &iptr)));
|
||||||
ab = (int)(255 * (1 - modff(v, &iptr)));
|
ab = (int)(255 * (1 - modff(v, &iptr)));
|
||||||
iru = uu + 1;
|
iru = uu + 1;
|
||||||
irv = vv + 1;
|
irv = vv + 1;
|
||||||
|
|
||||||
px = *(sbuf + (vv * sw) + uu);
|
px = *(sbuf + (vv * image->stride) + uu);
|
||||||
|
|
||||||
/* horizontal interpolate */
|
/* horizontal interpolate */
|
||||||
if (iru < sw) {
|
if (iru < sw) {
|
||||||
/* right pixel */
|
/* right pixel */
|
||||||
int px2 = *(sbuf + (vv * sw) + iru);
|
int px2 = *(sbuf + (vv * image->stride) + iru);
|
||||||
px = INTERPOLATE(px, px2, ar);
|
px = INTERPOLATE(px, px2, ar);
|
||||||
}
|
}
|
||||||
/* vertical interpolate */
|
/* vertical interpolate */
|
||||||
if (irv < sh) {
|
if (irv < sh) {
|
||||||
/* bottom pixel */
|
/* bottom pixel */
|
||||||
int px2 = *(sbuf + (irv * sw) + uu);
|
int px2 = *(sbuf + (irv * image->stride) + uu);
|
||||||
|
|
||||||
/* horizontal interpolate */
|
/* horizontal interpolate */
|
||||||
if (iru < sw) {
|
if (iru < sw) {
|
||||||
/* bottom right pixel */
|
/* bottom right pixel */
|
||||||
int px3 = *(sbuf + (irv * sw) + iru);
|
int px3 = *(sbuf + (irv * image->stride) + iru);
|
||||||
px2 = INTERPOLATE(px2, px3, ar);
|
px2 = INTERPOLATE(px2, px3, ar);
|
||||||
}
|
}
|
||||||
px = INTERPOLATE(px, px2, ab);
|
px = INTERPOLATE(px, px2, ab);
|
||||||
|
@ -234,8 +231,6 @@ static void _rasterBlendingPolygonImageSegment(SwSurface* surface, const SwImage
|
||||||
//Step UV horizontally
|
//Step UV horizontally
|
||||||
u += _dudx;
|
u += _dudx;
|
||||||
v += _dvdx;
|
v += _dvdx;
|
||||||
//range over?
|
|
||||||
if ((uint32_t)(int32_t)v >= image->h) break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -264,9 +259,8 @@ static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image,
|
||||||
float _xa = xa, _xb = xb, _ua = ua, _va = va;
|
float _xa = xa, _xb = xb, _ua = ua, _va = va;
|
||||||
auto sbuf = image->buf32;
|
auto sbuf = image->buf32;
|
||||||
auto dbuf = surface->buf32;
|
auto dbuf = surface->buf32;
|
||||||
int32_t sw = static_cast<int32_t>(image->stride);
|
int32_t sw = static_cast<int32_t>(image->w);
|
||||||
int32_t sh = image->h;
|
int32_t sh = static_cast<int32_t>(image->h);
|
||||||
int32_t dw = surface->stride;
|
|
||||||
int32_t x1, x2, x, y, ar, ab, iru, irv, px, ay;
|
int32_t x1, x2, x, y, ar, ab, iru, irv, px, ay;
|
||||||
int32_t vv = 0, uu = 0;
|
int32_t vv = 0, uu = 0;
|
||||||
int32_t minx = INT32_MAX, maxx = 0;
|
int32_t minx = INT32_MAX, maxx = 0;
|
||||||
|
@ -328,7 +322,7 @@ static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image,
|
||||||
u = _ua + dx * _dudx;
|
u = _ua + dx * _dudx;
|
||||||
v = _va + dx * _dvdx;
|
v = _va + dx * _dvdx;
|
||||||
|
|
||||||
buf = dbuf + ((y * dw) + x1);
|
buf = dbuf + ((y * surface->stride) + x1);
|
||||||
|
|
||||||
x = x1;
|
x = x1;
|
||||||
|
|
||||||
|
@ -338,32 +332,32 @@ static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image,
|
||||||
//Draw horizontal line
|
//Draw horizontal line
|
||||||
while (x++ < x2) {
|
while (x++ < x2) {
|
||||||
uu = (int) u;
|
uu = (int) u;
|
||||||
if (uu >= sw) continue;
|
|
||||||
vv = (int) v;
|
vv = (int) v;
|
||||||
if (vv >= sh) continue;
|
|
||||||
|
if ((uint32_t) uu >= image->w || (uint32_t) vv >= image->h) continue;
|
||||||
|
|
||||||
ar = (int)(255.0f * (1.0f - modff(u, &iptr)));
|
ar = (int)(255.0f * (1.0f - modff(u, &iptr)));
|
||||||
ab = (int)(255.0f * (1.0f - modff(v, &iptr)));
|
ab = (int)(255.0f * (1.0f - modff(v, &iptr)));
|
||||||
iru = uu + 1;
|
iru = uu + 1;
|
||||||
irv = vv + 1;
|
irv = vv + 1;
|
||||||
|
|
||||||
px = *(sbuf + (vv * sw) + uu);
|
px = *(sbuf + (vv * image->stride) + uu);
|
||||||
|
|
||||||
/* horizontal interpolate */
|
/* horizontal interpolate */
|
||||||
if (iru < sw) {
|
if (iru < sw) {
|
||||||
/* right pixel */
|
/* right pixel */
|
||||||
int px2 = *(sbuf + (vv * sw) + iru);
|
int px2 = *(sbuf + (vv * image->stride) + iru);
|
||||||
px = INTERPOLATE(px, px2, ar);
|
px = INTERPOLATE(px, px2, ar);
|
||||||
}
|
}
|
||||||
/* vertical interpolate */
|
/* vertical interpolate */
|
||||||
if (irv < sh) {
|
if (irv < sh) {
|
||||||
/* bottom pixel */
|
/* bottom pixel */
|
||||||
int px2 = *(sbuf + (irv * sw) + uu);
|
int px2 = *(sbuf + (irv * image->stride) + uu);
|
||||||
|
|
||||||
/* horizontal interpolate */
|
/* horizontal interpolate */
|
||||||
if (iru < sw) {
|
if (iru < sw) {
|
||||||
/* bottom right pixel */
|
/* bottom right pixel */
|
||||||
int px3 = *(sbuf + (irv * sw) + iru);
|
int px3 = *(sbuf + (irv * image->stride) + iru);
|
||||||
px2 = INTERPOLATE(px2, px3, ar);
|
px2 = INTERPOLATE(px2, px3, ar);
|
||||||
}
|
}
|
||||||
px = INTERPOLATE(px, px2, ab);
|
px = INTERPOLATE(px, px2, ab);
|
||||||
|
@ -381,8 +375,6 @@ static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image,
|
||||||
//Step UV horizontally
|
//Step UV horizontally
|
||||||
u += _dudx;
|
u += _dudx;
|
||||||
v += _dvdx;
|
v += _dvdx;
|
||||||
//range over?
|
|
||||||
if ((uint32_t)(int32_t)v >= image->h) break;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//Draw horizontal line
|
//Draw horizontal line
|
||||||
|
@ -390,30 +382,30 @@ static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image,
|
||||||
uu = (int) u;
|
uu = (int) u;
|
||||||
vv = (int) v;
|
vv = (int) v;
|
||||||
|
|
||||||
|
if ((uint32_t) uu >= image->w || (uint32_t) vv >= image->h) continue;
|
||||||
|
|
||||||
ar = (int)(255.0f * (1.0f - modff(u, &iptr)));
|
ar = (int)(255.0f * (1.0f - modff(u, &iptr)));
|
||||||
ab = (int)(255.0f * (1.0f - modff(v, &iptr)));
|
ab = (int)(255.0f * (1.0f - modff(v, &iptr)));
|
||||||
iru = uu + 1;
|
iru = uu + 1;
|
||||||
irv = vv + 1;
|
irv = vv + 1;
|
||||||
|
|
||||||
if (vv >= sh) continue;
|
|
||||||
|
|
||||||
px = *(sbuf + (vv * sw) + uu);
|
px = *(sbuf + (vv * sw) + uu);
|
||||||
|
|
||||||
/* horizontal interpolate */
|
/* horizontal interpolate */
|
||||||
if (iru < sw) {
|
if (iru < sw) {
|
||||||
/* right pixel */
|
/* right pixel */
|
||||||
int px2 = *(sbuf + (vv * sw) + iru);
|
int px2 = *(sbuf + (vv * image->stride) + iru);
|
||||||
px = INTERPOLATE(px, px2, ar);
|
px = INTERPOLATE(px, px2, ar);
|
||||||
}
|
}
|
||||||
/* vertical interpolate */
|
/* vertical interpolate */
|
||||||
if (irv < sh) {
|
if (irv < sh) {
|
||||||
/* bottom pixel */
|
/* bottom pixel */
|
||||||
int px2 = *(sbuf + (irv * sw) + uu);
|
int px2 = *(sbuf + (irv * image->stride) + uu);
|
||||||
|
|
||||||
/* horizontal interpolate */
|
/* horizontal interpolate */
|
||||||
if (iru < sw) {
|
if (iru < sw) {
|
||||||
/* bottom right pixel */
|
/* bottom right pixel */
|
||||||
int px3 = *(sbuf + (irv * sw) + iru);
|
int px3 = *(sbuf + (irv * image->stride) + iru);
|
||||||
px2 = INTERPOLATE(px2, px3, ar);
|
px2 = INTERPOLATE(px2, px3, ar);
|
||||||
}
|
}
|
||||||
px = INTERPOLATE(px, px2, ab);
|
px = INTERPOLATE(px, px2, ab);
|
||||||
|
@ -431,8 +423,6 @@ static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image,
|
||||||
//Step UV horizontally
|
//Step UV horizontally
|
||||||
u += _dudx;
|
u += _dudx;
|
||||||
v += _dvdx;
|
v += _dvdx;
|
||||||
//range over?
|
|
||||||
if ((uint32_t)(int32_t)v >= image->h) break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue