From fba0b493cdc3089433fe9951b35e3fcdb8f1a9e3 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Thu, 10 Dec 2015 12:25:46 +0100 Subject: [PATCH] Make sure that all strings in the IDO database are UTF8-encoded fixes #10554 --- lib/base/utility.cpp | 36 +++++++++++++++++++++++++ lib/base/utility.hpp | 2 ++ lib/db_ido_mysql/idomysqlconnection.cpp | 8 +++--- lib/db_ido_pgsql/idopgsqlconnection.cpp | 8 +++--- 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/lib/base/utility.cpp b/lib/base/utility.cpp index 834e5dec5..22b7ed380 100644 --- a/lib/base/utility.cpp +++ b/lib/base/utility.cpp @@ -1654,3 +1654,39 @@ String Utility::GetPlatformArchitecture(void) return UnameHelper('m'); #endif /* _WIN32 */ } + +String Utility::ValidateUTF8(const String& input) +{ + String output; + size_t length = input.GetLength(); + + for (size_t i = 0; i < length; i++) { + if ((input[i] & 0x80) == 0) { + output += input[i]; + continue; + } + + if ((input[i] & 0xE0) == 0xC0 && length > i + 1 && + (input[i + 1] & 0xC0) == 0x80) { + output += input[i]; + output += input[i + 1]; + i++; + continue; + } + + if ((input[i] & 0xF0) == 0xE0 && length > i + 2 && + (input[i + 1] & 0xC0) == 0x80 && (input[i + 2] & 0xC0) == 0x80) { + output += input[i]; + output += input[i + 1]; + output += input[i + 2]; + i += 2; + continue; + } + + output += '\xEF'; + output += '\xBF'; + output += '\xBD'; + } + + return output; +} diff --git a/lib/base/utility.hpp b/lib/base/utility.hpp index 3a44c176b..e4f4120e9 100644 --- a/lib/base/utility.hpp +++ b/lib/base/utility.hpp @@ -139,6 +139,8 @@ public: static String GetPlatformVersion(void); static String GetPlatformArchitecture(void); + static String ValidateUTF8(const String& input); + private: Utility(void); static void CollectPaths(const String& path, std::vector& paths); diff --git a/lib/db_ido_mysql/idomysqlconnection.cpp b/lib/db_ido_mysql/idomysqlconnection.cpp index 97b45e336..e9ddea685 100644 --- a/lib/db_ido_mysql/idomysqlconnection.cpp +++ b/lib/db_ido_mysql/idomysqlconnection.cpp @@ -574,10 +574,12 @@ String IdoMysqlConnection::Escape(const String& s) { AssertOnWorkQueue(); - size_t length = s.GetLength(); - char *to = new char[s.GetLength() * 2 + 1]; + String utf8s = Utility::ValidateUTF8(s); - mysql_real_escape_string(&m_Connection, to, s.CStr(), length); + size_t length = utf8s.GetLength(); + char *to = new char[utf8s.GetLength() * 2 + 1]; + + mysql_real_escape_string(&m_Connection, to, utf8s.CStr(), length); String result = String(to); diff --git a/lib/db_ido_pgsql/idopgsqlconnection.cpp b/lib/db_ido_pgsql/idopgsqlconnection.cpp index d93145c1d..1286717ef 100644 --- a/lib/db_ido_pgsql/idopgsqlconnection.cpp +++ b/lib/db_ido_pgsql/idopgsqlconnection.cpp @@ -464,10 +464,12 @@ String IdoPgsqlConnection::Escape(const String& s) { AssertOnWorkQueue(); - size_t length = s.GetLength(); - char *to = new char[s.GetLength() * 2 + 1]; + String utf8s = Utility::ValidateUTF8(s); - PQescapeStringConn(m_Connection, to, s.CStr(), length, NULL); + size_t length = utf8s.GetLength(); + char *to = new char[utf8s.GetLength() * 2 + 1]; + + PQescapeStringConn(m_Connection, to, utf8s.CStr(), length, NULL); String result = String(to); -- 2.40.0