diff --git a/src/nhttpd/yhttpd_core/yhook.cpp b/src/nhttpd/yhttpd_core/yhook.cpp index 0fd1f59fe..6cdce404b 100644 --- a/src/nhttpd/yhttpd_core/yhook.cpp +++ b/src/nhttpd/yhttpd_core/yhook.cpp @@ -10,6 +10,8 @@ // UTF8 convert #include +#include + // yhttpd #include "yhook.h" #include "helper.h" @@ -542,7 +544,7 @@ std::string CyhookHandler::outValue(std::string _content) { std::string result = ""; switch (outType) { case xml: - result = convert_UTF8_To_UTF8_XML(_content.c_str()); + result = convert_UTF8_To_UTF8_XML(utf8_check_is_valid(_content) ? _content.c_str() : iso_8859_1_to_utf8(_content).c_str()); break; case json: result = json_convert_string(_content); diff --git a/src/system/helpers.cpp b/src/system/helpers.cpp index a117a7c7d..c198ff271 100644 --- a/src/system/helpers.cpp +++ b/src/system/helpers.cpp @@ -1651,3 +1651,60 @@ bool parseJsonFromString(string& jData, Json::Value *root, string *errMsg) delete reader; return ret; } + +std::string iso_8859_1_to_utf8(std::string &str) +{ + std::string strOut; + for (std::string::iterator it = str.begin(); it != str.end(); ++it) + { + uint8_t ch = *it; + if (ch < 0x80) + { + strOut.push_back(ch); + } + else + { + strOut.push_back(0xc0 | ch >> 6); + strOut.push_back(0x80 | (ch & 0x3f)); + } + } + return strOut; +} + +bool utf8_check_is_valid(const std::string &str) +{ + int c, i, ix, n, j; + for (i = 0, ix = str.length(); i < ix; i++) + { + c = (unsigned char) str[i]; + /* + if (c==0x09 || c==0x0a || c==0x0d || (0x20 <= c && c <= 0x7e)) + n = 0; // is_printable_ascii + */ + if (0x00 <= c && c <= 0x7f) + n = 0; // 0bbbbbbb + else if ((c & 0xE0) == 0xC0) + n = 1; // 110bbbbb + else if (c == 0xed && i < (ix - 1) && ((unsigned char)str[i + 1] & 0xa0) == 0xa0) + return false; // U+d800 to U+dfff + else if ((c & 0xF0) == 0xE0) + n = 2; // 1110bbbb + else if ((c & 0xF8) == 0xF0) + n = 3; // 11110bbb + /* + else if (($c & 0xFC) == 0xF8) + n=4; // 111110bb //byte 5, unnecessary in 4 byte UTF-8 + else if (($c & 0xFE) == 0xFC) + n=5; // 1111110b //byte 6, unnecessary in 4 byte UTF-8 + */ + else + return false; + + for (j = 0; j < n && i < ix; j++) // n bytes matching 10bbbbbb follow? + { + if ((++i == ix) || (((unsigned char)str[i] & 0xC0) != 0x80)) + return false; + } + } + return true; +} diff --git a/src/system/helpers.h b/src/system/helpers.h index c39eac448..2c0827083 100644 --- a/src/system/helpers.h +++ b/src/system/helpers.h @@ -157,4 +157,7 @@ inline bool file_exists(const std::string file) { return file_exists(file.c_str( std::string readFile(std::string file); +std::string iso_8859_1_to_utf8(std::string &str); +bool utf8_check_is_valid(const std::string &str); + #endif