From 23f4d5eba27e4df927add8b27df9db039e7abcc9 Mon Sep 17 00:00:00 2001 From: lbartoletti Date: Thu, 12 Sep 2019 20:58:20 +0200 Subject: [PATCH] [FEATURE][needs-docs] Add hash functions --- src/core/expression/qgsexpressionfunction.cpp | 109 ++++++++++++++++++ tests/src/core/testqgsexpression.cpp | 32 +++++ 2 files changed, 141 insertions(+) diff --git a/src/core/expression/qgsexpressionfunction.cpp b/src/core/expression/qgsexpressionfunction.cpp index cc2ce04c586..6e4775bff20 100644 --- a/src/core/expression/qgsexpressionfunction.cpp +++ b/src/core/expression/qgsexpressionfunction.cpp @@ -4991,8 +4991,85 @@ static QVariant fcnFileSize( const QVariantList &values, const QgsExpressionCont return QFileInfo( file ).size(); } +static QVariant fcnHash( const QString str, const QCryptographicHash::Algorithm algorithm ) +{ + return QString( QCryptographicHash::hash( str.toUtf8(), algorithm ).toHex() ); +} +static QVariant fcnHashMd4( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * ) +{ + return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Md4 ); +} +static QVariant fcnHashMd5( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * ) +{ + return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Md5 ); +} + +static QVariant fcnHashSha1( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * ) +{ + return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Sha1 ); +} + +static QVariant fcnHashSha224( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * ) +{ + return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Sha224 ); +} + +static QVariant fcnHashSha256( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * ) +{ + return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Sha256 ); +} + +static QVariant fcnHashSha384( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * ) +{ + return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Sha384 ); +} + +static QVariant fcnHashSha512( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * ) +{ + return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Sha512 ); +} + +static QVariant fcnHashSha3_224( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * ) +{ + return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Sha3_224 ); +} + +static QVariant fcnHashSha3_256( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * ) +{ + return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Sha3_256 ); +} + +static QVariant fcnHashSha3_384( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * ) +{ + return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Sha3_384 ); +} + +static QVariant fcnHashSha3_512( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * ) +{ + return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Sha3_512 ); +} + +static QVariant fcnHashKeccak_224( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * ) +{ + return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Keccak_224 ); +} + +static QVariant fcnHashKeccak_256( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * ) +{ + return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Keccak_256 ); +} + +static QVariant fcnHashKeccak_384( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * ) +{ + return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Keccak_384 ); +} + +static QVariant fcnHashKeccak_512( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * ) +{ + return fcnHash( QgsExpressionUtils::getStringValue( values.at( 0 ), parent ), QCryptographicHash::Keccak_512 ); +} const QList &QgsExpression::Functions() { @@ -5288,6 +5365,38 @@ const QList &QgsExpression::Functions() << new QgsStaticExpressionFunction( QStringLiteral( "file_size" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "path" ) ), fcnFileSize, QStringLiteral( "Files and Paths" ) ) + // hash + << new QgsStaticExpressionFunction( QStringLiteral( "md4" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), + fcnHashMd4, QStringLiteral( "Hash" ) ) + << new QgsStaticExpressionFunction( QStringLiteral( "md5" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), + fcnHashMd5, QStringLiteral( "Hash" ) ) + << new QgsStaticExpressionFunction( QStringLiteral( "sha1" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), + fcnHashSha1, QStringLiteral( "Hash" ) ) + << new QgsStaticExpressionFunction( QStringLiteral( "sha224" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), + fcnHashSha224, QStringLiteral( "Hash" ) ) + << new QgsStaticExpressionFunction( QStringLiteral( "sha256" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), + fcnHashSha256, QStringLiteral( "Hash" ) ) + << new QgsStaticExpressionFunction( QStringLiteral( "sha384" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), + fcnHashSha384, QStringLiteral( "Hash" ) ) + << new QgsStaticExpressionFunction( QStringLiteral( "sha512" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), + fcnHashSha512, QStringLiteral( "Hash" ) ) + << new QgsStaticExpressionFunction( QStringLiteral( "sha3_224" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), + fcnHashSha3_224, QStringLiteral( "Hash" ) ) + << new QgsStaticExpressionFunction( QStringLiteral( "sha3_256" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), + fcnHashSha3_256, QStringLiteral( "Hash" ) ) + << new QgsStaticExpressionFunction( QStringLiteral( "sha3_384" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), + fcnHashSha3_384, QStringLiteral( "Hash" ) ) + << new QgsStaticExpressionFunction( QStringLiteral( "sha3_512" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), + fcnHashSha3_512, QStringLiteral( "Hash" ) ) + << new QgsStaticExpressionFunction( QStringLiteral( "keccak_224" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), + fcnHashKeccak_224, QStringLiteral( "Hash" ) ) + << new QgsStaticExpressionFunction( QStringLiteral( "keccak_256" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), + fcnHashKeccak_256, QStringLiteral( "Hash" ) ) + << new QgsStaticExpressionFunction( QStringLiteral( "keccak_384" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), + fcnHashKeccak_384, QStringLiteral( "Hash" ) ) + << new QgsStaticExpressionFunction( QStringLiteral( "keccak_512" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), + fcnHashKeccak_512, QStringLiteral( "Hash" ) ) + // deprecated stuff - hidden from users << new QgsStaticExpressionFunction( QStringLiteral( "$scale" ), QgsExpressionFunction::ParameterList(), fcnMapScale, QStringLiteral( "deprecated" ) ); diff --git a/tests/src/core/testqgsexpression.cpp b/tests/src/core/testqgsexpression.cpp index 7cd0c3bbfbc..77b8b3fd58b 100644 --- a/tests/src/core/testqgsexpression.cpp +++ b/tests/src/core/testqgsexpression.cpp @@ -1471,6 +1471,38 @@ class TestQgsExpression: public QObject QTest::newRow( "is_file(points.shp)" ) << QStringLiteral( "is_file('%1/points.shp')" ).arg( TEST_DATA_DIR ) << false << QVariant( true ); QTest::newRow( "is_file(valid)" ) << QStringLiteral( "is_file('%1')" ).arg( TEST_DATA_DIR ) << false << QVariant( false ); + // hash functions + QTest::newRow( "md4(NULL)" ) << QStringLiteral( "md4(NULL)" ) << false << QVariant(); + QTest::newRow( "md4('QGIS')" ) << QStringLiteral( "md4('QGIS')" ) << false << QVariant( "c0fc71c241cdebb6e888cbac0e2b68eb" ); + QTest::newRow( "md5(NULL)" ) << QStringLiteral( "md5(NULL)" ) << false << QVariant(); + QTest::newRow( "md5('QGIS')" ) << QStringLiteral( "md5('QGIS')" ) << false << QVariant( "57470aaa9e22adaefac7f5f342f1c6da" ); + QTest::newRow( "sha1(NULL)" ) << QStringLiteral( "sha1(NULL)" ) << false << QVariant(); + QTest::newRow( "sha1('QGIS')" ) << QStringLiteral( "sha1('QGIS')" ) << false << QVariant( "f87cfb2b74cdd5867db913237024e7001e62b114" ); + QTest::newRow( "sha224(NULL)" ) << QStringLiteral( "sha224(NULL)" ) << false << QVariant(); + QTest::newRow( "sha224('QGIS')" ) << QStringLiteral( "sha224('QGIS')" ) << false << QVariant( "4093a619ada631c770f44bc643ead18fb393b93d6a6af1861fcfece0" ); + QTest::newRow( "sha256(NULL)" ) << QStringLiteral( "sha256(NULL)" ) << false << QVariant(); + QTest::newRow( "sha256('QGIS')" ) << QStringLiteral( "sha256('QGIS')" ) << false << QVariant( "eb045cba7a797aaa06ac58830846e40c8e8c780bc0676d3393605fae50c05309" ); + QTest::newRow( "sha384(NULL)" ) << QStringLiteral( "sha384(NULL)" ) << false << QVariant(); + QTest::newRow( "sha384('QGIS')" ) << QStringLiteral( "sha384('QGIS')" ) << false << QVariant( "91c1de038cc3d09fdd512e99f9dd9922efadc39ed21d3922e69a4305cc25506033aee388e554b78714c8734f9cd7e610" ); + QTest::newRow( "sha512(NULL)" ) << QStringLiteral( "sha512(NULL)" ) << false << QVariant(); + QTest::newRow( "sha512('QGIS')" ) << QStringLiteral( "sha512('QGIS')" ) << false << QVariant( "c2c092f2ab743bf8edbeb6d028a745f30fc720408465ed369421f0a4e20fa5e27f0c90ad72d3f1d836eaa5d25cd39897d4cf77e19984668ef58da6e3159f18ac" ); + QTest::newRow( "sha3_224(NULL)" ) << QStringLiteral( "sha3_224(NULL)" ) << false << QVariant(); + QTest::newRow( "sha3_224('QGIS')" ) << QStringLiteral( "sha3_224('QGIS')" ) << false << QVariant( "467f49a5039e7280d5d42fd433e80d203439e338eaabd701f0d6c17d" ); + QTest::newRow( "sha3_256(NULL)" ) << QStringLiteral( "sha3_256(NULL)" ) << false << QVariant(); + QTest::newRow( "sha3_256('QGIS')" ) << QStringLiteral( "sha3_256('QGIS')" ) << false << QVariant( "540f7354b6b8a6e735f2845250f15f4f3ba4f666c55574d9e9354575de0e980f" ); + QTest::newRow( "sha3_384(NULL)" ) << QStringLiteral( "sha3_384(NULL)" ) << false << QVariant(); + QTest::newRow( "sha3_384('QGIS')" ) << QStringLiteral( "sha3_384('QGIS')" ) << false << QVariant( "96052da1e77679e9a65f60d7ead961b287977823144786386eb43647b0901fd8516fa6f1b9d243fb3f28775e6dde6107" ); + QTest::newRow( "sha3_512(NULL)" ) << QStringLiteral( "sha3_512(NULL)" ) << false << QVariant(); + QTest::newRow( "sha3_512('QGIS')" ) << QStringLiteral( "sha3_512('QGIS')" ) << false << QVariant( "900d079dc69761da113980253aa8ac0414a8bd6d09879a916228f8743707c4758051c98445d6b8945ec854ff90655005e02aceb0a2ffc6a0ebf818745d665349" ); + QTest::newRow( "keccak_224(NULL)" ) << QStringLiteral( "keccak_224(NULL)" ) << false << QVariant(); + QTest::newRow( "keccak_224('QGIS')" ) << QStringLiteral( "keccak_224('QGIS')" ) << false << QVariant( "5b0ce6acef8b0a121d4ac4f3eaa8503c799ad4e26a3392d1fb201478" ); + QTest::newRow( "keccak_256(NULL)" ) << QStringLiteral( "keccak_256(NULL)" ) << false << QVariant(); + QTest::newRow( "keccak_256('QGIS')" ) << QStringLiteral( "keccak_256('QGIS')" ) << false << QVariant( "991c520aa6815392de24087f61b2ae0fd56abbfeee4a8ca019c1011d327c577e" ); + QTest::newRow( "keccak_384(NULL)" ) << QStringLiteral( "keccak_384(NULL)" ) << false << QVariant(); + QTest::newRow( "keccak_384('QGIS')" ) << QStringLiteral( "keccak_384('QGIS')" ) << false << QVariant( "c57a3aed9d856fa04e5eeee9b62b6e027cca81ba574116d3cc1f0d48a1ef9e5886ff463ea8d0fac772ee473bf92f810d" ); + QTest::newRow( "keccak_512(NULL)" ) << QStringLiteral( "keccak_512(NULL)" ) << false << QVariant(); + QTest::newRow( "keccak_512('QGIS')" ) << QStringLiteral( "keccak_512('QGIS')" ) << false << QVariant( "6f0f751776b505e317de222508fa5d3ed7099d8f07c74fed54ccee6e7cdc6b89b4a085e309f2ee5210c942bbeb142bdfe48f84f912e0f3f41bdbf47110c2d344" ); + }