From 279139b4ac72e41856bb7c5fde61ce87746d4905 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 13 May 2019 13:31:21 +1000 Subject: [PATCH] Avoid crashes on debug builds when trying to write xml for more value types --- src/core/qgsapplication.cpp | 1 + src/core/qgsxmlutils.cpp | 26 ++++++++++++++++++++++++++ tests/src/python/test_qgsxmlutils.py | 27 ++++++++++++++++++++++++++- 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/core/qgsapplication.cpp b/src/core/qgsapplication.cpp index 44cca250f6b..3ea0530a8ed 100644 --- a/src/core/qgsapplication.cpp +++ b/src/core/qgsapplication.cpp @@ -209,6 +209,7 @@ void QgsApplication::init( QString profileFolder ) qRegisterMetaType( "QgsAuthManager::MessageLevel" ); qRegisterMetaType( "QgsNetworkRequestParameters" ); qRegisterMetaType( "QgsNetworkReplyContent" ); + qRegisterMetaType( "QgsGeometry" ); ( void ) resolvePkgPath(); diff --git a/src/core/qgsxmlutils.cpp b/src/core/qgsxmlutils.cpp index 78ff81f577f..c09a041f678 100644 --- a/src/core/qgsxmlutils.cpp +++ b/src/core/qgsxmlutils.cpp @@ -154,8 +154,11 @@ QDomElement QgsXmlUtils::writeVariant( const QVariant &value, QDomDocument &doc } case QVariant::Int: + case QVariant::UInt: case QVariant::Bool: case QVariant::Double: + case QVariant::LongLong: + case QVariant::ULongLong: case QVariant::String: element.setAttribute( QStringLiteral( "type" ), QVariant::typeToName( value.type() ) ); element.setAttribute( QStringLiteral( "value" ), value.toString() ); @@ -177,6 +180,13 @@ QDomElement QgsXmlUtils::writeVariant( const QVariant &value, QDomDocument &doc crs.writeXml( element, doc ); break; } + else if ( value.canConvert< QgsGeometry >() ) + { + element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "QgsGeometry" ) ); + const QgsGeometry geom = value.value< QgsGeometry >(); + element.setAttribute( QStringLiteral( "value" ), geom.asWkt() ); + break; + } FALLTHROUGH } @@ -200,6 +210,18 @@ QVariant QgsXmlUtils::readVariant( const QDomElement &element ) { return element.attribute( QStringLiteral( "value" ) ).toInt(); } + else if ( type == QLatin1String( "uint" ) ) + { + return element.attribute( QStringLiteral( "value" ) ).toUInt(); + } + else if ( type == QLatin1String( "qlonglong" ) ) + { + return element.attribute( QStringLiteral( "value" ) ).toLongLong(); + } + else if ( type == QLatin1String( "qulonglong" ) ) + { + return element.attribute( QStringLiteral( "value" ) ).toULongLong(); + } else if ( type == QLatin1String( "double" ) ) { return element.attribute( QStringLiteral( "value" ) ).toDouble(); @@ -265,6 +287,10 @@ QVariant QgsXmlUtils::readVariant( const QDomElement &element ) crs.readXml( element ); return crs; } + else if ( type == QLatin1String( "QgsGeometry" ) ) + { + return QgsGeometry::fromWkt( element.attribute( "value" ) ); + } else { return QVariant(); diff --git a/tests/src/python/test_qgsxmlutils.py b/tests/src/python/test_qgsxmlutils.py index 4b29734ac26..c53a0d4bfcf 100644 --- a/tests/src/python/test_qgsxmlutils.py +++ b/tests/src/python/test_qgsxmlutils.py @@ -13,9 +13,9 @@ __copyright__ = 'Copyright 2016, The QGIS Project' __revision__ = '$Format:%H$' import qgis # NOQA switch sip api - from qgis.core import (QgsXmlUtils, QgsProperty, + QgsGeometry, QgsCoordinateReferenceSystem) from qgis.PyQt.QtXml import QDomDocument @@ -50,6 +50,19 @@ class TestQgsXmlUtils(unittest.TestCase): prop2 = QgsXmlUtils.readVariant(elem) self.assertEqual(my_properties, prop2) + def test_long(self): + """ + Test that maps are correctly loaded and written + """ + doc = QDomDocument("properties") + + # not sure if this actually does map to a long? + my_properties = {'a': 9223372036854775808} + elem = QgsXmlUtils.writeVariant(my_properties, doc) + + prop2 = QgsXmlUtils.readVariant(elem) + self.assertEqual(my_properties, prop2) + def test_string(self): """ Test that maps are correctly loaded and written @@ -160,6 +173,18 @@ class TestQgsXmlUtils(unittest.TestCase): crs2 = QgsXmlUtils.readVariant(elem) self.assertFalse(crs2.isValid()) + def test_geom(self): + """ + Test that QgsGeometry values are correctly loaded and written + """ + doc = QDomDocument("properties") + + g = QgsGeometry.fromWkt('Point(3 4)') + elem = QgsXmlUtils.writeVariant(g, doc) + + g2 = QgsXmlUtils.readVariant(elem) + self.assertEqual(g2.asWkt(), 'Point (3 4)') + if __name__ == '__main__': unittest.main()