GraphicsMagick: Minor adjustments/fixes for Coverity

GraphicsMagick Commits <[email protected]> Sun, 07 Jul 2024 17:55:29 -0500
Newsgroups gmane.comp.video.graphicsmagick.cvs
Message-ID <mailman.21698.1720392942.8015.graphicsmagick-commit@lists.sourceforge.net>
changeset 89e12551753e in /hg/GraphicsMagick
details: http://hg.GraphicsMagick.org/hg/GraphicsMagick?cmd=changeset;node=89e12551753e
summary: Minor adjustments/fixes for Coverity

diffstat:

 ChangeLog          |   17 +++
 coders/gif.c       |    6 +-
 coders/pnm.c       |   11 +-
 coders/sct.c       |    3 +
 coders/tiff.c      |    9 +
 coders/txt.c       |    1 +
 www/ChangeLog.html |   10 +
 www/api/blob.html  |  282 ++++++++++++++++++++++++++--------------------------
 8 files changed, 192 insertions(+), 147 deletions(-)

diffs (truncated from 698 to 500 lines):

diff -r 01647b4f343c -r 89e12551753e ChangeLog
--- a/ChangeLog	Sun Jul 07 14:18:58 2024 -0500
+++ b/ChangeLog	Sun Jul 07 17:54:29 2024 -0500
@@ -1,5 +1,22 @@
 2024-07-07  Bob Friesenhahn  <[email protected]>
 
+	* coders/tiff.c (InitializeImageColormap): Verify that
+	TIFFTAG_BITSPERSAMPLE is within a rational range.
+
+	* coders/gif.c (ReadGIFImage): Don't evaluate background color if
+	image->colors == 0.  Coverity did not detect that previous error
+	handling would already have caught this issue.
+
+	* coders/pnm.c (PNMInteger): Code simplification, and convince
+	Coverity that value returned by ReadBlobByte() is positive if it
+	is not EOF.
+
+	* coders/txt.c (ReadInt): Convince Coverity that value returned by
+	ReadBlobByte() is positive if it is not EOF.
+
+	* coders/sct.c (ReadSCTImage): Convince Coverity that value
+	returned by ReadBlobByte() is positive if it is not EOF.
+
 	* coders/png.c (ReadMNGImage): Eliminate warning: variable
 	'loops_active' set but not used".
 
diff -r 01647b4f343c -r 89e12551753e coders/gif.c
--- a/coders/gif.c	Sun Jul 07 14:18:58 2024 -0500
+++ b/coders/gif.c	Sun Jul 07 17:54:29 2024 -0500
@@ -1129,8 +1129,10 @@
           if ((long) i == opacity)
             image->colormap[i].opacity=(Quantum) TransparentOpacity;
         }
-        image->background_color=
-          image->colormap[Min(background,image->colors-1)];
+
+        if (image->colors > 0)
+          image->background_color=
+            image->colormap[Min(background,image->colors-1)];
       }
     else
       {
diff -r 01647b4f343c -r 89e12551753e coders/pnm.c
--- a/coders/pnm.c	Sun Jul 07 14:18:58 2024 -0500
+++ b/coders/pnm.c	Sun Jul 07 17:54:29 2024 -0500
@@ -143,21 +143,23 @@
     if (c == EOF)
       return(0);
   } while (!isdigit(c));
+  c &= 0xff;
   if (base == 2)
     return(c-'0');
   /*
     Evaluate number.
   */
   value=0;
-  do
+  while(1)
   {
     value*=10;
     value+=c-'0';
     c=ReadBlobByte(image);
-    if (c == EOF)
-      return(value);
+    if ((c == EOF) || !(isdigit(c)))
+      break;
+    c &= 0xff;
   }
-  while (isdigit(c));
+
   return(value);
 }
 
@@ -179,6 +181,7 @@
     c=ReadBlobByte(image);
     if (c == EOF)
       return(0);
