Skip to content

Commit 263f2bd

Browse files
authored
Test shared_ptr before accessing members (etr#239)
* Add check for empty shared_ptr<http_response> Users can register arbitrary resources and could technically return empty shared_ptr without managed http_response object. This case should not crash the library. Signed-off-by: Alexander Dahl <ada@thorsis.com> References: etr#238 * Test shared_ptr before accessing members Avoid possible segfault if someone returns an empty shared_ptr<http_response> in her render method. Signed-off-by: Alexander Dahl <ada@thorsis.com> Fixes: etr#238
1 parent c5cf5ea commit 263f2bd

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

src/webserver.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ MHD_Result webserver::finalize_answer(MHD_Connection* connection, struct details
596596
try {
597597
if (hrm->is_allowed(method)) {
598598
mr->dhrs = ((hrm)->*(mr->callback))(*mr->dhr); // copy in memory (move in case)
599-
if (mr->dhrs->get_response_code() == -1) {
599+
if (mr->dhrs.get() == nullptr || mr->dhrs->get_response_code() == -1) {
600600
mr->dhrs = internal_error_page(mr);
601601
}
602602
} else {

test/integ/basic.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,13 @@ class no_response_resource : public http_resource {
193193
}
194194
};
195195

196+
class empty_response_resource : public http_resource {
197+
public:
198+
const shared_ptr<http_response> render_GET(const http_request&) {
199+
return shared_ptr<http_response>(nullptr);
200+
}
201+
};
202+
196203
class file_response_resource : public http_resource {
197204
public:
198205
const shared_ptr<http_response> render_GET(const http_request&) {
@@ -629,6 +636,22 @@ LT_BEGIN_AUTO_TEST(basic_suite, no_response)
629636
curl_easy_cleanup(curl);
630637
LT_END_AUTO_TEST(no_response)
631638

639+
LT_BEGIN_AUTO_TEST(basic_suite, empty_response)
640+
empty_response_resource resource;
641+
ws->register_resource("base", &resource);
642+
curl_global_init(CURL_GLOBAL_ALL);
643+
644+
CURL* curl = curl_easy_init();
645+
curl_easy_setopt(curl, CURLOPT_URL, "localhost:8080/base");
646+
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
647+
CURLcode res = curl_easy_perform(curl);
648+
LT_ASSERT_EQ(res, 0);
649+
int64_t http_code = 0;
650+
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
651+
LT_ASSERT_EQ(http_code, 500);
652+
curl_easy_cleanup(curl);
653+
LT_END_AUTO_TEST(empty_response)
654+
632655
LT_BEGIN_AUTO_TEST(basic_suite, regex_matching)
633656
simple_resource resource;
634657
ws->register_resource("regex/matching/number/[0-9]+", &resource);

0 commit comments

Comments
 (0)