diff options
author | est31 <MTest31@outlook.com> | 2015-06-17 19:00:31 +0200 |
---|---|---|
committer | est31 <MTest31@outlook.com> | 2015-06-17 19:03:58 +0200 |
commit | 6dcf549ba9d522ed991184401658e85d3554ad8e (patch) | |
tree | 91e5a985ab903de6724927404223f3422cf7f023 /src | |
parent | a1a2ac7954e09b3c53c4f0ce1a7f88abf631afcd (diff) | |
download | minetest-6dcf549ba9d522ed991184401658e85d3554ad8e.tar.gz minetest-6dcf549ba9d522ed991184401658e85d3554ad8e.tar.bz2 minetest-6dcf549ba9d522ed991184401658e85d3554ad8e.zip |
Fail iconv call gracefully
No freezing when inbuf_size doesn't decrease over time.
Diffstat (limited to 'src')
-rw-r--r-- | src/util/string.cpp | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/src/util/string.cpp b/src/util/string.cpp index 0a7ab5c3a..e847f3a8e 100644 --- a/src/util/string.cpp +++ b/src/util/string.cpp @@ -40,7 +40,7 @@ static bool parseHexColorString(const std::string &value, video::SColor &color); static bool parseNamedColorString(const std::string &value, video::SColor &color); #ifndef _WIN32 -size_t convert(const char *to, const char *from, char *outbuf, +bool convert(const char *to, const char *from, char *outbuf, size_t outbuf_size, char *inbuf, size_t inbuf_size) { iconv_t cd = iconv_open(to, from); @@ -56,11 +56,18 @@ size_t convert(const char *to, const char *from, char *outbuf, size_t *inbuf_left_ptr = &inbuf_size; size_t *outbuf_left_ptr = &outbuf_size; - while (inbuf_size > 0) + size_t old_size = inbuf_size; + while (inbuf_size > 0) { iconv(cd, &inbuf_ptr, inbuf_left_ptr, &outbuf_ptr, outbuf_left_ptr); + if (inbuf_size == old_size) { + iconv_close(cd); + return false; + } + old_size = inbuf_size; + } iconv_close(cd); - return 0; + return true; } std::wstring utf8_to_wide(const std::string &input) @@ -74,7 +81,13 @@ std::wstring utf8_to_wide(const std::string &input) char *outbuf = new char[outbuf_size]; memset(outbuf, 0, outbuf_size); - convert("WCHAR_T", "UTF-8", outbuf, outbuf_size, inbuf, inbuf_size); + if (!convert("WCHAR_T", "UTF-8", outbuf, outbuf_size, inbuf, inbuf_size)) { + infostream << "Couldn't convert UTF-8 string 0x" << hex_encode(input) + << " into wstring" << std::endl; + delete[] inbuf; + delete[] outbuf; + return L"<invalid UTF-8 string>"; + } std::wstring out((wchar_t*)outbuf); delete[] inbuf; @@ -101,7 +114,13 @@ std::string wide_to_utf8(const std::wstring &input) char *outbuf = new char[outbuf_size]; memset(outbuf, 0, outbuf_size); - convert("UTF-8", "WCHAR_T", outbuf, outbuf_size, inbuf, inbuf_size); + if (!convert("UTF-8", "WCHAR_T", outbuf, outbuf_size, inbuf, inbuf_size)) { + infostream << "Couldn't convert wstring 0x" << hex_encode(inbuf, inbuf_size) + << " into wstring" << std::endl; + delete[] inbuf; + delete[] outbuf; + return "<invalid wstring>"; + } std::string out(outbuf); delete[] inbuf; |