summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/io/qurl.cpp205
-rw-r--r--src/corelib/io/qurl.h16
2 files changed, 186 insertions, 35 deletions
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index bb97890d15..a7ceb7337f 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -503,6 +503,10 @@ static const ushort decodedQueryInUrlActions[] = {
0
};
+static inline void parseDecodedComponent(QString &data)
+{
+ data.replace(QLatin1Char('%'), QStringLiteral("%25"));
+}
static inline QString
recodeFromUser(const QString &input, const ushort *actions, int from, int to)
@@ -1560,7 +1564,7 @@ void QUrl::clear()
StrictMode, isValid() will return false. The parsing mode DecodedMode is
not permitted in this context and will produce a run-time warning.
- \sa setEncodedUrl()
+ \sa url(), toString()
*/
void QUrl::setUrl(const QString &url, ParsingMode parsingMode)
{
@@ -1576,7 +1580,7 @@ void QUrl::setUrl(const QString &url, ParsingMode parsingMode)
/*!
Sets the scheme of the URL to \a scheme. As a scheme can only
contain ASCII characters, no conversion or encoding is done on the
- input.
+ input. It must also start with an ASCII letter.
The scheme describes the type (or protocol) of the URL. It's
represented by one or more ASCII characters at the start the URL,
@@ -1607,6 +1611,9 @@ void QUrl::setScheme(const QString &scheme)
Returns the scheme of the URL. If an empty string is returned,
this means the scheme is undefined and the URL is then relative.
+ The scheme can only contain US-ASCII letters or digits, which means it
+ cannot contain any character that would otherwise require encoding.
+
\sa setScheme(), isRelative()
*/
QString QUrl::scheme() const
@@ -1631,11 +1638,29 @@ QString QUrl::scheme() const
The following example shows a valid authority string:
\image qurl-authority.png
+
+ The \a authority data is interpreted according to \a mode: in StrictMode,
+ any '%' characters must be followed by exactly two hexadecimal characters
+ and some characters (including space) are not allowed in undecoded form. In
+ TolerantMode (the default), all characters are accepted in undecoded form
+ and the tolerant parser will correct stray '%' not followed by two hex
+ characters. In DecodedMode, '%' stand for themselves and encoded characters
+ are not possible. Because of that, in DecodedMode, it is not possible to
+ use the delimiter characters as non-delimiters (e.g., a password containing
+ a '@').
+
+ \sa setUserInfo, setHost, setPort
*/
-void QUrl::setAuthority(const QString &authority)
+void QUrl::setAuthority(const QString &authority, ParsingMode mode)
{
detach();
- d->setAuthority(authority, 0, authority.length());
+ QString data = authority;
+ if (mode == DecodedMode) {
+ parseDecodedComponent(data);
+ mode = TolerantMode;
+ }
+
+ d->setAuthority(data, 0, data.length());
if (authority.isNull()) {
// QUrlPrivate::setAuthority cleared almost everything
// but it leaves the Host bit set
@@ -1669,12 +1694,26 @@ QString QUrl::authority(ComponentFormattingOptions options) const
\image qurl-authority3.png
+ The \a userInfo data is interpreted according to \a mode: in StrictMode,
+ any '%' characters must be followed by exactly two hexadecimal characters
+ and some characters (including space) are not allowed in undecoded form. In
+ TolerantMode (the default), all characters are accepted in undecoded form
+ and the tolerant parser will correct stray '%' not followed by two hex
+ characters. In DecodedMode, '%' stand for themselves and encoded characters
+ are not possible. Because of that, in DecodedMode, it is not possible to
+ use the ':' delimiter characters as non-delimiter in the user name.
+
\sa userInfo(), setUserName(), setPassword(), setAuthority()
*/
-void QUrl::setUserInfo(const QString &userInfo)
+void QUrl::setUserInfo(const QString &userInfo, ParsingMode mode)
{
detach();
QString trimmed = userInfo.trimmed();
+ if (mode == DecodedMode) {
+ parseDecodedComponent(trimmed);
+ mode = TolerantMode;
+ }
+
d->setUserInfo(trimmed, 0, trimmed.length());
if (userInfo.isNull()) {
// QUrlPrivate::setUserInfo cleared almost everything
@@ -1701,12 +1740,33 @@ QString QUrl::userInfo(ComponentFormattingOptions options) const
of the user info element in the authority of the URL, as described
in setUserInfo().
- \sa setEncodedUserName(), userName(), setUserInfo()
+ The \a userName data is interpreted according to \a mode: in StrictMode,
+ any '%' characters must be followed by exactly two hexadecimal characters
+ and some characters (including space) are not allowed in undecoded form. In
+ TolerantMode (the default), all characters are accepted in undecoded form
+ and the tolerant parser will correct stray '%' not followed by two hex
+ characters. In DecodedMode, '%' stand for themselves and encoded characters
+ are not possible.
+
+ QUrl::DecodedMode should be used when setting the user name from a data
+ source which is not a URL, such as a password dialog shown to the user or
+ with a user name obtained by calling userName() with the QUrl::FullyEncoded
+ formatting option.
+
+ \sa userName(), setUserInfo()
*/
-void QUrl::setUserName(const QString &userName)
+void QUrl::setUserName(const QString &userName, ParsingMode mode)
{
detach();
- d->setUserName(userName, 0, userName.length());
+
+ QString data = userName;
+ if (mode == DecodedMode) {
+ parseDecodedComponent(data);
+ mode = TolerantMode;
+ }
+
+
+ d->setUserName(data, 0, data.length());
if (userName.isNull())
d->sectionIsPresent &= ~QUrlPrivate::UserName;
}
@@ -1731,12 +1791,32 @@ QString QUrl::userName(ComponentFormattingOptions options) const
the user info element in the authority of the URL, as described in
setUserInfo().
+ The \a password data is interpreted according to \a mode: in StrictMode,
+ any '%' characters must be followed by exactly two hexadecimal characters
+ and some characters (including space) are not allowed in undecoded form. In
+ TolerantMode, all characters are accepted in undecoded form and the
+ tolerant parser will correct stray '%' not followed by two hex characters.
+ In DecodedMode, '%' stand for themselves and encoded characters are not
+ possible.
+
+ QUrl::DecodedMode should be used when setting the password from a data
+ source which is not a URL, such as a password dialog shown to the user or
+ with a password obtained by calling password() with the QUrl::FullyEncoded
+ formatting option.
+
\sa password(), setUserInfo()
*/
-void QUrl::setPassword(const QString &password)
+void QUrl::setPassword(const QString &password, ParsingMode mode)
{
detach();
- d->setPassword(password, 0, password.length());
+
+ QString data = password;
+ if (mode == DecodedMode) {
+ parseDecodedComponent(data);
+ mode = TolerantMode;
+ }
+
+ d->setPassword(data, 0, data.length());
if (password.isNull())
d->sectionIsPresent &= ~QUrlPrivate::Password;
}
@@ -1760,21 +1840,43 @@ QString QUrl::password(ComponentFormattingOptions options) const
Sets the host of the URL to \a host. The host is part of the
authority.
+ The \a host data is interpreted according to \a mode: in StrictMode,
+ any '%' characters must be followed by exactly two hexadecimal characters
+ and some characters (including space) are not allowed in undecoded form. In
+ TolerantMode, all characters are accepted in undecoded form and the
+ tolerant parser will correct stray '%' not followed by two hex characters.
+ In DecodedMode, '%' stand for themselves and encoded characters are not
+ possible.
+
+ Note that, in all cases, the result of the parsing must be a valid hostname
+ according to STD 3 rules, as modified by the Internationalized Resource
+ Identifiers specification (RFC 3987). Invalid hostnames are not permitted
+ and will cause isValid() to become false.
+
\sa host(), setAuthority()
*/
-void QUrl::setHost(const QString &host)
+void QUrl::setHost(const QString &host, ParsingMode mode)
{
detach();
- if (d->setHost(host, 0, host.length())) {
+
+ QString data = host;
+ if (mode == DecodedMode) {
+ parseDecodedComponent(data);
+ mode = TolerantMode;
+ }
+
+ if (d->setHost(data, 0, data.length())) {
if (host.isNull())
d->sectionIsPresent &= ~QUrlPrivate::Host;
- } else if (!host.startsWith(QLatin1Char('['))) {
+ } else if (!data.startsWith(QLatin1Char('['))) {
// setHost failed, it might be IPv6 or IPvFuture in need of bracketing
ushort oldCode = d->errorCode;
ushort oldSupplement = d->errorSupplement;
- if (!d->setHost(QLatin1Char('[') + host + QLatin1Char(']'), 0, host.length() + 2)) {
+ data.prepend(QLatin1Char('['));
+ data.append(QLatin1Char(']'));
+ if (!d->setHost(data, 0, data.length())) {
// failed again: choose if this was an IPv6 error or not
- if (!host.contains(QLatin1Char(':'))) {
+ if (!data.contains(QLatin1Char(':'))) {
d->errorCode = oldCode;
d->errorSupplement = oldSupplement;
}
@@ -1847,12 +1949,31 @@ int QUrl::port(int defaultPort) const
\image qurl-mailtopath.png
+ The \a path data is interpreted according to \a mode: in StrictMode,
+ any '%' characters must be followed by exactly two hexadecimal characters
+ and some characters (including space) are not allowed in undecoded form. In
+ TolerantMode (the default), all characters are accepted in undecoded form and the
+ tolerant parser will correct stray '%' not followed by two hex characters.
+ In DecodedMode, '%' stand for themselves and encoded characters are not
+ possible.
+
+ QUrl::DecodedMode should be used when setting the path from a data source
+ which is not a URL, such as a dialog shown to the user or with a path
+ obtained by calling path() with the QUrl::FullyEncoded formatting option.
+
\sa path()
*/
-void QUrl::setPath(const QString &path)
+void QUrl::setPath(const QString &path, ParsingMode mode)
{
detach();
- d->setPath(path, 0, path.length());
+
+ QString data = path;
+ if (mode == DecodedMode) {
+ parseDecodedComponent(data);
+ mode = TolerantMode;
+ }
+
+ d->setPath(data, 0, data.length());
// optimized out, since there is no path delimiter
// if (path.isNull())
@@ -1887,27 +2008,39 @@ bool QUrl::hasQuery() const
}
/*!
- Sets the query string of the URL to \a query. The string is
- inserted as-is, and no further encoding is performed when calling
- toEncoded().
+ Sets the query string of the URL to \a query.
This function is useful if you need to pass a query string that
does not fit into the key-value pattern, or that uses a different
scheme for encoding special characters than what is suggested by
QUrl.
- Passing a value of QByteArray() to \a query (a null QByteArray) unsets
- the query completely. However, passing a value of QByteArray("")
+ Passing a value of QString() to \a query (a null QString) unsets
+ the query completely. However, passing a value of QString("")
will set the query to an empty value, as if the original URL
had a lone "?".
+ The \a query data is interpreted according to \a mode: in StrictMode,
+ any '%' characters must be followed by exactly two hexadecimal characters
+ and some characters (including space) are not allowed in undecoded form. In
+ TolerantMode, all characters are accepted in undecoded form and the
+ tolerant parser will correct stray '%' not followed by two hex characters.
+ In DecodedMode, '%' stand for themselves and encoded characters are not
+ possible.
+
\sa encodedQuery(), hasQuery()
*/
-void QUrl::setQuery(const QString &query)
+void QUrl::setQuery(const QString &query, ParsingMode mode)
{
detach();
- d->setQuery(query, 0, query.length());
+ QString data = query;
+ if (mode == DecodedMode) {
+ parseDecodedComponent(data);
+ mode = TolerantMode;
+ }
+
+ d->setQuery(data, 0, data.length());
if (query.isNull())
d->sectionIsPresent &= ~QUrlPrivate::Query;
}
@@ -1953,13 +2086,31 @@ QString QUrl::query(ComponentFormattingOptions options) const
will set the fragment to an empty string (as if the original URL
had a lone "#").
+ The \a fragment data is interpreted according to \a mode: in StrictMode,
+ any '%' characters must be followed by exactly two hexadecimal characters
+ and some characters (including space) are not allowed in undecoded form. In
+ TolerantMode, all characters are accepted in undecoded form and the
+ tolerant parser will correct stray '%' not followed by two hex characters.
+ In DecodedMode, '%' stand for themselves and encoded characters are not
+ possible.
+
+ QUrl::DecodedMode should be used when setting the fragment from a data
+ source which is not a URL or with a fragment obtained by calling
+ fragment() with the QUrl::FullyEncoded formatting option.
+
\sa fragment(), hasFragment()
*/
-void QUrl::setFragment(const QString &fragment)
+void QUrl::setFragment(const QString &fragment, ParsingMode mode)
{
detach();
- d->setFragment(fragment, 0, fragment.length());
+ QString data = fragment;
+ if (mode == DecodedMode) {
+ parseDecodedComponent(data);
+ mode = TolerantMode;
+ }
+
+ d->setFragment(data, 0, data.length());
if (fragment.isNull())
d->sectionIsPresent &= ~QUrlPrivate::Fragment;
}
@@ -2514,7 +2665,7 @@ QUrl QUrl::fromLocalFile(const QString &localFile)
deslashified.clear();
}
- url.setPath(deslashified.replace(QLatin1Char('%'), QStringLiteral("%25")));
+ url.setPath(deslashified, DecodedMode);
return url;
}
diff --git a/src/corelib/io/qurl.h b/src/corelib/io/qurl.h
index 533489ae2b..41e6c17fd5 100644
--- a/src/corelib/io/qurl.h
+++ b/src/corelib/io/qurl.h
@@ -194,36 +194,36 @@ public:
void setScheme(const QString &scheme);
QString scheme() const;
- void setAuthority(const QString &authority);
+ void setAuthority(const QString &authority, ParsingMode mode = TolerantMode);
QString authority(ComponentFormattingOptions options = PrettyDecoded) const;
- void setUserInfo(const QString &userInfo);
+ void setUserInfo(const QString &userInfo, ParsingMode mode = TolerantMode);
QString userInfo(ComponentFormattingOptions options = PrettyDecoded) const;
- void setUserName(const QString &userName);
+ void setUserName(const QString &userName, ParsingMode mode = TolerantMode);
QString userName(ComponentFormattingOptions options = PrettyDecoded) const;
- void setPassword(const QString &password);
+ void setPassword(const QString &password, ParsingMode mode = TolerantMode);
QString password(ComponentFormattingOptions = PrettyDecoded) const;
- void setHost(const QString &host);
+ void setHost(const QString &host, ParsingMode mode = TolerantMode);
QString host(ComponentFormattingOptions = PrettyDecoded) const;
QString topLevelDomain(ComponentFormattingOptions options = PrettyDecoded) const;
void setPort(int port);
int port(int defaultPort = -1) const;
- void setPath(const QString &path);
+ void setPath(const QString &path, ParsingMode mode = TolerantMode);
QString path(ComponentFormattingOptions options = PrettyDecoded) const;
bool hasQuery() const;
- void setQuery(const QString &query);
+ void setQuery(const QString &query, ParsingMode mode = TolerantMode);
void setQuery(const QUrlQuery &query);
QString query(ComponentFormattingOptions = PrettyDecoded) const;
bool hasFragment() const;
QString fragment(ComponentFormattingOptions options = PrettyDecoded) const;
- void setFragment(const QString &fragment);
+ void setFragment(const QString &fragment, ParsingMode mode = TolerantMode);
QUrl resolved(const QUrl &relative) const;