[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 98062caae200a69484ef07816ec54c0c7f192218..470d89643f3fad67660d38d75f66ad897e04d64a 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 2249bbacfd7068d4b7f1d3a684c495908edbd41d..fc060efdb1c521a091f1017210af146868338325 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 27668ef919a04799ad3c917cb15f4a551154e0e0..4e1234bbd3013175c928a43f698bb7258b34c962 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 07f75b87f8dd1a44a21bfbc8c796e61e39ffa3b2..2f61d4ec24a0a5e604fe217e96efbdecae36d89d 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 7ecc5e84fb6a6e8855640a0d8706b8de090f687b..d85bd5bb72e7c2c1e3062b6e4611ee50f0d3b4f8 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 59c5173c93c7dac3e001ee1c2d83a219d9d169bd..07e363cb98864a350e6f55b9c02271fa22b7baf8 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 48de989a5510d04cb892e8cea9720c2c607b9151..84785a2a2fd59d0a188b979198b84e55ec8cb991 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 08fdd19571e8e3506d26ca671cf9d517e95745c6..9b07315b8124d3e1392cd28cab50794b73182fb2 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 82efec962b9b5e86e1cc1ae759f4c19c89feca77..4e78cd78f20b4fdbc8e9d9dbd64735610805f669 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 0a807e7086919aaa1f1590cff29d97d354d6fa2f..1306e1898385e5b29d5dfb05866a0b897d7b2bf5 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
   }
 }