summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2021-11-29 13:43:16 +0100
committerEdward Welbourne <edward.welbourne@qt.io>2021-11-30 16:34:01 +0100
commit064c3d35e6809672323e8d912e9140ddd0ad48cd (patch)
tree2efc99f7fb086cbc9d84dd0f721ffa99746bb224 /src
parentdafed13eb563cb3060787468f1ea0f6ca5f39703 (diff)
Don't allocate an OCIDateTime object unless we're going to use it
The QOCIDateTime destructor carefully checks that dateTime is non-null before tidying it away, but the constructor allocated it independently of whether it was used, leaving it in a still-not-constructed state if the date-time it was to represent was invalid. Only allocate if the date-time is valid; and check against null when an OCIDateTime is being converted back to QDateTime. Add warnings if either allocation or construction fails. Incidentally use static_cast<> instead of C-casting (and split a long line) in the other place that allocates an OCIDateTime descriptor. Pick-to: 6.2 5.15 Task-number: QTBUG-98471 Change-Id: Idd5531d9f7101878802cb9a3a016d3fd80903543 Reviewed-by: Andy Shaw <andy.shaw@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/sqldrivers/oci/qsql_oci.cpp29
1 files changed, 22 insertions, 7 deletions
diff --git a/src/plugins/sqldrivers/oci/qsql_oci.cpp b/src/plugins/sqldrivers/oci/qsql_oci.cpp
index 638b01b022..b0f68c0d09 100644
--- a/src/plugins/sqldrivers/oci/qsql_oci.cpp
+++ b/src/plugins/sqldrivers/oci/qsql_oci.cpp
@@ -168,16 +168,27 @@ public:
QOCIDateTime::QOCIDateTime(OCIEnv *env, OCIError *err, const QDateTime &dt)
: dateTime(nullptr)
{
- OCIDescriptorAlloc(env, reinterpret_cast<void**>(&dateTime), OCI_DTYPE_TIMESTAMP_TZ, 0, 0);
- if (dt.isValid()) {
+ if (!dt.isValid()) {
+ // nothing to do, leave dateTime null
+ } else if (OCIDescriptorAlloc(env, reinterpret_cast<void**>(&dateTime),
+ OCI_DTYPE_TIMESTAMP_TZ, 0, 0) == OCI_SUCCESS) {
+ Q_ASSERT(!dt.isNull());
const QDate date = dt.date();
+ Q_ASSERT(date.isValid());
const QTime time = dt.time();
+ Q_ASSERT(time.isValid());
// Zone in +hh:mm format (stripping UTC prefix from OffsetName)
- QString timeZone = dt.timeZone().displayName(dt, QTimeZone::OffsetName).mid(3);
+ QString timeZone = dt.timeZone().displayName(dt, QTimeZone::OffsetName);
+ Q_ASSERT(timeZone.startsWith(u"UTC"));
+ timeZone = std::move(timeZone).sliced(3);
const OraText *tz = reinterpret_cast<const OraText *>(timeZone.utf16());
- OCIDateTimeConstruct(env, err, dateTime, date.year(), date.month(), date.day(), time.hour(),
- time.minute(), time.second(), time.msec() * 1000000,
- const_cast<OraText *>(tz), timeZone.length() * sizeof(QChar));
+ if (OCIDateTimeConstruct(env, err, dateTime, date.year(), date.month(), date.day(),
+ time.hour(), time.minute(), time.second(), time.msec() * 1000000,
+ const_cast<OraText *>(tz), timeZone.length() * sizeof(QChar))) {
+ qWarning("QOCIDateTime: Failed to construct the OCIDateTime descriptor");
+ }
+ } else {
+ qWarning("QOCIDateTime: Failed to allocate the OCIDateTime descriptor");
}
}
@@ -189,6 +200,9 @@ QOCIDateTime::~QOCIDateTime()
QDateTime QOCIDateTime::fromOCIDateTime(OCIEnv *env, OCIError *err, OCIDateTime *dateTime)
{
+ if (!dateTime)
+ return QDateTime();
+
sb2 year;
ub1 month, day, hour, minute, second;
ub4 nsec;
@@ -937,7 +951,8 @@ QOCICols::QOCICols(int size, QOCIResultPrivate* dp)
switch (ofi.type.id()) {
case QMetaType::QDateTime:
- r = OCIDescriptorAlloc(d->env, (void **)&fieldInf[idx].dataPtr, OCI_DTYPE_TIMESTAMP_TZ, 0, 0);
+ r = OCIDescriptorAlloc(d->env, static_cast<void **>(&fieldInf[idx].dataPtr),
+ OCI_DTYPE_TIMESTAMP_TZ, 0, 0);
if (r != OCI_SUCCESS) {
qWarning("QOCICols: Unable to allocate the OCIDateTime descriptor");
break;