#573150 psi: accented characters in addresses

Package:
psi
Source:
psi
Description:
Qt-based XMPP client
Submitter:
Riccardo Stagni
Date:
2010-03-13 17:51:18 UTC
Severity:
normal
#573150#5
Date:
2010-03-09 11:57:57 UTC
From:
To:
A friend of mine sent me a link containing an accent, http://öpnvkarte.de/
Clicking on it opened "http://pnvkarte.de/" in my browser.

I made some other check, and it appears that this issue happens only with .de domains and with any type of accented character.

ciao
Riccardo

#573150#8
Date:
2010-03-09 13:24:39 UTC
From:
To:
and that would be great if another method were added openUrl(const QUrl&
url) here and in the urlobject.
QUrl guarantees to store proper url.

2010/3/9 Jan Niehusmann <jan@gondor.com>

#573150#13
Date:
2010-03-09 13:19:53 UTC
From:
To:
Hi,

I got the following bug report through the debian bts. Looking at the
source code, it seems like the following function in desktoputil.cpp is
not correct:

bool DesktopUtil::openUrl(const QString& url)
{
        QByteArray ascii = url.toAscii();
        if (ascii == url)
                return doOpenUrl(QUrl::fromEncoded(ascii));
        else
                return doOpenUrl(QUrl(url, QUrl::TolerantMode));
}


QString.toAscii is passing on latin1 characters unchanged (assuming no
QTextCodec has been set). So (ascii == url) is true even though the url
contains the character 'ö', which is then discarded by QUrl::fromEncoded.

Just calling doOpenUrl(QUrl(url, QUrl::TolerantMode)) without checking
for pure-ascii urls first does work. But of course, this essentially
reverts 9790593a9b0c72b335a5c724cd0deca443d8fa1e, so directly entering
percent-encoded URLs doesn't work any more.

I guess it's necessary to explicitely check if the url only contains
legal 7-bit characters to decide how to interpret it.

Regards,
Jan

#573150#16
Date:
2010-03-09 13:19:53 UTC
From:
To:
Hi,

I got the following bug report through the debian bts. Looking at the
source code, it seems like the following function in desktoputil.cpp is
not correct:

bool DesktopUtil::openUrl(const QString& url)
{
        QByteArray ascii = url.toAscii();
        if (ascii == url)
                return doOpenUrl(QUrl::fromEncoded(ascii));
        else
                return doOpenUrl(QUrl(url, QUrl::TolerantMode));
}


QString.toAscii is passing on latin1 characters unchanged (assuming no
QTextCodec has been set). So (ascii == url) is true even though the url
contains the character 'ö', which is then discarded by QUrl::fromEncoded.

Just calling doOpenUrl(QUrl(url, QUrl::TolerantMode)) without checking
for pure-ascii urls first does work. But of course, this essentially
reverts 9790593a9b0c72b335a5c724cd0deca443d8fa1e, so directly entering
percent-encoded URLs doesn't work any more.

I guess it's necessary to explicitely check if the url only contains
legal 7-bit characters to decide how to interpret it.

Regards,
Jan

#573150#17
Date:
2010-03-13 17:48:51 UTC
From:
To:
Indeed unnecessary conversions between string and url should be
prevented, but when a message contains an url within the message text,
the conversion QString -> QUrl must be done somewhere.

To keep the changes small, I didn't touch the signature of openUrl, but
instead just changed the if condition. What do you think about the
following patch? It just checks if the url only contains printable 7-bit
ascii characters (range 0x21-0x7e) instead of checking if toAscii does
modify the contents of the string.

Jan

diff --git a/src/desktoputil.cpp b/src/desktoputil.cpp
index 4bc08a0..a9c7145 100644
--- a/src/desktoputil.cpp
+++ b/src/desktoputil.cpp
@@ -27,6 +27,7 @@
 #include <QProcess>
 #include <QSysInfo>
 #include <QSet>
+#include <QRegExp>

 #ifdef Q_WS_WIN
 #include <windows.h>
@@ -84,9 +85,11 @@ static bool doOpenUrl(const QUrl& url)
  */
 bool DesktopUtil::openUrl(const QString& url)
 {
-	QByteArray ascii = url.toAscii();
-	if (ascii == url)
-		return doOpenUrl(QUrl::fromEncoded(ascii));
+	// If url only contains characters in the ASCII-range 0x21 (!) - 0x7E (~),
+	// it can be used without further encoding.
+	QRegExp regexp = QRegExp("[\041-\176]*");
+	if (regexp.exactMatch(url))
+		return doOpenUrl(QUrl::fromEncoded(url.toAscii()));
 	else
 		return doOpenUrl(QUrl(url, QUrl::TolerantMode));
 }