diff --git a/code/AssetLib/HMP/HMPLoader.cpp b/code/AssetLib/HMP/HMPLoader.cpp index 56401f5c9..cd14cb9c3 100644 --- a/code/AssetLib/HMP/HMPLoader.cpp +++ b/code/AssetLib/HMP/HMPLoader.cpp @@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "AssetLib/HMP/HMPLoader.h" #include "AssetLib/MD2/MD2FileData.h" +#include #include #include #include @@ -151,12 +152,7 @@ void HMPImporter::InternReadFile(const std::string &pFile, InternReadFile_HMP7(); } else { // Print the magic word to the logger - char szBuffer[5]; - szBuffer[0] = ((char *)&iMagic)[0]; - szBuffer[1] = ((char *)&iMagic)[1]; - szBuffer[2] = ((char *)&iMagic)[2]; - szBuffer[3] = ((char *)&iMagic)[3]; - szBuffer[4] = '\0'; + std::string szBuffer = ai_str_toprintable((const char *)&iMagic, sizeof(iMagic)); delete[] mBuffer; mBuffer = nullptr; diff --git a/code/AssetLib/MDL/MDLLoader.cpp b/code/AssetLib/MDL/MDLLoader.cpp index a4286a716..4c0fcd339 100644 --- a/code/AssetLib/MDL/MDLLoader.cpp +++ b/code/AssetLib/MDL/MDLLoader.cpp @@ -252,7 +252,7 @@ void MDLImporter::InternReadFile(const std::string &pFile, } else { // print the magic word to the log file throw DeadlyImportError("Unknown MDL subformat ", pFile, - ". Magic word (", std::string((char *)&iMagicWord, 4), ") is not known"); + ". Magic word (", ai_str_toprintable((const char *)&iMagicWord, sizeof(iMagicWord)), ") is not known"); } // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system diff --git a/code/AssetLib/Q3D/Q3DLoader.cpp b/code/AssetLib/Q3D/Q3DLoader.cpp index b52f86672..b6684d1b8 100644 --- a/code/AssetLib/Q3D/Q3DLoader.cpp +++ b/code/AssetLib/Q3D/Q3DLoader.cpp @@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // internal headers #include "Q3DLoader.h" +#include #include #include #include @@ -115,7 +116,7 @@ void Q3DImporter::InternReadFile(const std::string &pFile, // Check the file's signature if (ASSIMP_strincmp((const char *)stream.GetPtr(), "quick3Do", 8) && ASSIMP_strincmp((const char *)stream.GetPtr(), "quick3Ds", 8)) { - throw DeadlyImportError("Not a Quick3D file. Signature string is: ", std::string((const char *)stream.GetPtr(), 8)); + throw DeadlyImportError("Not a Quick3D file. Signature string is: ", ai_str_toprintable((const char *)stream.GetPtr(), 8)); } // Print the file format version diff --git a/include/assimp/StringUtils.h b/include/assimp/StringUtils.h index 4afd717cf..5ee1f48d8 100644 --- a/include/assimp/StringUtils.h +++ b/include/assimp/StringUtils.h @@ -249,4 +249,31 @@ AI_FORCE_INLINE std::string ai_str_toupper(const std::string &in) { return out; } +// --------------------------------------------------------------------------------- +/// @brief Make a string printable by replacing all non-printable characters with +/// the specified placeholder character. +/// @param in The incoming string. +/// @param placeholder Placeholder character, default is a question mark. +/// @return The string, with all non-printable characters replaced. +AI_FORCE_INLINE std::string ai_str_toprintable(const std::string &in, char placeholder = '?') { + std::string out(in); + std::transform(out.begin(), out.end(), out.begin(), [placeholder] (unsigned char c) { + return isprint(c) ? (char)c : placeholder; + }); + return out; +} + +// --------------------------------------------------------------------------------- +/// @brief Make a string printable by replacing all non-printable characters with +/// the specified placeholder character. +/// @param in The incoming string. +/// @param len The length of the incoming string. +/// @param placeholder Placeholder character, default is a question mark. +/// @return The string, with all non-printable characters replaced. Will return an +/// empty string if in is null or len is <= 0. +AI_FORCE_INLINE std::string ai_str_toprintable(const char *in, int len, char placeholder = '?') { + return (in && len > 0) ? ai_str_toprintable(std::string(in, len), placeholder) : std::string(); +} + + #endif