Browse Source

sprintf replacement: introduce au_snprintf to support snprintf for v2013
and earier ( closes https://github.com/assimp/assimp/issues/743 )

Kim Kulling 9 years ago
parent
commit
6bfdeb6a12

+ 1 - 1
code/3DSConverter.cpp

@@ -757,7 +757,7 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
             pcNode->mNumMeshes = 1;
 
             // Build a name for the node
-            pcNode->mName.length = snprintf(pcNode->mName.data, MAXLEN, "3DSMesh_%u",i);
+            pcNode->mName.length = ai_snprintf(pcNode->mName.data, MAXLEN, "3DSMesh_%u",i);
         }
 
         // Build dummy nodes for all cameras

+ 4 - 3
code/3DSHelper.h

@@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "SpatialSort.h"
 #include "SmoothingGroups.h"
+#include "StringUtils.h"
 #include "qnan.h"
 #include "./../include/assimp/material.h"
 #include "./../include/assimp/camera.h"
@@ -379,7 +380,7 @@ struct Material
         static int iCnt = 0;
 
         char szTemp[128];
-        snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
+        ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
         mName = szTemp;
     }
 
@@ -435,7 +436,7 @@ struct Mesh : public MeshWithSmoothingGroups<D3DS::Face>
 
         // Generate a default name for the mesh
         char szTemp[128];
-        ::snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
+        ::ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
         mName = szTemp;
     }
 
@@ -495,7 +496,7 @@ struct Node
 
         // Generate a default name for the node
         char szTemp[128];
-        ::snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
+        ::ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
         mName = szTemp;
 
         aRotationKeys.reserve (20);

+ 5 - 5
code/ACLoader.cpp

@@ -211,7 +211,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
 
         // Generate a default name for both the light source and the node
         // FIXME - what's the right way to print a size_t? Is 'zu' universally available? stick with the safe version.
-        light->mName.length = ::snprintf(light->mName.data, MAXLEN, "ACLight_%i",static_cast<unsigned int>(mLights->size())-1);
+        light->mName.length = ::ai_snprintf(light->mName.data, MAXLEN, "ACLight_%i",static_cast<unsigned int>(mLights->size())-1);
         obj.name = std::string( light->mName.data );
 
         DefaultLogger::get()->debug("AC3D: Light source encountered");
@@ -733,18 +733,18 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
         switch (object.type)
         {
         case Object::Group:
-            node->mName.length = ::snprintf(node->mName.data, MAXLEN, "ACGroup_%i",groups++);
+            node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACGroup_%i",groups++);
             break;
         case Object::Poly:
-            node->mName.length = ::snprintf(node->mName.data, MAXLEN, "ACPoly_%i",polys++);
+            node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACPoly_%i",polys++);
             break;
         case Object::Light:
-            node->mName.length = ::snprintf(node->mName.data, MAXLEN, "ACLight_%i",lights++);
+            node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACLight_%i",lights++);
             break;
 
             // there shouldn't be more than one world, but we don't care
         case Object::World:
-            node->mName.length = ::snprintf(node->mName.data, MAXLEN, "ACWorld_%i",worlds++);
+            node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACWorld_%i",worlds++);
             break;
         }
     }

+ 6 - 6
code/ASEParser.cpp

@@ -145,7 +145,7 @@ void Parser::LogWarning(const char* szWarn)
 #if _MSC_VER >= 1400
     sprintf_s(szTemp, "Line %u: %s",iLineNumber,szWarn);
 #else
-    snprintf(szTemp,1024,"Line %u: %s",iLineNumber,szWarn);
+    ai_snprintf(szTemp,1024,"Line %u: %s",iLineNumber,szWarn);
 #endif
 
     // output the warning to the logger ...
@@ -161,7 +161,7 @@ void Parser::LogInfo(const char* szWarn)
 #if _MSC_VER >= 1400
     sprintf_s(szTemp,"Line %u: %s",iLineNumber,szWarn);
 #else
-    snprintf(szTemp,1024,"Line %u: %s",iLineNumber,szWarn);
+    ai_snprintf(szTemp,1024,"Line %u: %s",iLineNumber,szWarn);
 #endif
 
     // output the information to the logger ...
@@ -177,7 +177,7 @@ AI_WONT_RETURN void Parser::LogError(const char* szWarn)
 #if _MSC_VER >= 1400
     sprintf_s(szTemp,"Line %u: %s",iLineNumber,szWarn);
 #else
-    snprintf(szTemp,1024,"Line %u: %s",iLineNumber,szWarn);
+    ai_snprintf(szTemp,1024,"Line %u: %s",iLineNumber,szWarn);
 #endif
 
     // throw an exception
@@ -825,7 +825,7 @@ bool Parser::ParseString(std::string& out,const char* szName)
     if (!SkipSpaces(&filePtr))
     {
 
-        snprintf(szBuffer, 1023, "Unable to parse %s block: Unexpected EOL",szName);
+        ai_snprintf(szBuffer, 1023, "Unable to parse %s block: Unexpected EOL",szName);
         LogWarning(szBuffer);
         return false;
     }
