[x264-devel] msvc: Add snprintf/vsnprintf replacements

Henrik Gramner git at videolan.org
Tue Apr 12 20:36:14 CEST 2016


x264 | branch: master | Henrik Gramner <henrik at gramner.com> | Mon Apr 11 16:59:46 2016 +0200| [215afdbd8ecc924f2028f79851458076683e97ad] | committer: Henrik Gramner

msvc: Add snprintf/vsnprintf replacements

MSVC pre-VS2015 has broken snprintf/vsnprintf implementations which are
incompatible with C99 and may lead to buffer overflows.

> http://git.videolan.org/gitweb.cgi/x264.git/?a=commit;h=215afdbd8ecc924f2028f79851458076683e97ad
---

 common/osdep.c |   35 +++++++++++++++++++++++++++++++++++
 common/osdep.h |    5 ++++-
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/common/osdep.c b/common/osdep.c
index 074a1f3..81301f5 100644
--- a/common/osdep.c
+++ b/common/osdep.c
@@ -168,4 +168,39 @@ int x264_is_pipe( const char *path )
     return 0;
 }
 #endif
+
+#if defined(_MSC_VER) && _MSC_VER < 1900
+/* MSVC pre-VS2015 has broken snprintf/vsnprintf implementations which are incompatible with C99. */
+int x264_snprintf( char *s, size_t n, const char *fmt, ... )
+{
+    va_list arg;
+    va_start( arg, fmt );
+    int length = x264_vsnprintf( s, n, fmt, arg );
+    va_end( arg );
+    return length;
+}
+
+int x264_vsnprintf( char *s, size_t n, const char *fmt, va_list arg )
+{
+    int length = -1;
+
+    if( n )
+    {
+        va_list arg2;
+        va_copy( arg2, arg );
+        length = _vsnprintf( s, n, fmt, arg2 );
+        va_end( arg2 );
+
+        /* _(v)snprintf adds a null-terminator only if the length is less than the buffer size. */
+        if( length < 0 || length >= n )
+            s[n-1] = '\0';
+    }
+
+    /* _(v)snprintf returns a negative number if the length is greater than the buffer size. */
+    if( length < 0 )
+        return _vscprintf( fmt, arg );
+
+    return length;
+}
+#endif
 #endif
diff --git a/common/osdep.h b/common/osdep.h
index 995d03c..520710a 100644
--- a/common/osdep.h
+++ b/common/osdep.h
@@ -55,7 +55,10 @@
 #define strtok_r strtok_s
 #define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
 #if _MSC_VER < 1900
-#define snprintf _snprintf
+int x264_snprintf( char *s, size_t n, const char *fmt, ... );
+int x264_vsnprintf( char *s, size_t n, const char *fmt, va_list arg );
+#define snprintf  x264_snprintf
+#define vsnprintf x264_vsnprintf
 #endif
 #endif
 



More information about the x264-devel mailing list