Skip to content

Commit 1c877f1

Browse files
committed
Fix another crash with rule-based labeling + data-defined properties (fixes #13453)
The writing of data-defined properties to XML was using invalid data. Also fixes a possible memory leak in assignment operator. Thanks Nyall for help tracking it down! This code has been funded by Tuscany Region (Italy) - SITA (CIG: 63526840AE) and commissioned to Gis3W s.a.s.
1 parent 8ed7850 commit 1c877f1

File tree

4 files changed

+33
-18
lines changed

4 files changed

+33
-18
lines changed

python/core/qgspallabeling.sip

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,11 @@ class QgsPalLayerSettings
512512
/** Set a property to static instead data defined */
513513
void removeDataDefinedProperty( QgsPalLayerSettings::DataDefinedProperties p );
514514

515+
/** Clear all data-defined properties
516+
* @note added in QGIS 2.12
517+
*/
518+
void removeAllDataDefinedProperties();
519+
515520
/** Convert old property value to new one as delimited values
516521
* @note not available in python bindings; as temporary solution until refactoring of project settings
517522
*/

src/core/qgspallabeling.cpp

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,7 @@ QgsPalLayerSettings& QgsPalLayerSettings::operator=( const QgsPalLayerSettings &
469469
shadowBlendMode = s.shadowBlendMode;
470470

471471
// data defined
472+
removeAllDataDefinedProperties();
472473
QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::const_iterator it = s.dataDefinedProperties.constBegin();
473474
for ( ; it != s.dataDefinedProperties.constEnd(); ++it )
474475
{
@@ -492,13 +493,7 @@ QgsPalLayerSettings::~QgsPalLayerSettings()
492493
delete extentGeom;
493494

494495
// delete all QgsDataDefined objects (which also deletes their QgsExpression object)
495-
QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::iterator it = dataDefinedProperties.begin();
496-
for ( ; it != dataDefinedProperties.constEnd(); ++it )
497-
{
498-
delete( it.value() );
499-
it.value() = 0;
500-
}
501-
dataDefinedProperties.clear();
496+
removeAllDataDefinedProperties();
502497
}
503498

504499

@@ -628,6 +623,14 @@ void QgsPalLayerSettings::writeDataDefinedPropertyMap( QgsVectorLayer* layer, QD
628623
propertyValue = QVariant( values.join( "~~" ) );
629624
}
630625
}
626+
627+
if ( parentElem )
628+
{
629+
// writing to XML document (instead of writing to layer)
630+
QDomDocument doc = parentElem->ownerDocument();
631+
QDomElement e = dd->toXmlElement( doc, i.value().first );
632+
parentElem->appendChild( e );
633+
}
631634
}
632635
}
633636

@@ -651,17 +654,6 @@ void QgsPalLayerSettings::writeDataDefinedPropertyMap( QgsVectorLayer* layer, QD
651654
layer->removeCustomProperty( QString( "labeling/dataDefinedProperty" ) + QString::number( i.value().second ) );
652655
}
653656
}
654-
else if ( parentElem )
655-
{
656-
// writing to XML document
657-
QgsDataDefined* dd = it.value();
658-
if ( dd )
659-
{
660-
QDomDocument doc = parentElem->ownerDocument();
661-
QDomElement e = dd->toXmlElement( doc, i.value().first );
662-
parentElem->appendChild( e );
663-
}
664-
}
665657
}
666658
}
667659

@@ -1541,6 +1533,17 @@ void QgsPalLayerSettings::removeDataDefinedProperty( DataDefinedProperties p )
15411533
}
15421534
}
15431535

1536+
void QgsPalLayerSettings::removeAllDataDefinedProperties()
1537+
{
1538+
QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::iterator it = dataDefinedProperties.begin();
1539+
for ( ; it != dataDefinedProperties.constEnd(); ++it )
1540+
{
1541+
delete( it.value() );
1542+
it.value() = 0;
1543+
}
1544+
dataDefinedProperties.clear();
1545+
}
1546+
15441547
QString QgsPalLayerSettings::updateDataDefinedString( const QString& value )
15451548
{
15461549
// TODO: update or remove this when project settings for labeling are migrated to better XML layout

src/core/qgspallabeling.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,11 @@ class CORE_EXPORT QgsPalLayerSettings
505505
/** Set a property to static instead data defined */
506506
void removeDataDefinedProperty( QgsPalLayerSettings::DataDefinedProperties p );
507507

508+
/** Clear all data-defined properties
509+
* @note added in QGIS 2.12
510+
*/
511+
void removeAllDataDefinedProperties();
512+
508513
/** Convert old property value to new one as delimited values
509514
* @note not available in python bindings; as temporary solution until refactoring of project settings
510515
*/

tests/src/core/testqgslabelingenginev2.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ void TestQgsLabelingEngineV2::testRuleBased()
168168
s2.obstacle = false;
169169
s2.dist = 2;
170170
s2.textColor = Qt::red;
171+
s2.setDataDefinedProperty( QgsPalLayerSettings::Size, true, true, "18", QString() );
172+
171173
root->appendChild( new QgsRuleBasedLabeling::Rule( new QgsPalLayerSettings( s2 ), 0, 0, "Class = 'Jet'" ) );
172174

173175
vl->setLabeling( new QgsRuleBasedLabeling( root ) );

0 commit comments

Comments
 (0)