Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-41403

QVariant associative container conversion misses built-in check.

    XMLWordPrintable

Details

    Description

      It is possible to convert from a QMap<QString, T> to a QVariantMap or a QVariantHash via QVariant::value(), where T is a user-chosen type which is a metatype. The conversion uses a custom converter.

      If T is QVariant, the type is a QVariantMap, which is a built-in metatype. That means there is no user-specified converter.

      That means that if a QVariant contains a QMap<QString, int>, then var.value<QVariantHash>() works, but if it contains a QVariantMap, then var.value<QVariantHash>() does not work.

      QVariantValueHelperInterface<QVariantHash> and QVariantValueHelperInterface<QVariantMap> only check for user-defined converters, but should also check if the contained type is exactly a built-in metatype.

      QVariantValueHelperInterface<QVariantList> already has such a check for built-ins, so it does not exhibit a comparable bug.

        QMap<QString, int> mp;
        QVariantMap varmp;
        mp.insert("3", 4);
        varmp.insert("3", 4);
      
        QStringList li;
        li.append("Hello");
        QVariantList varli;
        varli.append("World");
      
        QVariant var;
      
        var = QVariant::fromValue(li);
        qDebug() << var.value<QVariantList>();
      
        var = QVariant::fromValue(varli);
        qDebug() << var.value<QVariantList>();
      
        var = QVariant::fromValue(mp);
        qDebug() << var.value<QVariantHash>();
      
        var = QVariant::fromValue(varmp);
        qDebug() << var.value<QVariantHash>();
      
        qDebug() << QMetaType::hasRegisteredConverterFunction(qMetaTypeId<QVariantList>(), qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>());
        qDebug() << QMetaType::hasRegisteredConverterFunction(qMetaTypeId<QStringList>(), qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>());
        qDebug() << QMetaType::hasRegisteredConverterFunction(qMetaTypeId<QVariantHash>(), qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>());
        qDebug() << QMetaType::hasRegisteredConverterFunction(qMetaTypeId<QVariantMap>(), qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>());
        qDebug() << QMetaType::hasRegisteredConverterFunction(qMetaTypeId<QMap<int, int> >(), qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>());
        qDebug() << QMetaType::hasRegisteredConverterFunction(qMetaTypeId<QHash<QString, int> >(), qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>());
      

      Output

      (QVariant(QString, "Hello") ) 
      (QVariant(QString, "World") ) 
      QHash(("3", QVariant(int, 4) ) ) 
      QHash()
      false
      false
      false
      false
      true
      true
      

      Attachments

        For Gerrit Dashboard: QTBUG-41403
        # Subject Branch Project Status CR V

        Activity

          People

            nierob Nierob
            steveire Stephen Kelly (Personal)
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes