[rt #69147] detect and use snprintf() more
authorTony Cook <tony@develop-help.com>
Sun, 21 Aug 2011 01:41:00 +0000 (11:41 +1000)
committerTony Cook <tony@develop-help.com>
Sun, 21 Aug 2011 01:41:00 +0000 (11:41 +1000)
Changes
FT2/freetyp2.c
GIF/imgif.c
JPEG/imexif.c
Makefile.PL
TIFF/imtiff.c
error.c
imageri.h
io.c
log.c

diff --git a/Changes b/Changes
index 98062ca..470d896 100644 (file)
--- a/Changes
+++ b/Changes
@@ -29,6 +29,10 @@ Bug fixes:
    modernize the tests a bit.
    https://rt.cpan.org/Ticket/Display.html?id=70126
 
+ - detect snprintf()/vsnprintf() (cheat by using Config.pm) and use
+   them when available.
+   https://rt.cpan.org/Ticket/Display.html?id=69147
+
 Imager 0.84_01 - 8 Aug 2011
 ==============
 
index 2249bba..fc060ef 100644 (file)
@@ -897,14 +897,22 @@ Pushes an error message corresponding to code onto the error stack.
 
 =cut
 */
-static void ft2_push_message(int code) {
+
+#define UNKNOWN_ERROR_FORMAT "Unknown Freetype2 error code 0x%04X"
+
+static void
+ft2_push_message(int code) {
   char unknown[40];
 
   switch (code) {
 #include FT_ERRORS_H
   }
 
-  sprintf(unknown, "Unknown Freetype2 error code 0x%04X\n", code);
+#ifdef IMAGER_SNPRINTF
+  snprintf(unknown, sizeof(unknown), UNKNOWN_ERROR_FORMAT, code);
+#else
+  sprintf(unknown, UNKNOWN_ERROR_FORMAT, code);
+#endif
   i_push_error(code, unknown);
 }
 
index 27668ef..4e1234b 100644 (file)
@@ -1037,7 +1037,11 @@ static int do_comments(GifFileType *gf, i_img *img) {
     }
     else {
       char buf[50];
+#ifdef IMAGER_SNPRINTF
+      snprintf(buf, sizeof(buf), "%d", img->tags.tags[pos].idata);
+#else
       sprintf(buf, "%d", img->tags.tags[pos].idata);
+#endif
       if (EGifPutComment(gf, buf) == GIF_ERROR) {
         return 0;
       }
@@ -1887,7 +1891,11 @@ static char const *gif_error_msg(int code) {
     return "Unexpected EOF - invalid file";
 
   default:
+#ifdef IMAGER_SNPRINTF
+    snprintf(msg, sizeof(msg), "Unknown giflib error code %d", code);
+#else
     sprintf(msg, "Unknown giflib error code %d", code);
+#endif
     return msg;
   }
 }
index 07f75b8..2f61d4e 100644 (file)
@@ -1299,14 +1299,26 @@ copy_num_array_tags(i_img *im, imtiff *tiff, tag_map *map, int map_count) {
          double value;
          char workstr[MAX_ARRAY_STRING];
          *workstr = '\0';
+         size_t len = 0, item_len;
          for (j = 0; j < entry->count; ++j) {
            if (!tiff_get_tag_double_array(tiff, tag_index, &value, j)) {
              mm_log((3, "unexpected failure from tiff_get_tag_double_array(..., %d, ..., %d)\n", tag_index, j));
              return;
            }
-           if (j) 
+           if (len >= sizeof(workstr) - 1) {
+             mm_log((3, "Buffer would overflow reading tag %#x\n", entry->tag));
+             return;
+           }
+           if (j) {
              strcat(workstr, " ");
-           sprintf(workstr + strlen(workstr), "%.6g", value);
+             ++len;
+           }
+#ifdef IMAGER_SNPRINTF
+           item_len = snprintf(workstr + len, sizeof(workstr)-len, "%.6g", value);
+#else
+           item_len = sprintf(workstr + len, "%.6g", value);
+#endif
+           len += item_len;
          }
          i_tags_set(&im->tags, map[i].name, workstr, -1);
        }
@@ -1315,15 +1327,27 @@ copy_num_array_tags(i_img *im, imtiff *tiff, tag_map *map, int map_count) {
                 || entry->type == ift_byte) {
          int value;
          char workstr[MAX_ARRAY_STRING];
+         size_t len = 0, item_len;
          *workstr = '\0';
          for (j = 0; j < entry->count; ++j) {
            if (!tiff_get_tag_int_array(tiff, tag_index, &value, j)) {
              mm_log((3, "unexpected failure from tiff_get_tag_int_array(..., %d, ..., %d)\n", tag_index, j));
              return;
            }
-           if (j) 
+           if (len >= sizeof(workstr) - 1) {
+             mm_log((3, "Buffer would overflow reading tag %#x\n", entry->tag));
+             return;
+           }
+           if (j) {
              strcat(workstr, " ");
-           sprintf(workstr + strlen(workstr), "%d", value);
+             ++len;
+           }
+#ifdef IMAGER_SNPRINTF
+           item_len = snprintf(workstr + len, sizeof(workstr) - len, "%d", value);
+#else
+           item_len = sprintf(workstr + len, "%d", value);
+#endif
+           len += item_len;
          }
          i_tags_set(&im->tags, map[i].name, workstr, -1);
        }
index 7ecc5e8..d85bd5b 100644 (file)
@@ -589,6 +589,22 @@ Compiler supports the GCC __attribute__((format...)) syntax.
 
 #define IMAGER_FORMAT_ATTR 1
 
+EOS
+  }
+
+  if ($Config{d_snprintf}) {
+    print CONFIG <<EOS;
+/* We can use snprintf() */
+#define IMAGER_SNPRINTF 1
+
+EOS
+  }
+
+  if ($Config{d_vsnprintf}) {
+    print CONFIG <<EOS;
+/* We can use vsnprintf() */
+#define IMAGER_VSNPRINTF 1
+
 EOS
   }
 
index 59c5173..07e363c 100644 (file)
@@ -184,7 +184,7 @@ static void warn_handler(char const *module, char const *fmt, va_list ap) {
   char buf[1000];
 
   buf[0] = '\0';
-#ifdef HAVE_SNPRINTF
+#ifdef IMAGER_VSNPRINTF
   vsnprintf(buf, sizeof(buf), fmt, ap);
 #else
   vsprintf(buf, fmt, ap);
diff --git a/error.c b/error.c
index 48de989..84785a2 100644 (file)
--- a/error.c
+++ b/error.c
@@ -260,7 +260,9 @@ Does not support perl specific format codes.
 */
 void i_push_errorvf(int code, char const *fmt, va_list ap) {
   char buf[1024];
-#if defined(_MSC_VER)
+#if defined(IMAGER_VSNPRINTF)
+  vsnprintf(buf, sizeof(buf), fmt, ap);
+#elif defined(_MSC_VER)
   _vsnprintf(buf, sizeof(buf), fmt, ap);
 #else
   /* is there a way to detect vsnprintf()? 
index 08fdd19..9b07315 100644 (file)
--- a/imageri.h
+++ b/imageri.h
@@ -53,12 +53,6 @@ extern void i_get_combine(int combine, i_fill_combine_f *, i_fill_combinef_f *);
 
 extern UTIL_table_t i_UTIL_table;
 
-/* Ideally this will move into imconfig.h if we ever probe */
-#if defined(_GNU_SOURCE) || __STDC_VERSION__ >= 199901L
-/* snprintf() is part of C99 and provided by Glibc */
-#define HAVE_SNPRINTF
-#endif
-
 /* test if all channels are writable */
 #define I_ALL_CHANNELS_WRITABLE(im) (((im)->ch_mask & 0xF) == 0xf)
 
diff --git a/io.c b/io.c
index 82efec9..4e78cd7 100644 (file)
--- a/io.c
+++ b/io.c
@@ -69,7 +69,12 @@ set_entry(int i, char *buf, size_t size, char *file, int line) {
   buf += UNDRRNVAL;
   malloc_pointers[i].ptr  = buf;
   malloc_pointers[i].size = size;
+#ifdef IMAGER_SNPRINTF
+  snprintf(malloc_pointers[i].comm, sizeof(malloc_pointers[i].comm), 
+          "%s (%d)", file, line);
+#else
   sprintf(malloc_pointers[i].comm,"%s (%d)", file, line);
+#endif
   return buf;
 }
 
diff --git a/log.c b/log.c
index 0a807e7..1306e18 100644 (file)
--- a/log.c
+++ b/log.c
@@ -104,7 +104,11 @@ i_lhead(const char *file, int line) {
     timi = time(NULL);
     str_tm = localtime(&timi);
     strftime(date_buffer, DTBUFF, date_format, str_tm);
+#ifdef IMAGER_SNPRINTF
+    snprintf(data_buffer, sizeof(data_buffer), "[%s] %10s:%-5d ", date_buffer, file, line);
+#else
     sprintf(data_buffer, "[%s] %10s:%-5d ", date_buffer, file, line);
+#endif
   }
 }