diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2013-07-01 18:26:59 -0700 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-07-20 05:08:16 +0200 |
commit | 9d0ff90760bed65451fb665fecf9f770e3b05967 (patch) | |
tree | c48a1cd4cd5c2822f915d553428b9fbc44f3940b /src/corelib/io/qurl.cpp | |
parent | 9063119268821a5ea5c1fec0156efa72b84752c6 (diff) |
Make QUrl store the first bad IPv6 character in the error string
Change-Id: I9a0a521ff5c3188ba6f862e2b91369cb61787359
Reviewed-by: David Faure (KDE) <faure@kde.org>
Diffstat (limited to 'src/corelib/io/qurl.cpp')
-rw-r--r-- | src/corelib/io/qurl.cpp | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index d7729b7cb9..3d7e18fdfa 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -374,6 +374,7 @@ public: InvalidRegNameError = Host << 8, InvalidIPv4AddressError, InvalidIPv6AddressError, + InvalidCharacterInIPv6Error, InvalidIPvFutureError, HostMissingEndBracket, @@ -1138,7 +1139,7 @@ static const QChar *parseIpFuture(QString &host, const QChar *begin, const QChar } // ONLY the IPv6 address is parsed here, WITHOUT the brackets -static bool parseIp6(QString &host, const QChar *begin, const QChar *end, QUrl::ParsingMode mode) +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); @@ -1149,21 +1150,24 @@ static bool parseIp6(QString &host, const QChar *begin, const QChar *end, QUrl:: // 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)) { - // no transformation, nothing to re-parse - return false; + 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); + + // we can't return ret, otherwise it would be dangling + return ret ? end : 0; } - // recurse - // if the parsing fails again, the qt_urlRecode above will return 0 - return parseIp6(host, decoded.constBegin(), decoded.constEnd(), mode); + // no transformation, nothing to re-parse + return ret; } host.reserve(host.size() + (end - begin)); host += QLatin1Char('['); QIPAddressUtils::toString(host, address); host += QLatin1Char(']'); - return true; + return 0; } inline bool QUrlPrivate::setHost(const QString &value, int from, int iend, QUrl::ParsingMode mode) @@ -1191,13 +1195,18 @@ inline bool QUrlPrivate::setHost(const QString &value, int from, int iend, QUrl: if (c) setError(InvalidIPvFutureError, value, c - value.constData()); return !c; + } else if (begin[1].unicode() == 'v') { + setError(InvalidIPvFutureError, value, from); } - if (parseIp6(host, begin + 1, end - 1, mode)) + const QChar *c = parseIp6(host, begin + 1, end - 1, mode); + if (!c) return true; - setError(begin[1].unicode() == 'v' ? InvalidIPvFutureError : InvalidIPv6AddressError, - value, from); + if (c == end - 1) + setError(InvalidIPv6AddressError, value, from); + else + setError(InvalidCharacterInIPv6Error, value, c - value.constData()); return false; } @@ -3659,6 +3668,8 @@ static QString errorMessage(QUrlPrivate::ErrorCode errorCode, const QString &err return QString(); // doesn't happen yet case QUrlPrivate::InvalidIPv6AddressError: return QStringLiteral("Invalid IPv6 address"); + case QUrlPrivate::InvalidCharacterInIPv6Error: + return QStringLiteral("Invalid IPv6 address (character '%1' not permitted)").arg(c); case QUrlPrivate::InvalidIPvFutureError: return QStringLiteral("Invalid IPvFuture address (character '%1' not permitted)").arg(c); case QUrlPrivate::HostMissingEndBracket: |