QJsonValue review

several bugs were discovered

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2021-01-01 23:50:23 +02:00
parent e4f167ec4c
commit 8ccef75a96
3 changed files with 30 additions and 62 deletions

View file

@ -423,7 +423,7 @@ void Value::copyData(const QJsonValue &v, char *dest, bool compressed)
switch (v.t) { switch (v.t) {
case QJsonValue::Double: case QJsonValue::Double:
if (!compressed) { if (!compressed) {
qToLittleEndian(v.ui, (uchar *)dest); qToLittleEndian(v.dbl, (uchar *)dest);
} }
break; break;
case QJsonValue::String: { case QJsonValue::String: {

View file

@ -83,36 +83,34 @@ QT_BEGIN_NAMESPACE
The default is to create a Null value. The default is to create a Null value.
*/ */
QJsonValue::QJsonValue(Type type) 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 \internal
*/ */
QJsonValue::QJsonValue(QJsonPrivate::Data *data, QJsonPrivate::Base *base, const QJsonPrivate::Value &v) QJsonValue::QJsonValue(QJsonPrivate::Data *data, QJsonPrivate::Base *privbase, const QJsonPrivate::Value &v)
: d(0) : b(false), dbl(0), stringData(Q_NULLPTR), base(Q_NULLPTR), d(Q_NULLPTR), t(static_cast<Type>(uint(v.type)))
{ {
t = (Type)(uint)v.type;
switch (t) { switch (t) {
case Undefined: case Undefined:
case Null: case Null:
dbl = 0;
break; break;
case Bool: case Bool:
b = v.toBoolean(); b = v.toBoolean();
break; break;
case Double: case Double:
dbl = v.toDouble(base); dbl = v.toDouble(privbase);
break; break;
case String: { case String: {
stringData = new QString(v.toString(base)); stringData = new QString(v.toString(privbase));
break; break;
} }
case Array: case Array:
case Object: case Object:
d = data; d = data;
this->base = v.base(base); base = v.base(privbase);
break; break;
} }
if (d) { 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) QJsonValue::QJsonValue(bool a)
: d(0), t(Bool) : 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. Creates a value of type Double, with value \a n.
*/ */
QJsonValue::QJsonValue(double 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. Creates a value of type Double, with value \a n.
*/ */
QJsonValue::QJsonValue(int 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. If you pass in values outside this range expect a loss of precision to occur.
*/ */
QJsonValue::QJsonValue(qint64 n) 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. Creates a value of type String, with value \a s.
*/ */
QJsonValue::QJsonValue(const QString &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. Creates a value of type String, with value \a s.
*/ */
QJsonValue::QJsonValue(QLatin1String 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. Creates a value of type Array, with value \a a.
*/ */
QJsonValue::QJsonValue(const QJsonArray &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) { if (d) {
d->ref.ref(); d->ref.ref();
} }
@ -194,9 +185,8 @@ QJsonValue::QJsonValue(const QJsonArray &a)
Creates a value of type Object, with value \a o. Creates a value of type Object, with value \a o.
*/ */
QJsonValue::QJsonValue(const QJsonObject &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) { if (d) {
d->ref.ref(); d->ref.ref();
} }
@ -221,16 +211,14 @@ QJsonValue::~QJsonValue()
Creates a copy of \a other. Creates a copy of \a other.
*/ */
QJsonValue::QJsonValue(const QJsonValue &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) { if (d) {
d->ref.ref(); d->ref.ref();
} }
if (t == String && stringData) { if (t == String && other.stringData) {
stringData = new QString(*stringData); stringData = new QString(*other.stringData);
} }
} }
@ -241,25 +229,17 @@ QJsonValue &QJsonValue::operator =(const QJsonValue &other)
{ {
if (t == String) { if (t == String) {
delete stringData; delete stringData;
stringData = Q_NULLPTR;
} }
t = other.t; t = other.t;
b = other.b;
dbl = other.dbl; dbl = other.dbl;
if (d != other.d) { qAtomicAssign(d, other.d);
if (d && !d->ref.deref()) { if (t == String && other.stringData) {
delete d; stringData = new QString(*other.stringData);
}
d = other.d;
if (d) {
d->ref.ref();
}
}
if (t == String && stringData) {
stringData = new QString(*stringData);
} }
return *this; return *this;
@ -621,12 +601,7 @@ void QJsonValue::detach()
return; return;
} }
QJsonPrivate::Data *x = d->clone(base); qAtomicAssign(d, d->clone(base));
x->ref.ref();
if (!d->ref.deref()) {
delete d;
}
d = x;
base = static_cast<QJsonPrivate::Object *>(d->header->root()); base = static_cast<QJsonPrivate::Object *>(d->header->root());
} }

View file

@ -136,17 +136,10 @@ class Q_CORE_EXPORT QJsonValue
void detach(); void detach();
union { bool b;
quint64 ui; double dbl;
bool b; QString *stringData;
double dbl; QJsonPrivate::Base *base;
/* Qt 5 Beta 1
QStringData *stringData;
*/
// Temporary for QStringData:
QString *stringData;
QJsonPrivate::Base *base;
};
QJsonPrivate::Data *d; // needed for Objects and Arrays QJsonPrivate::Data *d; // needed for Objects and Arrays
Type t; Type t;
}; };