summaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorest31 <MTest31@outlook.com>2015-06-17 19:00:31 +0200
committerest31 <MTest31@outlook.com>2015-06-17 19:03:58 +0200
commit6dcf549ba9d522ed991184401658e85d3554ad8e (patch)
tree91e5a985ab903de6724927404223f3422cf7f023 /src/util
parenta1a2ac7954e09b3c53c4f0ce1a7f88abf631afcd (diff)
downloadminetest-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/util')
-rw-r--r--src/util/string.cpp29
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;