Skip to content

Commit

Permalink
[apps] Fixed URI decoding in UriParser (#3041).
Browse files Browse the repository at this point in the history
Fixed % followed by wrong sequence only skips this % character, not 3 characters whatever they are.
  • Loading branch information
ethouris authored Oct 8, 2024
1 parent 62f46aa commit 8f6fd4e
Showing 1 changed file with 27 additions and 17 deletions.
44 changes: 27 additions & 17 deletions apps/uriparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,32 +153,42 @@ string UriParser::queryValue(const string& strKey) const
static string url_decode(const string& str)
{
string ret;
size_t prev_idx;
size_t idx;
ret.reserve(str.size());

for (prev_idx = 0; string::npos != (idx = str.find('%', prev_idx)); prev_idx = idx + 3)
size_t end_idx = 0;

for (;;)
{
char tmp[3];
unsigned hex;
size_t idx = str.find('%', end_idx);
if (idx == string::npos)
break;

if (idx + 2 >= str.size()) // bad percent encoding
if (idx + 2 >= str.size()) // bad percent encoding at the end
break;

tmp[0] = str[idx + 1];
tmp[1] = str[idx + 2];
tmp[2] = '\0';
ret += str.substr(end_idx, idx - end_idx);

if (!isxdigit((unsigned char) tmp[0]) || // bad percent encoding
!isxdigit((unsigned char) tmp[1]) ||
1 != sscanf(tmp, "%x", &hex) ||
0 == hex)
break;
// make a "string" out of only two characters following %
char tmp[3] = { str[idx+1], str[idx+2], '\0' };
char* endptr = 0;
unsigned val = strtoul(tmp, &endptr, 16);
if (endptr != &tmp[2])
{
// Processing was not correct. Skip these and proceed.
ret += str[idx];
end_idx = idx + 1;
}
else
{
ret += char(val);
end_idx = idx + 3;
}

ret += str.substr(prev_idx, idx - prev_idx);
ret += (char) hex;
// And again search anew since end_idx.
}

ret += str.substr(prev_idx, str.size() - prev_idx);
// Copy the rest of the string that wasn't processed.
ret += str.substr(end_idx, str.size() - end_idx);

return ret;
}
Expand Down

0 comments on commit 8f6fd4e

Please sign in to comment.