diff --git a/simgear/misc/strutils.cxx b/simgear/misc/strutils.cxx index ff16e64c..47f0b4ef 100644 --- a/simgear/misc/strutils.cxx +++ b/simgear/misc/strutils.cxx @@ -26,6 +26,8 @@ #include "strutils.hxx" +#include + using std::string; using std::vector; using std::stringstream; @@ -484,6 +486,17 @@ std::string unescape(const char* s) return r; } +string sanitizePrintfFormat(const string& input) +{ + string::size_type i = input.find("%n"); + if (i != string::npos) { + SG_LOG(SG_IO, SG_WARN, "sanitizePrintfFormat: bad format string:" << input); + return string(); + } + + return input; +} + } // end namespace strutils } // end namespace simgear diff --git a/simgear/misc/strutils.hxx b/simgear/misc/strutils.hxx index 73e24fc4..977aa894 100644 --- a/simgear/misc/strutils.hxx +++ b/simgear/misc/strutils.hxx @@ -137,7 +137,7 @@ namespace simgear { /** * Like strcmp(), but for dotted versions strings NN.NN.NN - * any number of terms are support. + * any number of terms are supported. * @return 0 if versions match, -ve number if v1 is lower, +ve if v1 * is greater */ @@ -180,6 +180,13 @@ namespace simgear { inline std::string unescape(const std::string& str) { return unescape(str.c_str()); } + + /** + * Check a printf-style format string for dangerous (buffer-overflowing, + * memory re-writing) format tokens. If a problematic token is + * found, logs an error (SG_WARN) and returns an empty format string. + */ + std::string sanitizePrintfFormat(const std::string& input); } // end namespace strutils } // end namespace simgear diff --git a/simgear/scene/model/SGText.cxx b/simgear/scene/model/SGText.cxx index 747e4098..fdb7fe96 100644 --- a/simgear/scene/model/SGText.cxx +++ b/simgear/scene/model/SGText.cxx @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -43,7 +44,7 @@ public: offset( aOffset ), truncate( aTruncate ), numeric( aNumeric ), - format( aFormat ) + format( simgear::strutils::sanitizePrintfFormat( aFormat ) ) { if( format.empty() ) { if( numeric ) format = "%f";