diff options
author | Bryce Anderson <bryce.anderson22@gmail.com> | 2015-04-30 20:56:28 -0400 |
---|---|---|
committer | Bryce Anderson <bryce.anderson22@gmail.com> | 2015-04-30 20:56:28 -0400 |
commit | 243995f36f4ee40aa88c1d29b976b944a3d1ac74 (patch) | |
tree | aea8aa1abd9466db3bf249bc8d937a97897d7314 | |
parent | c94fc46a7a7b8a2947e3625edbfd5ee2c4ce9817 (diff) | |
download | crow-243995f36f4ee40aa88c1d29b976b944a3d1ac74.tar.gz crow-243995f36f4ee40aa88c1d29b976b944a3d1ac74.zip |
Fix memory error and invalid param when no params are present
Also added a unit test that fails with the previous behavior.
Note that `-fsanitize=address` exposes the invalid memory access in
qs_parse.
-rw-r--r-- | include/query_string.h | 9 | ||||
-rw-r--r-- | tests/unittest.cpp | 15 |
2 files changed, 20 insertions, 4 deletions
diff --git a/include/query_string.h b/include/query_string.h index 86c99cc..03e5cfd 100644 --- a/include/query_string.h +++ b/include/query_string.h @@ -99,11 +99,12 @@ inline int qs_parse(char * qs, char * qs_kv[], int qs_kv_size) for(i=0; i<qs_kv_size; i++) qs_kv[i] = NULL; - // find the beginning of the k/v substrings - if ( (substr_ptr = strchr(qs, '?')) != NULL ) + // find the beginning of the k/v substrings or the fragment + substr_ptr = qs + strcspn(qs, "?#"); + if (substr_ptr[0] != '\0') substr_ptr++; else - substr_ptr = qs; + return 0; // no query or fragment i=0; while(i<qs_kv_size) @@ -121,7 +122,7 @@ inline int qs_parse(char * qs, char * qs_kv[], int qs_kv_size) for(j=0; j<i; j++) { substr_ptr = qs_kv[j] + strcspn(qs_kv[j], "=&#"); - if ( substr_ptr[0] == '&' ) // blank value: skip decoding + if ( substr_ptr[0] == '&' || substr_ptr[0] == '\0') // blank value: skip decoding substr_ptr[0] = '\0'; else qs_decode(++substr_ptr); diff --git a/tests/unittest.cpp b/tests/unittest.cpp index 460abac..e1c440b 100644 --- a/tests/unittest.cpp +++ b/tests/unittest.cpp @@ -1,6 +1,7 @@ //#define CROW_ENABLE_LOGGING #define CROW_ENABLE_DEBUG #include <iostream> +#include <sstream> #include <vector> #include "settings.h" #undef CROW_LOG_LEVEL @@ -943,6 +944,20 @@ TEST(simple_url_params) asio::io_service is; std::string sendmsg; + // check empty params + sendmsg = "GET /params\r\n\r\n"; + { + asio::ip::tcp::socket c(is); + c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 45451)); + c.send(asio::buffer(sendmsg)); + c.receive(asio::buffer(buf, 2048)); + c.close(); + + stringstream ss; + ss << last_url_params; + + ASSERT_EQUAL("[ ]", ss.str()); + } // check single presence sendmsg = "GET /params?foobar\r\n\r\n"; { |