Fix T70356: Scaling up 1x1 pixel image reads past buffer bounds
Also resolve a crash when when displaying thumbnails, see T89868.
This commit is contained in:
parent
0de54a9cfe
commit
1a1510a3a0
Notes:
blender-bot
2023-02-14 10:11:54 +01:00
Referenced by issue #77348, Blender LTS: Maintenance Task 2.83 Referenced by issue #70356, Scaling up 1x1 pixel image reads past buffer bounds
|
@ -1193,22 +1193,9 @@ static ImBuf *scaleupx(struct ImBuf *ibuf, int newx)
|
|||
{
|
||||
uchar *rect, *_newrect = NULL, *newrect;
|
||||
float *rectf, *_newrectf = NULL, *newrectf;
|
||||
float sample, add;
|
||||
float val_a, nval_a, diff_a;
|
||||
float val_b, nval_b, diff_b;
|
||||
float val_g, nval_g, diff_g;
|
||||
float val_r, nval_r, diff_r;
|
||||
float val_af, nval_af, diff_af;
|
||||
float val_bf, nval_bf, diff_bf;
|
||||
float val_gf, nval_gf, diff_gf;
|
||||
float val_rf, nval_rf, diff_rf;
|
||||
int x, y;
|
||||
bool do_rect = false, do_float = false;
|
||||
|
||||
val_a = nval_a = diff_a = val_b = nval_b = diff_b = 0;
|
||||
val_g = nval_g = diff_g = val_r = nval_r = diff_r = 0;
|
||||
val_af = nval_af = diff_af = val_bf = nval_bf = diff_bf = 0;
|
||||
val_gf = nval_gf = diff_gf = val_rf = nval_rf = diff_rf = 0;
|
||||
if (ibuf == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
|
@ -1234,119 +1221,158 @@ static ImBuf *scaleupx(struct ImBuf *ibuf, int newx)
|
|||
}
|
||||
}
|
||||
|
||||
add = (ibuf->x - 1.001) / (newx - 1.0);
|
||||
|
||||
rect = (uchar *)ibuf->rect;
|
||||
rectf = (float *)ibuf->rect_float;
|
||||
newrect = _newrect;
|
||||
newrectf = _newrectf;
|
||||
|
||||
for (y = ibuf->y; y > 0; y--) {
|
||||
|
||||
sample = 0;
|
||||
|
||||
/* Special case, copy all columns, needed since the scaling logic assumes there is at least
|
||||
* two rows to interpolate between causing out of bounds read for 1px images, see T70356. */
|
||||
if (UNLIKELY(ibuf->x == 1)) {
|
||||
if (do_rect) {
|
||||
val_a = rect[0];
|
||||
nval_a = rect[4];
|
||||
diff_a = nval_a - val_a;
|
||||
val_a += 0.5f;
|
||||
|
||||
val_b = rect[1];
|
||||
nval_b = rect[5];
|
||||
diff_b = nval_b - val_b;
|
||||
val_b += 0.5f;
|
||||
|
||||
val_g = rect[2];
|
||||
nval_g = rect[6];
|
||||
diff_g = nval_g - val_g;
|
||||
val_g += 0.5f;
|
||||
|
||||
val_r = rect[3];
|
||||
nval_r = rect[7];
|
||||
diff_r = nval_r - val_r;
|
||||
val_r += 0.5f;
|
||||
|
||||
rect += 8;
|
||||
for (y = ibuf->y; y > 0; y--) {
|
||||
for (x = newx; x > 0; x--) {
|
||||
memcpy(newrect, rect, sizeof(char[4]));
|
||||
newrect += 4;
|
||||
}
|
||||
rect += 4;
|
||||
}
|
||||
}
|
||||
if (do_float) {
|
||||
val_af = rectf[0];
|
||||
nval_af = rectf[4];
|
||||
diff_af = nval_af - val_af;
|
||||
|
||||
val_bf = rectf[1];
|
||||
nval_bf = rectf[5];
|
||||
diff_bf = nval_bf - val_bf;
|
||||
|
||||
val_gf = rectf[2];
|
||||
nval_gf = rectf[6];
|
||||
diff_gf = nval_gf - val_gf;
|
||||
|
||||
val_rf = rectf[3];
|
||||
nval_rf = rectf[7];
|
||||
diff_rf = nval_rf - val_rf;
|
||||
|
||||
rectf += 8;
|
||||
}
|
||||
for (x = newx; x > 0; x--) {
|
||||
if (sample >= 1.0f) {
|
||||
sample -= 1.0f;
|
||||
|
||||
if (do_rect) {
|
||||
val_a = nval_a;
|
||||
nval_a = rect[0];
|
||||
diff_a = nval_a - val_a;
|
||||
val_a += 0.5f;
|
||||
|
||||
val_b = nval_b;
|
||||
nval_b = rect[1];
|
||||
diff_b = nval_b - val_b;
|
||||
val_b += 0.5f;
|
||||
|
||||
val_g = nval_g;
|
||||
nval_g = rect[2];
|
||||
diff_g = nval_g - val_g;
|
||||
val_g += 0.5f;
|
||||
|
||||
val_r = nval_r;
|
||||
nval_r = rect[3];
|
||||
diff_r = nval_r - val_r;
|
||||
val_r += 0.5f;
|
||||
rect += 4;
|
||||
}
|
||||
if (do_float) {
|
||||
val_af = nval_af;
|
||||
nval_af = rectf[0];
|
||||
diff_af = nval_af - val_af;
|
||||
|
||||
val_bf = nval_bf;
|
||||
nval_bf = rectf[1];
|
||||
diff_bf = nval_bf - val_bf;
|
||||
|
||||
val_gf = nval_gf;
|
||||
nval_gf = rectf[2];
|
||||
diff_gf = nval_gf - val_gf;
|
||||
|
||||
val_rf = nval_rf;
|
||||
nval_rf = rectf[3];
|
||||
diff_rf = nval_rf - val_rf;
|
||||
rectf += 4;
|
||||
for (y = ibuf->y; y > 0; y--) {
|
||||
for (x = newx; x > 0; x--) {
|
||||
memcpy(newrectf, rectf, sizeof(float[4]));
|
||||
newrectf += 4;
|
||||
}
|
||||
rectf += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
const float add = (ibuf->x - 1.001) / (newx - 1.0);
|
||||
float sample;
|
||||
|
||||
float val_a, nval_a, diff_a;
|
||||
float val_b, nval_b, diff_b;
|
||||
float val_g, nval_g, diff_g;
|
||||
float val_r, nval_r, diff_r;
|
||||
float val_af, nval_af, diff_af;
|
||||
float val_bf, nval_bf, diff_bf;
|
||||
float val_gf, nval_gf, diff_gf;
|
||||
float val_rf, nval_rf, diff_rf;
|
||||
|
||||
val_a = nval_a = diff_a = val_b = nval_b = diff_b = 0;
|
||||
val_g = nval_g = diff_g = val_r = nval_r = diff_r = 0;
|
||||
val_af = nval_af = diff_af = val_bf = nval_bf = diff_bf = 0;
|
||||
val_gf = nval_gf = diff_gf = val_rf = nval_rf = diff_rf = 0;
|
||||
|
||||
for (y = ibuf->y; y > 0; y--) {
|
||||
|
||||
sample = 0;
|
||||
|
||||
if (do_rect) {
|
||||
newrect[0] = val_a + sample * diff_a;
|
||||
newrect[1] = val_b + sample * diff_b;
|
||||
newrect[2] = val_g + sample * diff_g;
|
||||
newrect[3] = val_r + sample * diff_r;
|
||||
newrect += 4;
|
||||
val_a = rect[0];
|
||||
nval_a = rect[4];
|
||||
diff_a = nval_a - val_a;
|
||||
val_a += 0.5f;
|
||||
|
||||
val_b = rect[1];
|
||||
nval_b = rect[5];
|
||||
diff_b = nval_b - val_b;
|
||||
val_b += 0.5f;
|
||||
|
||||
val_g = rect[2];
|
||||
nval_g = rect[6];
|
||||
diff_g = nval_g - val_g;
|
||||
val_g += 0.5f;
|
||||
|
||||
val_r = rect[3];
|
||||
nval_r = rect[7];
|
||||
diff_r = nval_r - val_r;
|
||||
val_r += 0.5f;
|
||||
|
||||
rect += 8;
|
||||
}
|
||||
if (do_float) {
|
||||
newrectf[0] = val_af + sample * diff_af;
|
||||
newrectf[1] = val_bf + sample * diff_bf;
|
||||
newrectf[2] = val_gf + sample * diff_gf;
|
||||
newrectf[3] = val_rf + sample * diff_rf;
|
||||
newrectf += 4;
|
||||
val_af = rectf[0];
|
||||
nval_af = rectf[4];
|
||||
diff_af = nval_af - val_af;
|
||||
|
||||
val_bf = rectf[1];
|
||||
nval_bf = rectf[5];
|
||||
diff_bf = nval_bf - val_bf;
|
||||
|
||||
val_gf = rectf[2];
|
||||
nval_gf = rectf[6];
|
||||
diff_gf = nval_gf - val_gf;
|
||||
|
||||
val_rf = rectf[3];
|
||||
nval_rf = rectf[7];
|
||||
diff_rf = nval_rf - val_rf;
|
||||
|
||||
rectf += 8;
|
||||
}
|
||||
for (x = newx; x > 0; x--) {
|
||||
if (sample >= 1.0f) {
|
||||
sample -= 1.0f;
|
||||
|
||||
if (do_rect) {
|
||||
val_a = nval_a;
|
||||
nval_a = rect[0];
|
||||
diff_a = nval_a - val_a;
|
||||
val_a += 0.5f;
|
||||
|
||||
val_b = nval_b;
|
||||
nval_b = rect[1];
|
||||
diff_b = nval_b - val_b;
|
||||
val_b += 0.5f;
|
||||
|
||||
val_g = nval_g;
|
||||
nval_g = rect[2];
|
||||
diff_g = nval_g - val_g;
|
||||
val_g += 0.5f;
|
||||
|
||||
val_r = nval_r;
|
||||
nval_r = rect[3];
|
||||
diff_r = nval_r - val_r;
|
||||
val_r += 0.5f;
|
||||
rect += 4;
|
||||
}
|
||||
if (do_float) {
|
||||
val_af = nval_af;
|
||||
nval_af = rectf[0];
|
||||
diff_af = nval_af - val_af;
|
||||
|
||||
val_bf = nval_bf;
|
||||
nval_bf = rectf[1];
|
||||
diff_bf = nval_bf - val_bf;
|
||||
|
||||
val_gf = nval_gf;
|
||||
nval_gf = rectf[2];
|
||||
diff_gf = nval_gf - val_gf;
|
||||
|
||||
val_rf = nval_rf;
|
||||
nval_rf = rectf[3];
|
||||
diff_rf = nval_rf - val_rf;
|
||||
rectf += 4;
|
||||
}
|
||||
}
|
||||
if (do_rect) {
|
||||
newrect[0] = val_a + sample * diff_a;
|
||||
newrect[1] = val_b + sample * diff_b;
|
||||
newrect[2] = val_g + sample * diff_g;
|
||||
newrect[3] = val_r + sample * diff_r;
|
||||
newrect += 4;
|
||||
}
|
||||
if (do_float) {
|
||||
newrectf[0] = val_af + sample * diff_af;
|
||||
newrectf[1] = val_bf + sample * diff_bf;
|
||||
newrectf[2] = val_gf + sample * diff_gf;
|
||||
newrectf[3] = val_rf + sample * diff_rf;
|
||||
newrectf += 4;
|
||||
}
|
||||
sample += add;
|
||||
}
|
||||
sample += add;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1369,22 +1395,9 @@ static ImBuf *scaleupy(struct ImBuf *ibuf, int newy)
|
|||
{
|
||||
uchar *rect, *_newrect = NULL, *newrect;
|
||||
float *rectf, *_newrectf = NULL, *newrectf;
|
||||
float sample, add;
|
||||
float val_a, nval_a, diff_a;
|
||||
float val_b, nval_b, diff_b;
|
||||
float val_g, nval_g, diff_g;
|
||||
float val_r, nval_r, diff_r;
|
||||
float val_af, nval_af, diff_af;
|
||||
float val_bf, nval_bf, diff_bf;
|
||||
float val_gf, nval_gf, diff_gf;
|
||||
float val_rf, nval_rf, diff_rf;
|
||||
int x, y, skipx;
|
||||
bool do_rect = false, do_float = false;
|
||||
|
||||
val_a = nval_a = diff_a = val_b = nval_b = diff_b = 0;
|
||||
val_g = nval_g = diff_g = val_r = nval_r = diff_r = 0;
|
||||
val_af = nval_af = diff_af = val_bf = nval_bf = diff_bf = 0;
|
||||
val_gf = nval_gf = diff_gf = val_rf = nval_rf = diff_rf = 0;
|
||||
if (ibuf == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
|
@ -1410,126 +1423,159 @@ static ImBuf *scaleupy(struct ImBuf *ibuf, int newy)
|
|||
}
|
||||
}
|
||||
|
||||
add = (ibuf->y - 1.001) / (newy - 1.0);
|
||||
skipx = 4 * ibuf->x;
|
||||
|
||||
rect = (uchar *)ibuf->rect;
|
||||
rectf = (float *)ibuf->rect_float;
|
||||
newrect = _newrect;
|
||||
newrectf = _newrectf;
|
||||
|
||||
for (x = ibuf->x; x > 0; x--) {
|
||||
skipx = 4 * ibuf->x;
|
||||
|
||||
sample = 0;
|
||||
/* Special case, copy all rows, needed since the scaling logic assumes there is at least
|
||||
* two rows to interpolate between causing out of bounds read for 1px images, see T70356. */
|
||||
if (UNLIKELY(ibuf->y == 1)) {
|
||||
if (do_rect) {
|
||||
rect = ((uchar *)ibuf->rect) + 4 * (x - 1);
|
||||
newrect = _newrect + 4 * (x - 1);
|
||||
|
||||
val_a = rect[0];
|
||||
nval_a = rect[skipx];
|
||||
diff_a = nval_a - val_a;
|
||||
val_a += 0.5f;
|
||||
|
||||
val_b = rect[1];
|
||||
nval_b = rect[skipx + 1];
|
||||
diff_b = nval_b - val_b;
|
||||
val_b += 0.5f;
|
||||
|
||||
val_g = rect[2];
|
||||
nval_g = rect[skipx + 2];
|
||||
diff_g = nval_g - val_g;
|
||||
val_g += 0.5f;
|
||||
|
||||
val_r = rect[3];
|
||||
nval_r = rect[skipx + 3];
|
||||
diff_r = nval_r - val_r;
|
||||
val_r += 0.5f;
|
||||
|
||||
rect += 2 * skipx;
|
||||
}
|
||||
if (do_float) {
|
||||
rectf = ibuf->rect_float + 4 * (x - 1);
|
||||
newrectf = _newrectf + 4 * (x - 1);
|
||||
|
||||
val_af = rectf[0];
|
||||
nval_af = rectf[skipx];
|
||||
diff_af = nval_af - val_af;
|
||||
|
||||
val_bf = rectf[1];
|
||||
nval_bf = rectf[skipx + 1];
|
||||
diff_bf = nval_bf - val_bf;
|
||||
|
||||
val_gf = rectf[2];
|
||||
nval_gf = rectf[skipx + 2];
|
||||
diff_gf = nval_gf - val_gf;
|
||||
|
||||
val_rf = rectf[3];
|
||||
nval_rf = rectf[skipx + 3];
|
||||
diff_rf = nval_rf - val_rf;
|
||||
|
||||
rectf += 2 * skipx;
|
||||
}
|
||||
|
||||
for (y = newy; y > 0; y--) {
|
||||
if (sample >= 1.0f) {
|
||||
sample -= 1.0f;
|
||||
|
||||
if (do_rect) {
|
||||
val_a = nval_a;
|
||||
nval_a = rect[0];
|
||||
diff_a = nval_a - val_a;
|
||||
val_a += 0.5f;
|
||||
|
||||
val_b = nval_b;
|
||||
nval_b = rect[1];
|
||||
diff_b = nval_b - val_b;
|
||||
val_b += 0.5f;
|
||||
|
||||
val_g = nval_g;
|
||||
nval_g = rect[2];
|
||||
diff_g = nval_g - val_g;
|
||||
val_g += 0.5f;
|
||||
|
||||
val_r = nval_r;
|
||||
nval_r = rect[3];
|
||||
diff_r = nval_r - val_r;
|
||||
val_r += 0.5f;
|
||||
rect += skipx;
|
||||
}
|
||||
if (do_float) {
|
||||
val_af = nval_af;
|
||||
nval_af = rectf[0];
|
||||
diff_af = nval_af - val_af;
|
||||
|
||||
val_bf = nval_bf;
|
||||
nval_bf = rectf[1];
|
||||
diff_bf = nval_bf - val_bf;
|
||||
|
||||
val_gf = nval_gf;
|
||||
nval_gf = rectf[2];
|
||||
diff_gf = nval_gf - val_gf;
|
||||
|
||||
val_rf = nval_rf;
|
||||
nval_rf = rectf[3];
|
||||
diff_rf = nval_rf - val_rf;
|
||||
rectf += skipx;
|
||||
}
|
||||
}
|
||||
if (do_rect) {
|
||||
newrect[0] = val_a + sample * diff_a;
|
||||
newrect[1] = val_b + sample * diff_b;
|
||||
newrect[2] = val_g + sample * diff_g;
|
||||
newrect[3] = val_r + sample * diff_r;
|
||||
for (y = newy; y > 0; y--) {
|
||||
memcpy(newrect, rect, sizeof(char) * skipx);
|
||||
newrect += skipx;
|
||||
}
|
||||
if (do_float) {
|
||||
newrectf[0] = val_af + sample * diff_af;
|
||||
newrectf[1] = val_bf + sample * diff_bf;
|
||||
newrectf[2] = val_gf + sample * diff_gf;
|
||||
newrectf[3] = val_rf + sample * diff_rf;
|
||||
}
|
||||
if (do_float) {
|
||||
for (y = newy; y > 0; y--) {
|
||||
memcpy(newrectf, rectf, sizeof(float) * skipx);
|
||||
newrectf += skipx;
|
||||
}
|
||||
sample += add;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const float add = (ibuf->y - 1.001) / (newy - 1.0);
|
||||
float sample;
|
||||
|
||||
float val_a, nval_a, diff_a;
|
||||
float val_b, nval_b, diff_b;
|
||||
float val_g, nval_g, diff_g;
|
||||
float val_r, nval_r, diff_r;
|
||||
float val_af, nval_af, diff_af;
|
||||
float val_bf, nval_bf, diff_bf;
|
||||
float val_gf, nval_gf, diff_gf;
|
||||
float val_rf, nval_rf, diff_rf;
|
||||
|
||||
val_a = nval_a = diff_a = val_b = nval_b = diff_b = 0;
|
||||
val_g = nval_g = diff_g = val_r = nval_r = diff_r = 0;
|
||||
val_af = nval_af = diff_af = val_bf = nval_bf = diff_bf = 0;
|
||||
val_gf = nval_gf = diff_gf = val_rf = nval_rf = diff_rf = 0;
|
||||
|
||||
for (x = ibuf->x; x > 0; x--) {
|
||||
sample = 0;
|
||||
if (do_rect) {
|
||||
rect = ((uchar *)ibuf->rect) + 4 * (x - 1);
|
||||
newrect = _newrect + 4 * (x - 1);
|
||||
|
||||
val_a = rect[0];
|
||||
nval_a = rect[skipx];
|
||||
diff_a = nval_a - val_a;
|
||||
val_a += 0.5f;
|
||||
|
||||
val_b = rect[1];
|
||||
nval_b = rect[skipx + 1];
|
||||
diff_b = nval_b - val_b;
|
||||
val_b += 0.5f;
|
||||
|
||||
val_g = rect[2];
|
||||
nval_g = rect[skipx + 2];
|
||||
diff_g = nval_g - val_g;
|
||||
val_g += 0.5f;
|
||||
|
||||
val_r = rect[3];
|
||||
nval_r = rect[skipx + 3];
|
||||
diff_r = nval_r - val_r;
|
||||
val_r += 0.5f;
|
||||
|
||||
rect += 2 * skipx;
|
||||
}
|
||||
if (do_float) {
|
||||
rectf = ibuf->rect_float + 4 * (x - 1);
|
||||
newrectf = _newrectf + 4 * (x - 1);
|
||||
|
||||
val_af = rectf[0];
|
||||
nval_af = rectf[skipx];
|
||||
diff_af = nval_af - val_af;
|
||||
|
||||
val_bf = rectf[1];
|
||||
nval_bf = rectf[skipx + 1];
|
||||
diff_bf = nval_bf - val_bf;
|
||||
|
||||
val_gf = rectf[2];
|
||||
nval_gf = rectf[skipx + 2];
|
||||
diff_gf = nval_gf - val_gf;
|
||||
|
||||
val_rf = rectf[3];
|
||||
nval_rf = rectf[skipx + 3];
|
||||
diff_rf = nval_rf - val_rf;
|
||||
|
||||
rectf += 2 * skipx;
|
||||
}
|
||||
|
||||
for (y = newy; y > 0; y--) {
|
||||
if (sample >= 1.0f) {
|
||||
sample -= 1.0f;
|
||||
|
||||
if (do_rect) {
|
||||
val_a = nval_a;
|
||||
nval_a = rect[0];
|
||||
diff_a = nval_a - val_a;
|
||||
val_a += 0.5f;
|
||||
|
||||
val_b = nval_b;
|
||||
nval_b = rect[1];
|
||||
diff_b = nval_b - val_b;
|
||||
val_b += 0.5f;
|
||||
|
||||
val_g = nval_g;
|
||||
nval_g = rect[2];
|
||||
diff_g = nval_g - val_g;
|
||||
val_g += 0.5f;
|
||||
|
||||
val_r = nval_r;
|
||||
nval_r = rect[3];
|
||||
diff_r = nval_r - val_r;
|
||||
val_r += 0.5f;
|
||||
rect += skipx;
|
||||
}
|
||||
if (do_float) {
|
||||
val_af = nval_af;
|
||||
nval_af = rectf[0];
|
||||
diff_af = nval_af - val_af;
|
||||
|
||||
val_bf = nval_bf;
|
||||
nval_bf = rectf[1];
|
||||
diff_bf = nval_bf - val_bf;
|
||||
|
||||
val_gf = nval_gf;
|
||||
nval_gf = rectf[2];
|
||||
diff_gf = nval_gf - val_gf;
|
||||
|
||||
val_rf = nval_rf;
|
||||
nval_rf = rectf[3];
|
||||
diff_rf = nval_rf - val_rf;
|
||||
rectf += skipx;
|
||||
}
|
||||
}
|
||||
if (do_rect) {
|
||||
newrect[0] = val_a + sample * diff_a;
|
||||
newrect[1] = val_b + sample * diff_b;
|
||||
newrect[2] = val_g + sample * diff_g;
|
||||
newrect[3] = val_r + sample * diff_r;
|
||||
newrect += skipx;
|
||||
}
|
||||
if (do_float) {
|
||||
newrectf[0] = val_af + sample * diff_af;
|
||||
newrectf[1] = val_bf + sample * diff_bf;
|
||||
newrectf[2] = val_gf + sample * diff_gf;
|
||||
newrectf[3] = val_rf + sample * diff_rf;
|
||||
newrectf += skipx;
|
||||
}
|
||||
sample += add;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue