diff -r 41300fa6a67c -r f7bc934e204c src/corelib/io/qurl.cpp --- a/src/corelib/io/qurl.cpp Tue Feb 02 00:43:10 2010 +0200 +++ b/src/corelib/io/qurl.cpp Wed Mar 31 11:06:36 2010 +0300 @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -350,8 +350,8 @@ }; int stateFlags; - QByteArray encodedNormalized; - const QByteArray & normalized(); + mutable QByteArray encodedNormalized; + const QByteArray & normalized() const; mutable QUrlErrorInfo errorInfo; QString createErrorString(); @@ -437,17 +437,19 @@ } // scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) -static void QT_FASTCALL _scheme(const char **ptr, QUrlParseData *parseData) +static bool QT_FASTCALL _scheme(const char **ptr, QUrlParseData *parseData) { bool first = true; + bool isSchemeValid = true; parseData->scheme = *ptr; for (;;) { char ch = **ptr; if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) { ; - } else if (!first && ((ch >= '0' && ch <= '9') || ch == '+' || ch == '-' || ch == '.')) { - ; + } else if ((ch >= '0' && ch <= '9') || ch == '+' || ch == '-' || ch == '.') { + if (first) + isSchemeValid = false; } else { break; } @@ -457,11 +459,14 @@ } if (**ptr != ':') { + isSchemeValid = true; *ptr = parseData->scheme; } else { parseData->schemeLength = *ptr - parseData->scheme; ++(*ptr); // skip ':' } + + return isSchemeValid; } // IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) @@ -3241,8 +3246,11 @@ while (1) { int idx = nextDotDelimiter(domain, lastIdx); int labelLength = idx - lastIdx; - if (labelLength == 0) + if (labelLength == 0) { + if (idx == domain.length()) + break; return QString(); // two delimiters in a row -- empty label not allowed + } // RFC 3490 says, about the ToASCII operation: // 3. If the UseSTD3ASCIIRules flag is set, then perform these checks: @@ -3740,7 +3748,19 @@ #endif // optional scheme - _scheme(ptr, &parseData); + bool isSchemeValid = _scheme(ptr, &parseData); + + if (isSchemeValid == false) { + that->isValid = false; + char ch = *((*ptr)++); + that->errorInfo.setParams(*ptr, QT_TRANSLATE_NOOP(QUrl, "unexpected URL scheme"), + 0, ch); + QURL_SETFLAG(that->stateFlags, Validated | Parsed); +#if defined (QURL_DEBUG) + qDebug("QUrlPrivate::parse(), unrecognized: %c%s", ch, *ptr); +#endif + return; + } // hierpart _hierPart(ptr, &parseData); @@ -3850,6 +3870,9 @@ if (!QURL_HASFLAG(stateFlags, Parsed)) parse(); else ensureEncodedParts(); + if (options==0x100) // private - see qHash(QUrl) + return normalized(); + QByteArray url; if (!(options & QUrl::RemoveScheme) && !scheme.isEmpty()) { @@ -3864,14 +3887,18 @@ url += "//"; if ((options & QUrl::RemoveUserInfo) != QUrl::RemoveUserInfo) { + bool hasUserOrPass = false; if (!userName.isEmpty()) { url += encodedUserName; - if (!(options & QUrl::RemovePassword) && !password.isEmpty()) { - url += ':'; - url += encodedPassword; - } + hasUserOrPass = true; + } + if (!(options & QUrl::RemovePassword) && !password.isEmpty()) { + url += ':'; + url += encodedPassword; + hasUserOrPass = true; + } + if (hasUserOrPass) url += '@'; - } } if (host.startsWith(QLatin1Char('['))) { @@ -3916,12 +3943,13 @@ #define qToLower(ch) (((ch|32) >= 'a' && (ch|32) <= 'z') ? (ch|32) : ch) -const QByteArray &QUrlPrivate::normalized() +const QByteArray &QUrlPrivate::normalized() const { if (QURL_HASFLAG(stateFlags, QUrlPrivate::Normalized)) return encodedNormalized; - QURL_SETFLAG(stateFlags, QUrlPrivate::Normalized); + QUrlPrivate *that = const_cast(this); + QURL_SETFLAG(that->stateFlags, QUrlPrivate::Normalized); QUrlPrivate tmp = *this; tmp.scheme = tmp.scheme.toLower(); @@ -4070,7 +4098,7 @@ \sa setUrl(), setEncodedUrl(), fromEncoded(), TolerantMode */ -QUrl::QUrl(const QString &url) : d(new QUrlPrivate) +QUrl::QUrl(const QString &url) : d(0) { if (!url.isEmpty()) setUrl(url); @@ -4083,18 +4111,20 @@ \sa setUrl() */ -QUrl::QUrl(const QString &url, ParsingMode parsingMode) : d(new QUrlPrivate) +QUrl::QUrl(const QString &url, ParsingMode parsingMode) : d(0) { if (!url.isEmpty()) setUrl(url, parsingMode); - else + else { + d = new QUrlPrivate; d->parsingMode = parsingMode; + } } /*! Constructs an empty QUrl object. */ -QUrl::QUrl() : d(new QUrlPrivate) +QUrl::QUrl() : d(0) { } @@ -4103,7 +4133,8 @@ */ QUrl::QUrl(const QUrl &other) : d(other.d) { - d->ref.ref(); + if (d) + d->ref.ref(); } /*! @@ -4111,7 +4142,7 @@ */ QUrl::~QUrl() { - if (!d->ref.deref()) + if (d && !d->ref.deref()) delete d; } @@ -4126,6 +4157,8 @@ */ bool QUrl::isValid() const { + if (!d) return false; + if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Validated)) d->validate(); @@ -4137,6 +4170,8 @@ */ bool QUrl::isEmpty() const { + if (!d) return true; + if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) return d->encodedOriginal.isEmpty(); else @@ -4157,8 +4192,9 @@ */ void QUrl::clear() { - detach(); - d->clear(); + if (d && !d->ref.deref()) + delete d; + d = 0; } /*! @@ -4257,8 +4293,9 @@ */ void QUrl::setEncodedUrl(const QByteArray &encodedUrl, ParsingMode parsingMode) { - clear(); QByteArray tmp = encodedUrl; + if (!d) d = new QUrlPrivate; + else d->clear(); if ((d->parsingMode = parsingMode) == TolerantMode) { // Replace stray % with %25 QByteArray copy = tmp; @@ -4332,6 +4369,7 @@ */ void QUrl::setScheme(const QString &scheme) { + if (!d) d = new QUrlPrivate; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); detach(); QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized); @@ -4347,6 +4385,7 @@ */ QString QUrl::scheme() const { + if (!d) return QString(); if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); return d->scheme; @@ -4370,6 +4409,8 @@ */ void QUrl::setAuthority(const QString &authority) { + if (!d) d = new QUrlPrivate; + if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); detach(); QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized); @@ -4385,6 +4426,8 @@ */ QString QUrl::authority() const { + if (!d) return QString(); + if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); return d->authority(); @@ -4405,6 +4448,8 @@ */ void QUrl::setUserInfo(const QString &userInfo) { + if (!d) d = new QUrlPrivate; + if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); detach(); QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized); @@ -4418,6 +4463,8 @@ */ QString QUrl::userInfo() const { + if (!d) return QString(); + if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); return d->userInfo(); @@ -4432,6 +4479,8 @@ */ void QUrl::setUserName(const QString &userName) { + if (!d) d = new QUrlPrivate; + if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); detach(); QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized); @@ -4448,6 +4497,8 @@ */ QString QUrl::userName() const { + if (!d) return QString(); + if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); d->userInfo(); // causes the unencoded form to be set @@ -4469,6 +4520,7 @@ */ void QUrl::setEncodedUserName(const QByteArray &userName) { + if (!d) d = new QUrlPrivate; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); detach(); QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized); @@ -4489,6 +4541,7 @@ */ QByteArray QUrl::encodedUserName() const { + if (!d) return QByteArray(); if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); d->ensureEncodedParts(); @@ -4504,6 +4557,7 @@ */ void QUrl::setPassword(const QString &password) { + if (!d) d = new QUrlPrivate; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); detach(); QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized); @@ -4520,6 +4574,7 @@ */ QString QUrl::password() const { + if (!d) return QString(); if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); d->userInfo(); // causes the unencoded form to be set @@ -4541,6 +4596,7 @@ */ void QUrl::setEncodedPassword(const QByteArray &password) { + if (!d) d = new QUrlPrivate; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); detach(); QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized); @@ -4561,6 +4617,7 @@ */ QByteArray QUrl::encodedPassword() const { + if (!d) return QByteArray(); if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); d->ensureEncodedParts(); @@ -4575,6 +4632,7 @@ */ void QUrl::setHost(const QString &host) { + if (!d) d = new QUrlPrivate; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); detach(); QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized | QUrlPrivate::HostCanonicalized); @@ -4588,6 +4646,7 @@ */ QString QUrl::host() const { + if (!d) return QString(); if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); if (d->host.isEmpty() || d->host.at(0) != QLatin1Char('[')) @@ -4641,6 +4700,7 @@ */ void QUrl::setPort(int port) { + if (!d) d = new QUrlPrivate; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); detach(); QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized); @@ -4658,6 +4718,7 @@ */ int QUrl::port() const { + if (!d) return -1; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Validated)) d->validate(); return d->port; @@ -4676,6 +4737,7 @@ */ int QUrl::port(int defaultPort) const { + if (!d) return defaultPort; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); return d->port == -1 ? defaultPort : d->port; } @@ -4695,6 +4757,7 @@ */ void QUrl::setPath(const QString &path) { + if (!d) d = new QUrlPrivate; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); detach(); QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized); @@ -4710,6 +4773,7 @@ */ QString QUrl::path() const { + if (!d) return QString(); if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); if (d->path.isNull()) { @@ -4741,6 +4805,7 @@ */ void QUrl::setEncodedPath(const QByteArray &path) { + if (!d) d = new QUrlPrivate; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); detach(); QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized); @@ -4761,6 +4826,7 @@ */ QByteArray QUrl::encodedPath() const { + if (!d) return QByteArray(); if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); d->ensureEncodedParts(); @@ -4776,6 +4842,7 @@ */ bool QUrl::hasQuery() const { + if (!d) return false; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); return d->hasQuery; @@ -4805,6 +4872,7 @@ */ void QUrl::setQueryDelimiters(char valueDelimiter, char pairDelimiter) { + if (!d) d = new QUrlPrivate; detach(); d->valueDelimiter = valueDelimiter; @@ -4817,6 +4885,7 @@ */ char QUrl::queryPairDelimiter() const { + if (!d) return '&'; return d->pairDelimiter; } @@ -4826,6 +4895,7 @@ */ char QUrl::queryValueDelimiter() const { + if (!d) return '='; return d->valueDelimiter; } @@ -4848,6 +4918,7 @@ */ void QUrl::setEncodedQuery(const QByteArray &query) { + if (!d) d = new QUrlPrivate; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); detach(); QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized); @@ -4867,6 +4938,7 @@ */ void QUrl::setQueryItems(const QList > &query) { + if (!d) d = new QUrlPrivate; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); detach(); @@ -4906,6 +4978,7 @@ */ void QUrl::setEncodedQueryItems(const QList > &query) { + if (!d) d = new QUrlPrivate; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); detach(); @@ -4935,6 +5008,7 @@ */ void QUrl::addQueryItem(const QString &key, const QString &value) { + if (!d) d = new QUrlPrivate; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); detach(); @@ -4969,6 +5043,7 @@ */ void QUrl::addEncodedQueryItem(const QByteArray &key, const QByteArray &value) { + if (!d) d = new QUrlPrivate; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); detach(); @@ -4989,6 +5064,7 @@ */ QList > QUrl::queryItems() const { + if (!d) return QList >(); if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); QList > itemMap; @@ -5021,6 +5097,7 @@ */ QList > QUrl::encodedQueryItems() const { + if (!d) return QList >(); if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); QList > itemMap; @@ -5049,6 +5126,7 @@ */ bool QUrl::hasQueryItem(const QString &key) const { + if (!d) return false; return hasEncodedQueryItem(toPercentEncoding(key, queryExcludeChars)); } @@ -5067,6 +5145,7 @@ */ bool QUrl::hasEncodedQueryItem(const QByteArray &key) const { + if (!d) return false; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); int pos = 0; @@ -5089,6 +5168,7 @@ */ QString QUrl::queryItemValue(const QString &key) const { + if (!d) return QString(); QByteArray tmp = encodedQueryItemValue(toPercentEncoding(key, queryExcludeChars)); return fromPercentEncodingMutable(&tmp); } @@ -5108,6 +5188,7 @@ */ QByteArray QUrl::encodedQueryItemValue(const QByteArray &key) const { + if (!d) return QByteArray(); if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); int pos = 0; @@ -5131,6 +5212,7 @@ */ QStringList QUrl::allQueryItemValues(const QString &key) const { + if (!d) return QStringList(); if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); QByteArray encodedKey = toPercentEncoding(key, queryExcludeChars); @@ -5168,6 +5250,7 @@ */ QList QUrl::allEncodedQueryItemValues(const QByteArray &key) const { + if (!d) return QList(); if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); QList values; @@ -5195,6 +5278,7 @@ */ void QUrl::removeQueryItem(const QString &key) { + if (!d) return; removeEncodedQueryItem(toPercentEncoding(key, queryExcludeChars)); } @@ -5213,6 +5297,7 @@ */ void QUrl::removeEncodedQueryItem(const QByteArray &key) { + if (!d) return; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); detach(); @@ -5239,6 +5324,7 @@ */ void QUrl::removeAllQueryItems(const QString &key) { + if (!d) return; removeAllEncodedQueryItems(toPercentEncoding(key, queryExcludeChars)); } @@ -5257,6 +5343,7 @@ */ void QUrl::removeAllEncodedQueryItems(const QByteArray &key) { + if (!d) return; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); detach(); @@ -5280,6 +5367,7 @@ */ QByteArray QUrl::encodedQuery() const { + if (!d) return QByteArray(); if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); return d->query; @@ -5304,6 +5392,7 @@ */ void QUrl::setFragment(const QString &fragment) { + if (!d) d = new QUrlPrivate; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); detach(); QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized); @@ -5320,6 +5409,7 @@ */ QString QUrl::fragment() const { + if (!d) return QString(); if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); if (d->fragment.isNull() && !d->encodedFragment.isNull()) { @@ -5350,6 +5440,7 @@ */ void QUrl::setEncodedFragment(const QByteArray &fragment) { + if (!d) d = new QUrlPrivate; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); detach(); QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized); @@ -5371,6 +5462,7 @@ */ QByteArray QUrl::encodedFragment() const { + if (!d) return QByteArray(); if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); d->ensureEncodedParts(); @@ -5386,6 +5478,7 @@ */ bool QUrl::hasFragment() const { + if (!d) return false; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); return d->hasFragment; @@ -5412,6 +5505,8 @@ */ QUrl QUrl::resolved(const QUrl &relative) const { + if (!d) return relative; + if (!relative.d) return *this; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); if (!QURL_HASFLAG(relative.d->stateFlags, QUrlPrivate::Parsed)) @@ -5428,6 +5523,7 @@ if (!relative.authority().isEmpty()) { t = relative; } else { + t.d = new QUrlPrivate; if (relative.d->encodedPath.isEmpty()) { t.d->encodedPath = d->encodedPath; t.setEncodedQuery(relative.d->hasQuery ? relative.d->query : d->query); @@ -5458,6 +5554,7 @@ */ bool QUrl::isRelative() const { + if (!d) return true; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); return d->scheme.isEmpty(); @@ -5472,6 +5569,7 @@ */ QString QUrl::toString(FormattingOptions options) const { + if (!d) return QString(); if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); QString url; @@ -5523,6 +5621,7 @@ */ QByteArray QUrl::toEncoded(FormattingOptions options) const { + if (!d) return QByteArray(); return d->toEncoded(options); } @@ -5773,7 +5872,9 @@ */ bool QUrl::operator <(const QUrl &url) const { + if (!d) return url.d ? QByteArray() < url.d->normalized() : false; if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); + if (!url.d) return d->normalized() < QByteArray(); if (!QURL_HASFLAG(url.d->stateFlags, QUrlPrivate::Parsed)) url.d->parse(); return d->normalized() < url.d->normalized(); } @@ -5784,6 +5885,8 @@ */ bool QUrl::operator ==(const QUrl &url) const { + if (!d) return url.isEmpty(); + if (!url.d) return isEmpty(); if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); if (!QURL_HASFLAG(url.d->stateFlags, QUrlPrivate::Parsed)) url.d->parse(); return d->normalized() == url.d->normalized(); @@ -5803,7 +5906,17 @@ */ QUrl &QUrl::operator =(const QUrl &url) { - qAtomicAssign(d, url.d); + if (!d) { + if (url.d) { + url.d->ref.ref(); + d = url.d; + } + } else { + if (url.d) + qAtomicAssign(d, url.d); + else + clear(); + } return *this; } @@ -5812,8 +5925,13 @@ */ QUrl &QUrl::operator =(const QString &url) { - QUrl tmp(url); - qAtomicAssign(d, tmp.d); + if (url.isEmpty()) { + clear(); + } else { + QUrl tmp(url); + if (!d) d = new QUrlPrivate; + qAtomicAssign(d, tmp.d); + } return *this; } @@ -5822,14 +5940,19 @@ Forces a detach. */ void QUrl::detach() -{ qAtomicDetach(d); } +{ + if (!d) + d = new QUrlPrivate; + else + qAtomicDetach(d); +} /*! \internal */ bool QUrl::isDetached() const { - return d->ref == 1; + return !d || d->ref == 1; } @@ -5871,6 +5994,7 @@ */ QString QUrl::toLocalFile() const { + if (!d) return QString(); if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); QString tmp; @@ -5899,9 +6023,15 @@ */ bool QUrl::isParentOf(const QUrl &childUrl) const { + QString childPath = childUrl.path(); + + if (!d) + return ((childUrl.scheme().isEmpty()) + && (childUrl.authority().isEmpty()) + && childPath.length() > 0 && childPath.at(0) == QLatin1Char('/')); + if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse(); - QString childPath = childUrl.path(); QString ourPath = path(); return ((childUrl.scheme().isEmpty() || d->scheme == childUrl.scheme()) @@ -6141,6 +6271,8 @@ */ QString QUrl::errorString() const { + if (!d) + return QLatin1String(QT_TRANSLATE_NOOP(QUrl, "Invalid URL \"\": ")); // XXX not a good message, but the one an empty URL produces return d->createErrorString(); }