From ca857fcb25a2fae93f29f489ced080fe32a26d20 Mon Sep 17 00:00:00 2001 From: James Turner Date: Tue, 10 Nov 2020 11:43:39 +0000 Subject: [PATCH] Strutils: add printf format validation Moved from NewGUI code in FG, better it lives here for re-use. --- simgear/misc/strutils.cxx | 50 +++++++++++++++++++++++++++++++++++++++ simgear/misc/strutils.hxx | 13 ++++++++++ 2 files changed, 63 insertions(+) diff --git a/simgear/misc/strutils.cxx b/simgear/misc/strutils.cxx index 36d20418..51ade886 100644 --- a/simgear/misc/strutils.cxx +++ b/simgear/misc/strutils.cxx @@ -1587,6 +1587,56 @@ std::string formatGeodAsString(const SGGeod& geod, LatLonFormat format, + formatLatLonValueAsString(geod.getLongitudeDeg(), format, ew, degreeSymbol); } +PrintfFormatType validatePrintfFormat(const char* f) +{ + bool l = false; + for (; *f; f++) { + if (*f == '%') { + if (f[1] == '%') + f++; + else + break; + } + } + if (*f++ != '%') + return PrintfFormatType::Invalid; + + PrintfFormatType type = PrintfFormatType::Invalid; + while (*f == ' ' || *f == '+' || *f == '-' || *f == '#' || *f == '0') + f++; + while (*f && isdigit(*f)) + f++; + if (*f == '.') { + f++; + while (*f && isdigit(*f)) + f++; + } + + if (*f == 'l') + l = true, f++; + + if (*f == 'd') { + type = l ? PrintfFormatType::Long : PrintfFormatType::Int; + } else if (*f == 'f') + type = l ? PrintfFormatType::Double : PrintfFormatType::Float; + else if (*f == 's') { + if (l) + return PrintfFormatType::Invalid; + type = PrintfFormatType::CharPointer; + } else + return PrintfFormatType::Invalid; + + for (++f; *f; f++) { + if (*f == '%') { + if (f[1] == '%') + f++; + else + return PrintfFormatType::Invalid; + } + } + return type; +} + } // end namespace strutils } // end namespace simgear diff --git a/simgear/misc/strutils.hxx b/simgear/misc/strutils.hxx index 6175e2a1..139882f8 100644 --- a/simgear/misc/strutils.hxx +++ b/simgear/misc/strutils.hxx @@ -448,6 +448,19 @@ namespace simgear { std::string formatGeodAsString(const SGGeod& geod, LatLonFormat format = LatLonFormat::DECIMAL_DEGREES, DegreeSymbol degreeSymbol = DegreeSymbol::ASTERISK); + + + enum class PrintfFormatType { + Invalid, + Int, + Long, + Float, + Double, + CharPointer + }; + + PrintfFormatType validatePrintfFormat(const char* f); + } // end namespace strutils } // end namespace simgear