diff options
author | Marc Mutz <marc.mutz@qt.io> | 2023-01-31 11:06:56 +0100 |
---|---|---|
committer | Marc Mutz <marc.mutz@qt.io> | 2023-02-02 08:32:57 +0000 |
commit | 54fd964b179569dec2dc3e8e301e6ff928278323 (patch) | |
tree | 4a03569b44ac05ecbe16caa280d052222af8ebf2 | |
parent | 5c3dd23ac7637ab13f1d4c092bd2a5feed526fbc (diff) |
ODBC SQL driver: fix conversion of QByteArray to QVLA<SQLTCHAR>
The QByteArray is assumed to contain an SQLTCHAR string (so, either
UTF-8, UTF-16 or UTF-32-encoded). Only in the UTF-8 case would the
size of the byte array be the same as the size of the SQLTCHAR string
in codepoints, yet the size in bytes is what the code passed to the
QVLA<SQLTCHAR> append() call, causing it to read past the QByteArray
buffer in the UTF-16 and UTF-32 cases.
Fix by properly calculating the string size from the size-in-bytes and
then memcpy()ing into the QVLA. We use memcpy() and not
QVLA::append(T*, n) because the QByteArray buffer need not be aligned
on an alignof(SQLTCHAR) boundary (certainly not since it gained the
prepend "optimization").
Manual conflict resolutions:
- dealt with 32-bit-ness of container size_type vs. Qt 6's 64-bit
Change-Id: If3838c3dee89e6aca65541242642315b8e1fa6b4
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 4c445ef0bae8b36ec4a742552f0ebd81a1a90723)
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
-rw-r--r-- | src/plugins/sqldrivers/odbc/qsql_odbc.cpp | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp index 2cddefd6e7..fdef313d46 100644 --- a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp +++ b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp @@ -1732,10 +1732,11 @@ bool QODBCResult::exec() case QVariant::String: if (d->unicode) { if (bindValueType(i) & QSql::Out) { - const QByteArray &first = tmpStorage.at(i); - QVarLengthArray<SQLTCHAR> array; - array.append((const SQLTCHAR *)first.constData(), first.size()); - values[i] = fromSQLTCHAR(array, first.size()/sizeof(SQLTCHAR)); + const QByteArray &bytes = tmpStorage.at(i); + const auto strSize = bytes.size() / int(sizeof(SQLTCHAR)); + QVarLengthArray<SQLTCHAR> string(strSize); + memcpy(string.data(), bytes.data(), strSize * sizeof(SQLTCHAR)); + values[i] = fromSQLTCHAR(string); } break; } |