diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2021-12-26 09:16:41 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2021-12-26 09:16:41 +0000 |
commit | e15e137ba527ba97c82149ad8c6bed59088d8616 (patch) | |
tree | d97d0742d8fa448232faad05a7b40ccc18641b68 | |
parent | 2d31b9e0a06dde404131dbc2300502bfd2698819 (diff) | |
download | netpbm-mirror-e15e137ba527ba97c82149ad8c6bed59088d8616.tar.gz netpbm-mirror-e15e137ba527ba97c82149ad8c6bed59088d8616.tar.xz netpbm-mirror-e15e137ba527ba97c82149ad8c6bed59088d8616.zip |
Release 10.73.38
git-svn-id: http://svn.code.sf.net/p/netpbm/code/super_stable@4219 9d0c8265-081b-0410-96cb-a4ca84ce46f8
-rw-r--r-- | converter/other/pamtogif.c | 144 | ||||
-rw-r--r-- | converter/other/pnmtopalm/palmtopnm.c | 22 | ||||
-rw-r--r-- | converter/other/sunicontopnm.c | 20 | ||||
-rw-r--r-- | converter/pbm/escp2topbm.c | 19 | ||||
-rw-r--r-- | converter/pbm/mgrtopbm.c | 50 | ||||
-rw-r--r-- | converter/pbm/ybmtopbm.c | 31 | ||||
-rw-r--r-- | doc/HISTORY | 20 | ||||
-rw-r--r-- | editor/pamcut.c | 4 | ||||
-rw-r--r-- | editor/pamrubber.c | 8 | ||||
-rw-r--r-- | editor/pbmpscale.c | 6 | ||||
-rw-r--r-- | editor/pnmcat.c | 3 | ||||
-rw-r--r-- | editor/pnmpad.c | 2 | ||||
-rw-r--r-- | lib/libpbm2.c | 7 | ||||
-rw-r--r-- | version.mk | 2 |
14 files changed, 243 insertions, 95 deletions
diff --git a/converter/other/pamtogif.c b/converter/other/pamtogif.c index d20fa650..592a0472 100644 --- a/converter/other/pamtogif.c +++ b/converter/other/pamtogif.c @@ -24,6 +24,13 @@ static bool verbose; typedef int stringCode; + +enum TransparencyType {TRANS_NONE, TRANS_COLOR, TRANS_ALPHA}; + /* The source of transparency for the GIF: nothing is transparent, + All pixels of a certain color are transparent, or the alpha plane + in the input tells what is transparent. + */ + /* A code to be place in the GIF raster. It represents a string of one or more pixels. You interpret this in the context of a current code size. The lower half of the values representable @@ -89,7 +96,12 @@ struct cmdlineInfo { static unsigned int pamAlphaPlane(struct pam * const pamP) { +/*---------------------------------------------------------------------------- + The number of the alpha plane, or zero if there is no alpha plane, as + indicated by *pamP. + Note that the alpha plane is never zero in any Netpbm tuple type. +-----------------------------------------------------------------------------*/ unsigned int alphaPlane; if (streq(pamP->tuple_type, "RGB_ALPHA")) @@ -440,18 +452,25 @@ gifPixel(struct pam * const pamP, sample const alphaThreshold, struct cmap * const cmapP) { /*---------------------------------------------------------------------------- - Return as *colorIndexP the colormap index of the tuple 'tuple', - whose format is described by *pamP, using colormap *cmapP. + Return the colormap index of the tuple 'tuple', whose format is described + by *pamP, using colormap *cmapP. + + 'alphaPlane' is the number of the plane in 'tuple' to use for transparency, + or zero if we aren't to use any plane for transparency. (note that Caller + cannot specify plane 0 for transparency). + + 'alphaThreshold' is the alpha level below which we consider a pixel + transparent for GIF purposes. - 'alphaThreshold' is the alpha level below which we consider a - pixel transparent for GIF purposes. + If 'alphaPlane' is nonzero, we assume *cmapP contains a transparent + entry. -----------------------------------------------------------------------------*/ int colorIndex; - if (alphaPlane && tuple[alphaPlane] < alphaThreshold && - cmapP->haveTransparent) + if (alphaPlane && tuple[alphaPlane] < alphaThreshold) { + assert(cmapP->haveTransparent); colorIndex = cmapP->transparent; - else { + } else { int found; pnm_lookuptuple(pamP, cmapP->tuplehash, tuple, @@ -1223,6 +1242,14 @@ writeRaster(struct pam * const pamP, Get the raster to write from 'rowReaderP', which gives tuples whose format is described by 'pamP'. + 'alphaPlane' is the number of the plane in the tuples supplied by + 'rowReaderP' that we should use for transparency information, and + 'alphaThreshold' is the value in that plane below which we should consider + the pixel transparent for GIF purposes. + + 'alphaPlane' is zero to indicate we should not use any plane as an alpha + plane (so it's not possible to specify Plane 0 as alpha). + Use the colormap 'cmapP' to generate the raster ('rowReaderP' gives pixel values as RGB samples; the GIF raster is colormap indices). @@ -1438,8 +1465,13 @@ gifEncode(struct pam * const pamP, struct cmap * const cmapP, char const comment[], float const aspect, - bool const lzw) { - + bool const lzw, + bool const usingAlpha) { +/*---------------------------------------------------------------------------- + 'usingAlpha' means use the alpha (transparency) plane, if there is one, to + determine which GIF pixels are transparent. When this is true, the + colormap *cmapP must contain a transparent entry. +-----------------------------------------------------------------------------*/ unsigned int const leftOffset = 0; unsigned int const topOffset = 0; @@ -1451,7 +1483,7 @@ gifEncode(struct pam * const pamP, pixels in the output image. */ - unsigned int const alphaPlane = pamAlphaPlane(pamP); + unsigned int const alphaPlane = usingAlpha ? pamAlphaPlane(pamP) : 0; rowReader * rowReaderP; @@ -1493,9 +1525,22 @@ gifEncode(struct pam * const pamP, static void -reportTransparent(struct cmap * const cmapP) { +reportTransparent(enum TransparencyType const transType, + struct cmap * const cmapP) { if (verbose) { + switch (transType) { + case TRANS_NONE: + pm_message("Not making transparent pixels"); + break; + case TRANS_COLOR: + pm_message("Making pixels of a certain color transparent"); + break; + case TRANS_ALPHA: + pm_message("Making pixels transparent per input alpha mask"); + break; + } + if (cmapP->haveTransparent) { tuple const color = cmapP->color[cmapP->transparent]; pm_message("Color %u (%lu, %lu, %lu) is transparent", @@ -1511,42 +1556,46 @@ reportTransparent(struct cmap * const cmapP) { static void -computeTransparent(char const colorarg[], - bool const usingFakeTrans, - unsigned int const fakeTransparent, - struct cmap * const cmapP) { +computeTransparent(enum TransparencyType const transType, + char const colorarg[], + unsigned int const fakeTransparent, + struct cmap * const cmapP) { /*---------------------------------------------------------------------------- Figure out the color index (index into the colormap) of the color - that is to be transparent in the GIF. + that is to be transparent in the GIF and set it in the colormap. + + 'transType' tells what the source of the transparency is. + + If 'transType' says all pixels of a single foreground color are to be + transparent: - colorarg[] is the string that specifies the color the user wants to - be transparent (e.g. "red", "#fefefe"). Its maxval is the maxval - of the colormap. 'cmap' is the full colormap except that its - 'transparent' component isn't valid. + 'colorarg' is the specification of that color. Its + maxval is the maxval of the colormap. - colorarg[] is a standard Netpbm color specification, except that - may have a "=" prefix, which means it specifies a particular exact - color, as opposed to without the "=", which means "the color that - is closest to this and actually in the image." + colorarg[] is a standard Netpbm color specification (e.g. "red", + "#fefefe"), except that may have a "=" prefix, which means it specifies a + particular exact color, as opposed to without the "=", which means "the + color that is closest to this and actually in the image." - colorarg[] null means the color didn't ask for a particular color - to be transparent. + Establish no transparent color if colorarg[] specifies an exact + color and that color is not in the image. Also issue an + informational message. - Establish no transparent color if colorarg[] specifies an exact - color and that color is not in the image. Also issue an - informational message. + If 'transType' says an input alpha channel will dtermine what pixels are + transparent: - 'usingFakeTrans' means pixels will be transparent because of something - other than their foreground color, and 'fakeTransparent' is the - color map index for transparent colors. + 'fakeTransparent' is the special color map index for transparent pixels. -----------------------------------------------------------------------------*/ - if (colorarg) { + switch (transType) { + case TRANS_COLOR: { const char * colorspec; bool exact; tuple transcolor; int found; int colorindex; + assert(colorarg); + if (colorarg[0] == '=') { colorspec = &colorarg[1]; exact = TRUE; @@ -1570,13 +1619,16 @@ computeTransparent(char const colorarg[], pm_message("Warning: specified transparent color " "does not occur in image."); } - } else if (usingFakeTrans) { + } break; + case TRANS_ALPHA: { cmapP->haveTransparent = TRUE; cmapP->transparent = fakeTransparent; - } else + } break; + case TRANS_NONE: { cmapP->haveTransparent = FALSE; - - reportTransparent(cmapP); + } break; + } /* switch */ + reportTransparent(transType, cmapP); } @@ -1889,13 +1941,13 @@ main(int argc, char *argv[]) { struct pam pam; unsigned int bitsPerPixel; pm_filepos rasterPos; - struct cmap cmap; /* The colormap, with all its accessories */ + enum TransparencyType transType; unsigned int fakeTransparent; /* colormap index of the fake transparency color we're using to - implement the alpha mask. Undefined if we're not doing an alpha - mask. + implement the alpha mask. Defined only if 'transType' is + TRANS_ALPHA. */ pnm_init(&argc, argv); @@ -1916,7 +1968,11 @@ main(int argc, char *argv[]) { assert(cmap.pam.maxval == pam.maxval); - if (pamAlphaPlane(&pam)) { + transType = cmdline.transparent ? TRANS_COLOR : + pamAlphaPlane(&pam) ? TRANS_ALPHA : + TRANS_NONE; + + if (transType == TRANS_ALPHA) { /* Add a fake entry to the end of the colormap for transparency. Make its color black. */ @@ -1925,14 +1981,12 @@ main(int argc, char *argv[]) { bitsPerPixel = cmap.cmapSize == 1 ? 1 : nSignificantBits(cmap.cmapSize-1); - computeTransparent(cmdline.transparent, - !!pamAlphaPlane(&pam), fakeTransparent, &cmap); + computeTransparent(transType, cmdline.transparent, fakeTransparent, &cmap); /* All set, let's do it. */ gifEncode(&pam, stdout, rasterPos, cmdline.interlace, 0, bitsPerPixel, &cmap, cmdline.comment, - cmdline.aspect, !cmdline.nolzw); - + cmdline.aspect, !cmdline.nolzw, !cmdline.transparent); destroyCmap(&cmap); pm_close(ifP); diff --git a/converter/other/pnmtopalm/palmtopnm.c b/converter/other/pnmtopalm/palmtopnm.c index 0f76207d..e7138cce 100644 --- a/converter/other/pnmtopalm/palmtopnm.c +++ b/converter/other/pnmtopalm/palmtopnm.c @@ -817,11 +817,12 @@ readPackBitsRow16(FILE * const ifP, unsigned int j; for (j = 0; j < bytesPerRow; ) { - char incount; - pm_readchar(ifP, &incount); - if (incount < 0) { + unsigned char incountByte; + pm_readcharu(ifP, &incountByte); + if (incountByte & 0x80) { + int const signedIncount = (signed char)incountByte; /* How do we handle incount == -128 ? */ - unsigned int const runlength = (-incount + 1) * 2; + unsigned int const runlength = (-signedIncount + 1) * 2; unsigned int k; unsigned short inval; pm_readlittleshortu(ifP, &inval); @@ -832,7 +833,7 @@ readPackBitsRow16(FILE * const ifP, j += runlength; } else { /* We just read the stream of shorts as a stream of chars */ - unsigned int const nonrunlength = (incount + 1) * 2; + unsigned int const nonrunlength = (incountByte + 1) * 2; unsigned int k; for (k = 0; (k < nonrunlength) && (j + k <= bytesPerRow); ++k) { unsigned char inval; @@ -859,18 +860,19 @@ readPackBitsRow(FILE * const ifP, unsigned int j; for (j = 0; j < bytesPerRow; ) { - char incount; - pm_readchar(ifP, &incount); - if (incount < 0) { + unsigned char incountByte; + pm_readcharu(ifP, &incountByte); + if (incountByte & 0x80) { /* How do we handle incount == -128 ? */ - unsigned int const runlength = -incount + 1; + int const signedIncount = (char)incountByte; + unsigned int const runlength = -signedIncount + 1; unsigned char inval; pm_readcharu(ifP, &inval); if (j + runlength <= bytesPerRow) memset(palmrow + j, inval, runlength); j += runlength; } else { - unsigned int const nonrunlength = incount + 1; + unsigned int const nonrunlength = incountByte + 1; unsigned int k; for (k = 0; k < nonrunlength && j + k <= bytesPerRow; ++k) { unsigned char inval; diff --git a/converter/other/sunicontopnm.c b/converter/other/sunicontopnm.c index eff1be58..db26663e 100644 --- a/converter/other/sunicontopnm.c +++ b/converter/other/sunicontopnm.c @@ -12,10 +12,12 @@ /* Most icon images are monochrome: Depth=1 + Depth=8 images are extremely rare. At least some of these are color - images but we can't tell the palette color order. + images but we haven't found information on the palette color order. Output will be in pgm. Convert to ppm with pgmtoppm or pamlookup - if necessary. + if necessary. It is up to the user to provide the color palette in + a form acceptable by the above conversion utilities. */ #include <assert.h> @@ -93,12 +95,19 @@ ReadIconFileHeader(FILE * const file, if (*widthP <= 0) pm_error("invalid width (must be positive): %d", *widthP); + else if (*widthP % 8 > 0) + pm_message("warning: width not a multiple of 8: %d", *widthP); + /* We don't know whether widths which are not a multiple of 8 + are allowed. The program must gracefully handle this case + because sun icon files are easy to edit by hand. + */ if (*heightP <= 0) pm_error("invalid height (must be positive): %d", *heightP); } + int main(int argc, const char ** argv) { @@ -125,7 +134,7 @@ main(int argc, const char ** argv) { maxval = 1; pbm_writepbminit(stdout, cols, rows, 0); bitrow = pbm_allocrow_packed(cols); - colChars = cols / 8; + colChars = pbm_packed_bytes(cols); } else { assert(depth == 8); format = PGM_TYPE; @@ -166,6 +175,11 @@ main(int argc, const char ** argv) { pgm_writepgmrow(stdout, grayrow, cols, maxval, 0); } + if (format == PBM_TYPE) + pbm_freerow_packed(bitrow); + else + pgm_freerow(grayrow); + pm_close(ifP); pm_close(stdout); return 0; diff --git a/converter/pbm/escp2topbm.c b/converter/pbm/escp2topbm.c index 632e6345..8acd13d6 100644 --- a/converter/pbm/escp2topbm.c +++ b/converter/pbm/escp2topbm.c @@ -47,10 +47,17 @@ #include <stdbool.h> +#include <assert.h> #include "mallocvar.h" #include "pbm.h" +static unsigned int widthMax = 127 * 256 + 255; + /* Limit in official Epson manual */ + +static unsigned int const heightMax = 5120 * 200; + /* 5120 rows is sufficient for US legal at 360 DPI */ + #define ESC 033 @@ -120,6 +127,10 @@ readStripeHeader(unsigned int * const widthThisStripeP, pm_error("Error: Abnormal value in data block header: " "Says stripe has zero width or height"); + if (widthThisStripe > widthMax) + pm_error("Error: Abnormal width value in data block header: %u", + widthThisStripe); + if (compression != 0 && compression != 1) pm_error("Error: Unknown compression mode %u", compression); @@ -221,12 +232,10 @@ expandBitarray(unsigned char *** const bitarrayP, unsigned int * const bitarraySizeP) { unsigned int const heightIncrement = 5120; - unsigned int const heightMax = 5120 * 200; - /* 5120 rows is sufficient for US legal at 360 DPI */ *bitarraySizeP += heightIncrement; if (*bitarraySizeP > heightMax) - pm_error("Image too tall"); + pm_error("Error: Image too tall"); else REALLOCARRAY_NOFAIL(*bitarrayP, *bitarraySizeP); } @@ -326,6 +335,10 @@ main(int argc, width, widthThisStripe); } height += rowsThisStripe; + assert(height <= INT_MAX - 10); + /* Becuse image height is tested in expandBitarray() + with a more stringent condition. + */ if (height > bitarraySize) expandBitarray(&bitarray, &bitarraySize); diff --git a/converter/pbm/mgrtopbm.c b/converter/pbm/mgrtopbm.c index 9f7004a1..712e3be9 100644 --- a/converter/pbm/mgrtopbm.c +++ b/converter/pbm/mgrtopbm.c @@ -16,6 +16,48 @@ static void +interpHdrWidth(struct b_header const head, + unsigned int * const colsP) { + + if (head.h_wide < ' ' || head.l_wide < ' ') + pm_error("Invalid width field in MGR header"); + else { + unsigned int const maxDimension = 4095; + + unsigned int const cols = + (((int)head.h_wide - ' ') << 6) + ((int)head.l_wide - ' '); + + if (cols == 0 || cols > maxDimension) + pm_error("Invalid width value (%u) in MGR header", cols); + else + *colsP = cols; + } +} + + + +static void +interpHdrHeight(struct b_header const head, + unsigned int * const rowsP) { + + if (head.h_high < ' ' || head.l_high < ' ') + pm_error("Invalid height field in MGR header"); + else { + unsigned int const maxDimension = 4095; + + unsigned int const rows = + (((int)head.h_high - ' ') << 6) + ((int)head.l_high - ' '); + + if (rows == 0 || rows > maxDimension) + pm_error("Invalid height value (%u) in MGR header", rows); + else + *rowsP = rows; + } +} + + + +static void readMgrHeader(FILE * const ifP, unsigned int * const colsP, unsigned int * const rowsP, @@ -60,13 +102,9 @@ readMgrHeader(FILE * const ifP, pad = 0; /* should never reach here */ } - if (head.h_wide < ' ' || head.l_wide < ' ') - pm_error("Invalid width field in MGR header"); - if (head.h_high < ' ' || head.l_high < ' ') - pm_error("Invalid width field in MGR header"); + interpHdrWidth (head, colsP); + interpHdrHeight(head, rowsP); - *colsP = (((int)head.h_wide - ' ') << 6) + ((int)head.l_wide - ' '); - *rowsP = (((int)head.h_high - ' ') << 6) + ((int) head.l_high - ' '); *padrightP = ( ( *colsP + pad - 1 ) / pad ) * pad - *colsP; } diff --git a/converter/pbm/ybmtopbm.c b/converter/pbm/ybmtopbm.c index 2a429086..ea7e66a7 100644 --- a/converter/pbm/ybmtopbm.c +++ b/converter/pbm/ybmtopbm.c @@ -20,44 +20,47 @@ static short const ybmMagic = ( ( '!' << 8 ) | '!' ); static void getinit(FILE * const ifP, - short * const colsP, - short * const rowsP, - short * const depthP) { + unsigned int * const colsP, + unsigned int * const rowsP, + int * const depthP) { - short magic; + short int magic; + short int cols, rows; int rc; rc = pm_readbigshort(ifP, &magic); if (rc == -1) pm_error("EOF / read error"); - - if (magic != ybmMagic) + else if (magic != ybmMagic) pm_error("bad magic number in YBM file"); - rc = pm_readbigshort(ifP, colsP); + rc = pm_readbigshort(ifP, &cols); if (rc == -1 ) pm_error("EOF / read error"); + else if (cols <= 0) + pm_error("invalid width value in YBM file"); - rc = pm_readbigshort(ifP, rowsP); + rc = pm_readbigshort(ifP, &rows); if (rc == -1) pm_error("EOF / read error"); + else if (rows <= 0) + pm_error("invalid height value in YBM file"); + *colsP = (unsigned int) cols; + *rowsP = (unsigned int) rows; *depthP = 1; } - - - int main(int argc, const char * argv[]) { FILE * ifP; bit * bitrow; - short rows, cols; + unsigned int rows, cols; unsigned int row; - short depth; + int depth; const char * inputFile; pm_proginit(&argc, argv); @@ -76,7 +79,7 @@ main(int argc, const char * argv[]) { getinit(ifP, &cols, &rows, &depth); if (depth != 1) - pm_error("YBM file has depth of %u, must be 1", (unsigned)depth); + pm_error("YBM file has depth of %u, must be 1", (unsigned int) depth); pbm_writepbminit(stdout, cols, rows, 0); diff --git a/doc/HISTORY b/doc/HISTORY index ff4a346b..005dd131 100644 --- a/doc/HISTORY +++ b/doc/HISTORY @@ -4,6 +4,24 @@ Netpbm. CHANGE HISTORY -------------- +21.12.26 BJH Release 10.73.38 + + pamtogif: Fix bug: doesn't ignore the input alpha mask when user + specified -transparent. Broken in Netpbm 10.37 (December 2006). + + palmtopnm: Fix bug: fails with PackBits input on platform with + default unsigned char, such as ppc64. Always broken. (Ability + to convert PackBits input was new in Netpbm 10.27 (March 2005). + + pamrubber: Fix bug: random behavior with -quad when you specify + both points for source or target and the second one is lower in + the image than the first. Always broken (Pamrubber was new in + Netpbm 10.54 (March 2011)). + + sunicontopnm, escp2topbm, mgrtopbm, ybmtopbm, pamcut, pbmpscale, + pnmcat, pnmpad: Fix arithmetic overrun with ridiculously large + image. + 21.09.25 BJH Release 10.73.37 ximtoppm: Fix bug: invalid memory references with pathological @@ -168,7 +186,7 @@ CHANGE HISTORY 19.12.25 BJH Release 10.73.30 pamrubber: Fix bug: -frame doesn't work. Always broken. - (Pamrubber was new in Netpbm 10.54 (March 2011). + (Pamrubber was new in Netpbm 10.54 (March 2011)). 19.09.28 BJH Release 10.73.29 diff --git a/editor/pamcut.c b/editor/pamcut.c index 7c41af38..0f0144ef 100644 --- a/editor/pamcut.c +++ b/editor/pamcut.c @@ -570,7 +570,7 @@ extractRowsPBM(const struct pam * const inpamP, if (leftcol > 0) { totalWidth = MAX(rightcol+1, inpamP->width) + 7; - if (totalWidth > INT_MAX) + if (totalWidth > INT_MAX - 10) /* Prevent overflows in pbm_allocrow_packed() */ pm_error("Specified right edge is too far " "from the right end of input image"); @@ -579,7 +579,7 @@ extractRowsPBM(const struct pam * const inpamP, writeOffset = leftcol; } else { totalWidth = -leftcol + MAX(rightcol+1, inpamP->width); - if (totalWidth > INT_MAX) + if (totalWidth > INT_MAX - 10) pm_error("Specified left/right edge is too far " "from the left/right end of input image"); diff --git a/editor/pamrubber.c b/editor/pamrubber.c index 1890ac58..aaf62788 100644 --- a/editor/pamrubber.c +++ b/editor/pamrubber.c @@ -1007,10 +1007,10 @@ prepQuad(void) { } else if ((oldCP[0].x > oldCP[1].x) && (oldCP[0].y < oldCP[1].y)) { /* top-right and bottom-left */ quad1 = quadRect(oldCP[1].x, oldCP[0].x, oldCP[0].y, oldCP[1].y); - } else if ((oldCP[0].x < oldCP[1].x) && (oldCP[0].y < oldCP[1].y)) { + } else if ((oldCP[0].x < oldCP[1].x) && (oldCP[0].y > oldCP[1].y)) { /* bottom-left and top-right */ quad1 = quadRect(oldCP[0].x, oldCP[1].x, oldCP[1].y, oldCP[0].y); - } else if ((oldCP[0].x > oldCP[1].x) && (oldCP[0].y < oldCP[1].y)) { + } else if ((oldCP[0].x > oldCP[1].x) && (oldCP[0].y > oldCP[1].y)) { /* bottom-right and top-left */ quad1 = quadRect(oldCP[1].x, oldCP[0].x, oldCP[1].y, oldCP[0].y); } @@ -1021,10 +1021,10 @@ prepQuad(void) { } else if ((newCP[0].x > newCP[1].x) && (newCP[0].y < newCP[1].y)) { /* top-right and bottom-left */ quad2 = quadRect(newCP[1].x, newCP[0].x, newCP[0].y, newCP[1].y); - } else if ((newCP[0].x < newCP[1].x) && (newCP[0].y < newCP[1].y)) { + } else if ((newCP[0].x < newCP[1].x) && (newCP[0].y > newCP[1].y)) { /* bottom-left and top-right */ quad2 = quadRect(newCP[0].x, newCP[1].x, newCP[1].y, newCP[0].y); - } else if ((newCP[0].x > newCP[1].x) && (newCP[0].y < newCP[1].y)) { + } else if ((newCP[0].x > newCP[1].x) && (newCP[0].y > newCP[1].y)) { /* bottom-right and top-left */ quad2 = quadRect(newCP[1].x, newCP[0].x, newCP[1].y, newCP[0].y); } diff --git a/editor/pbmpscale.c b/editor/pbmpscale.c index 9ab89350..3b6935b2 100644 --- a/editor/pbmpscale.c +++ b/editor/pbmpscale.c @@ -141,7 +141,7 @@ validateComputableDimensions(unsigned int const width, See validateComputetableSize() in libpam.c and pbm_readpbminitrest() in libpbm2.c -----------------------------------------------------------------------------*/ - unsigned int const maxWidthHeight = INT_MAX - 2; + unsigned int const maxWidthHeight = INT_MAX - 10; unsigned int const maxScaleFactor = maxWidthHeight / MAX(height, width); if (scaleFactor > maxScaleFactor) @@ -154,8 +154,8 @@ validateComputableDimensions(unsigned int const width, static void writeBitSpan(unsigned char * const packedBitrow, - int const cols, - int const offset, + unsigned int const cols, + unsigned int const offset, int const color) { /*---------------------------------------------------------------------------- Write white (color="0") or black (="1") bits into packedBitrow[], diff --git a/editor/pnmcat.c b/editor/pnmcat.c index a26dcf3e..217f6b57 100644 --- a/editor/pnmcat.c +++ b/editor/pnmcat.c @@ -367,7 +367,8 @@ getPbmImageInfo(struct imgInfo const img[], switch (backcolor) { case BACK_AUTO: { bit bgBit; - img2[i].proberow = pbm_allocrow_packed(img[i].cols+7); + img2[i].proberow = + pbm_allocrow_packed((unsigned int)img[i].cols + 7); pbm_readpbmrow_bitoffset( img[i].ifP, img2[i].proberow, img[i].cols, img[i].format, img2[i].offset % 8); diff --git a/editor/pnmpad.c b/editor/pnmpad.c index 051f3895..a4f7c5cb 100644 --- a/editor/pnmpad.c +++ b/editor/pnmpad.c @@ -10,7 +10,7 @@ #include "shhopt.h" #include "pnm.h" -#define MAX_WIDTHHEIGHT INT_MAX-10 +#define MAX_WIDTHHEIGHT ((INT_MAX)-10) /* The maximum width or height value we can handle without risking arithmetic overflow */ diff --git a/lib/libpbm2.c b/lib/libpbm2.c index f199c51a..8fde27fd 100644 --- a/lib/libpbm2.c +++ b/lib/libpbm2.c @@ -216,6 +216,9 @@ pbm_readpbmrow_bitoffset(FILE * const ifP, Read it into packedBits[], preserving surrounding image data. Logic not tested for negative offsets. + + Because we are reading in packed mode large cols and offset values are + acceptable; dividing by 8 prevents overflows. -----------------------------------------------------------------------------*/ unsigned int const rsh = offset % 8; unsigned int const lsh = (8 - rsh) % 8; @@ -224,13 +227,15 @@ pbm_readpbmrow_bitoffset(FILE * const ifP, Aligned to nearest byte boundary to the left, so the first few bits might contain original data, not output. */ - unsigned int const last = pbm_packed_bytes(cols+rsh) - 1; + unsigned int const last = pbm_packed_bytes((unsigned int)cols + rsh) - 1; /* Position within window of rightmost byte after shift */ /* The original leftmost and rightmost chars. */ unsigned char const origHead = window[0]; unsigned char const origEnd = window[last]; + assert(cols > 0 && pbm_packed_bytes(cols) > 0); + pbm_readpbmrow_packed(ifP, window, cols, format); if (rsh > 0) { diff --git a/version.mk b/version.mk index a9ce42e8..f2b4ef46 100644 --- a/version.mk +++ b/version.mk @@ -1,3 +1,3 @@ NETPBM_MAJOR_RELEASE = 10 NETPBM_MINOR_RELEASE = 73 -NETPBM_POINT_RELEASE = 37 +NETPBM_POINT_RELEASE = 38 |