AusweisApp2/patches/qt-QUrl-Support-IPv6-addres...

109 lines
4.2 KiB
Diff

From 2e492dc6a6cf9e73a04f65e133ea4e97324a68da Mon Sep 17 00:00:00 2001
From: Robbert Proost <robbert.proost@outlook.com>
Date: Thu, 18 Jan 2018 09:52:49 +0100
Subject: [PATCH] QUrl: Support IPv6 addresses with zone id
Task-number: QTBUG-25550
Change-Id: I37ec02b655abe2779aa11945e20550ce00e43723
---
src/corelib/io/qurl.cpp | 63 ++++++++++++++++---------
tests/auto/corelib/io/qurl/tst_qurl.cpp | 52 ++++++++++++++++++++
2 files changed, 92 insertions(+), 23 deletions(-)
diff --git x/qtbase/src/corelib/io/qurl.cpp y/qtbase/src/corelib/io/qurl.cpp
index 4587b9fcd6..e2a66c8459 100644
--- x/qtbase/src/corelib/io/qurl.cpp
+++ y/qtbase/src/corelib/io/qurl.cpp
@@ -1203,16 +1203,18 @@ inline void QUrlPrivate::setQuery(const QString &value, int from, int iend)
inline void QUrlPrivate::appendHost(QString &appendTo, QUrl::FormattingOptions options) const
{
- // EncodeUnicode is the only flag that matters
- if ((options & QUrl::FullyDecoded) == QUrl::FullyDecoded)
- options = 0;
- else
- options &= QUrl::EncodeUnicode;
if (host.isEmpty())
return;
if (host.at(0).unicode() == '[') {
- // IPv6Address and IPvFuture address never require any transformation
- appendTo += host;
+ // IPv6 addresses might contain a zone-id which needs to be recoded
+ QString hostInCorrectFormat;
+ if (options != 0)
+ qt_urlRecode(hostInCorrectFormat, host.constBegin(), host.constEnd(), options, 0);
+
+ if (hostInCorrectFormat.isEmpty())
+ hostInCorrectFormat = host;
+
+ appendTo += hostInCorrectFormat;
} else {
// this is either an IPv4Address or a reg-name
// if it is a reg-name, it is already stored in Unicode form
@@ -1278,31 +1280,46 @@ static const QChar *parseIpFuture(QString &host, const QChar *begin, const QChar
// ONLY the IPv6 address is parsed here, WITHOUT the brackets
static const QChar *parseIp6(QString &host, const QChar *begin, const QChar *end, QUrl::ParsingMode mode)
{
- QIPAddressUtils::IPv6Address address;
- const QChar *ret = QIPAddressUtils::parseIp6(address, begin, end);
- if (ret) {
- // this struct is kept in automatic storage because it's only 4 bytes
+ QString decoded;
+ if (mode == QUrl::TolerantMode) {
const ushort decodeColon[] = { decode(':'), 0 };
+ if (qt_urlRecode(decoded, begin, end, QUrl::ComponentFormattingOption::PrettyDecoded, decodeColon) == 0) {
+ decoded = QString(begin, end-begin);
+ }
+ }
+ else {
+ decoded = QString(begin, end-begin);
+ }
- // IPv6 failed parsing, check if it was a percent-encoded character in
- // the middle and try again
- QString decoded;
- if (mode == QUrl::TolerantMode && qt_urlRecode(decoded, begin, end, 0, decodeColon)) {
- // recurse
- // if the parsing fails again, the qt_urlRecode above will return 0
- ret = parseIp6(host, decoded.constBegin(), decoded.constEnd(), mode);
+ const QLatin1String zoneIdIdentifier("%25");
+ QIPAddressUtils::IPv6Address address;
+ QString zoneId;
+
+ const QChar *endBeforeZoneId = decoded.constEnd();
+
+ int zoneIdPosition = decoded.indexOf(zoneIdIdentifier);
+ if ((zoneIdPosition != -1) && (decoded.lastIndexOf(zoneIdIdentifier) == zoneIdPosition)) {
+ zoneId = decoded.mid(zoneIdPosition + zoneIdIdentifier.size());
+ endBeforeZoneId = decoded.constBegin() + zoneIdPosition;
- // we can't return ret, otherwise it would be dangling
- return ret ? end : 0;
+ if (zoneId.isEmpty() == true) {
+ return end;
}
+ }
- // no transformation, nothing to re-parse
- return ret;
+ const QChar *ret = QIPAddressUtils::parseIp6(address, decoded.constBegin(), endBeforeZoneId);
+ if (ret) {
+ return begin + (ret - decoded.constBegin());
}
- host.reserve(host.size() + (end - begin));
+ host.reserve(host.size() + (decoded.constEnd() - decoded.constBegin()));
host += QLatin1Char('[');
QIPAddressUtils::toString(host, address);
+
+ if (zoneId.isEmpty() == false) {
+ host += zoneIdIdentifier;
+ host += zoneId;
+ }
host += QLatin1Char(']');
return 0;
}
--
2.18.0