@@ -833,7 +833,7 @@ bool Parser::ParseString(std::string& out,const char* szName)
     if ('\"' != *filePtr)
     {
 
-        snprintf(szBuffer, 1023, "Unable to parse %s block: Strings are expected "
+        ai_snprintf(szBuffer, 1023, "Unable to parse %s block: Strings are expected "
             "to be enclosed in double quotation marks",szName);
         LogWarning(szBuffer);
         return false;
@@ -845,7 +845,7 @@ bool Parser::ParseString(std::string& out,const char* szName)
         if ('\"' == *sz)break;
         else if ('\0' == *sz)
         {
-            snprintf(szBuffer, 1024, "Unable to parse %s block: Strings are expected to "
+            ai_snprintf(szBuffer, 1024, "Unable to parse %s block: Strings are expected to "
                 "be enclosed in double quotation marks but EOF was reached before "
                 "a closing quotation mark was encountered",szName);
             LogWarning(szBuffer);

+ 2 - 2
code/ASEParser.h

@@ -133,7 +133,7 @@ struct Bone
 
         // Generate a default name for the bone
         char szTemp[128];
-        ::snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
+        ::ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
         mName = szTemp;
     }
 
@@ -223,7 +223,7 @@ struct BaseNode
         // generate a default name for the  node
         static int iCnt = 0;
         char szTemp[128]; // should be sufficiently large
-        ::snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
+        ::ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
         mName = szTemp;
 
         // Set mTargetPosition to qnan

+ 1 - 1
code/AssbinExporter.cpp

@@ -702,7 +702,7 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
 #if _MSC_VER >= 1400
             sprintf_s(s,"ASSIMP.binary-dump.%s",asctime(p));
 #else
-            snprintf(s,64,"ASSIMP.binary-dump.%s",asctime(p));
+            ai_snprintf(s,64,"ASSIMP.binary-dump.%s",asctime(p));
 #endif
             out->Write( s, 44, 1 );
             // == 44 bytes

+ 2 - 2
code/AssxmlExporter.cpp

@@ -70,8 +70,8 @@ int ioprintf( IOStream * io, const char * format, ... )
     char sz[4096];
     va_list va;
     va_start( va, format );
-    int nSize = vsnprintf( sz, 4096, format, va );
-  ai_assert( nSize < 4096 );
+    int nSize = ai_snprintf( sz, 4096, format, va );
+   ai_assert( nSize < 4096 );
     va_end( va );
 
     io->Write( sz, sizeof(char), nSize );

+ 2 - 1
code/B3DImporter.cpp

@@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "B3DImporter.h"
 #include "TextureTransform.h"
 #include "ConvertToLHProcess.h"
+#include "StringUtils.h"
 #include <boost/scoped_ptr.hpp>
 #include "../include/assimp/IOSystem.hpp"
 #include "../include/assimp/anim.h"
@@ -571,7 +572,7 @@ void B3DImporter::ReadBB3D( aiScene *scene ){
         
         if (!DefaultLogger::isNullLogger()) {
             char dmp[128];
-            snprintf(dmp, 128, "B3D file format version: %i",version);
+            ai_snprintf(dmp, 128, "B3D file format version: %i",version);
             DefaultLogger::get()->info(dmp);
         }
 

+ 2 - 1
code/BlenderLoader.cpp

@@ -52,6 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "BlenderIntermediate.h"
 #include "BlenderModifier.h"
 #include "BlenderBMesh.h"
+#include "StringUtils.h"
 #include "../include/assimp/scene.h"
 #include "StringComparison.h"
 
@@ -496,7 +497,7 @@ void BlenderImporter::AddSentinelTexture(aiMaterial* out, const Material* mat, c
     (void)mat; (void)tex; (void)conv_data;
 
     aiString name;
-    name.length = snprintf(name.data, MAXLEN, "Procedural,num=%i,type=%s",conv_data.sentinel_cnt++,
+    name.length = ai_snprintf(name.data, MAXLEN, "Procedural,num=%i,type=%s",conv_data.sentinel_cnt++,
         GetTextureTypeDisplayString(tex->tex->type)
     );
     out->AddProperty(&name,AI_MATKEY_TEXTURE_DIFFUSE(

+ 1 - 0
code/CMakeLists.txt

@@ -113,6 +113,7 @@ SET( Common_SRCS
   StreamReader.h
   StreamWriter.h
   StringComparison.h
+  StringUtils.h
   SGSpatialSort.cpp
   SGSpatialSort.h
   VertexTriangleAdjacency.cpp

+ 1 - 1
code/ComputeUVMappingProcess.cpp

@@ -412,7 +412,7 @@ void ComputeUVMappingProcess::Execute( aiScene* pScene)
                 {
                     if (!DefaultLogger::isNullLogger())
                     {
-                        sprintf(buffer, "Found non-UV mapped texture (%s,%u). Mapping type: %s",
+                        ai_snprintf(buffer, 1024, "Found non-UV mapped texture (%s,%u). Mapping type: %s",
                             TextureTypeToString((aiTextureType)prop->mSemantic),prop->mIndex,
                             MappingTypeToString(mapping));
 

+ 1 - 1
code/DeboneProcess.cpp

@@ -147,7 +147,7 @@ void DeboneProcess::Execute( aiScene* pScene)
 
                 if(!DefaultLogger::isNullLogger()) {
                     char buffer[1024];
-                    ::sprintf(buffer,"Removed %u bones. Input bones: %u. Output bones: %u",in-out,in,out);
+                    ::ai_snprintf(buffer,1024,"Removed %u bones. Input bones: %u. Output bones: %u",in-out,in,out);
                     DefaultLogger::get()->info(buffer);
                 }
 

+ 7 - 8
code/DefaultLogger.cpp

@@ -49,6 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "Win32DebugLogStream.h"
 #include "StdOStreamLogStream.h"
 #include "FileLogStream.h"
+#include "StringUtils.h"
 #include "../include/assimp/NullLogger.hpp"
 #include "../include/assimp/DefaultLogger.hpp"
 #include "../include/assimp/ai_assert.h"
@@ -255,7 +256,7 @@ void DefaultLogger::OnDebug( const char* message )
 
 	static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;
 	char msg[Size];
-	::snprintf(msg, Size-1, "Debug, T%u: %s", GetThreadID(), message);
+	ai_snprintf(msg, Size, "Debug, T%u: %s", GetThreadID(), message);
 
     WriteToStreams( msg, Logger::Debugging );
 }
@@ -266,7 +267,7 @@ void DefaultLogger::OnInfo( const char* message )
 {
 	static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;
 	char msg[Size];
-    ::snprintf(msg, Size-1, "Info,  T%u: %s", GetThreadID(), message );
+    ai_snprintf(msg, Size, "Info,  T%u: %s", GetThreadID(), message );
 
     WriteToStreams( msg , Logger::Info );
 }
@@ -277,7 +278,7 @@ void DefaultLogger::OnWarn( const char* message )
 {
 	static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;
 	char msg[Size];
-	::snprintf(msg, Size - 1, "Warn,  T%u: %s", GetThreadID(), message );
+	ai_snprintf(msg, Size, "Warn,  T%u: %s", GetThreadID(), message );
 
     WriteToStreams( msg, Logger::Warn );
 }
@@ -288,7 +289,7 @@ void DefaultLogger::OnError( const char* message )
 {
 	static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;
 	char msg[ Size ];
-    ::snprintf(msg, Size-1, "Error, T%u: %s", GetThreadID(), message );
+    ai_snprintf(msg, Size, "Error, T%u: %s", GetThreadID(), message );
 
     WriteToStreams( msg, Logger::Err );
 }
@@ -321,7 +322,7 @@ bool DefaultLogger::attachStream( LogStream *pStream, unsigned int severity )
 }
 
 // ----------------------------------------------------------------------------------
-//  Detatch a stream
+//  Detach a stream
 bool DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity )
 {
     if (!pStream)
@@ -355,7 +356,6 @@ bool DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity )
 // ----------------------------------------------------------------------------------
 //  Constructor
 DefaultLogger::DefaultLogger(LogSeverity severity)
-
     :   Logger  ( severity )
     ,   noRepeatMsg (false)
     ,   lastLen( 0 )
@@ -375,8 +375,7 @@ DefaultLogger::~DefaultLogger()
 
 // ----------------------------------------------------------------------------------
 //  Writes message to stream
-void DefaultLogger::WriteToStreams(const char *message,
-    ErrorSeverity ErrorSev )
+void DefaultLogger::WriteToStreams(const char *message, ErrorSeverity ErrorSev )
 {
     ai_assert(NULL != message);
 

+ 1 - 1
code/FindInstancesProcess.cpp

@@ -267,7 +267,7 @@ void FindInstancesProcess::Execute( aiScene* pScene)
             if (!DefaultLogger::isNullLogger()) {
 
                 char buffer[512];
-                ::sprintf(buffer,"FindInstancesProcess finished. Found %i instances",pScene->mNumMeshes-numMeshesOut);
+                ::ai_snprintf(buffer,512,"FindInstancesProcess finished. Found %i instances",pScene->mNumMeshes-numMeshesOut);
                 DefaultLogger::get()->info(buffer);
             }
             pScene->mNumMeshes = numMeshesOut;

+ 2 - 1
code/FixNormalsStep.cpp

@@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // internal headers
 #include "FixNormalsStep.h"
+#include "StringUtils.h"
 #include "../include/assimp/DefaultLogger.hpp"
 #include "../include/assimp/postprocess.h"
 #include "../include/assimp/scene.h"
@@ -158,7 +159,7 @@ bool FixInfacingNormalsProcess::ProcessMesh( aiMesh* pcMesh, unsigned int index)
         if (!DefaultLogger::isNullLogger())
         {
             char buffer[128]; // should be sufficiently large
-            ::sprintf(buffer,"Mesh %u: Normals are facing inwards (or the mesh is planar)",index);
+            ai_snprintf(buffer,128,"Mesh %u: Normals are facing inwards (or the mesh is planar)",index);
             DefaultLogger::get()->info(buffer);
         }
 

+ 2 - 2
code/IRRLoader.cpp

@@ -196,7 +196,7 @@ void IRRImporter::BuildSkybox(std::vector<aiMesh*>& meshes, std::vector<aiMateri
         aiMaterial* out = ( aiMaterial* ) (*(materials.end()-(6-i)));
 
         aiString s;
-        s.length = ::snprintf( s.data, MAXLEN, "SkyboxSide_%u",i );
+        s.length = ::ai_snprintf( s.data, MAXLEN, "SkyboxSide_%u",i );
         out->AddProperty(&s,AI_MATKEY_NAME);
 
         int shading = aiShadingMode_NoShading;
@@ -347,7 +347,7 @@ void IRRImporter::ComputeAnimations(Node* root, aiNode* real, std::vector<aiNode
         if (cur != total-1) {
             // Build a new name - a prefix instead of a suffix because it is
             // easier to check against
-            anim->mNodeName.length = ::snprintf(anim->mNodeName.data, MAXLEN,
+            anim->mNodeName.length = ::ai_snprintf(anim->mNodeName.data, MAXLEN,
                 "$INST_DUMMY_%i_%s",total-1,
                 (root->name.length() ? root->name.c_str() : ""));
 

+ 2 - 1
code/IRRLoader.h

@@ -49,6 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "IRRShared.h"
 #include "SceneCombiner.h"
 #include "Importer.h"
+#include "StringUtils.h"
 #include "../include/assimp/anim.h"
 
 namespace Assimp    {
@@ -177,7 +178,7 @@ private:
             // Generate a default name for the node
             char buffer[128];
             static int cnt;
-            ::snprintf(buffer, 128, "IrrNode_%i",cnt++);
+            ai_snprintf(buffer, 128, "IrrNode_%i",cnt++);
             name = std::string(buffer);
 
             // reserve space for up to 5 materials

+ 1 - 1
code/Importer.cpp

@@ -505,7 +505,7 @@ const aiScene* Importer::ReadFileFromMemory( const void* pBuffer,
     // read the file and recover the previous IOSystem
     static const size_t BufferSize(Importer::MaxLenHint + 28);
     char fbuff[ BufferSize ];
-    snprintf(fbuff, BufferSize, "%s.%s",AI_MEMORYIO_MAGIC_FILENAME,pHint);
+    ai_snprintf(fbuff, BufferSize, "%s.%s",AI_MEMORYIO_MAGIC_FILENAME,pHint);
 
     ReadFile(fbuff,pFlags);
     SetIOHandler(io);

+ 4 - 3
code/ImproveCacheLocality.cpp

@@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // internal headers
 #include "ImproveCacheLocality.h"
 #include "VertexTriangleAdjacency.h"
+#include "StringUtils.h"
 #include "../include/assimp/postprocess.h"
 #include "../include/assimp/scene.h"
 #include "../include/assimp/DefaultLogger.hpp"
@@ -110,7 +111,7 @@ void ImproveCacheLocalityProcess::Execute( aiScene* pScene)
     }
     if (!DefaultLogger::isNullLogger()) {
         char szBuff[128]; // should be sufficiently large in every case
-        ::sprintf(szBuff,"Cache relevant are %u meshes (%u faces). Average output ACMR is %f",
+        ai_snprintf(szBuff,128,"Cache relevant are %u meshes (%u faces). Average output ACMR is %f",
             numm,numf,out/numf);
 
         DefaultLogger::get()->info(szBuff);
@@ -182,7 +183,7 @@ float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int mesh
             // the JoinIdenticalVertices process has not been executed on this
             // mesh, otherwise this value would normally be at least minimally
             // smaller than 3.0 ...
-            sprintf(szBuff,"Mesh %u: Not suitable for vcache optimization",meshNum);
+            ai_snprintf(szBuff,128,"Mesh %u: Not suitable for vcache optimization",meshNum);
             DefaultLogger::get()->warn(szBuff);
             return 0.f;
         }
@@ -361,7 +362,7 @@ float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int mesh
         if ( DefaultLogger::get()->getLogSeverity() == Logger::VERBOSE) {
             char szBuff[128]; // should be sufficiently large in every case
 
-            ::sprintf(szBuff,"Mesh %u | ACMR in: %f out: %f | ~%.1f%%",meshNum,fACMR,fACMR2,
+            ai_snprintf(szBuff,128,"Mesh %u | ACMR in: %f out: %f | ~%.1f%%",meshNum,fACMR,fACMR2,
                 ((fACMR - fACMR2) / fACMR) * 100.f);
             DefaultLogger::get()->debug(szBuff);
         }

+ 1 - 1
code/JoinVerticesProcess.cpp

@@ -102,7 +102,7 @@ void JoinVerticesProcess::Execute( aiScene* pScene)
         } else
         {
             char szBuff[128]; // should be sufficiently large in every case
-            sprintf(szBuff,"JoinVerticesProcess finished | Verts in: %i out: %i | ~%.1f%%",
+            ::ai_snprintf(szBuff,128,"JoinVerticesProcess finished | Verts in: %i out: %i | ~%.1f%%",
                 iNumOldVertices,
                 iNumVertices,
                 ((iNumOldVertices - iNumVertices) / (float)iNumOldVertices) * 100.f);

+ 1 - 1
code/LWOLoader.cpp

@@ -1370,7 +1370,7 @@ void LWOImporter::LoadLWO2File()
                 // if the name is empty, generate a default name
                 if (layer.mName.empty())    {
                     char buffer[128]; // should be sufficiently large
-                    ::snprintf(buffer, 128, "Layer_%i", iUnnamed++);
+                    ::ai_snprintf(buffer, 128, "Layer_%i", iUnnamed++);
                     layer.mName = buffer;
                 }
 

+ 2 - 2
code/LWSLoader.cpp

@@ -323,11 +323,11 @@ void LWSImporter::SetupNodeName(aiNode* nd, LWS::NodeDesc& src)
             else ++s;
             std::string::size_type t = src.path.substr(s).find_last_of(".");
 
-            nd->mName.length = ::snprintf(nd->mName.data, MAXLEN, "%s_(%08X)",src.path.substr(s).substr(0,t).c_str(),combined);
+            nd->mName.length = ::ai_snprintf(nd->mName.data, MAXLEN, "%s_(%08X)",src.path.substr(s).substr(0,t).c_str(),combined);
             return;
         }
     }
-    nd->mName.length = ::snprintf(nd->mName.data, MAXLEN, "%s_(%08X)",src.name,combined);
+    nd->mName.length = ::ai_snprintf(nd->mName.data, MAXLEN, "%s_(%08X)",src.name,combined);
 }
 
 // ------------------------------------------------------------------------------------------------

+ 2 - 1
code/LimitBoneWeightsProcess.cpp

@@ -42,6 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 #include "LimitBoneWeightsProcess.h"
+#include "StringUtils.h"
 #include "../include/assimp/postprocess.h"
 #include "../include/assimp/DefaultLogger.hpp"
 #include "../include/assimp/scene.h"
@@ -193,7 +194,7 @@ void LimitBoneWeightsProcess::ProcessMesh( aiMesh* pMesh)
 
         if (!DefaultLogger::isNullLogger()) {
             char buffer[1024];
-            ::sprintf(buffer,"Removed %u weights. Input bones: %u. Output bones: %u",removed,old_bones,pMesh->mNumBones);
+            ai_snprintf(buffer,1024,"Removed %u weights. Input bones: %u. Output bones: %u",removed,old_bones,pMesh->mNumBones);
             DefaultLogger::get()->info(buffer);
         }
     }

+ 1 - 1
code/MD5Loader.cpp

@@ -735,7 +735,7 @@ void MD5Importer::LoadMD5CameraFile ()
     for (std::vector<unsigned int>::const_iterator it = cuts.begin(); it != cuts.end()-1; ++it) {
 
         aiAnimation* anim = *tmp++ = new aiAnimation();
-        anim->mName.length = ::snprintf(anim->mName.data, MAXLEN, "anim%u_from_%u_to_%u",(unsigned int)(it-cuts.begin()),(*it),*(it+1));
+        anim->mName.length = ::ai_snprintf(anim->mName.data, MAXLEN, "anim%u_from_%u_to_%u",(unsigned int)(it-cuts.begin()),(*it),*(it+1));
 
         anim->mTicksPerSecond = cameraParser.fFrameRate;
         anim->mChannels = new aiNodeAnim*[anim->mNumChannels = 1];

+ 2 - 2
code/MD5Parser.cpp

@@ -85,7 +85,7 @@ MD5Parser::MD5Parser(char* _buffer, unsigned int _fileSize )
 
     if ( !DefaultLogger::isNullLogger())    {
         char szBuffer[128]; // should be sufficiently large
-        ::snprintf(szBuffer,128,"MD5Parser end. Parsed %i sections",(int)mSections.size());
+        ::ai_snprintf(szBuffer,128,"MD5Parser end. Parsed %i sections",(int)mSections.size());
         DefaultLogger::get()->debug(szBuffer);
     }
 }
@@ -95,7 +95,7 @@ MD5Parser::MD5Parser(char* _buffer, unsigned int _fileSize )
 /*static*/ AI_WONT_RETURN void MD5Parser::ReportError (const char* error, unsigned int line)
 {
     char szBuffer[1024];
-    ::snprintf(szBuffer, 1024, "[MD5] Line %u: %s",line,error);
+    ::ai_snprintf(szBuffer, 1024, "[MD5] Line %u: %s",line,error);
     throw DeadlyImportError(szBuffer);
 }
 

+ 3 - 2
code/MDLLoader.cpp

@@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "MDLLoader.h"
 #include "MDLDefaultColorMap.h"
 #include "MD2FileData.h"
+#include "StringUtils.h"
 #include "../include/assimp/Importer.hpp"
 #include <boost/scoped_ptr.hpp>
 #include "../include/assimp/IOSystem.hpp"
@@ -942,7 +943,7 @@ void MDLImporter::CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7** apcOutBones)
 
                 if (AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE == pcHeader->bone_stc_size) {
                     // no real name for our poor bone is specified :-(
-                    pcOutBone->mName.length = ::snprintf(pcOutBone->mName.data, MAXLEN,
+                    pcOutBone->mName.length = ai_snprintf(pcOutBone->mName.data, MAXLEN,
                         "UnnamedBone_%i",iBone);
                 }
                 else    {
@@ -1547,7 +1548,7 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
             char* const szBuffer = &aszGroupNameBuffer[i*AI_MDL7_MAX_GROUPNAMESIZE];
 			if ('\0' == *szBuffer) {
 				const size_t maxSize(buffersize - (i*AI_MDL7_MAX_GROUPNAMESIZE));
-				pcNode->mName.length = ::snprintf(szBuffer, maxSize, "Group_%u", p);
+				pcNode->mName.length = ai_snprintf(szBuffer, maxSize, "Group_%u", p);
 			} else {
 				pcNode->mName.length = ::strlen(szBuffer);
 			}

+ 2 - 1
code/MDLMaterialLoader.cpp

@@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // internal headers
 #include "MDLLoader.h"
 #include "MDLDefaultColorMap.h"
+#include "StringUtils.h"
 #include "../include/assimp/texture.h"
 #include "../include/assimp/IOSystem.hpp"
 #include "../include/assimp/DefaultLogger.hpp"
@@ -699,7 +700,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
 
         // place this as diffuse texture
         char szCurrent[5];
-        ::snprintf(szCurrent,5,"*%i",this->pScene->mNumTextures);
+        ai_snprintf(szCurrent,5,"*%i",this->pScene->mNumTextures);
 
         aiString szFile;
         const size_t iLen = strlen((const char*)szCurrent);

+ 8 - 8
code/NFFLoader.cpp

@@ -862,7 +862,7 @@ void NFFImporter::InternReadFile( const std::string& pFile,
                 currentMesh.faces.resize(currentMesh.vertices.size()/3,3);
 
                 // generate a name for the mesh
-                ::snprintf(currentMesh.name,128,"sphere_%i",sphere++);
+                ::ai_snprintf(currentMesh.name,128,"sphere_%i",sphere++);
             }
             // 'dod' - dodecahedron
             else if (TokenMatch(sz,"dod",3))
@@ -879,7 +879,7 @@ void NFFImporter::InternReadFile( const std::string& pFile,
                 currentMesh.faces.resize(currentMesh.vertices.size()/3,3);
 
                 // generate a name for the mesh
-                ::snprintf(currentMesh.name,128,"dodecahedron_%i",dodecahedron++);
+                ::ai_snprintf(currentMesh.name,128,"dodecahedron_%i",dodecahedron++);
             }
 
             // 'oct' - octahedron
@@ -897,7 +897,7 @@ void NFFImporter::InternReadFile( const std::string& pFile,
                 currentMesh.faces.resize(currentMesh.vertices.size()/3,3);
 
                 // generate a name for the mesh
-                ::snprintf(currentMesh.name,128,"octahedron_%i",octahedron++);
+                ::ai_snprintf(currentMesh.name,128,"octahedron_%i",octahedron++);
             }
 
             // 'tet' - tetrahedron
@@ -915,7 +915,7 @@ void NFFImporter::InternReadFile( const std::string& pFile,
                 currentMesh.faces.resize(currentMesh.vertices.size()/3,3);
 
                 // generate a name for the mesh
-                ::sprintf(currentMesh.name,"tetrahedron_%i",tetrahedron++);
+                ::ai_snprintf(currentMesh.name,128,"tetrahedron_%i",tetrahedron++);
             }
 
             // 'hex' - hexahedron
@@ -933,7 +933,7 @@ void NFFImporter::InternReadFile( const std::string& pFile,
                 currentMesh.faces.resize(currentMesh.vertices.size()/3,3);
 
                 // generate a name for the mesh
-                ::sprintf(currentMesh.name,"hexahedron_%i",hexahedron++);
+                ::ai_snprintf(currentMesh.name,128,"hexahedron_%i",hexahedron++);
             }
             // 'c' - cone
             else if (TokenMatch(sz,"c",1))
@@ -988,8 +988,8 @@ void NFFImporter::InternReadFile( const std::string& pFile,
                 // generate a name for the mesh. 'cone' if it a cone,
                 // 'cylinder' if it is a cylinder. Funny, isn't it?
                 if (radius1 != radius2)
-                    ::sprintf(currentMesh.name,"cone_%i",cone++);
-                else ::sprintf(currentMesh.name,"cylinder_%i",cylinder++);
+                    ::ai_snprintf(currentMesh.name,128,"cone_%i",cone++);
+                else ::ai_snprintf(currentMesh.name,128,"cylinder_%i",cylinder++);
             }
             // 'tess' - tesselation
             else if (TokenMatch(sz,"tess",4))
@@ -1115,7 +1115,7 @@ void NFFImporter::InternReadFile( const std::string& pFile,
             aiNode* nd = *ppcChildren  = new aiNode();
             nd->mParent = root;
 
-            nd->mName.length = ::sprintf(nd->mName.data,"<NFF_Light%u>",i);
+            nd->mName.length = ::ai_snprintf(nd->mName.data,1024,"<NFF_Light%u>",i);
 
             // allocate the light in the scene data structure
             aiLight* out = pScene->mLights[i] = new aiLight();

+ 2 - 2
code/OptimizeGraph.cpp

@@ -177,7 +177,7 @@ void OptimizeGraphProcess::CollectNewChildren(aiNode* nd, std::list<aiNode*>& no
             ++it;
         }
         if (join_master && !join.empty()) {
-            join_master->mName.length = sprintf(join_master->mName.data,"$MergedNode_%i",count_merged++);
+            join_master->mName.length = ::ai_snprintf(join_master->mName.data, MAXLEN, "$MergedNode_%i",count_merged++);
 
             unsigned int out_meshes = 0;
             for (std::list<aiNode*>::iterator it = join.begin(); it != join.end(); ++it) {
@@ -335,7 +335,7 @@ void OptimizeGraphProcess::Execute( aiScene* pScene)
         if ( nodes_in != nodes_out) {
 
             char buf[512];
-            sprintf(buf,"OptimizeGraphProcess finished; Input nodes: %u, Output nodes: %u",nodes_in,nodes_out);
+            ::ai_snprintf(buf,512,"OptimizeGraphProcess finished; Input nodes: %u, Output nodes: %u",nodes_in,nodes_out);
             DefaultLogger::get()->info(buf);
         }
         else DefaultLogger::get()->debug("OptimizeGraphProcess finished");

+ 1 - 1
code/OptimizeMeshes.cpp

@@ -150,7 +150,7 @@ void OptimizeMeshesProcess::Execute( aiScene* pScene)
 
     if (output.size() != num_old) {
         char tmp[512];
-        ::sprintf(tmp,"OptimizeMeshesProcess finished. Input meshes: %u, Output meshes: %u",num_old,pScene->mNumMeshes);
+        ::ai_snprintf(tmp,512,"OptimizeMeshesProcess finished. Input meshes: %u, Output meshes: %u",num_old,pScene->mNumMeshes);
         DefaultLogger::get()->info(tmp);
     } else {
         DefaultLogger::get()->debug( "OptimizeMeshesProcess finished" );

+ 1 - 0
code/ParsingUtils.h

@@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define AI_PARSING_UTILS_H_INC
 
 #include "StringComparison.h"
+#include "StringUtils.h"
 #include "../include/assimp/defs.h"
 
 namespace Assimp {

+ 5 - 5
code/PretransformVertices.cpp

@@ -644,7 +644,7 @@ void PretransformVertices::Execute( aiScene* pScene)
             {
                 aiNode* pcNode = *nodes = new aiNode();
                 pcNode->mParent = pScene->mRootNode;
-                pcNode->mName.length = ::sprintf(pcNode->mName.data,"mesh_%u",i);
+                pcNode->mName.length = ::ai_snprintf(pcNode->mName.data,MAXLEN,"mesh_%u",i);
 
                 // setup mesh indices
                 pcNode->mNumMeshes = 1;
@@ -664,7 +664,7 @@ void PretransformVertices::Execute( aiScene* pScene)
             {
                 aiNode* pcNode = *nodes = new aiNode();
                 pcNode->mParent = pScene->mRootNode;
-                pcNode->mName.length = ::sprintf(pcNode->mName.data,"cam_%u",i);
+                pcNode->mName.length = ::ai_snprintf(pcNode->mName.data,MAXLEN,"cam_%u",i);
                 pScene->mCameras[i]->mName = pcNode->mName;
             }
         }
@@ -707,15 +707,15 @@ void PretransformVertices::Execute( aiScene* pScene)
 
         DefaultLogger::get()->debug("PretransformVerticesProcess finished");
 
-        sprintf(buffer,"Removed %u nodes and %u animation channels (%u output nodes)",
+        ::ai_snprintf(buffer,4096,"Removed %u nodes and %u animation channels (%u output nodes)",
             iOldNodes,iOldAnimationChannels,CountNodes(pScene->mRootNode));
         DefaultLogger::get()->info(buffer);
 
-        sprintf(buffer,"Kept %u lights and %u cameras",
+        ai_snprintf(buffer, 4096,"Kept %u lights and %u cameras",
             pScene->mNumLights,pScene->mNumCameras);
         DefaultLogger::get()->info(buffer);
 
-        sprintf(buffer,"Moved %u meshes to WCS (number of output meshes: %u)",
+        ai_snprintf(buffer, 4096,"Moved %u meshes to WCS (number of output meshes: %u)",
             iOldMeshes,pScene->mNumMeshes);
         DefaultLogger::get()->info(buffer);
     }

+ 2 - 2
code/RemoveRedundantMaterials.cpp

@@ -181,7 +181,7 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
                 const unsigned int idx = aiMappingTable[p];
                 if (ppcMaterials[idx]) {
                     aiString sz;
-                    sz.length = ::sprintf(sz.data,"JoinedMaterial_#%u",p);
+                    sz.length = ::ai_snprintf(sz.data,MAXLEN,"JoinedMaterial_#%u",p);
                     ((aiMaterial*)ppcMaterials[idx])->AddProperty(&sz,AI_MATKEY_NAME);
                 } else {
                     ppcMaterials[idx] = pScene->mMaterials[p];
@@ -209,7 +209,7 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
     else
     {
         char szBuffer[128]; // should be sufficiently large
-        ::sprintf(szBuffer,"RemoveRedundantMatsProcess finished. Removed %u redundant and %u unused materials.",
+        ::ai_snprintf(szBuffer,128,"RemoveRedundantMatsProcess finished. Removed %u redundant and %u unused materials.",
             redundantRemoved,unreferencedRemoved);
         DefaultLogger::get()->info(szBuffer);
     }

+ 2 - 1
code/SceneCombiner.cpp

@@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 // ----------------------------------------------------------------------------
 #include "SceneCombiner.h"
+#include "StringUtils.h"
 #include "fast_atof.h"
 #include "Hash.h"
 #include "time.h"
@@ -310,7 +311,7 @@ void SceneCombiner::MergeScenes(aiScene** _dest, aiScene* master,
             //  continue;
             //}
 
-            src[i].idlen = ::snprintf(src[i].id, 32, "$%.6X$_",i);
+            src[i].idlen = ai_snprintf(src[i].id, 32, "$%.6X$_",i);
 
             if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) {
 

+ 1 - 1
code/SortByPTypeProcess.cpp

@@ -397,7 +397,7 @@ void SortByPTypeProcess::Execute( aiScene* pScene)
     if (!DefaultLogger::isNullLogger())
     {
         char buffer[1024];
-        ::sprintf(buffer,"Points: %u%s, Lines: %u%s, Triangles: %u%s, Polygons: %u%s (Meshes, X = removed)",
+        ::ai_snprintf(buffer,1024,"Points: %u%s, Lines: %u%s, Triangles: %u%s, Polygons: %u%s (Meshes, X = removed)",
             aiNumMeshesPerPType[0], ((configRemoveMeshes & aiPrimitiveType_POINT)     ? "X" : ""),
             aiNumMeshesPerPType[1], ((configRemoveMeshes & aiPrimitiveType_LINE)      ? "X" : ""),
             aiNumMeshesPerPType[2], ((configRemoveMeshes & aiPrimitiveType_TRIANGLE)  ? "X" : ""),

+ 98 - 0
code/StringUtils.h

@@ -0,0 +1,98 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2016, assimp team
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+#ifndef INCLUDED_AI_STRINGUTILS_H
+#define INCLUDED_AI_STRINGUTILS_H
+
+#include <cstdarg>
+#include <string.h>
+#include <stdio.h>
+
+namespace Assimp {
+
+///	@fn		ai_snprintf
+///	@brief	The portable version of the function snprintf ( C99 standard ), which works on visual studio compilers 2013 and earlier.
+///	@param	outBuf		The buffer to write in
+///	@param	size		The buffer size
+///	@param	format		The format string
+///	@param	ap			The additional arguments.
+///	@return	The number of written characters if the buffer size was big enough. If an encoding error occurs, a negative number is returned.
+#if defined(_MSC_VER) && _MSC_VER < 1900
+
+	inline int c99_ai_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) {
+		int count(-1);
+		if (0 != size) {
+			count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
+		}
+		if (count == -1) {
+			count = _vscprintf(format, ap);
+		}
+
+		return count;
+	}
+
+	inline int ai_snprintf(char *s, size_t n, const char *fmt, ...) {
+		int count;
+		va_list ap;
+
+		va_start(ap, fmt);
+		count = c99_ai_vsnprintf(outBuf, size, fmt, ap);
+		va_end(ap);
+
+		return count;
+	}
+
+#else
+
+	inline int ai_snprintf(char *s, size_t n, const char *format, ...) {
+		int count;
+		va_list ap;
+		va_start(ap, format);
+		count = snprintf(s, n, format, ap);
+		va_end(ap);
+
+		return count;
+	}
+
+#endif
+
+} // Namespace Assimp
+
+#endif // INCLUDED_AI_STRINGUTILS_H
+

+ 1 - 1
code/Subdivision.cpp

@@ -344,7 +344,7 @@ void CatmullClarkSubdivider::InternSubdivide (
         // faces in the mesh. They occur at outer model boundaries in non-closed
         // shapes.
         char tmp[512];
-        snprintf(tmp, 512, "Catmull-Clark Subdivider: got %u bad edges touching only one face (totally %u edges). ",
+        ai_snprintf(tmp, 512, "Catmull-Clark Subdivider: got %u bad edges touching only one face (totally %u edges). ",
             bad_cnt,static_cast<unsigned int>(edges.size()));
 
         DefaultLogger::get()->debug(tmp);

+ 11 - 11
code/TextureTransform.cpp

@@ -48,10 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/scene.h>
 
 #include "TextureTransform.h"
+#include "StringUtils.h"
 
 using namespace Assimp;
 
-
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
 TextureTransformStep::TextureTransformStep() :
@@ -107,7 +107,7 @@ void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info)
         {
             out -= rounded*(float)AI_MATH_PI;
 
-            sprintf(szTemp,"Texture coordinate rotation %f can be simplified to %f",info.mRotation,out);
+            ai_snprintf(szTemp, 512, "Texture coordinate rotation %f can be simplified to %f",info.mRotation,out);
             DefaultLogger::get()->info(szTemp);
         }
 
@@ -131,7 +131,7 @@ void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info)
         if (aiTextureMapMode_Wrap == info.mapU) {
             // Wrap - simple take the fraction of the field
             out = info.mTranslation.x-(float)rounded;
-            sprintf(szTemp,"[w] UV U offset %f can be simplified to %f",info.mTranslation.x,out);
+			ai_snprintf(szTemp, 512, "[w] UV U offset %f can be simplified to %f", info.mTranslation.x, out);
         }
         else if (aiTextureMapMode_Mirror == info.mapU && 1 != rounded)  {
             // Mirror
@@ -139,11 +139,11 @@ void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info)
                 rounded--;
             out = info.mTranslation.x-(float)rounded;
 
-            sprintf(szTemp,"[m/d] UV U offset %f can be simplified to %f",info.mTranslation.x,out);
+            ai_snprintf(szTemp,512,"[m/d] UV U offset %f can be simplified to %f",info.mTranslation.x,out);
         }
         else if (aiTextureMapMode_Clamp == info.mapU || aiTextureMapMode_Decal == info.mapU)    {
             // Clamp - translations beyond 1,1 are senseless
-            sprintf(szTemp,"[c] UV U offset %f can be clamped to 1.0f",info.mTranslation.x);
+            ai_snprintf(szTemp,512,"[c] UV U offset %f can be clamped to 1.0f",info.mTranslation.x);
 
             out = 1.f;
         }
@@ -164,7 +164,7 @@ void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info)
         if (aiTextureMapMode_Wrap == info.mapV) {
             // Wrap - simple take the fraction of the field
             out = info.mTranslation.y-(float)rounded;
-            sprintf(szTemp,"[w] UV V offset %f can be simplified to %f",info.mTranslation.y,out);
+            ::ai_snprintf(szTemp,512,"[w] UV V offset %f can be simplified to %f",info.mTranslation.y,out);
         }
         else if (aiTextureMapMode_Mirror == info.mapV  && 1 != rounded) {
             // Mirror
@@ -172,11 +172,11 @@ void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info)
                 rounded--;
             out = info.mTranslation.x-(float)rounded;
 
-            sprintf(szTemp,"[m/d] UV V offset %f can be simplified to %f",info.mTranslation.y,out);
+            ::ai_snprintf(szTemp,512,"[m/d] UV V offset %f can be simplified to %f",info.mTranslation.y,out);
         }
         else if (aiTextureMapMode_Clamp == info.mapV || aiTextureMapMode_Decal == info.mapV)    {
             // Clamp - translations beyond 1,1 are senseless
-            sprintf(szTemp,"[c] UV V offset %f canbe clamped to 1.0f",info.mTranslation.y);
+            ::ai_snprintf(szTemp,512,"[c] UV V offset %f canbe clamped to 1.0f",info.mTranslation.y);
 
             out = 1.f;
         }
@@ -447,7 +447,7 @@ void TextureTransformStep::Execute( aiScene* pScene)
         if (size > AI_MAX_NUMBER_OF_TEXTURECOORDS) {
 
             if (!DefaultLogger::isNullLogger()) {
-                ::sprintf(buffer,"%u UV channels required but just %u available",
+                ::ai_snprintf(buffer,1024,"%u UV channels required but just %u available",
                     static_cast<unsigned int>(trafo.size()),AI_MAX_NUMBER_OF_TEXTURECOORDS);
 
                 DefaultLogger::get()->error(buffer);
@@ -475,7 +475,7 @@ void TextureTransformStep::Execute( aiScene* pScene)
 
             // Write to the log
             if (!DefaultLogger::isNullLogger()) {
-                sprintf(buffer,"Mesh %u, channel %u: t(%.3f,%.3f), s(%.3f,%.3f), r(%.3f), %s%s",
+                ::ai_snprintf(buffer,1024,"Mesh %u, channel %u: t(%.3f,%.3f), s(%.3f,%.3f), r(%.3f), %s%s",
                     q,n,
                     (*it).mTranslation.x,
                     (*it).mTranslation.y,
@@ -558,7 +558,7 @@ void TextureTransformStep::Execute( aiScene* pScene)
     if (!DefaultLogger::isNullLogger()) {
 
         if (transformedChannels)    {
-            ::sprintf(buffer,"TransformUVCoordsProcess end: %u output channels (in: %u, modified: %u)",
+            ::ai_snprintf(buffer,1024,"TransformUVCoordsProcess end: %u output channels (in: %u, modified: %u)",
                 outChannels,inChannels,transformedChannels);
 
             DefaultLogger::get()->info(buffer);

+ 1 - 1
code/TriangulateProcess.cpp

@@ -342,7 +342,7 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
                     for(;*loc != ' '; ++loc);
                     *loc++ = '_';
                 }
-                *(loc+sprintf(loc,"%i",i)) = ' ';
+                *(loc+::ai_snprintf(loc, POLY_GRID_XPAD,"%i",i)) = ' ';
             }
 
 

+ 2 - 2
code/UnrealLoader.cpp

@@ -377,7 +377,7 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
         aiColor3D color(1.f,1.f,1.f);
 
         aiString s;
-        ::snprintf( s.data, MAXLEN, "mat%u_tx%u_",i,materials[i].tex );
+        ::ai_snprintf( s.data, MAXLEN, "mat%u_tx%u_",i,materials[i].tex );
 
         // set the two-sided flag
         if (materials[i].type == Unreal::MF_NORMAL_TS) {
@@ -397,7 +397,7 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
 
         // a special name for the weapon attachment point
         if (materials[i].type == Unreal::MF_WEAPON_PLACEHOLDER) {
-            s.length = ::snprintf( s.data, MAXLEN, "$WeaponTag$" );
+            s.length = ::ai_snprintf( s.data, MAXLEN, "$WeaponTag$" );
             color = aiColor3D(0.f,0.f,0.f);
         }
 

+ 6 - 4
code/glTFAsset.inl

@@ -38,6 +38,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ----------------------------------------------------------------------
 */
 
+#include "StringUtils.h"
+
 namespace glTF {
 
 namespace {
@@ -840,7 +842,7 @@ inline void AssetMetadata::Read(Document& doc)
 
     if (version != 1) {
         char msg[128];
-		::snprintf(msg, 128, "Unsupported glTF version: %d", version);
+		Assimp::ai_snprintf(msg, 128, "Unsupported glTF version: %d", version);
         throw DeadlyImportError(msg);
     }
 }
@@ -923,7 +925,7 @@ inline void Asset::Load(const std::string& pFile, bool isBinary)
 
     if (doc.HasParseError()) {
         char buffer[32];
-        ::snprintf(buffer, 32, "%d", static_cast<int>(doc.GetErrorOffset()));
+        Assimp::ai_snprintf(buffer, 32, "%d", static_cast<int>(doc.GetErrorOffset()));
         throw DeadlyImportError(std::string("JSON parse error, offset ") + buffer + ": "
             + GetParseError_En(doc.GetParseError()));
     }
@@ -1027,9 +1029,9 @@ inline std::string Asset::FindUniqueID(const std::string& str, const char* suffi
         if (it == mUsedIds.end()) break;
 
         char buffer[256];
-        int offset = snprintf(buffer, 256, "%s_", id.c_str());
+        int offset = Assimp::ai_snprintf(buffer, 256, "%s_", id.c_str());
         for (int i = 0; it != mUsedIds.end(); ++i) {
-            ::snprintf(buffer + offset, 256, "%d", i);
+			Assimp::ai_snprintf(buffer + offset, 256, "%d", i);
 
             id = buffer;
             it = mUsedIds.find(id);

+ 1 - 1
code/glTFAssetWriter.inl

@@ -190,7 +190,7 @@ namespace glTF {
             else {
                 for (size_t i = 0; i < lst.size(); ++i) {
                     char buffer[32];
-                    snprintf(buffer, 32, "%s_%d", semantic, int(i));
+					Assimp::ai_snprintf(buffer, 32, "%s_%d", semantic, int(i));
                     attrs.AddMember(Value(buffer, w.mAl).Move(), Value(lst[i]->id, w.mAl).Move(), w.mAl);
                 }
             }

+ 1 - 1
code/glTFExporter.cpp

@@ -351,7 +351,7 @@ void glTFExporter::ExportMetadata()
     asset.version = 1;
 
     char buffer[256];
-    snprintf(buffer, 256, "Open Asset Import Library (assimp v%d.%d.%d)",
+    ai_snprintf(buffer, 256, "Open Asset Import Library (assimp v%d.%d.%d)",
         aiGetVersionMajor(), aiGetVersionMinor(), aiGetVersionRevision());
 
     asset.generator = buffer;

+ 4 - 4
contrib/zlib/gzwrite.c

@@ -351,10 +351,10 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
 #  endif
 #else
 #  ifdef HAS_vsnprintf_void
-    (void)vsnprintf((char *)(state->in), size, format, va);
+    (void)vai_snprintf((char *)(state->in), size, format, va);
     len = strlen((char *)(state->in));
 #  else
-    len = vsnprintf((char *)(state->in), size, format, va);
+    len = vai_snprintf((char *)(state->in), size, format, va);
 #  endif
 #endif
 
@@ -438,11 +438,11 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
 #  endif
 #else
 #  ifdef HAS_snprintf_void
-    snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8,
+    ai_snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8,
              a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
     len = strlen((char *)(state->in));
 #  else
-    len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6,
+    len = ai_snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6,
                    a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18,
                    a19, a20);
 #  endif