fix checking validity of flags in read/write settings/layer properties (#44352)

This commit is contained in:
Denis Rouzaud 2021-07-23 15:14:57 +02:00 committed by GitHub
parent f041cda1b6
commit 38d6c91cb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 21 deletions

View File

@ -788,21 +788,33 @@ class CORE_EXPORT QgsMapLayer : public QObject
}
if ( !ok )
{
// if failed, try to read as int (old behavior)
// this code shall be removed later
// then the method could be marked as const
v = T( customProperty( key, static_cast<int>( defaultValue ) ).toInt( &ok ) );
// if failed, try to read as int
int intValue = customProperty( key, static_cast<int>( defaultValue ) ).toInt( &ok );
if ( metaEnum.isValid() )
{
if ( !ok || metaEnum.valueToKeys( static_cast<int>( v ) ).isEmpty() )
if ( ok )
{
v = defaultValue;
// check that the int value does correspond to a flag
// see https://stackoverflow.com/a/68495949/1548052
QByteArray keys = metaEnum.valueToKeys( intValue );
int intValueCheck = metaEnum.keysToValue( keys );
if ( intValue != intValueCheck )
{
v = defaultValue;
}
else
{
// found property as an integer
v = T( intValue );
// convert the property to the new form (string)
// this code could be removed
// then the method could be marked as const
setCustomFlagProperty( key, v );
}
}
else
{
// found property as an integer
// convert the property to the new form (string)
setCustomFlagProperty( key, v );
v = defaultValue;
}
}
}

View File

@ -349,21 +349,33 @@ class CORE_EXPORT QgsSettings : public QObject
}
if ( !ok )
{
// if failed, try to read as int (old behavior)
// this code shall be removed later (probably after QGIS 3.4 LTR for 3.6)
// then the method could be marked as const
v = T( value( key, static_cast<int>( defaultValue ), section ).toInt( &ok ) );
// if failed, try to read as int
int intValue = value( key, static_cast<int>( defaultValue ), section ).toInt( &ok );
if ( metaEnum.isValid() )
{
if ( !ok || metaEnum.valueToKeys( static_cast<int>( v ) ).isEmpty() )
if ( ok )
{
v = defaultValue;
// check that the int value does correspond to a flag
// see https://stackoverflow.com/a/68495949/1548052
QByteArray keys = metaEnum.valueToKeys( intValue );
int intValueCheck = metaEnum.keysToValue( keys );
if ( intValue != intValueCheck )
{
v = defaultValue;
}
else
{
// found property as an integer
v = T( intValue );
// convert the property to the new form (string)
// this code could be removed
// then the method could be marked as const
setFlagValue( key, v );
}
}
else
{
// found setting as an integer
// convert the setting to the new form (string)
setFlagValue( key, v, section );
v = defaultValue;
}
}
}

View File

@ -426,8 +426,7 @@ void TestQgsMapLayer::customEnumFlagProperties()
QgsMapLayerProxyModel::Filters pointAndLine = QgsMapLayerProxyModel::Filters( QgsMapLayerProxyModel::PointLayer | QgsMapLayerProxyModel::LineLayer );
QgsMapLayerProxyModel::Filters pointAndPolygon = QgsMapLayerProxyModel::Filters( QgsMapLayerProxyModel::PointLayer | QgsMapLayerProxyModel::PolygonLayer );
ml->setCustomProperty( QStringLiteral( "my_property_for_a_flag" ), 1e8 ); // invalid
// this should be switched to customFlagProperty (see https://stackoverflow.com/questions/68485843/how-to-test-if-a-value-is-valid-for-a-qflags)
QgsMapLayerProxyModel::Filters v4 = ml->customEnumProperty( QStringLiteral( "my_property_for_a_flag" ), pointAndLine );
QgsMapLayerProxyModel::Filters v4 = ml->customFlagProperty( QStringLiteral( "my_property_for_a_flag" ), pointAndLine );
QCOMPARE( v4, pointAndLine );
ml->setCustomProperty( QStringLiteral( "my_property_for_a_flag" ), static_cast<int>( pointAndPolygon ) );

View File

@ -74,7 +74,7 @@ void TestQgsSettings::flagValue()
QgsMapLayerProxyModel::Filters pointAndLine = QgsMapLayerProxyModel::Filters( QgsMapLayerProxyModel::PointLayer | QgsMapLayerProxyModel::LineLayer );
QgsMapLayerProxyModel::Filters pointAndPolygon = QgsMapLayerProxyModel::Filters( QgsMapLayerProxyModel::PointLayer | QgsMapLayerProxyModel::PolygonLayer );
settings.setValue( QStringLiteral( "qgis/testing/my_value_for_a_flag" ), 1e8 ); // invalid
QgsMapLayerProxyModel::Filters v4 = settings.enumValue( QStringLiteral( "qgis/testing/my_value_for_a_flag" ), pointAndLine );
QgsMapLayerProxyModel::Filters v4 = settings.flagValue( QStringLiteral( "qgis/testing/my_value_for_a_flag" ), pointAndLine );
QCOMPARE( v4, pointAndLine );
settings.setValue( QStringLiteral( "qgis/testing/my_value_for_a_flag" ), static_cast<int>( pointAndPolygon ) );