From fbe329bb701e855131be9bc093a048d8f4dd4944 Mon Sep 17 00:00:00 2001 From: Tsuda Kageyu Date: Wed, 1 May 2013 14:54:17 +0900 Subject: [PATCH] Use snprintf instead of sprintf if possible. --- ConfigureChecks.cmake | 14 +++++++++- config-taglib.h.cmake | 4 +++ taglib/mp4/mp4item.cpp | 59 ++++++++++++++++++++++++++++-------------- 3 files changed, 56 insertions(+), 21 deletions(-) diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake index c08f7377..42144de7 100644 --- a/ConfigureChecks.cmake +++ b/ConfigureChecks.cmake @@ -84,13 +84,25 @@ if(NOT HAVE_STD_SHARED_PTR AND NOT HAVE_TR1_SHARED_PTR AND NOT HAVE_BOOST_SHARED endif() endif() - # Determine whether your compiler supports codecvt header. check_cxx_source_compiles(" #include int main() { std::codecvt_utf8_utf16 x; return 0; } " HAVE_CODECVT) +# Determine whether your compiler supports some safer version of sprintf. +check_cxx_source_compiles(" + #include + int main() { char buf[20]; snprintf(buf, 20, \"%d\", 1); return 0; } +" HAVE_SNPRINTF) + +if(NOT HAVE_SNPRINTF) + check_cxx_source_compiles(" + #include + int main() { char buf[20]; sprintf_s(buf, \"%d\", 1); return 0; } + " HAVE_SPRINTF_S) +endif() + # check for libz using the cmake supplied FindZLIB.cmake find_package(ZLIB) if(ZLIB_FOUND) diff --git a/config-taglib.h.cmake b/config-taglib.h.cmake index 6d48cbf0..1e0adb37 100644 --- a/config-taglib.h.cmake +++ b/config-taglib.h.cmake @@ -14,6 +14,10 @@ #cmakedefine HAVE_WIN_ATOMIC 1 #cmakedefine HAVE_IA64_ATOMIC 1 +/* Defined if your compiler supports some safer version of sprintf */ +#cmakedefine HAVE_SNPRINTF 1 +#cmakedefine HAVE_SPRINTF_S 1 + /* Defined if your compiler has header */ #cmakedefine HAVE_CODECVT 1 diff --git a/taglib/mp4/mp4item.cpp b/taglib/mp4/mp4item.cpp index 6c1f3c40..65f45546 100644 --- a/taglib/mp4/mp4item.cpp +++ b/taglib/mp4/mp4item.cpp @@ -27,19 +27,44 @@ # include #endif -#include +#include +#include #include #include #include "mp4item.h" -#if defined(_MSC_VER) && (_MSC_VER >= 1400) // VC++2005 or later -# define SPRINTF sprintf_s +using namespace TagLib; + +namespace +{ + String format(const char *fmt, ...) + { + va_list args; + va_start(args,fmt); + + char buf[256]; + +#if defined(HAVE_SNPRINTF) + + vsnprintf(buf, sizeof(buf), fmt, args); + +#elif defined(HAVE_SPRINTF_S) + + vsprintf_s(buf, fmt, args); + #else -# define SPRINTF sprintf + + // Be careful. May cause a buffer overflow. + vsprintf(buf, fmt, args); + #endif -using namespace TagLib; + va_end(args); + + return String(buf); + } +} class MP4::Item::ItemPrivate { @@ -242,37 +267,31 @@ String MP4::Item::toString() const { StringList desc; - char tmp[256]; switch (d->type) { case TypeBool: return d->m_bool ? "true" : "false"; case TypeInt: - SPRINTF(tmp, "%d", d->m_int); - return tmp; + return format("%d", d->m_int); case TypeIntPair: - SPRINTF(tmp, "%d/%d", d->m_intPair.first, d->m_intPair.second); - return tmp; + return format("%d/%d", d->m_intPair.first, d->m_intPair.second); case TypeByte: - SPRINTF(tmp, "%d", d->m_byte); - return tmp; + return format("%d", d->m_byte); case TypeUInt: - SPRINTF(tmp, "%u", d->m_uint); - return tmp; + return format("%u", d->m_uint); case TypeLongLong: - SPRINTF(tmp, "%lld", d->m_longlong); - return tmp; + return format("%lld", d->m_longlong); case TypeStringList: return d->m_stringList.toString(" / "); case TypeByteVectorList: for(TagLib::uint i = 0; i < d->m_byteVectorList.size(); i++) { - SPRINTF(tmp, "[%d bytes of data]", static_cast(d->m_byteVectorList[i].size())); - desc.append(tmp); + desc.append(format( + "[%d bytes of data]", static_cast(d->m_byteVectorList[i].size()))); } return desc.toString(", "); case TypeCoverArtList: for(TagLib::uint i = 0; i < d->m_coverArtList.size(); i++) { - SPRINTF(tmp, "[%d bytes of data]", static_cast(d->m_coverArtList[i].data().size())); - desc.append(tmp); + desc.append(format( + "[%d bytes of data]", static_cast(d->m_coverArtList[i].data().size()))); } return desc.toString(", "); case TypeUndefined: