Poco::URI::decode() doesn't properly handle '+'

GH #27: Poco::URI::decode() doesn't properly handle '+'
This commit is contained in:
aleks-f 2012-12-05 22:28:25 -06:00
parent 569ea46817
commit 7327be4735
4 changed files with 31 additions and 3 deletions

View File

@ -246,10 +246,12 @@ public:
/// URI-encodes the given string by escaping reserved and non-ASCII /// URI-encodes the given string by escaping reserved and non-ASCII
/// characters. The encoded string is appended to encodedStr. /// characters. The encoded string is appended to encodedStr.
static void decode(const std::string& str, std::string& decodedStr); static void decode(const std::string& str, std::string& decodedStr, bool plusAsSpace = false);
/// URI-decodes the given string by replacing percent-encoded /// URI-decodes the given string by replacing percent-encoded
/// characters with the actual character. The decoded string /// characters with the actual character. The decoded string
/// is appended to decodedStr. /// is appended to decodedStr.
/// When plusAsSpace is true, non-encoded plus signs in the query are decoded as spaces.
/// (http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1)
protected: protected:
bool equals(const URI& uri) const; bool equals(const URI& uri) const;

View File

@ -595,14 +595,18 @@ void URI::encode(const std::string& str, const std::string& reserved, std::strin
} }
void URI::decode(const std::string& str, std::string& decodedStr) void URI::decode(const std::string& str, std::string& decodedStr, bool plusAsSpace)
{ {
bool inQuery = false;
std::string::const_iterator it = str.begin(); std::string::const_iterator it = str.begin();
std::string::const_iterator end = str.end(); std::string::const_iterator end = str.end();
while (it != end) while (it != end)
{ {
char c = *it++; char c = *it++;
if (c == '%') if (c == '?') inQuery = true;
// spaces may be encoded as plus signs in the query
if (inQuery && plusAsSpace && c == '+') c = ' ';
else if (c == '%')
{ {
if (it == end) throw SyntaxException("URI encoding: no hex digit following percent sign", str); if (it == end) throw SyntaxException("URI encoding: no hex digit following percent sign", str);
char hi = *it++; char hi = *it++;

View File

@ -767,6 +767,26 @@ void URITest::testOther()
} }
void URITest::testEncodeDecode()
{
std::string str;
URI::encode("http://google.com/search?q=hello+world#frag ment", "+#?", str);
assert (str == "http://google.com/search%3Fq=hello%2Bworld%23frag%20ment");
str = "";
URI::encode("http://google.com/search?q=hello+world#frag ment", "", str);
assert (str == "http://google.com/search?q=hello+world#frag%20ment");
str = "";
URI::decode("http://google.com/search?q=hello+world#frag%20ment", str, true);
assert (str == "http://google.com/search?q=hello world#frag ment");
str = "";
URI::decode("http://google.com/search?q=hello%2Bworld#frag%20ment", str);
assert (str == "http://google.com/search?q=hello+world#frag ment");
}
void URITest::setUp() void URITest::setUp()
{ {
} }
@ -788,6 +808,7 @@ CppUnit::Test* URITest::suite()
CppUnit_addTest(pSuite, URITest, testNormalize); CppUnit_addTest(pSuite, URITest, testNormalize);
CppUnit_addTest(pSuite, URITest, testResolve); CppUnit_addTest(pSuite, URITest, testResolve);
CppUnit_addTest(pSuite, URITest, testSwap); CppUnit_addTest(pSuite, URITest, testSwap);
CppUnit_addTest(pSuite, URITest, testEncodeDecode);
CppUnit_addTest(pSuite, URITest, testOther); CppUnit_addTest(pSuite, URITest, testOther);
return pSuite; return pSuite;

View File

@ -53,6 +53,7 @@ public:
void testNormalize(); void testNormalize();
void testResolve(); void testResolve();
void testSwap(); void testSwap();
void testEncodeDecode();
void testOther(); void testOther();
void setUp(); void setUp();