From: David Flynn Date: Wed, 1 Apr 2009 21:40:03 +0000 (+0000) Subject: win32: vlc_fix_format_string - various fixes X-Git-Tag: 1.0.0-pre2~255 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=3779d5bd1c335d724b31ce730a8387cb7770fc06;p=vlc win32: vlc_fix_format_string - various fixes - 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 Signed-off-by: Jean-Baptiste Kempf --- diff --git a/include/vlc_fixups.h b/include/vlc_fixups.h index 02cf88c804..6088eb5a9f 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 # include -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 @@ -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