@@ -153,32 +153,42 @@ string UriParser::queryValue(const string& strKey) const
153153static 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