+    c &= 0xff;
     if (c == '#')
       {
         char
diff -r 01647b4f343c -r 89e12551753e coders/sct.c
--- a/coders/sct.c	Sun Jul 07 14:18:58 2024 -0500
+++ b/coders/sct.c	Sun Jul 07 17:54:29 2024 -0500
@@ -238,6 +238,7 @@
     {
       if ((c = ReadBlobByte(image)) == EOF)
         break;
+      c &= 0xff;
       q->green=(Quantum) (MaxRGB-ScaleCharToQuantum(c));
       q++;
     }
@@ -251,6 +252,7 @@
     {
       if ((c = ReadBlobByte(image)) == EOF)
         break;
+      c &= 0xff;
       q->blue=(Quantum) (MaxRGB-ScaleCharToQuantum(c));
       q++;
     }
@@ -264,6 +266,7 @@
     {
       if ((c = ReadBlobByte(image)) == EOF)
         break;
+      c &= 0xff;
       q->opacity=(Quantum) (MaxRGB-ScaleCharToQuantum(c));
       q++;
     }
diff -r 01647b4f343c -r 89e12551753e coders/tiff.c
--- a/coders/tiff.c	Sun Jul 07 14:18:58 2024 -0500
+++ b/coders/tiff.c	Sun Jul 07 17:54:29 2024 -0500
@@ -1260,6 +1260,15 @@
   /*
     Compute colormap size
   */
+  if (bits_per_sample > 64)
+    {
+      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                            "Bits per sample (%u) is out of range!",
+                            (unsigned) bits_per_sample);
+      ThrowException(&image->exception,CorruptImageError,ImproperImageHeader,
+                     image->filename);
+      return status;
+    }
   max_sample_value=MaxValueGivenBits(bits_per_sample);
 
   image->colors=0;
diff -r 01647b4f343c -r 89e12551753e coders/txt.c
--- a/coders/txt.c	Sun Jul 07 14:18:58 2024 -0500
+++ b/coders/txt.c	Sun Jul 07 17:54:29 2024 -0500
@@ -131,6 +131,7 @@
       ch = ReadBlobByte(image);
       if (ch == EOF)
         return (n);
+      ch &= 0xff;
       digits++;
     }
 
diff -r 01647b4f343c -r 89e12551753e www/ChangeLog.html
--- a/www/ChangeLog.html	Sun Jul 07 14:18:58 2024 -0500
+++ b/www/ChangeLog.html	Sun Jul 07 17:54:29 2024 -0500
@@ -41,6 +41,16 @@
 <p>2024-07-07  Bob Friesenhahn  &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
 <blockquote>
 <ul class="simple">
+<li><p>coders/gif.c (ReadGIFImage): Don't evaluate background color if
+image-&gt;colors == 0.  Coverity did not detect that previous error
+handling would already have caught this issue.</p></li>
+<li><p>coders/pnm.c (PNMInteger): Code simplification, and convince
+Convince Coverity that value returned by ReadBlobByte() is
+positive if it is not EOF.</p></li>
+<li><p>coders/txt.c (ReadInt): Convince Coverity that value returned by
+ReadBlobByte() is positive if it is not EOF.</p></li>
+<li><p>coders/sct.c (ReadSCTImage): Convince Coverity that value
+returned by ReadBlobByte() is positive if it is not EOF.</p></li>
 <li><p>coders/png.c (ReadMNGImage): Eliminate warning: variable
 'loops_active' set but not used&quot;.</p></li>
 <li><p>coders/pcd.c (DecodeImage): Eliminate &quot;warning: variable 'count'
diff -r 01647b4f343c -r 89e12551753e www/api/blob.html
--- a/www/api/blob.html	Sun Jul 07 14:18:58 2024 -0500
+++ b/www/api/blob.html	Sun Jul 07 17:54:29 2024 -0500
@@ -36,7 +36,7 @@
 </ul>
 </div>
 
-<div class="document" id="blob">
+<main id="blob">
 <h1 class="title">blob</h1>
 <p class="subtitle" id="read-or-write-formatted-images-in-memory-blobs">Read or write formatted images in memory (BLOBs)</p>
 <div class="contents topic" id="contents">
@@ -67,13 +67,13 @@
 <li><p><a class="reference internal" href="#setblobtemporary" id="id67">SetBlobTemporary</a></p></li>
 </ul>
 </div>
-<div class="section" id="attachblob">
+<section id="attachblob">
 <h1><a class="toc-backref" href="#id45">AttachBlob</a></h1>
-<div class="section" id="synopsis">
+<section id="synopsis">
 <h2>Synopsis</h2>
 <pre class="literal-block">void AttachBlob( <a class="reference external" href="../api/types.html#blobinfo">BlobInfo</a> *blob_info, const void *blob, const size_t length );</pre>
-</div>
-<div class="section" id="description">
+</section>
+<section id="description">
 <h2>Description</h2>
 <p>AttachBlob() attaches a blob to the BlobInfo structure.</p>
 <p>The format of the AttachBlob method is:</p>
@@ -91,15 +91,15 @@
 <dd><p>This size_t integer reflects the length in bytes of the blob.</p>
 </dd>
 </dl>
-</div>
-</div>
-<div class="section" id="blobisseekable">
+</section>
+</section>
+<section id="blobisseekable">
 <h1><a class="toc-backref" href="#id46">BlobIsSeekable</a></h1>
-<div class="section" id="id1">
+<section id="id1">
 <h2>Synopsis</h2>
 <pre class="literal-block">MagickBool BlobIsSeekable( const <a class="reference external" href="../api/types.html#image">Image</a> *image );</pre>
-</div>
-<div class="section" id="id2">
+</section>
+<section id="id2">
 <h2>Description</h2>
 <p>BlobIsSeekable() returns MagickTrue if the blob supports seeks
 (SeekBlob() is functional).</p>
@@ -111,15 +111,15 @@
 <dd><p>Image to query</p>
 </dd>
 </dl>
-</div>
-</div>
-<div class="section" id="blobreservesize">
+</section>
+</section>
+<section id="blobreservesize">
 <h1><a class="toc-backref" href="#id47">BlobReserveSize</a></h1>
-<div class="section" id="id3">
+<section id="id3">
 <h2>Synopsis</h2>
 <pre class="literal-block">MagickPassFail BlobReserveSize( <a class="reference external" href="../api/types.html#image">Image</a> *image, magick_off_t size );</pre>
-</div>
-<div class="section" id="id4">
+</section>
+<section id="id4">
 <h2>Description</h2>
 <p>BlobReserveSize() sets the output size of the blob or file.  This is used
 as a means to minimize memory or filesystem fragmentation if the final
@@ -138,16 +138,16 @@
 <dd><p>New output size.</p>
 </dd>
 </dl>
-</div>
-</div>
-<div class="section" id="blobtofile">
+</section>
+</section>
+<section id="blobtofile">
 <h1><a class="toc-backref" href="#id48">BlobToFile</a></h1>
-<div class="section" id="id5">
+<section id="id5">
 <h2>Synopsis</h2>
 <pre class="literal-block">MagickPassFail BlobToFile( const char *filename, const void *blob, const size_t length,
                            <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );</pre>
-</div>
-<div class="section" id="id6">
+</section>
+<section id="id6">
 <h2>Description</h2>
 <p>BlobToFile() writes a blob to a file.  It returns MagickFail if an error
 occurs otherwise MagickPass.</p>
@@ -172,16 +172,16 @@
 <dd><p>Return any errors or warnings in this structure.</p>
 </dd>
 </dl>
-</div>
-</div>
-<div class="section" id="blobtoimage">
+</section>
+</section>
+<section id="blobtoimage">
 <h1><a class="toc-backref" href="#id49">BlobToImage</a></h1>
-<div class="section" id="id7">
+<section id="id7">
 <h2>Synopsis</h2>
 <pre class="literal-block"><a class="reference external" href="../api/types.html#image">Image</a> *BlobToImage( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, const void *blob,
                     const size_t length, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );</pre>
-</div>
-<div class="section" id="id8">
+</section>
+<section id="id8">
 <h2>Description</h2>
 <p>BlobToImage() implements direct to memory image formats.  It returns the
 blob as an image.</p>
@@ -203,15 +203,15 @@
 <dd><p>Return any errors or warnings in this structure.</p>
 </dd>
 </dl>
