Skip to content

Commit 6de4fce

Browse files
committedJan 14, 2017
GML parser: fix parsing of typenames and geometry names with non-ASCII character (#16009)
1 parent b412ceb commit 6de4fce

File tree

3 files changed

+67
-5
lines changed

3 files changed

+67
-5
lines changed
 

‎src/core/qgsgml.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -277,10 +277,12 @@ QgsGmlStreamingParser::QgsGmlStreamingParser( const QString& typeName,
277277
: mTypeName( typeName )
278278
, mTypeNameBA( mTypeName.toUtf8() )
279279
, mTypeNamePtr( mTypeNameBA.constData() )
280+
, mTypeNameUTF8Len( strlen( mTypeNamePtr ) )
280281
, mWkbType( QgsWkbTypes::Unknown )
281282
, mGeometryAttribute( geometryAttribute )
282283
, mGeometryAttributeBA( geometryAttribute.toUtf8() )
283284
, mGeometryAttributePtr( mGeometryAttributeBA.constData() )
285+
, mGeometryAttributeUTF8Len( strlen( mGeometryAttributePtr ) )
284286
, mFields( fields )
285287
, mIsException( false )
286288
, mTruncatedResponse( false )
@@ -315,6 +317,7 @@ QgsGmlStreamingParser::QgsGmlStreamingParser( const QString& typeName,
315317
mTypeName = mTypeName.mid( index + 1 );
316318
mTypeNameBA = mTypeName.toUtf8();
317319
mTypeNamePtr = mTypeNameBA.constData();
320+
mTypeNameUTF8Len = strlen( mTypeNamePtr );
318321
}
319322

320323
mParser = XML_ParserCreateNS( nullptr, NS_SEPARATOR );
@@ -340,8 +343,10 @@ QgsGmlStreamingParser::QgsGmlStreamingParser( const QList<LayerProperties>& laye
340343
bool invertAxisOrientation )
341344
: mLayerProperties( layerProperties )
342345
, mTypeNamePtr( nullptr )
346+
, mTypeNameUTF8Len( 0 )
343347
, mWkbType( QgsWkbTypes::Unknown )
344348
, mGeometryAttributePtr( nullptr )
349+
, mGeometryAttributeUTF8Len( 0 )
345350
, mFields( fields )
346351
, mIsException( false )
347352
, mTruncatedResponse( false )
@@ -397,13 +402,15 @@ QgsGmlStreamingParser::QgsGmlStreamingParser( const QList<LayerProperties>& laye
397402
mGeometryAttribute = mLayerProperties[0].mGeometryAttribute;
398403
mGeometryAttributeBA = mGeometryAttribute.toUtf8();
399404
mGeometryAttributePtr = mGeometryAttributeBA.constData();
405+
mGeometryAttributeUTF8Len = strlen( mGeometryAttributePtr );
400406
int index = mTypeName.indexOf( ':' );
401407
if ( index != -1 && index < mTypeName.length() )
402408
{
403409
mTypeName = mTypeName.mid( index + 1 );
404410
}
405411
mTypeNameBA = mTypeName.toUtf8();
406412
mTypeNamePtr = mTypeNameBA.constData();
413+
mTypeNameUTF8Len = strlen( mTypeNamePtr );
407414
}
408415

409416
mEndian = QgsApplication::endian();
@@ -542,7 +549,7 @@ void QgsGmlStreamingParser::startElement( const XML_Char* el, const XML_Char** a
542549
}
543550
}
544551
}
545-
else if ( localNameLen == mGeometryAttribute.size() &&
552+
else if ( localNameLen == static_cast<int>( mGeometryAttributeUTF8Len ) &&
546553
memcmp( pszLocalName, mGeometryAttributePtr, localNameLen ) == 0 )
547554
{
548555
mParseModeStack.push( QgsGmlStreamingParser::Geometry );
@@ -606,6 +613,7 @@ void QgsGmlStreamingParser::startElement( const XML_Char* el, const XML_Char** a
606613
}
607614
mGeometryAttributeBA = mGeometryAttribute.toUtf8();
608615
mGeometryAttributePtr = mGeometryAttributeBA.constData();
616+
mGeometryAttributeUTF8Len = strlen( mGeometryAttributePtr );
609617
mParseModeStack.push( QgsGmlStreamingParser::FeatureTuple );
610618
QString id;
611619
if ( mGMLNameSpaceURI.isEmpty() )
@@ -634,7 +642,8 @@ void QgsGmlStreamingParser::startElement( const XML_Char* el, const XML_Char** a
634642
}
635643
}
636644
else if ( theParseMode == None &&
637-
localNameLen == mTypeName.size() && memcmp( pszLocalName, mTypeNamePtr, mTypeName.size() ) == 0 )
645+
localNameLen == static_cast<int>( mTypeNameUTF8Len ) &&
646+
memcmp( pszLocalName, mTypeNamePtr, mTypeNameUTF8Len ) == 0 )
638647
{
639648
Q_ASSERT( !mCurrentFeature );
640649
mCurrentFeature = new QgsFeature( mFeatureCount );
@@ -857,7 +866,8 @@ void QgsGmlStreamingParser::endElement( const XML_Char* el )
857866

858867
setAttribute( mAttributeName, mStringCash );
859868
}
860-
else if ( theParseMode == Geometry && localNameLen == mGeometryAttribute.size() &&
869+
else if ( theParseMode == Geometry &&
870+
localNameLen == static_cast<int>( mGeometryAttributeUTF8Len ) &&
861871
memcmp( pszLocalName, mGeometryAttributePtr, localNameLen ) == 0 )
862872
{
863873
mParseModeStack.pop();
@@ -935,8 +945,9 @@ void QgsGmlStreamingParser::endElement( const XML_Char* el )
935945
}
936946
else if (( theParseMode == Tuple && !mTypeNamePtr &&
937947
LOCALNAME_EQUALS( "Tuple" ) ) ||
938-
( theParseMode == Feature && localNameLen == mTypeName.size() &&
939-
memcmp( pszLocalName, mTypeNamePtr, mTypeName.size() ) == 0 ) )
948+
( theParseMode == Feature &&
949+
localNameLen == static_cast<int>( mTypeNameUTF8Len ) &&
950+
memcmp( pszLocalName, mTypeNamePtr, mTypeNameUTF8Len ) == 0 ) )
940951
{
941952
Q_ASSERT( mCurrentFeature );
942953
if ( !mCurrentFeature->hasGeometry() )

‎src/core/qgsgml.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ class CORE_EXPORT QgsGmlStreamingParser
250250
QString mTypeName;
251251
QByteArray mTypeNameBA;
252252
const char* mTypeNamePtr;
253+
size_t mTypeNameUTF8Len;
253254

254255
QgsWkbTypes::Type mWkbType;
255256

@@ -259,6 +260,7 @@ class CORE_EXPORT QgsGmlStreamingParser
259260
QString mGeometryAttribute;
260261
QByteArray mGeometryAttributeBA;
261262
const char* mGeometryAttributePtr;
263+
size_t mGeometryAttributeUTF8Len;
262264

263265
QgsFields mFields;
264266
QMap<QString, QPair<int, QgsField> > mThematicAttributes;

‎tests/src/core/testqgsgml.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ class TestQgsGML : public QObject
7676
void testPartialFeature();
7777
void testThroughOGRGeometry();
7878
void testThroughOGRGeometry_urn_EPSG_4326();
79+
void testAccents();
7980
};
8081

