Skip to content

Commit

Permalink
Fix crash when parsing mapbox style with labeling containing mixed li…
Browse files Browse the repository at this point in the history
…teral and string references

Fixes #46321

(cherry picked from commit 5d3a8df)
(cherry picked from commit 950049b)
  • Loading branch information
nyalldawson committed Dec 7, 2021
1 parent 1662402 commit 8ad98bd
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/core/vectortile/qgsmapboxglstyleconverter.cpp
Expand Up @@ -1083,6 +1083,12 @@ void QgsMapBoxGlStyleConverter::parseSymbolLayer( const QVariantMap &jsonLayer,
if ( part.isEmpty() )
continue;

if ( !part.contains( '{' ) )
{
res << QgsExpression::quotedValue( part );
continue;
}

// part will start at a {field} reference
const QStringList split = part.split( '}' );
res << QgsExpression::quotedColumnRef( split.at( 0 ).mid( 1 ) );
Expand Down
68 changes: 68 additions & 0 deletions tests/src/python/test_qgsmapboxglconverter.py
Expand Up @@ -548,6 +548,74 @@ def testConvertLabels(self):
self.assertEqual(labeling.labelSettings().fieldName, '''lower(concat(concat("name_en",' - ',"name_fr"),"bar"))''')
self.assertTrue(labeling.labelSettings().isExpression)

def testLabelWithLiteral(self):
context = QgsMapBoxGlStyleConversionContext()
style = {
"layout": {
"visibility": "visible",
"text-field": "Quarry {substance}",
},
"paint": {
"text-color": "rgba(47, 47, 47, 1)",
},
"type": "symbol"
}
rendererStyle, has_renderer, labeling_style, has_labeling = QgsMapBoxGlStyleConverter.parseSymbolLayer(style, context)
self.assertTrue(has_labeling)
self.assertTrue(labeling_style.labelSettings().isExpression)
self.assertEqual(labeling_style.labelSettings().fieldName, 'concat(\'Quarry \',"substance")')

def testLabelWithLiteral2(self):
context = QgsMapBoxGlStyleConversionContext()
style = {
"layout": {
"visibility": "visible",
"text-field": "{substance} Quarry",
},
"paint": {
"text-color": "rgba(47, 47, 47, 1)",
},
"type": "symbol"
}
rendererStyle, has_renderer, labeling_style, has_labeling = QgsMapBoxGlStyleConverter.parseSymbolLayer(style, context)
self.assertTrue(has_labeling)
self.assertTrue(labeling_style.labelSettings().isExpression)
self.assertEqual(labeling_style.labelSettings().fieldName, 'concat("substance",\' Quarry\')')

def testLabelWithLiteral3(self):
context = QgsMapBoxGlStyleConversionContext()
style = {
"layout": {
"visibility": "visible",
"text-field": "A {substance} Quarry",
},
"paint": {
"text-color": "rgba(47, 47, 47, 1)",
},
"type": "symbol"
}
rendererStyle, has_renderer, labeling_style, has_labeling = QgsMapBoxGlStyleConverter.parseSymbolLayer(style, context)
self.assertTrue(has_labeling)
self.assertTrue(labeling_style.labelSettings().isExpression)
self.assertEqual(labeling_style.labelSettings().fieldName, 'concat(\'A \',"substance",\' Quarry\')')

def testLabelWithField(self):
context = QgsMapBoxGlStyleConversionContext()
style = {
"layout": {
"visibility": "visible",
"text-field": "{substance}",
},
"paint": {
"text-color": "rgba(47, 47, 47, 1)",
},
"type": "symbol"
}
rendererStyle, has_renderer, labeling_style, has_labeling = QgsMapBoxGlStyleConverter.parseSymbolLayer(style, context)
self.assertTrue(has_labeling)
self.assertFalse(labeling_style.labelSettings().isExpression)
self.assertEqual(labeling_style.labelSettings().fieldName, 'substance')


if __name__ == '__main__':
unittest.main()

0 comments on commit 8ad98bd

Please sign in to comment.