Inline double quotes work in QT 4.7.4 not in 4.8.6

I have a Qt 4.7.4 application. I'm trying to upgrade Qt 4.8.6, however version 4.8.6 does not handle embedded double quotes like 4.7.4.

As an example, the following line is one of twelve that we use as arguments for QApplication:

QString myData = 
    QString("{\"type\":\"IndexFlt\",\"media\":\"1\",\"entityid\":\"0:0:0\"}");

      

In version 4.7.4, twelve lines were passed to QApplication as part argv

.

When I return arguments via theApp.arguments()

in 4.7.4, I return all arguments with no formatting changes.

However, when I pass the same argumetns to version 4.8.6 and then called theApp.arguments()

, QStringList only has six entries instead of twelve.

When I look at the 6th line, I see that QT takes arguments 7-12 and adds them to the first six.

What I see in the debugger for the QStringList argument is different from 4.7.4 and 4.8.6. in 4.7.4

I see argument 6 as:

"{"type":"IndexFlt","media":"1","entityid":"0:0:0"}"

      

But with version 4.8.6 I see argument 6 as:

"{\type":"IndexFlt","media":"1","entityid":"0:0:0"} --ScriptArg:...

      

As you can see, instead of double quotation mark infront of the string type

, I get a /

, and the closure }

doesn't get "

after it got the 7-12 arguments appended to the 6 argument.

Any ideas on how to fix this? The only thing that has changed in the application is the Qt version.

You can use the following code to see the problem with embedded double quotes. Just make sure you use at least two arguments with the first argument containing embedded double quotes. So, for example, if the code below is compiled into an exe called test.exe, then you would suggest test.exe like this: test.exe --DoubleQuotes = "true" -NoDoubleQuotes = false

#include <QtGui/QApplication>
#include <QtCore/QStringList>
#include <iostream>

int main(int argc, char** argv)
{

    for (int i=0; i < argc ; i++)
    {
        std::string tmp = argv[i];
        std::cout << tmp << std::endl;
    }

    QApplication theApp(argc, argv);

    QStringList vArgs = theApp.arguments();
    foreach (QString t, vArgs)
    {
        std::cout << t.toStdString() << std::endl;
    }
}

      

+3


source to share


1 answer


The problem you are facing is due to a bug in the parsing argv

that Qt 4.8.6 brings into the template function qWinCmdLine<>()

(from qcorecmdlineargs_p.h

).

In Qt 4.7.4, the section of code in this function that handles escaped quotes on the command line looks like this (the comments in the left column are my annotations):

                    if (*p == '\\') {                // escape char?
/* skip escape */       p++;
                        if (*p == Char('\"') || *p == Char('\''))
/* keep quote */            ;                        // yes
                        else
/* else undo */             p--;                        // treat \ literally
                    } else {
                        if (!quote && (*p == Char('\"') || *p == Char('\''))) {        // " or ' quote
/* note and */              quote = *p++;               
/* skip quote */            continue;
                        } else if (QChar((short)(*p)).isSpace() && !quote)
                            break;
                    }

      

In Qt 4.8.6, this section of the function looks like this:

                    if (*p == '\\') {                // escape char?
/* BUG */               if (*(p+1) == quote)
                            p++;
                    } else {
                        if (!quote && (*p == Char('\"') || *p == Char('\''))) {        // " or ' quote
                            quote = *p++;
                            continue;
                        } else if (QChar((short)(*p)).isSpace() && !quote)
                            break;

      



The snapshots are very similar except that the 4.8.6 code tries to be a little smarter by skipping the escape character if it sees the next character, this is quote

instead of 4.7.4 the technique of skipping the escape char then undo this if it notices the next one the character is not '\"'

or '\'

. The problem is, in the line I annotated as /* BUG */

, the variable quote

is only set if you are already in the quoted section. It does not correctly handle an escaped quote character that is not in the quoted part of the command line.

Note that sometime between Qt 4.8.6 and Qt 5.3.1 the function is qWinCmdLine<>()

no longer used for Windows desktop purposes (it is only used for WinCE purposes). Instead, the Win32 API is CommandLineToArgvW()

used to parse the command line into an array argv

, and it looks like this is returning the behavior you are looking for (it looks like the bug is fixed in the WinCE version qWinCmdLine<>()

).

So, to fix your problem, you need to use a version of Qt other than 4.8.6 (I'm not sure which versions the bug happened or when it was fixed), or you can fix qcorecmdlineargs_p.h

and rebuild Qt if you need 4.8.6 by for any reason.

Also note that on Windows QCoreApplication

(and therefore QApplication

) ignores the argc

and arguments argv

that you pass. The parsed command line is always obtained from the Win32 API GetCommandLine()

. Although this behavior is documented, it was not what I expected and caused annoyance when I tried to test things by passing different values ​​to argc

/ argv

in QCoreApplication

with no effect.

+1


source







All Articles