[vlc-devel] [PATCH 5/5] win32: vlc_fix_format_string - various fixes
davidf+nntp at woaf.net
davidf+nntp at woaf.net
Thu Mar 26 15:22:32 CET 2009
From: David Flynn <davidf at rd.bbc.co.uk>
- avoid mingw problems with %l*
- avoid using %I32 on Win32, since wince doesn't support it
- unify WIN64 and WIN32 cases.
- if malloc were to fail(!), don't allow unfiltered format string
to get passed to *printf.
(substitues an error message)
Signed-off-by: David Flynn <davidf at rd.bbc.co.uk>
---
include/vlc_fixups.h | 94 +++++++++++++++++++++++++------------------------
1 files changed, 48 insertions(+), 46 deletions(-)
diff --git a/include/vlc_fixups.h b/include/vlc_fixups.h
index 02cf88c..6088eb5 100644
--- a/include/vlc_fixups.h
+++ b/include/vlc_fixups.h
@@ -39,56 +39,58 @@ static inline char *strdup (const char *str)
#endif
#ifdef WIN32
-/* Windows' printf doesn't support %z modifiers, thus we need to rewrite
- * the format string in a wrapper. */
# include <string.h>
# include <stdlib.h>
-static inline char *vlc_fix_format_string (const char *format)
+/**
+ * vlc_fix_format_string:
+ * @format: address of format string to fix (format string is not modified)
+ *
+ * Windows' printf doesn't support %z size modifiers.
+ * Fix a *printf format string to make it safe for mingw/MSVCRT run times:
+ * %z* (not supported in MSVCRT) -> either %I64* or %I32.
+ *
+ * Returns: 1 if *format must be free()d; 0 otherwise
+ */
+static inline int vlc_fix_format_string (const char **format)
{
- char *fmt;
-# ifdef WIN64
- const char *src = format, *tmp;
- char *dst;
- size_t n = 0;
- while ((tmp = strstr (src, "%z")) != NULL)
+ int n = 0;
+ const char *tmp = *format;
+ while ((tmp = strstr (tmp, "%z")) != NULL)
{
n++;
- src = tmp + 2;
+ tmp += 2;
}
- if (n == 0)
- return NULL;
+ if (!n)
+ return 0;
- fmt = (char*)malloc (strlen (format) + n + 1);
- if (fmt == NULL)
- return NULL;
+ char *dst = (char*)malloc (strlen (*format) + 2*n + 1);
+ if (!dst)
+ {
+ *format = "vlc_fix_format_string: due to malloc failure, unable to fix unsafe string";
+ return 0;
+ }
- src = format;
- dst = fmt;
+ const char *src = *format;
+ *format = dst;
while ((tmp = strstr (src, "%z")) != NULL)
{
+ /* NB, don't use %l*, as this is buggy in mingw*/
size_t d = tmp - src;
memcpy (dst, src, d);
dst += d;
- memcpy (dst, "%ll", 3);
- dst += 3;
+ *dst++ = '%';
+# ifdef WIN64
+ *dst++ = 'I';
+ *dst++ = '6';
+ *dst++ = '4';
+# else /* ie: WIN32 */
+ /* on win32, since the default size is 32bit, dont specify
+ * a modifer. (I32 isn't on wince, l doesn't work on mingw) */
+# endif
src = tmp + 2;
}
strcpy (dst, src);
-# else
- char *f;
- if (strstr (format, "%z") == NULL)
- return NULL;
-
- fmt = strdup (format);
- if (fmt == NULL)
- return NULL;
-
- while ((f = strstr (fmt, "%z")) != NULL)
- {
- f[1] = 'l';
- }
-# endif
- return fmt;
+ return 1;
}
# include <stdio.h>
@@ -96,40 +98,40 @@ static inline char *vlc_fix_format_string (const char *format)
static inline int vlc_vprintf (const char *format, va_list ap)
{
- char *fmt = vlc_fix_format_string (format);
- int ret = vprintf (fmt ? fmt : format, ap);
- free (fmt);
+ int must_free = vlc_fix_format_string (&format);
+ int ret = vprintf (format, ap);
+ if (must_free) free ((char *)format);
return ret;
}
# define vprintf vlc_vprintf
static inline int vlc_vfprintf (FILE *stream, const char *format, va_list ap)
{
- char *fmt = vlc_fix_format_string (format);
- int ret = vfprintf (stream, fmt ? fmt : format, ap);
- free (fmt);
+ int must_free = vlc_fix_format_string (&format);
+ int ret = vfprintf (stream, format, ap);
+ if (must_free) free ((char *)format);
return ret;
}
# define vfprintf vlc_vfprintf
static inline int vlc_vsprintf (char *str, const char *format, va_list ap)
{
- char *fmt = vlc_fix_format_string (format);
- int ret = vsprintf (str, fmt ? fmt : format, ap);
- free (fmt);
+ int must_free = vlc_fix_format_string (&format);
+ int ret = vsprintf (str, format, ap);
+ if (must_free) free ((char *)format);
return ret;
}
# define vsprintf vlc_vsprintf
static inline int vlc_vsnprintf (char *str, size_t size, const char *format, va_list ap)
{
- char *fmt = vlc_fix_format_string (format);
+ int must_free = vlc_fix_format_string (&format);
/* traditionally, MSVCRT has provided vsnprintf as _vsnprintf;
* to 'aid' portability/standards compliance, mingw provides a
* static version of vsnprintf that is buggy. Be sure to use
* MSVCRT version, at least it behaves as expected */
- int ret = _vsnprintf (str, size, fmt ? fmt : format, ap);
- free (fmt);
+ int ret = _vsnprintf (str, size, format, ap);
+ if (must_free) free ((char *)format);
return ret;
}
# define vsnprintf vlc_vsnprintf
--
1.5.6.5
More information about the vlc-devel
mailing list