File MySQL-treat-the-MYSQL_FIELD-as-read-only.patch of Package libqt4

From 549ee216fd5bf2b3810e940bcbd4bbd8c64ac73f Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@intel.com>
Date: Fri, 13 Aug 2021 15:19:55 -0700
Subject: [PATCH] MySQL: treat the MYSQL_FIELD as read-only

The MariaDB-connector-c version 3.2 and MariaDB server version 10.6
cooperate to avoid re-transferring the query metadata, so the fact that
we were modifying it was causing it to improperly decode the DATETIME
data types into string, as we had asked. We ended up with a 7-byte
string that was actually the date binary-encoded.

References:
 - https://jira.mariadb.org/browse/MDEV-26271
 - https://github.com/MythTV/mythtv/issues/373
 - https://bugs.kde.org/show_bug.cgi?id=440296

Pick-to: 5.12 5.15 6.2
Fixes: QTBUG-95639
Change-Id: I4a40ccbd3321467a8429fffd169afdbb26cf29f6
Reviewed-by: Andy Shaw <andy.shaw@qt.io>
---

diff --git a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
index 2c0ccc8..95d5bb3 100644
--- a/src/sql/drivers/mysql/qsql_mysql.cpp
+++ b/src/sql/drivers/mysql/qsql_mysql.cpp
@@ -196,7 +196,7 @@
         char *outField;
         my_bool nullIndicator;
         ulong bufLength;
-        MYSQL_FIELD *myField;
+        const MYSQL_FIELD *myField;
         QVariant::Type type;
     };
 
@@ -333,7 +333,7 @@
 void QMYSQLResultPrivate::bindBlobs()
 {
     int i;
-    MYSQL_FIELD *fieldInfo;
+    const MYSQL_FIELD *fieldInfo;
     MYSQL_BIND *bind;
 
     for(i = 0; i < fields.count(); ++i) {
@@ -364,39 +364,38 @@
     inBinds = new MYSQL_BIND[fields.size()];
     memset(inBinds, 0, fields.size() * sizeof(MYSQL_BIND));
 
-    MYSQL_FIELD *fieldInfo;
+    const MYSQL_FIELD *fieldInfo;
 
     while((fieldInfo = mysql_fetch_field(meta))) {
+        bind = &inBinds[i];
+
         QMyField &f = fields[i];
         f.myField = fieldInfo;
-
+        bind->buffer_length = f.bufLength = fieldInfo->length + 1;
+        bind->buffer_type = fieldInfo->type;
         f.type = qDecodeMYSQLType(fieldInfo->type, fieldInfo->flags);
         if (qIsBlob(fieldInfo->type)) {
             // the size of a blob-field is available as soon as we call
             // mysql_stmt_store_result()
             // after mysql_stmt_exec() in QMYSQLResult::exec()
-            fieldInfo->length = 0;
+            bind->buffer_length = f.bufLength = 0;
             hasBlobs = true;
         } else {
             // fieldInfo->length specifies the display width, which may be too
             // small to hold valid integer values (see
             // http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html ), so
             // always use the MAX_BIGINT_WIDTH for integer types
             if (qIsInteger(fieldInfo->type)) {
-                fieldInfo->length = MAX_BIGINT_WIDTH;
+                bind->buffer_length = f.bufLength = MAX_BIGINT_WIDTH;
             }
-            fieldInfo->type = MYSQL_TYPE_STRING;
+            bind->buffer_type = MYSQL_TYPE_STRING;
         }
-        bind = &inBinds[i];
-        field = new char[fieldInfo->length + 1];
-        memset(field, 0, fieldInfo->length + 1);
 
-        bind->buffer_type = fieldInfo->type;
-        bind->buffer = field;
-        bind->buffer_length = f.bufLength = fieldInfo->length + 1;
         bind->is_null = &f.nullIndicator;
         bind->length = &f.bufLength;
-        f.outField=field;
+
+        field = new char[bind->buffer_length + 1]{};
+        bind->buffer = f.outField = field;
 
         ++i;
     }
openSUSE Build Service is sponsored by