QDom: use QLocale::C when converting a double to a xml attribute

QDomElement::setAttribute(QString, double) did not use QString::setNum()
but qsnprintf(). This is wrong because qsnprintf() is using the current
locale instead QLocale::C. It was also inconsistent to
QDomElement::setAttributeNS() which was already using QString::setNum().

Also fix the documentation which stated that all
QDomElement::setAttribute() format the values according the current
locale.

Fixes: QTBUG-80068
Change-Id: Iabb0b39c0d0723060527542c283a5435f26f31ca
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Christian Ehrlicher 2019-11-15 21:46:32 +01:00
parent ede867f581
commit d7cb21ac08
2 changed files with 76 additions and 12 deletions

View File

@ -4818,20 +4818,20 @@ void QDomElement::setAttribute(const QString& name, const QString& value)
\fn void QDomElement::setAttribute(const QString& name, int value)
\overload
The number is formatted according to the current locale.
The formatting always uses QLocale::C.
*/
/*!
\fn void QDomElement::setAttribute(const QString& name, uint value)
\overload
The number is formatted according to the current locale.
The formatting always uses QLocale::C.
*/
/*!
\overload
The number is formatted according to the current locale.
The formatting always uses QLocale::C.
*/
void QDomElement::setAttribute(const QString& name, qlonglong value)
{
@ -4845,7 +4845,7 @@ void QDomElement::setAttribute(const QString& name, qlonglong value)
/*!
\overload
The number is formatted according to the current locale.
The formatting always uses QLocale::C.
*/
void QDomElement::setAttribute(const QString& name, qulonglong value)
{
@ -4859,7 +4859,7 @@ void QDomElement::setAttribute(const QString& name, qulonglong value)
/*!
\overload
The number is formatted according to the current locale.
The formatting always uses QLocale::C.
*/
void QDomElement::setAttribute(const QString& name, float value)
{
@ -4873,19 +4873,14 @@ void QDomElement::setAttribute(const QString& name, float value)
/*!
\overload
The number is formatted according to the current locale.
The formatting always uses QLocale::C.
*/
void QDomElement::setAttribute(const QString& name, double value)
{
if (!impl)
return;
QString x;
char buf[256];
int count = qsnprintf(buf, sizeof(buf), "%.16g", value);
if (count > 0)
x = QString::fromLatin1(buf, count);
else
x.setNum(value); // Fallback
x.setNum(value);
IMPL->setAttribute(name, x);
}

View File

@ -57,6 +57,7 @@ private slots:
void toString_02();
void hasAttributes_data();
void hasAttributes();
void setGetAttributes();
void save_data();
void save();
void saveWithSerialization() const;
@ -392,6 +393,74 @@ void tst_QDom::hasAttributes()
QTEST( visitedNodes, "visitedNodes" );
}
void tst_QDom::setGetAttributes()
{
QDomDocument doc;
QDomElement rootNode = doc.createElement("Root");
doc.appendChild(rootNode);
const QLocale oldLocale = QLocale();
QLocale::setDefault(QLocale::German); // decimal separator != '.'
const QString qstringVal("QString");
const qlonglong qlonglongVal = std::numeric_limits<qlonglong>::min();
const qulonglong qulonglongVal = std::numeric_limits<qulonglong>::max();
const int intVal = std::numeric_limits<int>::min();
const uint uintVal = std::numeric_limits<uint>::max();
const float floatVal = 0.1234f;
const double doubleVal = 0.1234;
rootNode.setAttribute("qstringVal", qstringVal);
rootNode.setAttribute("qlonglongVal", qlonglongVal);
rootNode.setAttribute("qulonglongVal", qulonglongVal);
rootNode.setAttribute("intVal", intVal);
rootNode.setAttribute("uintVal", uintVal);
rootNode.setAttribute("floatVal", floatVal);
rootNode.setAttribute("doubleVal", doubleVal);
QDomElement nsNode = doc.createElement("NS");
rootNode.appendChild(nsNode);
nsNode.setAttributeNS("namespace", "qstringVal", qstringVal);
nsNode.setAttributeNS("namespace", "qlonglongVal", qlonglongVal);
nsNode.setAttributeNS("namespace", "qulonglongVal", qulonglongVal);
nsNode.setAttributeNS("namespace", "intVal", intVal);
nsNode.setAttributeNS("namespace", "uintVal", uintVal);
nsNode.setAttributeNS("namespace", "floatVal", floatVal); // not available atm
nsNode.setAttributeNS("namespace", "doubleVal", doubleVal);
bool bOk;
QCOMPARE(rootNode.attribute("qstringVal"), qstringVal);
QCOMPARE(rootNode.attribute("qlonglongVal").toLongLong(&bOk), qlonglongVal);
QVERIFY(bOk);
QCOMPARE(rootNode.attribute("qulonglongVal").toULongLong(&bOk), qulonglongVal);
QVERIFY(bOk);
QCOMPARE(rootNode.attribute("intVal").toInt(&bOk), intVal);
QVERIFY(bOk);
QCOMPARE(rootNode.attribute("uintVal").toUInt(&bOk), uintVal);
QVERIFY(bOk);
QCOMPARE(rootNode.attribute("floatVal").toFloat(&bOk), floatVal);
QVERIFY(bOk);
QCOMPARE(rootNode.attribute("doubleVal").toDouble(&bOk), doubleVal);
QVERIFY(bOk);
QCOMPARE(nsNode.attributeNS("namespace", "qstringVal"), qstringVal);
QCOMPARE(nsNode.attributeNS("namespace", "qlonglongVal").toLongLong(&bOk), qlonglongVal);
QVERIFY(bOk);
QCOMPARE(nsNode.attributeNS("namespace", "qulonglongVal").toULongLong(&bOk), qulonglongVal);
QVERIFY(bOk);
QCOMPARE(nsNode.attributeNS("namespace", "intVal").toInt(&bOk), intVal);
QVERIFY(bOk);
QCOMPARE(nsNode.attributeNS("namespace", "uintVal").toUInt(&bOk), uintVal);
QVERIFY(bOk);
QCOMPARE(nsNode.attributeNS("namespace", "floatVal").toFloat(&bOk), floatVal);
QVERIFY(bOk);
QCOMPARE(nsNode.attributeNS("namespace", "doubleVal").toDouble(&bOk), doubleVal);
QVERIFY(bOk);
QLocale::setDefault(oldLocale);
}
int tst_QDom::hasAttributesHelper( const QDomNode& node )
{
int visitedNodes = 1;