8182
const QString data1( "<myns:FeatureCollection "
@@ -1103,5 +1104,53 @@ void TestQgsGML::testThroughOGRGeometry_urn_EPSG_4326()
11031104
delete features[0].first;
11041105
}
11051106

1107+
void TestQgsGML::testAccents()
1108+
{
1109+
QgsFields fields;
1110+
QgsGmlStreamingParser gmlParser( QString::fromUtf8( QByteArray( "my\xc3\xa9typename" ) ),
1111+
QString::fromUtf8( QByteArray( "my\xc3\xa9geom" ) ),
1112+
fields );
1113+
QCOMPARE( gmlParser.processData( QByteArray( "<myns:FeatureCollection "
1114+
"xmlns:myns='http://myns' "
1115+
"xmlns:gml='http://www.opengis.net/gml'>"
1116+
"<gml:featureMember>"
1117+
"<myns:my\xc3\xa9typename fid='mytypename.1'>"
1118+
"<myns:my\xc3\xa9geom>"
1119+
"<gml:MultiSurface srsName='EPSG:27700'>"
1120+
"<gml:surfaceMember>"
1121+
"<gml:Polygon srsName='EPSG:27700'>"
1122+
"<gml:exterior>"
1123+
"<gml:LinearRing>"
1124+
"<gml:posList>0 0 0 10 10 10 10 0 0 0</gml:posList>"
1125+
"</gml:LinearRing>"
1126+
"</gml:exterior>"
1127+
"</gml:Polygon>"
1128+
"</gml:surfaceMember>"
1129+
"<gml:surfaceMember>"
1130+
"<gml:Polygon srsName='EPSG:27700'>"
1131+
"<gml:exterior>"
1132+
"<gml:LinearRing>"
1133+
"<gml:posList>0 0 0 10 10 10 10 0 0 0</gml:posList>"
1134+
"</gml:LinearRing>"
1135+
"</gml:exterior>"
1136+
"</gml:Polygon>"
1137+
"</gml:surfaceMember>"
1138+
"</gml:MultiSurface>"
1139+
"</myns:my\xc3\xa9geom>"
1140+
"</myns:my\xc3\xa9typename>"
1141+
"</gml:featureMember>"
1142+
"</myns:FeatureCollection>" ), true ), true );
1143+
QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::MultiPolygon );
1144+
QVector<QgsGmlStreamingParser::QgsGmlFeaturePtrGmlIdPair> features = gmlParser.getAndStealReadyFeatures();
1145+
QCOMPARE( features.size(), 1 );
1146+
QVERIFY( features[0].first->hasGeometry() );
1147+
QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::MultiPolygon );
1148+
QgsMultiPolygon multi = features[0].first->geometry().asMultiPolygon();
1149+
QCOMPARE( multi.size(), 2 );
1150+
QCOMPARE( multi[0].size(), 1 );
1151+
QCOMPARE( multi[0][0].size(), 5 );
1152+
delete features[0].first;
1153+
}
1154+
11061155
QGSTEST_MAIN( TestQgsGML )
11071156
#include "testqgsgml.moc"

0 commit comments

Comments
 (0)
Please sign in to comment.