From ead18fc488ffd5bdac02076941ac2462a53b935b Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sun, 1 Jul 2018 07:11:53 +1000 Subject: [PATCH] [processing] Fix managled paths in history which contain '\' chars --- src/core/processing/qgsprocessingparameters.cpp | 17 ++++++++--------- src/core/processing/qgsprocessingutils.cpp | 4 ++++ tests/src/analysis/testqgsprocessing.cpp | 14 ++++++++++++++ 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/core/processing/qgsprocessingparameters.cpp b/src/core/processing/qgsprocessingparameters.cpp index 7bb9c2a514b9..b61b106b6c73 100644 --- a/src/core/processing/qgsprocessingparameters.cpp +++ b/src/core/processing/qgsprocessingparameters.cpp @@ -1543,7 +1543,7 @@ QString QgsProcessingParameterMapLayer::valueAsPythonString( const QVariant &val p.insert( name(), val ); QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context ); return layer ? QgsProcessingUtils::stringToPythonLiteral( QgsProcessingUtils::normalizeLayerSource( layer->source() ) ) - : QString(); + : QgsProcessingUtils::stringToPythonLiteral( val.toString() ); } QgsProcessingParameterMapLayer *QgsProcessingParameterMapLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition ) @@ -2418,7 +2418,8 @@ QString QgsProcessingParameterRasterLayer::valueAsPythonString( const QVariant & QVariantMap p; p.insert( name(), val ); QgsRasterLayer *layer = QgsProcessingParameters::parameterAsRasterLayer( this, p, context ); - return layer ? QgsProcessingUtils::stringToPythonLiteral( QgsProcessingUtils::normalizeLayerSource( layer->source() ) ) : QString(); + return layer ? QgsProcessingUtils::stringToPythonLiteral( QgsProcessingUtils::normalizeLayerSource( layer->source() ) ) + : QgsProcessingUtils::stringToPythonLiteral( val.toString() ); } QgsProcessingParameterRasterLayer *QgsProcessingParameterRasterLayer::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition ) @@ -2630,7 +2631,6 @@ QString QgsProcessingParameterString::valueAsPythonString( const QVariant &value return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() ); QString s = value.toString(); - s.replace( '\n', QStringLiteral( "\\n" ) ); return QgsProcessingUtils::stringToPythonLiteral( s ); } @@ -2715,7 +2715,6 @@ QString QgsProcessingParameterExpression::valueAsPythonString( const QVariant &v return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() ); QString s = value.toString(); - s.replace( '\n', QStringLiteral( "\\n" ) ); return QgsProcessingUtils::stringToPythonLiteral( s ); } @@ -2819,7 +2818,7 @@ QString QgsProcessingParameterVectorLayer::valueAsPythonString( const QVariant & p.insert( name(), val ); QgsVectorLayer *layer = QgsProcessingParameters::parameterAsVectorLayer( this, p, context ); return layer ? QgsProcessingUtils::stringToPythonLiteral( QgsProcessingUtils::normalizeLayerSource( layer->source() ) ) - : QString(); + : QgsProcessingUtils::stringToPythonLiteral( val.toString() ); } QList QgsProcessingParameterLimitedDataTypes::dataTypes() const @@ -3326,7 +3325,7 @@ QString QgsProcessingParameterFeatureSink::valueAsPythonString( const QVariant & QgsProcessingOutputLayerDefinition fromVar = qvariant_cast( value ); if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty ) { - return QStringLiteral( "'%1'" ).arg( fromVar.sink.staticValue().toString() ); + return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() ); } else { @@ -3551,7 +3550,7 @@ QString QgsProcessingParameterRasterDestination::valueAsPythonString( const QVar QgsProcessingOutputLayerDefinition fromVar = qvariant_cast( value ); if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty ) { - return QStringLiteral( "'%1'" ).arg( fromVar.sink.staticValue().toString() ); + return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() ); } else { @@ -3667,7 +3666,7 @@ QString QgsProcessingParameterFileDestination::valueAsPythonString( const QVaria QgsProcessingOutputLayerDefinition fromVar = qvariant_cast( value ); if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty ) { - return QStringLiteral( "'%1'" ).arg( fromVar.sink.staticValue().toString() ); + return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() ); } else { @@ -3890,7 +3889,7 @@ QString QgsProcessingParameterVectorDestination::valueAsPythonString( const QVar QgsProcessingOutputLayerDefinition fromVar = qvariant_cast( value ); if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty ) { - return QStringLiteral( "'%1'" ).arg( fromVar.sink.staticValue().toString() ); + return QgsProcessingUtils::stringToPythonLiteral( fromVar.sink.staticValue().toString() ); } else { diff --git a/src/core/processing/qgsprocessingutils.cpp b/src/core/processing/qgsprocessingutils.cpp index 3a261b59effb..953bde61e1b6 100644 --- a/src/core/processing/qgsprocessingutils.cpp +++ b/src/core/processing/qgsprocessingutils.cpp @@ -310,6 +310,10 @@ QString QgsProcessingUtils::normalizeLayerSource( const QString &source ) QString QgsProcessingUtils::stringToPythonLiteral( const QString &string ) { QString s = string; + s.replace( '\\', QStringLiteral( "\\\\" ) ); + s.replace( '\n', QStringLiteral( "\\n" ) ); + s.replace( '\r', QStringLiteral( "\\r" ) ); + s.replace( '\t', QStringLiteral( "\\t" ) ); s.replace( '"', QStringLiteral( "\\\"" ) ); s.replace( '\'', QStringLiteral( "\\\'" ) ); s = s.prepend( '\'' ).append( '\'' ); diff --git a/tests/src/analysis/testqgsprocessing.cpp b/tests/src/analysis/testqgsprocessing.cpp index b2be481ce176..789fb360d09e 100644 --- a/tests/src/analysis/testqgsprocessing.cpp +++ b/tests/src/analysis/testqgsprocessing.cpp @@ -2153,6 +2153,7 @@ void TestQgsProcessing::parameterCrs() QCOMPARE( def->valueAsPythonString( QVariant(), context ), QStringLiteral( "None" ) ); QCOMPARE( def->valueAsPythonString( "EPSG:12003", context ), QStringLiteral( "'EPSG:12003'" ) ); QCOMPARE( def->valueAsPythonString( "ProjectCrs", context ), QStringLiteral( "'ProjectCrs'" ) ); + QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); QCOMPARE( def->valueAsPythonString( raster1, context ), QString( "'" ) + testDataDir + QStringLiteral( "tenbytenraster.asc'" ) ); QCOMPARE( def->valueAsPythonString( r1->id(), context ), QString( "'" ) + testDataDir + QStringLiteral( "tenbytenraster.asc'" ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); @@ -2269,6 +2270,7 @@ void TestQgsProcessing::parameterLayer() QCOMPARE( def->valueAsPythonString( r1->id(), context ), QString( "'" ) + testDataDir + QStringLiteral( "tenbytenraster.asc'" ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( r1 ), context ), QString( "'" ) + testDataDir + QStringLiteral( "tenbytenraster.asc'" ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); + QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); QString code = def->asScriptCode(); QCOMPARE( code, QStringLiteral( "##non_optional=layer" ) ); @@ -2545,6 +2547,7 @@ void TestQgsProcessing::parameterExtent() QCOMPARE( def->valueAsPythonString( QgsReferencedRectangle( QgsRectangle( 11, 12, 13, 14 ), QgsCoordinateReferenceSystem( "epsg:4326" ) ), context ), QStringLiteral( "'11, 13, 12, 14 [EPSG:4326]'" ) ); QCOMPARE( def->valueAsPythonString( "1,2,3,4 [EPSG:4326]", context ), QStringLiteral( "'1,2,3,4 [EPSG:4326]'" ) ); QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\\\"complex\\\"'" ) ); + QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); QString code = def->asScriptCode(); QCOMPARE( code, QStringLiteral( "##non_optional=extent 1,2,3,4" ) ); @@ -2776,6 +2779,7 @@ void TestQgsProcessing::parameterFile() QCOMPARE( def->valueAsPythonString( "bricks.bmp", context ), QStringLiteral( "'bricks.bmp'" ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\\\"complex\\\"'" ) ); + QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); QString code = def->asScriptCode(); QCOMPARE( code, QStringLiteral( "##non_optional=file abc.bmp" ) ); @@ -3518,6 +3522,7 @@ void TestQgsProcessing::parameterRasterLayer() QCOMPARE( def->valueAsPythonString( r1->id(), context ), QString( "'" ) + testDataDir + QStringLiteral( "tenbytenraster.asc'" ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( r1 ), context ), QString( "'" ) + testDataDir + QStringLiteral( "tenbytenraster.asc'" ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); + QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); QString code = def->asScriptCode(); QCOMPARE( code, QStringLiteral( "##non_optional=raster" ) ); @@ -3806,6 +3811,7 @@ void TestQgsProcessing::parameterString() QCOMPARE( def->valueAsPythonString( QStringLiteral( "abc\ndef" ), context ), QStringLiteral( "'abc\\ndef'" ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\\\"complex\\\"'" ) ); + QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); QString code = def->asScriptCode(); QCOMPARE( code, QStringLiteral( "##non_optional=string" ) ); @@ -4251,6 +4257,7 @@ void TestQgsProcessing::parameterVectorLayer() QCOMPARE( def->valueAsPythonString( v1->id(), context ), QString( "'" ) + testDataDir + QStringLiteral( "multipoint.shp'" ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( v1 ), context ), QString( "'" ) + testDataDir + QStringLiteral( "multipoint.shp'" ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); + QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); QString code = def->asScriptCode(); QCOMPARE( code, QStringLiteral( "##non_optional=vector somelayer" ) ); @@ -4369,6 +4376,7 @@ void TestQgsProcessing::parameterFeatureSource() QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( v2 ), context ), QStringLiteral( "'%1'" ).arg( vector2 ) ); QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\\\"complex\\\"'" ) ); + QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); QVariantMap map = def->toVariantMap(); QgsProcessingParameterFeatureSource fromMap( "x" ); @@ -4481,6 +4489,7 @@ void TestQgsProcessing::parameterFeatureSink() QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProcessingOutputLayerDefinition( QgsProperty::fromExpression( "\"abc\" || \"def\"" ) ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"abc\" || \"def\"')" ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\\\"complex\\\"'" ) ); + QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); QCOMPARE( def->defaultFileExtension(), QStringLiteral( "shp" ) ); QCOMPARE( def->generateTemporaryDestination(), QStringLiteral( "memory:" ) ); @@ -4609,6 +4618,7 @@ void TestQgsProcessing::parameterVectorOut() QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProcessingOutputLayerDefinition( QgsProperty::fromExpression( "\"abc\" || \"def\"" ) ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"abc\" || \"def\"')" ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\\\"complex\\\"'" ) ); + QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); QCOMPARE( def->defaultFileExtension(), QStringLiteral( "shp" ) ); QVERIFY( def->generateTemporaryDestination().endsWith( QStringLiteral( ".shp" ) ) ); @@ -4725,6 +4735,7 @@ void TestQgsProcessing::parameterRasterOut() QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProcessingOutputLayerDefinition( QgsProperty::fromExpression( "\"abc\" || \"def\"" ) ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"abc\" || \"def\"')" ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\\\"complex\\\"'" ) ); + QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); QVariantMap map = def->toVariantMap(); QgsProcessingParameterRasterDestination fromMap( "x" ); @@ -4848,6 +4859,7 @@ void TestQgsProcessing::parameterFileOut() QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProcessingOutputLayerDefinition( QgsProperty::fromExpression( "\"abc\" || \"def\"" ) ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"abc\" || \"def\"')" ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\\\"complex\\\"'" ) ); + QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); QVariantMap map = def->toVariantMap(); QgsProcessingParameterFileDestination fromMap( "x" ); @@ -4943,6 +4955,7 @@ void TestQgsProcessing::parameterFolderOut() QCOMPARE( def->valueAsPythonString( QStringLiteral( "abc" ), context ), QStringLiteral( "'abc'" ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\\\"complex\\\"'" ) ); + QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\'" ) ); QVariantMap map = def->toVariantMap(); QgsProcessingParameterFolderDestination fromMap( "x" ); @@ -6664,6 +6677,7 @@ void TestQgsProcessing::stringToPythonLiteral() QCOMPARE( QgsProcessingUtils::stringToPythonLiteral( QString() ), QStringLiteral( "''" ) ); QCOMPARE( QgsProcessingUtils::stringToPythonLiteral( QStringLiteral( "a 'string'" ) ), QStringLiteral( "'a \\'string\\''" ) ); QCOMPARE( QgsProcessingUtils::stringToPythonLiteral( QStringLiteral( "a \"string\"" ) ), QStringLiteral( "'a \\\"string\\\"'" ) ); + QCOMPARE( QgsProcessingUtils::stringToPythonLiteral( QStringLiteral( "a \n str\tin\\g" ) ), QStringLiteral( "'a \\n str\\tin\\\\g'" ) ); } void TestQgsProcessing::defaultExtensionsForProvider()