From f71ea4dfe95a2ee98ea49bca77394a9b5bd1769b Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Thu, 8 Jun 2017 22:53:16 +0300 Subject: [PATCH] Merge pull request #8816 from mshabunin:sprintf-fix Fixed snprintf for VS 2013 (#8816) * Fixed snprintf for VS 2013 * snprintf: removed declaration from header, changed implementation * cv_snprintf corrected according to comments * update snprintf patch --- modules/core/src/lpsolver.cpp | 1 - modules/core/src/out.cpp | 2 +- modules/core/src/precomp.hpp | 3 +++ modules/core/src/system.cpp | 43 +++++++++++++++++++++-------------- 4 files changed, 30 insertions(+), 19 deletions(-) diff --git a/modules/core/src/lpsolver.cpp b/modules/core/src/lpsolver.cpp index 6c53108c49..e5f4d99739 100644 --- a/modules/core/src/lpsolver.cpp +++ b/modules/core/src/lpsolver.cpp @@ -41,7 +41,6 @@ #include "precomp.hpp" #include #include -#include #define dprintf(x) #define print_matrix(x) diff --git a/modules/core/src/out.cpp b/modules/core/src/out.cpp index 13c2b8f034..77c55aba82 100644 --- a/modules/core/src/out.cpp +++ b/modules/core/src/out.cpp @@ -103,7 +103,7 @@ namespace cv } else { - snprintf(floatFormat, 8, "%%.%dg", std::min(precision, 20)); + cv_snprintf(floatFormat, sizeof(floatFormat), "%%.%dg", std::min(precision, 20)); } switch(mtx.depth()) diff --git a/modules/core/src/precomp.hpp b/modules/core/src/precomp.hpp index 98b115a3fe..5fa2a742c6 100644 --- a/modules/core/src/precomp.hpp +++ b/modules/core/src/precomp.hpp @@ -65,6 +65,7 @@ #include #include #include +#include #include #include #include @@ -319,6 +320,8 @@ cv::Mutex& getInitializationMutex(); #define CV_SINGLETON_LAZY_INIT(TYPE, INITIALIZER) CV_SINGLETON_LAZY_INIT_(TYPE, INITIALIZER, instance) #define CV_SINGLETON_LAZY_INIT_REF(TYPE, INITIALIZER) CV_SINGLETON_LAZY_INIT_(TYPE, INITIALIZER, *instance) +int cv_snprintf(char* buf, int len, const char* fmt, ...); +int cv_vsnprintf(char* buf, int len, const char* fmt, va_list args); } #endif /*_CXCORE_INTERNAL_H_*/ diff --git a/modules/core/src/system.cpp b/modules/core/src/system.cpp index 6706306bb6..2dc11a0105 100644 --- a/modules/core/src/system.cpp +++ b/modules/core/src/system.cpp @@ -196,8 +196,6 @@ std::wstring GetTempFileNameWinRT(std::wstring prefix) #include "omp.h" #endif -#include - #if defined __linux__ || defined __APPLE__ || defined __EMSCRIPTEN__ || defined __FreeBSD__ #include #include @@ -752,16 +750,13 @@ String format( const char* fmt, ... ) va_list va; va_start(va, fmt); int bsize = static_cast(buf.size()); -#if defined _MSC_VER && __cplusplus < 201103L - int len = _vsnprintf_s((char *)buf, bsize, _TRUNCATE, fmt, va); -#else - int len = vsnprintf((char *)buf, bsize, fmt, va); -#endif + int len = cv_vsnprintf((char *)buf, bsize, fmt, va); va_end(va); - if (len < 0 || len >= bsize) + CV_Assert(len >= 0 && "Check format string for errors"); + if (len >= bsize) { - buf.resize(std::max(bsize << 1, len + 1)); + buf.resize(len + 1); continue; } buf[bsize - 1] = 0; @@ -856,19 +851,33 @@ bool setBreakOnError(bool value) return prevVal; } -static bool cv_snprintf(char* buf, int len, const char* fmt, ...) +int cv_snprintf(char* buf, int len, const char* fmt, ...) { va_list va; va_start(va, fmt); -#if defined _MSC_VER && __cplusplus < 201103L - int res = _vsnprintf_s((char *)buf, len - 1, _TRUNCATE, fmt, va); + int res = cv_vsnprintf(buf, len, fmt, va); va_end(va); - buf[len - 1] = 0; - return res >= 0 && res < len - 1; + return res; +} + +int cv_vsnprintf(char* buf, int len, const char* fmt, va_list args) +{ +#if defined _MSC_VER + if (len <= 0) return len == 0 ? 1024 : -1; + int res = _vsnprintf_s(buf, len, _TRUNCATE, fmt, args); + // ensure null terminating on VS + if (res >= 0 && res < len) + { + buf[res] = 0; + return res; + } + else + { + buf[len - 1] = 0; // truncate happened + return res >= len ? res : (len * 2); + } #else - int res = vsnprintf((char *)buf, len, fmt, va); - va_end(va); - return res >= 0 && res < len; + return vsnprintf(buf, len, fmt, args); #endif }