diff --git a/simgear/misc/strutils.cxx b/simgear/misc/strutils.cxx index d3a483db..9b4066ac 100644 --- a/simgear/misc/strutils.cxx +++ b/simgear/misc/strutils.cxx @@ -667,8 +667,9 @@ std::string unescape(const char* s) if (!*++s) break; int v = 0; - for (int i = 0; i < 2 && isxdigit(*s); i++, s++) + for (/* empty */; isxdigit(*s); s++) { v = v * 16 + (isdigit(*s) ? *s - '0' : 10 + tolower(*s) - 'a'); + } r += v; continue; diff --git a/simgear/misc/strutils_test.cxx b/simgear/misc/strutils_test.cxx index d2c19cd9..a485e432 100644 --- a/simgear/misc/strutils_test.cxx +++ b/simgear/misc/strutils_test.cxx @@ -144,6 +144,11 @@ void test_unescape() SG_CHECK_EQUAL(strutils::unescape("\\ \\n\\t\\x41\\117a"), " \n\tAOa"); // Two chars: '\033' (ESC) followed by '2' SG_CHECK_EQUAL(strutils::unescape("\\0332"), "\0332"); + // Hex escapes have no length limit and terminate at the first character + // that is not a valid hexadecimal digit. + SG_CHECK_EQUAL(strutils::unescape("\\x00020|"), " |"); + SG_CHECK_EQUAL(strutils::unescape("\\xA"), "\n"); + SG_CHECK_EQUAL(strutils::unescape("\\xA-"), "\n-"); } void test_compare_versions()