Skip to content

Commit 8f6fd4e

Browse files
authored
[apps] Fixed URI decoding in UriParser (#3041).
Fixed % followed by wrong sequence only skips this % character, not 3 characters whatever they are.
1 parent 62f46aa commit 8f6fd4e

File tree

1 file changed

+27
-17
lines changed

1 file changed

+27
-17
lines changed

apps/uriparser.cpp

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -153,32 +153,42 @@ string UriParser::queryValue(const string& strKey) const
153153
static string url_decode(const string& str)
154154
{
155155
string ret;
156-
size_t prev_idx;
157-
size_t idx;
156+
ret.reserve(str.size());
158157

159-
for (prev_idx = 0; string::npos != (idx = str.find('%', prev_idx)); prev_idx = idx + 3)
158+
size_t end_idx = 0;
159+
160+
for (;;)
160161
{
161-
char tmp[3];
162-
unsigned hex;
162+
size_t idx = str.find('%', end_idx);
163+
if (idx == string::npos)
164+
break;
163165

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

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

171-
if (!isxdigit((unsigned char) tmp[0]) || // bad percent encoding
172-
!isxdigit((unsigned char) tmp[1]) ||
173-
1 != sscanf(tmp, "%x", &hex) ||
174-
0 == hex)
175-
break;
171+
// make a "string" out of only two characters following %
172+
char tmp[3] = { str[idx+1], str[idx+2], '\0' };
173+
char* endptr = 0;
174+
unsigned val = strtoul(tmp, &endptr, 16);
175+
if (endptr != &tmp[2])
176+
{
177+
// Processing was not correct. Skip these and proceed.
178+
ret += str[idx];
179+
end_idx = idx + 1;
180+
}
181+
else
182+
{
183+
ret += char(val);
184+
end_idx = idx + 3;
185+
}
176186

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

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

183193
return ret;
184194
}

0 commit comments

Comments
 (0)