Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QSettings::beginWriteArray() produces incorrect output under Linux (bug?)
Forum Updated to NodeBB v4.3 + New Features

QSettings::beginWriteArray() produces incorrect output under Linux (bug?)

Scheduled Pinned Locked Moved Solved General and Desktop
17 Posts 3 Posters 1.1k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • JonBJ Offline
    JonBJ Offline
    JonB
    wrote on last edited by JonB
    #1

    Qt 5.12.2 as supplied with Ubuntu 19.04, at least.

    See the example code at https://doc.qt.io/qt-5/qsettings.html#beginWriteArray. Additionally I have called QSettings.setDefaultFormat(QSettings.Format.IniFormat), but I don't imagine that's relevant***.

    The sample output shown as intended is:

    The generated keys will have the form
    
        logins/size
        logins/1/userName
        logins/1/password
        logins/2/userName
        logins/2/password
        logins/3/userName
        logins/3/password
    

    However, I get that output but with \s where it should be /s, e.g. logins\1\userName :(

    We are admonished not to go for backslashes instead of forward slashes in our own keys, for good reason....

    Could someone kindly verify under Linux at least whether they get same? What about Windows? I worry about reporting this, because then if they fix it the previously-saved arrays in files may not read in? :(

    *** EDIT Hmmm... Perhaps that IniFormat is actually what the behaviour is all about? (I'm just using it at present so all platforms save to a file, not Windows registry.) But there is

    On Unix, NativeFormat and IniFormat mean the same thing

    and there is

    QSettings always treats backslash as a special character and provides no API for reading or writing such entries.

    though of course the backslashes I am seeing are in QSettings-generated key names, not my values.

    Nope: I just tried removing the IniFormat: Linux saved it as "native" .conf file instead of .ini, but they are still all backslashes.

    Still scary!?

    Pl45m4P 1 Reply Last reply
    0
    • JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #17

      For right or for wrong, raised https://bugreports.qt.io/browse/QTBUG-81951. Hopefully someone will check whether it's only a documentation issue or if it has any consequences.

      1 Reply Last reply
      2
      • JonBJ JonB

        Qt 5.12.2 as supplied with Ubuntu 19.04, at least.

        See the example code at https://doc.qt.io/qt-5/qsettings.html#beginWriteArray. Additionally I have called QSettings.setDefaultFormat(QSettings.Format.IniFormat), but I don't imagine that's relevant***.

        The sample output shown as intended is:

        The generated keys will have the form
        
            logins/size
            logins/1/userName
            logins/1/password
            logins/2/userName
            logins/2/password
            logins/3/userName
            logins/3/password
        

        However, I get that output but with \s where it should be /s, e.g. logins\1\userName :(

        We are admonished not to go for backslashes instead of forward slashes in our own keys, for good reason....

        Could someone kindly verify under Linux at least whether they get same? What about Windows? I worry about reporting this, because then if they fix it the previously-saved arrays in files may not read in? :(

        *** EDIT Hmmm... Perhaps that IniFormat is actually what the behaviour is all about? (I'm just using it at present so all platforms save to a file, not Windows registry.) But there is

        On Unix, NativeFormat and IniFormat mean the same thing

        and there is

        QSettings always treats backslash as a special character and provides no API for reading or writing such entries.

        though of course the backslashes I am seeing are in QSettings-generated key names, not my values.

        Nope: I just tried removing the IniFormat: Linux saved it as "native" .conf file instead of .ini, but they are still all backslashes.

        Still scary!?

        Pl45m4P Offline
        Pl45m4P Offline
        Pl45m4
        wrote on last edited by Pl45m4
        #2

        @JonB said in QSettings::beginWriteArray() produces incorrect output under Linux (bug?):

        logins\1\userName

        How did you print this? With toString() or is this in your settings file?

        1. Do not use slashes ('/' and '\') in section or key names; the backslash character is used to separate sub keys (see below). On windows '' are converted by QSettings to '/', which makes them identical.

        (From https://doc.qt.io/qt-5/qsettings.html#section-and-key-syntax)

        Maybe its a conversion issue from QSetting together with Linux OS (I would understand, if it was the other way round)
        I can test on Win 10 (Qt 5.11.2) and Ubuntu 18.04 (Qt 5.13.2) later.

        UPDATE:

        Windows (5.11.2):

        • ini file
        • QSettings::Format::IniFormat set
        [logins]
        1\userName=userName
        1\password=password
        2\userName=userName
        2\password=password
        

        Linux (Qt 5.13.2):

        • same code / project as on Windows
        • same, unsatisfying output... :(
        [logins]
        1\password=password
        1\userName=userName
        2\password=password
        2\userName=userName
        

        If debugging is the process of removing software bugs, then programming must be the process of putting them in.

        ~E. W. Dijkstra

        JonBJ 1 Reply Last reply
        2
        • Pl45m4P Pl45m4

          @JonB said in QSettings::beginWriteArray() produces incorrect output under Linux (bug?):

          logins\1\userName

          How did you print this? With toString() or is this in your settings file?

          1. Do not use slashes ('/' and '\') in section or key names; the backslash character is used to separate sub keys (see below). On windows '' are converted by QSettings to '/', which makes them identical.

          (From https://doc.qt.io/qt-5/qsettings.html#section-and-key-syntax)

          Maybe its a conversion issue from QSetting together with Linux OS (I would understand, if it was the other way round)
          I can test on Win 10 (Qt 5.11.2) and Ubuntu 18.04 (Qt 5.13.2) later.

          UPDATE:

          Windows (5.11.2):

          • ini file
          • QSettings::Format::IniFormat set
          [logins]
          1\userName=userName
          1\password=password
          2\userName=userName
          2\password=password
          

          Linux (Qt 5.13.2):

          • same code / project as on Windows
          • same, unsatisfying output... :(
          [logins]
          1\password=password
          1\userName=userName
          2\password=password
          2\userName=userName
          
          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #3

          @Pl45m4 said in QSettings::beginWriteArray() produces incorrect output under Linux (bug?):

          logins\1\userName

          How did you print this? With toString() or is this in your settings file?

          This is what ends up in the file (else I wouldn't be reporting an issue!) :)

          As per the docs and the example there I quoted, they claim it should be logins/1/userName, but it's logins\1\userName. Honest, guv!

          Do not use slashes ('/' and '') in section or key names; the backslash character is used to separate sub keys (see below). On windows '' are converted by QSettings to '/', which makes them identical.

          Yes, that's why they I said they admonish us not to use them ourselves. And I don't. In case you're not aware, this is an issue of what QSettings::beginWriteArray() is producing, not me. They are choosing to implement "save array" via multiple keys-worth of output. The docs say they will use '/', which I feel marginally safe about, but in practice at least under Ubuntu they are outputting \, which I'm less safe about :)

          This will presumably be either a big in the (intended) code, or incorrect documentation.

          Thank you, yes, please do try on whatever platform(s) you have. Armed with your results, I will presumably then have to go raise a bug report....

          EDIT I think your latest modification has just crossed with my reply. Then it looks like it's not any better/different under Windows either....

          Pl45m4P 1 Reply Last reply
          1
          • JonBJ JonB

            @Pl45m4 said in QSettings::beginWriteArray() produces incorrect output under Linux (bug?):

            logins\1\userName

            How did you print this? With toString() or is this in your settings file?

            This is what ends up in the file (else I wouldn't be reporting an issue!) :)

            As per the docs and the example there I quoted, they claim it should be logins/1/userName, but it's logins\1\userName. Honest, guv!

            Do not use slashes ('/' and '') in section or key names; the backslash character is used to separate sub keys (see below). On windows '' are converted by QSettings to '/', which makes them identical.

            Yes, that's why they I said they admonish us not to use them ourselves. And I don't. In case you're not aware, this is an issue of what QSettings::beginWriteArray() is producing, not me. They are choosing to implement "save array" via multiple keys-worth of output. The docs say they will use '/', which I feel marginally safe about, but in practice at least under Ubuntu they are outputting \, which I'm less safe about :)

            This will presumably be either a big in the (intended) code, or incorrect documentation.

            Thank you, yes, please do try on whatever platform(s) you have. Armed with your results, I will presumably then have to go raise a bug report....

            EDIT I think your latest modification has just crossed with my reply. Then it looks like it's not any better/different under Windows either....

            Pl45m4P Offline
            Pl45m4P Offline
            Pl45m4
            wrote on last edited by Pl45m4
            #4

            @JonB said in QSettings::beginWriteArray() produces incorrect output under Linux (bug?):

            Thank you, yes, please do try on whatever platform(s) you have. Armed with your results, I will presumably then have to go raise a bug report....

            Additionally I think there is a mistake or typo in the code example :)

            QList<Login> logins; // QList named LOGINS
            ...
            
            QSettings settings;
            settings.beginWriteArray("logins");
            for (int i = 0; i < logins.size(); ++i) {
                settings.setArrayIndex(i);
                settings.setValue("userName", list.at(i).userName); // LIST.at(i)???
                settings.setValue("password", list.at(i).password); // LIST.at(i)??? Shouldn't it be "logins.at(i)"?!
            }
            

            Discovered another weird thing, as I'm comparing the ini file on Window with the ini file on Linux.
            When you look at the order, you will see that Linux wrote password, userName, while on WIndows it's userName, password (as supposed due to code, where "userName" is written to settings first)...


            If debugging is the process of removing software bugs, then programming must be the process of putting them in.

            ~E. W. Dijkstra

            JonBJ 1 Reply Last reply
            0
            • Pl45m4P Pl45m4

              @JonB said in QSettings::beginWriteArray() produces incorrect output under Linux (bug?):

              Thank you, yes, please do try on whatever platform(s) you have. Armed with your results, I will presumably then have to go raise a bug report....

              Additionally I think there is a mistake or typo in the code example :)

              QList<Login> logins; // QList named LOGINS
              ...
              
              QSettings settings;
              settings.beginWriteArray("logins");
              for (int i = 0; i < logins.size(); ++i) {
                  settings.setArrayIndex(i);
                  settings.setValue("userName", list.at(i).userName); // LIST.at(i)???
                  settings.setValue("password", list.at(i).password); // LIST.at(i)??? Shouldn't it be "logins.at(i)"?!
              }
              

              Discovered another weird thing, as I'm comparing the ini file on Window with the ini file on Linux.
              When you look at the order, you will see that Linux wrote password, userName, while on WIndows it's userName, password (as supposed due to code, where "userName" is written to settings first)...

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #5

              @Pl45m4
              My code is actually in Python, it's the same as the example but I didn't copy that bit of the C++ code so I didn't notice. Yes, using list in their code example is wrong, it should be logins :)

              I wouldn't rely on the order being the same from code to file or across platforms. QSettings probably holds some unordered dictionary for the keys, so output order would not be guaranteed. And that would be reasonable for ini file/registry saving.

              The only bit I care about is whether the file ends up with forward or backward slashes!

              Pl45m4P 1 Reply Last reply
              0
              • JonBJ JonB

                @Pl45m4
                My code is actually in Python, it's the same as the example but I didn't copy that bit of the C++ code so I didn't notice. Yes, using list in their code example is wrong, it should be logins :)

                I wouldn't rely on the order being the same from code to file or across platforms. QSettings probably holds some unordered dictionary for the keys, so output order would not be guaranteed. And that would be reasonable for ini file/registry saving.

                The only bit I care about is whether the file ends up with forward or backward slashes!

                Pl45m4P Offline
                Pl45m4P Offline
                Pl45m4
                wrote on last edited by Pl45m4
                #6

                @JonB said in QSettings::beginWriteArray() produces incorrect output under Linux (bug?):

                The only bit I care about is whether the file ends up with forward or backward slashes!

                The slashes in the doc could be just for demonstration purposes. Just to show the QSetting hierarchy?!

                • The generated keys will have the form

                What if "form" is meant in terms of hierarchy, separated by single slashes and not showing the actual content of the save file?!

                If this is the case, it's very misleading, but occording to QSettings doc (at least on Windows) QSettings ignores '\' and converts them to '/' anyway...

                So it could be an unfortunately worded example for this:

                - logins
                -------- 1
                ------------- userName
                ------------- password
                -------- 2
                ------------- userName
                ------------- password

                Edit:

                Looks like arrays always have backslashes (if they should? I dont know...)
                https://forum.qt.io/topic/79494/qsetting-array/4

                Just found a version of QSettings code online.
                https://github.com/radekp/qt/blob/master/src/corelib/io/qsettings.cpp

                void QSettingsPrivate::processChild(QString key, ChildSpec spec, QMap<QString, QString> &result)
                {
                    if (spec != AllKeys) {
                        int slashPos = key.indexOf(QLatin1Char('/')); // ### SLASH
                        if (slashPos == -1) {
                            if (spec != ChildKeys)
                                return;
                        } else {
                            if (spec != ChildGroups)
                                return;
                            key.truncate(slashPos);
                        }
                    }
                    result.insert(key, QString());
                }
                
                void QSettingsPrivate::beginGroupOrArray(const QSettingsGroup &group)
                {
                    groupStack.push(group);
                    if (!group.name().isEmpty()) {
                        groupPrefix += group.name();
                        groupPrefix += QLatin1Char('/'); // # SLASH!!
                    }
                }
                

                In addition to that, QSettings uses the QDir::separator() which indeed returns a single slash ('/') on my Linux system and a backslash on Windows....

                I really don't know where the backslash is coming from and WHY? :-)


                If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                ~E. W. Dijkstra

                JonBJ 1 Reply Last reply
                1
                • Pl45m4P Pl45m4

                  @JonB said in QSettings::beginWriteArray() produces incorrect output under Linux (bug?):

                  The only bit I care about is whether the file ends up with forward or backward slashes!

                  The slashes in the doc could be just for demonstration purposes. Just to show the QSetting hierarchy?!

                  • The generated keys will have the form

                  What if "form" is meant in terms of hierarchy, separated by single slashes and not showing the actual content of the save file?!

                  If this is the case, it's very misleading, but occording to QSettings doc (at least on Windows) QSettings ignores '\' and converts them to '/' anyway...

                  So it could be an unfortunately worded example for this:

                  - logins
                  -------- 1
                  ------------- userName
                  ------------- password
                  -------- 2
                  ------------- userName
                  ------------- password

                  Edit:

                  Looks like arrays always have backslashes (if they should? I dont know...)
                  https://forum.qt.io/topic/79494/qsetting-array/4

                  Just found a version of QSettings code online.
                  https://github.com/radekp/qt/blob/master/src/corelib/io/qsettings.cpp

                  void QSettingsPrivate::processChild(QString key, ChildSpec spec, QMap<QString, QString> &result)
                  {
                      if (spec != AllKeys) {
                          int slashPos = key.indexOf(QLatin1Char('/')); // ### SLASH
                          if (slashPos == -1) {
                              if (spec != ChildKeys)
                                  return;
                          } else {
                              if (spec != ChildGroups)
                                  return;
                              key.truncate(slashPos);
                          }
                      }
                      result.insert(key, QString());
                  }
                  
                  void QSettingsPrivate::beginGroupOrArray(const QSettingsGroup &group)
                  {
                      groupStack.push(group);
                      if (!group.name().isEmpty()) {
                          groupPrefix += group.name();
                          groupPrefix += QLatin1Char('/'); // # SLASH!!
                      }
                  }
                  

                  In addition to that, QSettings uses the QDir::separator() which indeed returns a single slash ('/') on my Linux system and a backslash on Windows....

                  I really don't know where the backslash is coming from and WHY? :-)

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by JonB
                  #7

                  @Pl45m4
                  From your https://forum.qt.io/topic/79494/qsetting-array/4 it looks like it is producing \s elsewhere. At least I know. Then it's perhaps just a docs issue.

                  Pl45m4P 1 Reply Last reply
                  0
                  • JonBJ JonB

                    @Pl45m4
                    From your https://forum.qt.io/topic/79494/qsetting-array/4 it looks like it is producing \s elsewhere. At least I know. Then it's perhaps just a docs issue.

                    Pl45m4P Offline
                    Pl45m4P Offline
                    Pl45m4
                    wrote on last edited by Pl45m4
                    #8

                    @JonB said in QSettings::beginWriteArray() produces incorrect output under Linux (bug?):

                    @Pl45m4
                    From your https://forum.qt.io/topic/79494/qsetting-array/4 it looks like it is producing \s elsewhere.

                    Just because others face the same issue or behavior, it doesn't mean that it's intended or correct :)
                    Could be wrong (buggy) since years / many releases, but seems to work :)

                    @JonB said in QSettings::beginWriteArray() produces incorrect output under Linux (bug?):

                    Then it's perhaps just a docs issue.

                    The second part of my post (the Qt source code) shows that it's not a doc issue. You can also find the same comment in the source code ("The generated keys will have the form.... bla...")... Really weird...


                    If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                    ~E. W. Dijkstra

                    1 Reply Last reply
                    0
                    • Christian EhrlicherC Online
                      Christian EhrlicherC Online
                      Christian Ehrlicher
                      Lifetime Qt Champion
                      wrote on last edited by
                      #9

                      What's the problem as long as beginReadArray() can read them later on?

                      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                      Visit the Qt Academy at https://academy.qt.io/catalog

                      JonBJ 1 Reply Last reply
                      0
                      • Christian EhrlicherC Christian Ehrlicher

                        What's the problem as long as beginReadArray() can read them later on?

                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote on last edited by JonB
                        #10

                        @Christian-Ehrlicher
                        At the time I raised the question I did not yet know whether it could be read OK. Now I am pleased to report it does. I merely asked to see if it was the same for others. I do not know if there any other consequences, hopefully not.

                        So you belong to the "it doesn't matter what the docs say as long as it works" school ;-)

                        Pl45m4P Christian EhrlicherC 2 Replies Last reply
                        0
                        • JonBJ JonB

                          @Christian-Ehrlicher
                          At the time I raised the question I did not yet know whether it could be read OK. Now I am pleased to report it does. I merely asked to see if it was the same for others. I do not know if there any other consequences, hopefully not.

                          So you belong to the "it doesn't matter what the docs say as long as it works" school ;-)

                          Pl45m4P Offline
                          Pl45m4P Offline
                          Pl45m4
                          wrote on last edited by Pl45m4
                          #11

                          myCodeWorks.jpg

                          Nevertheless, it would be satisfying (for me as well) if someone could explain where the backslashes come from, because even in current sources arrays start explicitly with '/'. (https://github.com/radekp/qt/blob/master/src/corelib/io/qsettings.cpp#L393)


                          If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                          ~E. W. Dijkstra

                          JonBJ 1 Reply Last reply
                          2
                          • Pl45m4P Pl45m4

                            myCodeWorks.jpg

                            Nevertheless, it would be satisfying (for me as well) if someone could explain where the backslashes come from, because even in current sources arrays start explicitly with '/'. (https://github.com/radekp/qt/blob/master/src/corelib/io/qsettings.cpp#L393)

                            JonBJ Offline
                            JonBJ Offline
                            JonB
                            wrote on last edited by JonB
                            #12

                            @Pl45m4

                            Nevertheless, it would be satisfying (for me as well) if someone could explain where the backslashes come from

                            All backslashes live in a land of their own, where everything is the wrong way round. They emanate from there, mystically. And sometimes arrive in pairs.

                            I will raise a report on the Qt bug forum tomorrow and they can decide whether it's a documentation or behaviour issue.

                            1 Reply Last reply
                            0
                            • JonBJ JonB

                              @Christian-Ehrlicher
                              At the time I raised the question I did not yet know whether it could be read OK. Now I am pleased to report it does. I merely asked to see if it was the same for others. I do not know if there any other consequences, hopefully not.

                              So you belong to the "it doesn't matter what the docs say as long as it works" school ;-)

                              Christian EhrlicherC Online
                              Christian EhrlicherC Online
                              Christian Ehrlicher
                              Lifetime Qt Champion
                              wrote on last edited by
                              #13

                              @JonB said in QSettings::beginWriteArray() produces incorrect output under Linux (bug?):

                              So you belong to the "it doesn't matter what the docs say as long as it works" school ;-)

                              No, but to the 'I don't care about the internals as long as the library can read it again'. Or do you really care how e.g. QDataStream encodes and decodes the stuff as long as it is doing what you expect?

                              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                              Visit the Qt Academy at https://academy.qt.io/catalog

                              JonBJ 1 Reply Last reply
                              0
                              • Christian EhrlicherC Christian Ehrlicher

                                @JonB said in QSettings::beginWriteArray() produces incorrect output under Linux (bug?):

                                So you belong to the "it doesn't matter what the docs say as long as it works" school ;-)

                                No, but to the 'I don't care about the internals as long as the library can read it again'. Or do you really care how e.g. QDataStream encodes and decodes the stuff as long as it is doing what you expect?

                                JonBJ Offline
                                JonBJ Offline
                                JonB
                                wrote on last edited by JonB
                                #14

                                @Christian-Ehrlicher
                                So are you saying you'd rather I didn't report it? When the docs choose to tell me the file will look like such & such and I try it and it does not, I shouldn't question it, shouldn't ask about it here but just assume it's fine? I don't understand your point/suggestion?

                                1 Reply Last reply
                                0
                                • Christian EhrlicherC Online
                                  Christian EhrlicherC Online
                                  Christian Ehrlicher
                                  Lifetime Qt Champion
                                  wrote on last edited by
                                  #15

                                  From my pov that's only a documentation error.

                                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                  Visit the Qt Academy at https://academy.qt.io/catalog

                                  JonBJ 1 Reply Last reply
                                  0
                                  • Christian EhrlicherC Christian Ehrlicher

                                    From my pov that's only a documentation error.

                                    JonBJ Offline
                                    JonBJ Offline
                                    JonB
                                    wrote on last edited by JonB
                                    #16

                                    @Christian-Ehrlicher
                                    No problem. I'll log it tomorrow, if it's only docs and the behaviour is intended then at least someone (might be you!) will have seen it and can decide.

                                    1 Reply Last reply
                                    0
                                    • JonBJ Offline
                                      JonBJ Offline
                                      JonB
                                      wrote on last edited by
                                      #17

                                      For right or for wrong, raised https://bugreports.qt.io/browse/QTBUG-81951. Hopefully someone will check whether it's only a documentation issue or if it has any consequences.

                                      1 Reply Last reply
                                      2

                                      • Login

                                      • Login or register to search.
                                      • First post
                                        Last post
                                      0
                                      • Categories
                                      • Recent
                                      • Tags
                                      • Popular
                                      • Users
                                      • Groups
                                      • Search
                                      • Get Qt Extensions
                                      • Unsolved