DO NOT REPLY TO THIS MESSAGE.  INSTEAD, POST ANY RESPONSES TO THE LINK BELOW.

[STR New]

Link: http://www.fltk.org/str.php?L2398
Version: 2.0-current


This isn't an overly critical patch to the image test functions (which are
spread as thinly and over as many files as last night's pumpkin
soup.....), but, as far as I'm aware, there's no standard to suggests that
memcmp() *has* to stop when it reaches a null character, or even when it
meets the first differing character (IIRC, it's allowed to compare all n
characters if the implementation is done that way, or could potentially
compare garbage data to be equal and continue). Whilst this is done
sensibly in most implementations, I believe that it's a safer option to
keep these as strncmp() and let the compiler deal with it's own
implementation (in most cases, especially with gcc, AFAIK strncmp is
turned into a memcmp anyway, so it's not going to create much of a
difference in most systems).

Beyond this, gifImage::test() had only a half-test for a GIF file,
jpegImage had no size check and could thus segfault on an overly small
file with a user-read header, xpmFileImage::test() also only had a
half-test for an XPM image as well as no size checking, so on.

Tested and working on my i386 ubuntu; not that I'd expect otherwise given
the small fixes this patch makes.
It certainly makes the code far more logical though.....


Link: http://www.fltk.org/str.php?L2398
Version: 2.0-current
Index: src/gifImage.cxx
===================================================================
--- src/gifImage.cxx    (revision 7677)
+++ src/gifImage.cxx    (working copy)
@@ -59,7 +59,7 @@
 /*! Tests block of data to see if it looks like the start of a .gif file. */
 bool gifImage::test(const uchar *datas, unsigned size)
 {
-  return !strncmp((char*) datas,"GIF", 3);
+  return !strncmp((char*) datas,"GIF87a", (size < 6) ? size : 6) || 
!strncmp((char*) datas, "GIF89a", (size < 6) ? size : 6);
 }
 
 bool gifImage::fetch()
Index: src/bmpImage.cxx
===================================================================
--- src/bmpImage.cxx    (revision 7677)
+++ src/bmpImage.cxx    (working copy)
@@ -88,7 +88,7 @@
 
 bool bmpImage::test(const uchar* buffer, unsigned size)
 {
-  return !strncmp((char*)buffer, "BM", size<2? size:2);
+  return !strncmp((char*)buffer, "BM", (size < 2) ? size : 2);
 }
 
 //
Index: src/SharedImage.cxx
===================================================================
--- src/SharedImage.cxx (revision 7677)
+++ src/SharedImage.cxx (working copy)
@@ -180,10 +185,9 @@
   }
 
   // Load the image as appropriate...
-  if (memcmp(header, "BM", 2) == 0)    // BMP file
+  if (bmpImage::test(header, sizeof(header)))  // BMP file
       img = bmpImage::get(n);
-  else if (memcmp(header, "GIF87a", 6) == 0 ||
-      memcmp(header, "GIF89a", 6) == 0)        // GIF file
+  else if (gifImage::test(header, sizeof(header)))     // GIF file
     img = gifImage::get(n);
   else {
     // Not a standard format; try an image handler...
Index: images/fl_jpeg.cxx
===================================================================
--- images/fl_jpeg.cxx  (revision 7677)
+++ images/fl_jpeg.cxx  (working copy)
@@ -308,13 +410,7 @@
 
 bool jpegImage::test(const uchar* block, unsigned size)
 {
-// I don't know what the official test for jpeg is. There appears to
-// be some complexity at the start, probably they assumme you will use
-// a jpeg_decompress object. These 3 bytes are the only constant between
-// all the example files I have seen:
-  return block[0] == 0xff && block[1] == 0xd8 && block[2] == 0xff;
-//   return (!strcmp((char*)block+6, "JFIF") ||
-//       !strcmp((char*)block+6, "Exif"));
+  return !strncmp((char*)block, "\xff\xd8", (size < 2) ? size : 2);
 }
 
 //
Index: images/xpmFileImage.cxx
===================================================================
--- images/xpmFileImage.cxx     (revision 7677)
+++ images/xpmFileImage.cxx     (working copy)
@@ -126,9 +126,9 @@
   looks like the start of a .xpm file. This returns true if the 
   data contains "/\* XPM".
 */
-bool xpmFileImage::test(const unsigned char *data, unsigned)
+bool xpmFileImage::test(const unsigned char *data, unsigned size)
 {
-  return (strstr((char*) data,"/* XPM") != 0);
+  return !strncmp((char*) data,"/* XPM */", (size < 9) ? size : 9);
 }
 
 bool xpmFileImage::fetch()
Index: images/images_core.cxx
===================================================================
--- images/images_core.cxx      (revision 7677)
+++ images/images_core.cxx      (working copy)
@@ -30,17 +30,16 @@
 using namespace fltk;
 
 static SharedImage *check(const char *name, uchar *header, int headerlen) {
-  if (memcmp(header, "/* XPM */", 9) == 0) // XPM file
+  if (xpmFileImage::test(header, headerlen)) // XPM file
       return xpmFileImage::get(name);
 
 //if (header[0]=='P' && header[1]>='1' && header[1]<='7') // Portable anymap
 //  return new Fl_PNM_Image(name);
 
-  if (memcmp(header, "\211PNG", 4) == 0)// PNG file
+  if (pngImage::test(header, headerlen)) // PNG file
     return pngImage::get(name);
 
-  if (memcmp(header, "\377\330\377", 3) == 0 && // Start-of-Image
-      header[3] >= 0xe0 && header[3] <= 0xef)  // APPn for JPEG file
+  if (jpegImage::test(header, headerlen)) // JPEG file
     return jpegImage::get(name);
 
   return 0;
_______________________________________________
fltk-bugs mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-bugs

Reply via email to