Merge pull request #2959 from dahek/get_raw_fragment

Fix percent-encoded fragment modification in Poco::URI
This commit is contained in:
Günter Obiltschnig 2022-07-03 15:12:23 +02:00 committed by GitHub
commit b6dcb5bbd3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 15 deletions

View File

@ -40,15 +40,18 @@ class Foundation_API URI
/// The class automatically performs a few normalizations on
/// all URIs and URI parts passed to it:
/// * scheme identifiers are converted to lower case
/// * percent-encoded characters are decoded (except for the query string)
/// * percent-encoded characters are decoded (except for the query string and fragment string)
/// * optionally, dot segments are removed from paths (see normalize())
///
/// Note that dealing with query strings requires some precautions, as, internally,
/// query strings are stored in percent-encoded form, while all other parts of the URI
/// are stored in decoded form. While parsing query strings from properly encoded URLs
/// generally works, explicitly setting query strings with setQuery() or extracting
/// query strings with getQuery() may lead to ambiguities. See the descriptions of
/// setQuery(), setRawQuery(), getQuery() and getRawQuery() for more information.
/// Note that dealing with query strings and fragment strings requires some precautions,
/// as, internally, query strings and fragment strings are stored in percent-encoded
/// form, while all other parts of the URI are stored in decoded form. While parsing
/// query strings and fragment strings from properly encoded URLs generally works,
/// explicitly setting query strings (fragment strings) with setQuery() (setFragment())
/// or extracting query strings (fragment strings) with getQuery() (getFragment()) may
/// lead to ambiguities. See the descriptions of setQuery(), setRawQuery(), getQuery(),
/// getRawQuery(), setFragment(), setRawFragment(), getFragment() and getRawFragment()
/// for more information.
{
public:
using QueryParameters = std::vector<std::pair<std::string, std::string>>;
@ -230,12 +233,20 @@ public:
///
/// Calls addQueryParameter() for each parameter name and value.
const std::string& getFragment() const;
std::string getFragment() const;
/// Returns the fragment part of the URI.
void setFragment(const std::string& fragment);
/// Sets the fragment part of the URI.
std::string getRawFragment() const;
/// Returns the fragment part of the URI in raw form.
void setRawFragment(const std::string& fragment);
/// Sets the fragment part of the URI.
///
/// The given fragment string must be properly percent-encoded
void setPathEtc(const std::string& pathEtc);
/// Sets the path, query and fragment parts of the URI.
@ -400,7 +411,7 @@ inline const std::string& URI::getRawQuery() const
}
inline const std::string& URI::getFragment() const
inline std::string URI::getRawFragment() const
{
return _fragment;
}

View File

@ -257,7 +257,7 @@ std::string URI::toString() const
if (!_fragment.empty())
{
uri += '#';
encode(_fragment, RESERVED_FRAGMENT, uri);
uri.append(_fragment);
}
return uri;
}
@ -420,10 +420,24 @@ void URI::setQueryParameters(const QueryParameters& params)
}
std::string URI::getFragment() const
{
std::string fragment;
decode(_fragment, fragment);
return fragment;
}
void URI::setFragment(const std::string& fragment)
{
_fragment.clear();
decode(fragment, _fragment);
encode(fragment, RESERVED_FRAGMENT, _fragment);
}
void URI::setRawFragment(const std::string& fragment)
{
_fragment = fragment;
}
@ -450,7 +464,7 @@ std::string URI::getPathEtc() const
if (!_fragment.empty())
{
pathEtc += '#';
encode(_fragment, RESERVED_FRAGMENT, pathEtc);
pathEtc += _fragment;
}
return pathEtc;
}
@ -882,9 +896,8 @@ void URI::parseQuery(std::string::const_iterator& it, const std::string::const_i
void URI::parseFragment(std::string::const_iterator& it, const std::string::const_iterator& end)
{
std::string fragment;
while (it != end) fragment += *it++;
decode(fragment, _fragment);
_fragment.clear();
while (it != end) _fragment += *it++;
}

View File

@ -743,6 +743,7 @@ void URITest::testOther()
assertTrue (uri.getQuery() == "q=hello%world");
assertTrue (uri.getRawQuery() == "q=hello%25world");
assertTrue (uri.getFragment() == "frag ment");
assertTrue (uri.getRawFragment() == "frag%20ment");
assertTrue (uri.toString() == "http://google.com/search?q=hello%25world#frag%20ment");
assertTrue (uri.getPathEtc() == "/search?q=hello%25world#frag%20ment");
@ -783,8 +784,20 @@ void URITest::testOther()
assertTrue (uri.getQuery() == "q=hello+world");
assertTrue (uri.getRawQuery() == "q=hello+world");
assertTrue (uri.getFragment() == "frag ment");
assertTrue (uri.getRawFragment() == "frag%20ment");
assertTrue (uri.toString() == "http://google.com/search?q=hello+world#frag%20ment");
assertTrue (uri.getPathEtc() == "/search?q=hello+world#frag%20ment");
uri.setFragment("foo/bar");
assertTrue (uri.getFragment() == "foo/bar");
assertTrue (uri.getRawFragment() == "foo/bar");
assertTrue (uri.toString() == "http://google.com/search?q=hello+world#foo/bar");
assertTrue (uri.getPathEtc() == "/search?q=hello+world#foo/bar");
uri.setRawFragment("foo%2Fbar");
assertTrue (uri.getFragment() == "foo/bar");
assertTrue (uri.getRawFragment() == "foo%2Fbar");
assertTrue (uri.toString() == "http://google.com/search?q=hello+world#foo%2Fbar");
assertTrue (uri.getPathEtc() == "/search?q=hello+world#foo%2Fbar");
}