Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 16 additions & 23 deletions include/crow/query_string.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ inline char * qs_k2v(const char * key, char * const * qs_kv, size_t qs_kv_size,
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)
{
size_t i;
size_t name_len, skip_to_eq, skip_to_brace_open, skip_to_brace_close;
size_t name_len, eq_pos, key_size;

name_len = strlen(dict_name);

Expand All @@ -212,29 +212,22 @@ inline std::unique_ptr<std::pair<std::string, std::string>> qs_dict_name2kv(cons
#else // _qsSORTING
for(i=0; i<qs_kv_size; i++)
{
if ( strncmp(dict_name, qs_kv[i], name_len) == 0 )
eq_pos = key_size = strcspn(qs_kv[i], "=");
if (qs_kv[i][eq_pos] == '\0')
continue;
auto key = std::unique_ptr<char[]>(new char[key_size]);
memcpy(key.get(), qs_kv[i], key_size);
key[key_size] = '\0';
key_size = qs_decode(key.get());

if (strncmp(dict_name, key.get(), name_len) == 0 &&
key_size > name_len && key[name_len] == '[' &&
key[key_size - 1] == ']' &&
nth-- == 0)
{
skip_to_eq = strcspn(qs_kv[i], "=");
if ( qs_kv[i][skip_to_eq] == '=' )
skip_to_eq++;
skip_to_brace_open = strcspn(qs_kv[i], "[");
if ( qs_kv[i][skip_to_brace_open] == '[' )
skip_to_brace_open++;
skip_to_brace_close = strcspn(qs_kv[i], "]");

if ( skip_to_brace_open <= skip_to_brace_close &&
skip_to_brace_open > 0 &&
skip_to_brace_close > 0 &&
nth == 0 )
{
auto key = std::string(qs_kv[i] + skip_to_brace_open, skip_to_brace_close - skip_to_brace_open);
auto value = std::string(qs_kv[i] + skip_to_eq);
return std::unique_ptr<std::pair<std::string, std::string>>(new std::pair<std::string, std::string>(key, value));
}
else
{
--nth;
}
auto sub_key = std::string(key.get() + name_len + 1, key_size - name_len - 2);
auto value = std::string(qs_kv[i] + eq_pos + 1);
return std::unique_ptr<std::pair<std::string, std::string>>(new std::pair<std::string, std::string>(sub_key, value));
}
}
#endif // _qsSORTING
Expand Down
16 changes: 16 additions & 0 deletions tests/query_string_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,20 @@ TEST_CASE( "query string keys" )
return key == entry.first;});
REQUIRE(exist == true);
}
}

TEST_CASE("query string decoding in get_dict")
{
const std::vector<std::pair<std::string, std::string>> params{
{"foo%5Bkey1%5D", "bar1"},
{"foo%5Bkey2%5D", "bar2"},
{"foo%5B%5D", "bar3"},
{"foo%5B%5D", "bar4"},
{"foo%5B%5Bkey%5D", "bar%5B%1%5D"}};
const crow::query_string query_params("params?" + buildQueryStr(params));
auto map = query_params.get_dict("foo");
REQUIRE(map["key1"] == "bar1");
REQUIRE(map["key2"] == "bar2");
REQUIRE(map[""] == "bar3");
REQUIRE(map["[key"] == "bar[");
}
Loading