-</div>
-</div>
-<div class="section" id="cloneblobinfo">
+</section>
+</section>
+<section id="cloneblobinfo">
 <h1><a class="toc-backref" href="#id50">CloneBlobInfo</a></h1>
-<div class="section" id="id9">
+<section id="id9">
 <h2>Synopsis</h2>
 <pre class="literal-block"><a class="reference external" href="../api/types.html#blobinfo">BlobInfo</a> *CloneBlobInfo( const <a class="reference external" href="../api/types.html#blobinfo">BlobInfo</a> *blob_info );</pre>
-</div>
-<div class="section" id="id10">
+</section>
+<section id="id10">
 <h2>Description</h2>
 <p>CloneBlobInfo() makes a duplicate of the given blob info structure, or if
 blob info is NULL, a new one.</p>
@@ -227,15 +227,15 @@
 <dd><p>a structure of type info.</p>
 </dd>
 </dl>
-</div>
-</div>
-<div class="section" id="destroyblob">
+</section>
+</section>
+<section id="destroyblob">
 <h1><a class="toc-backref" href="#id51">DestroyBlob</a></h1>
-<div class="section" id="id11">
+<section id="id11">
 <h2>Synopsis</h2>
 <pre class="literal-block">void DestroyBlob( <a class="reference external" href="../api/types.html#image">Image</a> *image );</pre>
-</div>
-<div class="section" id="id12">
+</section>
+<section id="id12">
 <h2>Description</h2>
 <p>DestroyBlob() deallocates memory associated with a blob.  The blob is
 a reference counted object so the object is only destroyed once its
@@ -248,15 +248,15 @@
 <dd><p>The image.</p>
 </dd>
 </dl>
-</div>
-</div>
-<div class="section" id="destroyblobinfo">
+</section>
+</section>
+<section id="destroyblobinfo">
 <h1><a class="toc-backref" href="#id52">DestroyBlobInfo</a></h1>
-<div class="section" id="id13">
+<section id="id13">
 <h2>Synopsis</h2>
 <pre class="literal-block">void DestroyBlobInfo( <a class="reference external" href="../api/types.html#blobinfo">BlobInfo</a> *blob );</pre>
-</div>
-<div class="section" id="id14">
+</section>
+<section id="id14">
 <h2>Description</h2>
 <p>DestroyBlobInfo() deallocates memory associated with an BlobInfo structure.
 The blob is a reference counted object so the object is only destroyed once
@@ -271,15 +271,15 @@
 <dd><p>Specifies a pointer to a BlobInfo structure.</p>
 </dd>
 </dl>
-</div>
-</div>
-<div class="section" id="detachblob">
+</section>
+</section>
+<section id="detachblob">
 <h1><a class="toc-backref" href="#id53">DetachBlob</a></h1>
-<div class="section" id="id15">
+<section id="id15">
 <h2>Synopsis</h2>
 <pre class="literal-block">void DetachBlob( <a class="reference external" href="../api/types.html#blobinfo">BlobInfo</a> *blob_info );</pre>
-</div>
-<div class="section" id="id16">
+</section>
+<section id="id16">
 <h2>Description</h2>
 <p>DetachBlob() detaches a blob from the BlobInfo structure.</p>
 <p>The format of the DetachBlob method is:</p>
@@ -290,15 +290,15 @@
 <dd><p>Specifies a pointer to a BlobInfo structure.</p>
 </dd>
 </dl>
-</div>
-</div>
-<div class="section" id="filetoblob">
+</section>
+</section>
+<section id="filetoblob">
 <h1><a class="toc-backref" href="#id54">FileToBlob</a></h1>
-<div class="section" id="id17">
+<section id="id17">
 <h2>Synopsis</h2>
 <pre class="literal-block">void *FileToBlob( const char *filename, size_t *length, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );</pre>
-</div>
-<div class="section" id="id18">
+</section>
+<section id="id18">
 <h2>Description</h2>
 <p>FileToBlob() returns the contents of a file in a buffer allocated via
 MagickMalloc() (which is equivalent to the system malloc() by default).
@@ -326,15 +326,15 @@
 <dd><p>Return any errors or warnings in this structure.</p>
 </dd>
 </dl>
