From 8ccef75a9658e75a26ed1533364488ca33a1dfa2 Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Fri, 1 Jan 2021 23:50:23 +0200 Subject: [PATCH] QJsonValue review several bugs were discovered Signed-off-by: Ivailo Monev --- src/core/json/qjson.cpp | 2 +- src/core/json/qjsonvalue.cpp | 75 ++++++++++++------------------------ src/core/json/qjsonvalue.h | 15 ++------ 3 files changed, 30 insertions(+), 62 deletions(-) diff --git a/src/core/json/qjson.cpp b/src/core/json/qjson.cpp index fa3d281d4..0dc57a95a 100644 --- a/src/core/json/qjson.cpp +++ b/src/core/json/qjson.cpp @@ -423,7 +423,7 @@ void Value::copyData(const QJsonValue &v, char *dest, bool compressed) switch (v.t) { case QJsonValue::Double: if (!compressed) { - qToLittleEndian(v.ui, (uchar *)dest); + qToLittleEndian(v.dbl, (uchar *)dest); } break; case QJsonValue::String: { diff --git a/src/core/json/qjsonvalue.cpp b/src/core/json/qjsonvalue.cpp index c5e305c42..c74f7ed61 100644 --- a/src/core/json/qjsonvalue.cpp +++ b/src/core/json/qjsonvalue.cpp @@ -83,36 +83,34 @@ QT_BEGIN_NAMESPACE The default is to create a Null value. */ QJsonValue::QJsonValue(Type type) - : ui(0), d(0), t(type) + : b(false), dbl(0), stringData(Q_NULLPTR), base(Q_NULLPTR), d(Q_NULLPTR), t(type) { } /*! \internal */ -QJsonValue::QJsonValue(QJsonPrivate::Data *data, QJsonPrivate::Base *base, const QJsonPrivate::Value &v) - : d(0) +QJsonValue::QJsonValue(QJsonPrivate::Data *data, QJsonPrivate::Base *privbase, const QJsonPrivate::Value &v) + : b(false), dbl(0), stringData(Q_NULLPTR), base(Q_NULLPTR), d(Q_NULLPTR), t(static_cast(uint(v.type))) { - t = (Type)(uint)v.type; switch (t) { case Undefined: case Null: - dbl = 0; break; case Bool: b = v.toBoolean(); break; case Double: - dbl = v.toDouble(base); + dbl = v.toDouble(privbase); break; case String: { - stringData = new QString(v.toString(base)); + stringData = new QString(v.toString(privbase)); break; } case Array: case Object: d = data; - this->base = v.base(base); + base = v.base(privbase); break; } if (d) { @@ -121,21 +119,19 @@ QJsonValue::QJsonValue(QJsonPrivate::Data *data, QJsonPrivate::Base *base, const } /*! - Creates a value of type Bool, with value \a b. + Creates a value of type Bool, with value \a a. */ -QJsonValue::QJsonValue(bool b) - : d(0), t(Bool) +QJsonValue::QJsonValue(bool a) + : b(a), dbl(0), stringData(Q_NULLPTR), base(Q_NULLPTR), d(Q_NULLPTR), t(Bool) { - this->b = b; } /*! Creates a value of type Double, with value \a n. */ QJsonValue::QJsonValue(double n) - : d(0), t(Double) + : b(false), dbl(n), stringData(Q_NULLPTR), base(Q_NULLPTR), d(Q_NULLPTR), t(Double) { - this->dbl = n; } /*! @@ -143,9 +139,8 @@ QJsonValue::QJsonValue(double n) Creates a value of type Double, with value \a n. */ QJsonValue::QJsonValue(int n) - : d(0), t(Double) + : b(false), dbl(n), stringData(Q_NULLPTR), base(Q_NULLPTR), d(Q_NULLPTR), t(Double) { - this->dbl = n; } /*! @@ -155,36 +150,32 @@ QJsonValue::QJsonValue(int n) If you pass in values outside this range expect a loss of precision to occur. */ QJsonValue::QJsonValue(qint64 n) - : d(0), t(Double) + : b(false), dbl(n), stringData(Q_NULLPTR), base(Q_NULLPTR), d(Q_NULLPTR), t(Double) { - this->dbl = n; } /*! Creates a value of type String, with value \a s. */ QJsonValue::QJsonValue(const QString &s) - : d(0), t(String) + : b(false), dbl(0), stringData(new QString(s)), base(Q_NULLPTR), d(Q_NULLPTR), t(String) { - stringData = new QString(s); } /*! Creates a value of type String, with value \a s. */ QJsonValue::QJsonValue(QLatin1String s) - : d(0), t(String) + : b(false), dbl(0), stringData(new QString(s)), base(Q_NULLPTR), d(Q_NULLPTR), t(String) { - stringData = new QString(s); } /*! Creates a value of type Array, with value \a a. */ QJsonValue::QJsonValue(const QJsonArray &a) - : d(a.d), t(Array) + : b(false), dbl(0), stringData(Q_NULLPTR), base(a.a), d(a.d), t(Array) { - base = a.a; if (d) { d->ref.ref(); } @@ -194,9 +185,8 @@ QJsonValue::QJsonValue(const QJsonArray &a) Creates a value of type Object, with value \a o. */ QJsonValue::QJsonValue(const QJsonObject &o) - : d(o.d), t(Object) + : b(false), dbl(0), stringData(Q_NULLPTR), base(o.o), d(o.d), t(Object) { - base = o.o; if (d) { d->ref.ref(); } @@ -221,16 +211,14 @@ QJsonValue::~QJsonValue() Creates a copy of \a other. */ QJsonValue::QJsonValue(const QJsonValue &other) + : b(other.b), dbl(other.dbl), stringData(Q_NULLPTR), base(Q_NULLPTR), d(other.d), t(other.t) { - t = other.t; - d = other.d; - ui = other.ui; if (d) { d->ref.ref(); } - if (t == String && stringData) { - stringData = new QString(*stringData); + if (t == String && other.stringData) { + stringData = new QString(*other.stringData); } } @@ -241,25 +229,17 @@ QJsonValue &QJsonValue::operator =(const QJsonValue &other) { if (t == String) { delete stringData; + stringData = Q_NULLPTR; } t = other.t; + b = other.b; dbl = other.dbl; - if (d != other.d) { + qAtomicAssign(d, other.d); - if (d && !d->ref.deref()) { - delete d; - } - d = other.d; - if (d) { - d->ref.ref(); - } - - } - - if (t == String && stringData) { - stringData = new QString(*stringData); + if (t == String && other.stringData) { + stringData = new QString(*other.stringData); } return *this; @@ -621,12 +601,7 @@ void QJsonValue::detach() return; } - QJsonPrivate::Data *x = d->clone(base); - x->ref.ref(); - if (!d->ref.deref()) { - delete d; - } - d = x; + qAtomicAssign(d, d->clone(base)); base = static_cast(d->header->root()); } diff --git a/src/core/json/qjsonvalue.h b/src/core/json/qjsonvalue.h index 952a35034..0838ddcc7 100644 --- a/src/core/json/qjsonvalue.h +++ b/src/core/json/qjsonvalue.h @@ -136,17 +136,10 @@ class Q_CORE_EXPORT QJsonValue void detach(); - union { - quint64 ui; - bool b; - double dbl; - /* Qt 5 Beta 1 - QStringData *stringData; - */ - // Temporary for QStringData: - QString *stringData; - QJsonPrivate::Base *base; - }; + bool b; + double dbl; + QString *stringData; + QJsonPrivate::Base *base; QJsonPrivate::Data *d; // needed for Objects and Arrays Type t; };