Skip to content

Commit

Permalink
Issue 26393: morphapp_fuzzer: Divide-by-zero in blockconvLow
Browse files Browse the repository at this point in the history
* Removed the code that allowed divide by zero for tiny pix
* Ditto for 4 other block convolution functions.
  • Loading branch information
DanBloomberg committed Oct 29, 2020
1 parent 44a6bc6 commit f062b42
Showing 1 changed file with 40 additions and 50 deletions.
90 changes: 40 additions & 50 deletions src/convolve.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,17 +114,18 @@ static void blocksumLow(l_uint32 *datad, l_int32 w, l_int32 h, l_int32 wpl,
/*!
* \brief pixBlockconv()
*
* \param[in] pix 8 or 32 bpp; or 2, 4 or 8 bpp with colormap
* \param[in] pix 8 or 32 bpp; or 2, 4 or 8 bpp with colormap
* \param[in] wc, hc half width/height of convolution kernel
* \return pixd, or NULL on error
*
* <pre>
* Notes:
* (1) The full width and height of the convolution kernel
* are (2 * wc + 1) and (2 * hc + 1)
* (2) Returns a copy if both wc and hc are 0
* (2) Returns a copy if either wc or hc are 0
* (3) Require that w >= 2 * wc + 1 and h >= 2 * hc + 1,
* where (w,h) are the dimensions of pixs.
* where (w,h) are the dimensions of pixs. Otherwise,
* return a copy.
* </pre>
*/
PIX *
Expand All @@ -139,17 +140,14 @@ PIX *pixs, *pixd, *pixr, *pixrc, *pixg, *pixgc, *pixb, *pixbc;

if (!pix)
return (PIX *)ERROR_PTR("pix not defined", procName, NULL);
if (wc < 0) wc = 0;
if (hc < 0) hc = 0;
if (wc <= 0 || hc <= 0)
return pixCopy(NULL, pix);
pixGetDimensions(pix, &w, &h, &d);
if (w < 2 * wc + 1 || h < 2 * hc + 1) {
wc = L_MIN(wc, (w - 1) / 2);
hc = L_MIN(hc, (h - 1) / 2);
L_WARNING("kernel too large; reducing!\n", procName);
L_INFO("wc = %d, hc = %d\n", procName, wc, hc);
L_ERROR("kernel is too large: w = %d, wc = %d, h = %d, hc = %d\n",
procName, w, wc, h, hc);
return pixCopy(NULL, pix); /* no-op */
}
if (wc == 0 && hc == 0) /* no-op */
return pixCopy(NULL, pix);

/* Remove colormap if necessary */
if ((d == 2 || d == 4 || d == 8) && pixGetColormap(pix)) {
Expand Down Expand Up @@ -205,9 +203,10 @@ PIX *pixs, *pixd, *pixr, *pixrc, *pixg, *pixgc, *pixb, *pixbc;
* returning; otherwise, just use the input accum pix.
* (2) The full width and height of the convolution kernel
* are (2 * wc + 1) and (2 * hc + 1).
* (3) Returns a copy if both wc and hc are 0.
* (3) Returns a copy if either wc or hc are 0
* (4) Require that w >= 2 * wc + 1 and h >= 2 * hc + 1,
* where (w,h) are the dimensions of pixs.
* where (w,h) are the dimensions of pixs. Otherwise,
* return a copy.
* </pre>
*/
PIX *
Expand All @@ -227,13 +226,11 @@ PIX *pixd, *pixt;
pixGetDimensions(pixs, &w, &h, &d);
if (d != 8)
return (PIX *)ERROR_PTR("pixs not 8 bpp", procName, NULL);
if (wc < 0) wc = 0;
if (hc < 0) hc = 0;
if (wc == 0 && hc == 0) /* no-op */
if (wc <= 0 || hc <= 0) /* no-op */
return pixCopy(NULL, pixs);
if (w < 2 * wc + 1 || h < 2 * hc + 1) {
L_WARNING("kernel too large; returning a copy\n", procName);
L_INFO("w = %d, wc = %d, h = %d, hc = %d\n", procName, w, wc, h, hc);
L_ERROR("kernel is too large: w = %d, wc = %d, h = %d, hc = %d\n",
procName, w, wc, h, hc);
return pixCopy(NULL, pixs);
}

Expand Down Expand Up @@ -612,7 +609,7 @@ l_uint32 *lines, *lined, *linedp;
* are (2 * wc + 1) and (2 * hc + 1).
* (2) Require that w >= 2 * wc + 1 and h >= 2 * hc + 1,
* where (w,h) are the dimensions of pixs.
* (3) Returns a copy if both wc and hc are 0.
* (3) Returns a copy if either wc or hc are 0.
* (3) Adds mirrored border to avoid treating the boundary pixels
* specially. Note that we add wc + 1 pixels to the left
* and wc to the right. The added width is 2 * wc + 1 pixels,
Expand Down Expand Up @@ -650,16 +647,13 @@ PIX *pixsb, *pixacc, *pixd;
pixGetDimensions(pixs, &w, &h, &d);
if (d != 8)
return (PIX *)ERROR_PTR("pixs not 8 bpp", procName, NULL);
if (wc < 0) wc = 0;
if (hc < 0) hc = 0;
if (wc <= 0 || hc <= 0) /* no-op */
return pixCopy(NULL, pixs);
if (w < 2 * wc + 1 || h < 2 * hc + 1) {
wc = L_MIN(wc, (w - 1) / 2);
hc = L_MIN(hc, (h - 1) / 2);
L_WARNING("kernel too large; reducing!\n", procName);
L_INFO("wc = %d, hc = %d\n", procName, wc, hc);
}
if (wc == 0 && hc == 0) /* no-op */
L_ERROR("kernel is too large: w = %d, wc = %d, h = %d, hc = %d\n",
procName, w, wc, h, hc);
return pixCopy(NULL, pixs);
}

if ((pixsb = pixAddMirroredBorder(pixs, wc + 1, wc, hc + 1, hc)) == NULL)
return (PIX *)ERROR_PTR("pixsb not made", procName, NULL);
Expand Down Expand Up @@ -707,9 +701,10 @@ PIX *pixsb, *pixacc, *pixd;
* Notes:
* (1) The full width and height of the convolution kernel
* are (2 * wc + 1) and (2 * hc + 1)
* (2) Returns a copy if both wc and hc are 0
* (2) Returns a copy if either wc or hc are 0.
* (3) Require that w >= 2 * wc + 1 and h >= 2 * hc + 1,
* where (w,h) are the dimensions of pixs.
* where (w,h) are the dimensions of pixs. Otherwise,
* return a copy.
* (4) For nx == ny == 1, this defaults to pixBlockconv(), which
* is typically about twice as fast, and gives nearly
* identical results as pixBlockconvGrayTile().
Expand Down Expand Up @@ -741,19 +736,16 @@ PIXTILING *pt;

if (!pix)
return (PIX *)ERROR_PTR("pix not defined", procName, NULL);
if (wc < 0) wc = 0;
if (hc < 0) hc = 0;
pixGetDimensions(pix, &w, &h, &d);
if (w < 2 * wc + 3 || h < 2 * hc + 3) {
wc = L_MAX(0, L_MIN(wc, (w - 3) / 2));
hc = L_MAX(0, L_MIN(hc, (h - 3) / 2));
L_WARNING("kernel too large; reducing!\n", procName);
L_INFO("wc = %d, hc = %d\n", procName, wc, hc);
}
if (wc == 0 && hc == 0) /* no-op */
if (wc <= 0 || hc <= 0) /* no-op */
return pixCopy(NULL, pix);
if (nx <= 1 && ny <= 1)
return pixBlockconv(pix, wc, hc);
pixGetDimensions(pix, &w, &h, &d);
if (w < 2 * wc + 3 || h < 2 * hc + 3) {
L_ERROR("kernel is too large: w = %d, wc = %d, h = %d, hc = %d\n",
procName, w, wc, h, hc);
return pixCopy(NULL, pix);
}

/* Test to see if the tiles are too small. The required
* condition is that the tile dimensions must be at least
Expand Down Expand Up @@ -846,9 +838,10 @@ PIXTILING *pt;
* left and right, and with (hc + 1) pixels on top and bottom.
* The returned pix has these stripped off; they are only used
* for computation.
* (3) Returns a copy if both wc and hc are 0
* (4) Require that w > 2 * wc + 1 and h > 2 * hc + 1,
* where (w,h) are the dimensions of pixs.
* (3) Returns a copy if either wc or hc are 0.
* (4) Require that w > 2 * wc + 3 and h > 2 * hc + 3,
* where (w,h) are the dimensions of pixs. Otherwise,
* return a copy.
* </pre>
*/
PIX *
Expand All @@ -870,16 +863,13 @@ PIX *pixt, *pixd;
pixGetDimensions(pixs, &w, &h, &d);
if (d != 8)
return (PIX *)ERROR_PTR("pixs not 8 bpp", procName, NULL);
if (wc < 0) wc = 0;
if (hc < 0) hc = 0;
if (wc <= 0 || hc <= 0) /* no-op */
return pixCopy(NULL, pixs);
if (w < 2 * wc + 3 || h < 2 * hc + 3) {
wc = L_MAX(0, L_MIN(wc, (w - 3) / 2));
hc = L_MAX(0, L_MIN(hc, (h - 3) / 2));
L_WARNING("kernel too large; reducing!\n", procName);
L_INFO("wc = %d, hc = %d\n", procName, wc, hc);
}
if (wc == 0 && hc == 0)
L_ERROR("kernel is too large: w = %d, wc = %d, h = %d, hc = %d\n",
procName, w, wc, h, hc);
return pixCopy(NULL, pixs);
}
wd = w - 2 * wc;
hd = h - 2 * hc;

Expand Down

0 comments on commit f062b42

Please sign in to comment.