From 667674731fb539f654bca88101c93a9accad84b8 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Sun, 16 Jul 2017 11:56:56 +0200 Subject: [PATCH] pyodbc: really fix endianess of SQL_WCHAR auto-endian auf UTF-16 doesn't work with all drivers, some fail to interpret the byte-order-marking. Hence explicitely use UTF16BE on big-endian systems and UTF16LE otherwise. Signed-off-by: Daniel Golle --- lang/python/pyodbc/Makefile | 2 +- ...-assume-SQL_C_WCHAR-is-native-endian.patch | 38 +++++++++++++------ 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/lang/python/pyodbc/Makefile b/lang/python/pyodbc/Makefile index e0c6d4058..1c20e7a63 100644 --- a/lang/python/pyodbc/Makefile +++ b/lang/python/pyodbc/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=pyodbc PKG_VERSION:=4.0.17 -PKG_RELEASE:=3 +PKG_RELEASE:=4 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://pypi.python.org/packages/ce/57/6b92aa5b3497dde6be55fd6fcb76c7db215ed1d56fde45c613add4a43095/ diff --git a/lang/python/pyodbc/patches/100-connection-assume-SQL_C_WCHAR-is-native-endian.patch b/lang/python/pyodbc/patches/100-connection-assume-SQL_C_WCHAR-is-native-endian.patch index e03cd9486..4d03cb72a 100644 --- a/lang/python/pyodbc/patches/100-connection-assume-SQL_C_WCHAR-is-native-endian.patch +++ b/lang/python/pyodbc/patches/100-connection-assume-SQL_C_WCHAR-is-native-endian.patch @@ -1,34 +1,50 @@ --- a/src/connection.cpp +++ b/src/connection.cpp -@@ -90,7 +90,7 @@ static bool Connect(PyObject* pConnectSt +@@ -18,6 +18,15 @@ + #include "cnxninfo.h" + #include "sqlwchar.h" + ++#include ++#if __BYTE_ORDER == __BIG_ENDIAN ++# define OPTENC_UTF16NE OPTENC_UTF16BE ++# define ENCSTR_UTF16NE "utf-16be" ++#else ++# define OPTENC_UTF16NE OPTENC_UTF16LE ++# define ENCSTR_UTF16NE "utf-16le" ++#endif ++ + #if PY_MAJOR_VERSION < 3 + static bool IsStringType(PyObject* t) { return (void*)t == (void*)&PyString_Type; } + static bool IsUnicodeType(PyObject* t) { return (void*)t == (void*)&PyUnicode_Type; } +@@ -90,7 +99,7 @@ static bool Connect(PyObject* pConnectSt // indication that we can handle Unicode. We are going to use the same unicode ending // as we do for binding parameters. - SQLWChar wchar(pConnectString, SQL_C_WCHAR, encoding, "utf-16le"); -+ SQLWChar wchar(pConnectString, SQL_C_WCHAR, encoding, "utf-16"); ++ SQLWChar wchar(pConnectString, SQL_C_WCHAR, encoding, ENCSTR_UTF16NE); if (!wchar) return false; -@@ -216,24 +216,24 @@ PyObject* Connection_New(PyObject* pConn +@@ -216,24 +225,24 @@ PyObject* Connection_New(PyObject* pConn // single-byte text we don't actually know what the encoding is. For example, with SQL // Server the encoding is based on the database's collation. We ask the driver / DB to // convert to SQL_C_WCHAR and use the ODBC default of UTF-16LE. - cnxn->sqlchar_enc.optenc = OPTENC_UTF16LE; - cnxn->sqlchar_enc.name = _strdup("utf-16le"); -+ cnxn->sqlchar_enc.optenc = OPTENC_UTF16; -+ cnxn->sqlchar_enc.name = _strdup("utf-16"); ++ cnxn->sqlchar_enc.optenc = OPTENC_UTF16NE; ++ cnxn->sqlchar_enc.name = _strdup(ENCSTR_UTF16NE); cnxn->sqlchar_enc.ctype = SQL_C_WCHAR; - cnxn->sqlwchar_enc.optenc = OPTENC_UTF16LE; - cnxn->sqlwchar_enc.name = _strdup("utf-16le"); -+ cnxn->sqlwchar_enc.optenc = OPTENC_UTF16; -+ cnxn->sqlwchar_enc.name = _strdup("utf-16"); ++ cnxn->sqlwchar_enc.optenc = OPTENC_UTF16NE; ++ cnxn->sqlwchar_enc.name = _strdup(ENCSTR_UTF16NE); cnxn->sqlwchar_enc.ctype = SQL_C_WCHAR; - cnxn->metadata_enc.optenc = OPTENC_UTF16LE; - cnxn->metadata_enc.name = _strdup("utf-16le"); -+ cnxn->metadata_enc.optenc = OPTENC_UTF16; -+ cnxn->metadata_enc.name = _strdup("utf-16"); ++ cnxn->metadata_enc.optenc = OPTENC_UTF16NE; ++ cnxn->metadata_enc.name = _strdup(ENCSTR_UTF16NE); cnxn->metadata_enc.ctype = SQL_C_WCHAR; // Note: I attempted to use UTF-8 here too since it can hold any type, but SQL Server fails @@ -37,8 +53,8 @@ // something, so we'll stay with the default ODBC conversions. - cnxn->unicode_enc.optenc = OPTENC_UTF16LE; - cnxn->unicode_enc.name = _strdup("utf-16le"); -+ cnxn->unicode_enc.optenc = OPTENC_UTF16; -+ cnxn->unicode_enc.name = _strdup("utf-16"); ++ cnxn->unicode_enc.optenc = OPTENC_UTF16NE; ++ cnxn->unicode_enc.name = _strdup(ENCSTR_UTF16NE); cnxn->unicode_enc.ctype = SQL_C_WCHAR; #if PY_MAJOR_VERSION < 3