{"thread":{"id":"12519","subject":"[PATCH v2] Add compat/snprintf.c for systems that return bogus","startedAt":"2008-03-05T15:46:13Z","lastAt":"2008-03-05T15:46:13Z","messageCount":1,"participants":["Michal Rokos"],"isPatch":true,"patchVersion":2,"patchTotal":null},"messages":[{"id":"71087","messageId":"200803051646.13343.michal.rokos@nextsoft.cz","threadId":"12519","inReplyTo":null,"subject":"[PATCH v2] Add compat/snprintf.c for systems that return bogus","fromName":"Michal Rokos","fromEmail":"michal.rokos@nextsoft.cz","sentAt":"2008-03-05T15:46:13Z","receivedAt":"2008-03-05T15:46:13Z","isPatch":true,"sender":{"key":"michal.rokos@nextsoft.cz","avatar":null},"body":"Some systems (namely HPUX and Windows) return -1 when maxsize in snprintf() \nand in vsnprintf() is reached. So replace snprintf() and vsnprintf() \nfunctions with our own ones that return correct value upon overflow.\n\nSigned-off-by: Michal Rokos <michal.rokos@nextsoft.cz>\n\ndiff --git a/Makefile b/Makefile\nindex ca5aad9..6af7132 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -3,6 +3,10 @@ all::\n \n # Define V=1 to have a more verbose compile.\n #\n+# Define SNPRINTF_RETURNS_BOGUS if your are on a system which snprintf()\n+# or vsnprintf() return -1 instead of number of characters which would\n+# have been written to the final string if enough space had been available.\n+#\n # Define FREAD_READS_DIRECTORIES if your are on a system which succeeds\n # when attempting to read from an fopen'ed directory.\n #\n@@ -629,6 +633,10 @@ endif\n ifdef NO_C99_FORMAT\n \tBASIC_CFLAGS += -DNO_C99_FORMAT\n endif\n+ifdef SNPRINTF_RETURNS_BOGUS\n+\tCOMPAT_CFLAGS += -DSNPRINTF_RETURNS_BOGUS\n+\tCOMPAT_OBJS += compat/snprintf.o\n+endif\n ifdef FREAD_READS_DIRECTORIES\n \tCOMPAT_CFLAGS += -DFREAD_READS_DIRECTORIES\n \tCOMPAT_OBJS += compat/fopen.o\ndiff --git a/config.mak.in b/config.mak.in\nindex ee6c33d..8e1cd5f 100644\n--- a/config.mak.in\n+++ b/config.mak.in\n@@ -46,3 +46,4 @@ NO_MKDTEMP=@NO_MKDTEMP@\n NO_ICONV=@NO_ICONV@\n OLD_ICONV=@OLD_ICONV@\n NO_DEFLATE_BOUND=@NO_DEFLATE_BOUND@\n+SNPRINTF_RETURNS_BOGUS=@SNPRINTF_RETURNS_BOGUS@\ndiff --git a/configure.ac b/configure.ac\nindex 85d7ef5..a3bbfa6 100644\n--- a/configure.ac\n+++ b/configure.ac\n@@ -326,6 +326,38 @@ else\n \tNO_C99_FORMAT=\n fi\n AC_SUBST(NO_C99_FORMAT)\n+#\n+# Define SNPRINTF_RETURNS_BOGUS if your are on a system which snprintf()\n+# or vsnprintf() return -1 instead of number of characters which would\n+# have been written to the final string if enough space had been available.\n+AC_CACHE_CHECK([whether snprintf() and/or vsnprintf() return bogus],\n+ [ac_cv_snprintf_returns_bogus],\n+[\n+AC_RUN_IFELSE(\n+\t[AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT\n+\t\t#include \"stdarg.h\"\n+\n+\t\tint test_vsnprintf(char *str, size_t maxsize, const char *format, ...)\n+\t\t{\n+\t\t  int ret;\n+\t\t  va_list ap;\n+\t\t  va_start(ap, format);\n+\t\t  ret = vsnprintf(str, maxsize, format, ap);\n+\t\t  va_end(ap);\n+\t\t  return ret;\n+\t\t}],\n+\t\t[[char buf[1];\n+\t\t  if (test_vsnprintf(buf, 1, \"%s\", \"12345\") != 5) return 1;\n+\t\t  if (snprintf(buf, 1, \"%s\", \"12345\") != 5) return 1]])],\n+\t[ac_cv_snprintf_returns_bogus=no],\n+\t[ac_cv_snprintf_returns_bogus=yes])\n+])\n+if test $ac_cv_snprintf_returns_bogus = yes; then\n+\tSNPRINTF_RETURNS_BOGUS=UnfortunatelyYes\n+else\n+\tSNPRINTF_RETURNS_BOGUS=\n+fi\n+AC_SUBST(SNPRINTF_RETURNS_BOGUS)\n \n \n ## Checks for library functions.\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex 2a40703..0aa04eb 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -209,6 +209,15 @@ void *gitmemmem(const void *haystack, size_t haystacklen,\n extern FILE *git_fopen(const char*, const char*);\n #endif\n \n+#ifdef SNPRINTF_RETURNS_BOGUS\n+#define snprintf git_snprintf\n+extern int git_snprintf(char *str, size_t maxsize,\n+                        const char *format, ...);\n+#define vsnprintf git_vsnprintf\n+extern int git_vsnprintf(char *str, size_t maxsize,\n+                         const char *format, va_list ap);\n+#endif\n+\n #ifdef __GLIBC_PREREQ\n #if __GLIBC_PREREQ(2, 1)\n #define HAVE_STRCHRNUL\ndiff --git a/dev/null b/compat/snprintf.c\nnew file mode 100644\nindex 0000000..dbfc2d6\n--- /dev/null\n+++ b/compat/snprintf.c\n@@ -0,0 +1,40 @@\n+#include \"../git-compat-util.h\"\n+\n+#undef vsnprintf\n+int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap)\n+{\n+\tchar *s;\n+\tint ret;\n+\n+\tret = vsnprintf(str, maxsize, format, ap);\n+\tif (ret != -1)\n+\t\treturn ret;\n+\n+\ts = NULL;\n+\tif (maxsize < 128)\n+\t\tmaxsize = 128;\n+\n+\twhile (ret == -1) {\n+\t\tmaxsize *= 4;\n+\t\tstr = realloc(s, maxsize);\n+\t\tif (! str)\n+\t\t\tbreak;\n+\t\ts = str;\n+\t\tret = vsnprintf(str, maxsize, format, ap);\n+\t}\n+\tfree(s);\n+\treturn ret;\n+}\n+\n+int git_snprintf(char *str, size_t maxsize, const char *format, ...)\n+{\n+\tva_list ap;\n+\tint ret;\n+\n+\tva_start(ap, format);\n+\tret = git_vsnprintf(str, maxsize, format, ap);\n+\tva_end(ap);\n+\n+\treturn ret;\n+}\n+\n\n-- \nMichal Rokos\n\nNextSoft s.r.o.\nVyskočilova 1/1410\n140 21 Praha 4\nphone:  +420 267 224 311\nfax:    +420 267 224 307\nmobile: +420 736 646 591\ne-mail: michal.rokos@nextsoft.cz\n"}]}