-</div>
-</div>
-<div class="section" id="getblobfilehandle">
+</section>
+</section>
+<section id="getblobfilehandle">
 <h1><a class="toc-backref" href="#id55">GetBlobFileHandle</a></h1>
-<div class="section" id="id19">
+<section id="id19">
 <h2>Synopsis</h2>
 <pre class="literal-block">FILE *GetBlobFileHandle( const <a class="reference external" href="../api/types.html#image">Image</a> *image );</pre>
-</div>
-<div class="section" id="id20">
+</section>
+<section id="id20">
 <h2>Description</h2>
 <p>GetBlobFileHandle() returns the stdio file handle associated with the
 image blob.  If there is no associated file handle, then a null pointer
@@ -347,15 +347,15 @@
 <dd><p>Image to query</p>
 </dd>
 </dl>
-</div>
-</div>
-<div class="section" id="getblobinfo">
+</section>
+</section>
+<section id="getblobinfo">
 <h1><a class="toc-backref" href="#id56">GetBlobInfo</a></h1>
-<div class="section" id="id21">
+<section id="id21">
 <h2>Synopsis</h2>
 <pre class="literal-block">void GetBlobInfo( <a class="reference external" href="../api/types.html#blobinfo">BlobInfo</a> *blob_info );</pre>
-</div>
-<div class="section" id="id22">
+</section>
+<section id="id22">
 <h2>Description</h2>
 <p>GetBlobInfo() initializes the BlobInfo structure.</p>
 <p>The format of the GetBlobInfo method is:</p>
@@ -366,15 +366,15 @@
 <dd><p>Specifies a pointer to a BlobInfo structure.</p>
 </dd>
 </dl>
-</div>
-</div>
-<div class="section" id="getblobstatus">
+</section>
+</section>
+<section id="getblobstatus">
 <h1><a class="toc-backref" href="#id57">GetBlobStatus</a></h1>
-<div class="section" id="id23">
+<section id="id23">
 <h2>Synopsis</h2>
 <pre class="literal-block">int GetBlobStatus( const <a class="reference external" href="../api/types.html#image">Image</a> *image );</pre>
-</div>
-<div class="section" id="id24">
+</section>
+<section id="id24">
 <h2>Description</h2>
 <p>GetBlobStatus() returns the blob error status.  For GraphicsMagick
 1.3.26 and earlier, this was only set by CloseBlob() but now it is
@@ -387,15 +387,15 @@
 <dd><p>The image.</p>
 </dd>
 </dl>
-</div>
-</div>
-<div class="section" id="getblobfirsterrno">
+</section>
+</section>
+<section id="getblobfirsterrno">
 <h1><a class="toc-backref" href="#id58">GetBlobFirstErrno</a></h1>
-<div class="section" id="id25">
+<section id="id25">
 <h2>Synopsis</h2>
 <pre class="literal-block">int GetBlobFirstErrno( const <a class="reference external" href="../api/types.html#image">Image</a> *image );</pre>
-</div>
-<div class="section" id="id26">
+</section>
+<section id="id26">
 <h2>Description</h2>
 <p>GetBlobFirstErrno() returns the errno present (if any) when the blob
 first encountered as error, as indicated by GetBlobStatus().  The
@@ -409,15 +409,15 @@
 <dd><p>The image.</p>
 </dd>
 </dl>
-</div>
-</div>
-<div class="section" id="getblobstreamdata">
+</section>
+</section>
+<section id="getblobstreamdata">
 <h1><a class="toc-backref" href="#id59">GetBlobStreamData</a></h1>
-<div class="section" id="id27">
+<section id="id27">
 <h2>Synopsis</h2>
 <pre class="literal-block">unsigned char *GetBlobStreamData( const <a class="reference external" href="../api/types.html#image">Image</a> *image );</pre>
-</div>
-<div class="section" id="id28">
+</section>
+<section id="id28">
 <h2>Description</h2>
 <p>GetBlobStreamData() returns the stream data for the image. The data is only
 available if the data is stored on the heap, or is memory mapped.
@@ -430,15 +430,15 @@
 <dd><p>The image.</p>