Skip to content

Commit 7098fca

Browse files
author
Vivek Yamsani
committed
fix query params decoding for query_string::get_dict
#1109
1 parent 833f0ce commit 7098fca

File tree

2 files changed

+32
-23
lines changed

2 files changed

+32
-23
lines changed

include/crow/query_string.h

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ inline char * qs_k2v(const char * key, char * const * qs_kv, size_t qs_kv_size,
203203
inline std::unique_ptr<std::pair<std::string, std::string>> qs_dict_name2kv(const char * dict_name, char * const * qs_kv, size_t qs_kv_size, int nth = 0)
204204
{
205205
size_t i;
206-
size_t name_len, skip_to_eq, skip_to_brace_open, skip_to_brace_close;
206+
size_t name_len, eq_pos, key_size;
207207

208208
name_len = strlen(dict_name);
209209

@@ -212,29 +212,22 @@ inline std::unique_ptr<std::pair<std::string, std::string>> qs_dict_name2kv(cons
212212
#else // _qsSORTING
213213
for(i=0; i<qs_kv_size; i++)
214214
{
215-
if ( strncmp(dict_name, qs_kv[i], name_len) == 0 )
215+
eq_pos = key_size = strcspn(qs_kv[i], "=");
216+
if (qs_kv[i][eq_pos] == '\0')
217+
continue;
218+
auto key = std::unique_ptr<char[]>(new char[key_size]);
219+
memcpy(key.get(), qs_kv[i], key_size);
220+
key[key_size] = '\0';
221+
key_size = qs_decode(key.get());
222+
223+
if (strncmp(dict_name, key.get(), name_len) == 0 &&
224+
key_size > name_len && key[name_len] == '[' &&
225+
key[key_size - 1] == ']' &&
226+
nth-- == 0)
216227
{
217-
skip_to_eq = strcspn(qs_kv[i], "=");
218-
if ( qs_kv[i][skip_to_eq] == '=' )
219-
skip_to_eq++;
220-
skip_to_brace_open = strcspn(qs_kv[i], "[");
221-
if ( qs_kv[i][skip_to_brace_open] == '[' )
222-
skip_to_brace_open++;
223-
skip_to_brace_close = strcspn(qs_kv[i], "]");
224-
225-
if ( skip_to_brace_open <= skip_to_brace_close &&
226-
skip_to_brace_open > 0 &&
227-
skip_to_brace_close > 0 &&
228-
nth == 0 )
229-
{
230-
auto key = std::string(qs_kv[i] + skip_to_brace_open, skip_to_brace_close - skip_to_brace_open);
231-
auto value = std::string(qs_kv[i] + skip_to_eq);
232-
return std::unique_ptr<std::pair<std::string, std::string>>(new std::pair<std::string, std::string>(key, value));
233-
}
234-
else
235-
{
236-
--nth;
237-
}
228+
auto sub_key = std::string(key.get() + name_len + 1, key_size - name_len - 2);
229+
auto value = std::string(qs_kv[i] + eq_pos + 1);
230+
return std::unique_ptr<std::pair<std::string, std::string>>(new std::pair<std::string, std::string>(sub_key, value));
238231
}
239232
}
240233
#endif // _qsSORTING

tests/query_string_tests.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,20 @@ TEST_CASE( "query string keys" )
4242
return key == entry.first;});
4343
REQUIRE(exist == true);
4444
}
45+
}
46+
47+
TEST_CASE("query string decoding in get_dict")
48+
{
49+
const std::vector<std::pair<std::string, std::string>> params{
50+
{"foo%5Bkey1%5D", "bar1"},
51+
{"foo%5Bkey2%5D", "bar2"},
52+
{"foo%5B%5D", "bar3"},
53+
{"foo%5B%5D", "bar4"},
54+
{"foo%5B%5Bkey%5D", "bar%5B%1%5D"}};
55+
const crow::query_string query_params("params?" + buildQueryStr(params));
56+
auto map = query_params.get_dict("foo");
57+
REQUIRE(map["key1"] == "bar1");
58+
REQUIRE(map["key2"] == "bar2");
59+
REQUIRE(map[""] == "bar3");
60+
REQUIRE(map["[key"] == "bar[");
4561
}

0 commit comments

Comments
 (0)