Conversation
Summary of ChangesHello @heidi-dang, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the test coverage for the Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces unit test coverage for the HttpServer component, utilizing a static library to share code between the daemon and tests. However, making parse_request public for testing exposes a memory safety risk. The HttpRequest struct, with its non-owning std::string_view members, can lead to dangling pointers and Use-After-Free vulnerabilities if the input string's lifetime is not carefully managed. It is recommended to ensure HttpRequest owns its data or add explicit lifetime documentation. Additionally, some test assertions could be made more precise by checking for exact string matches rather than substring presence to improve robustness.
| private: | ||
| void handle_client(int client_fd); | ||
| // Exposed for testing | ||
| HttpRequest parse_request(const std::string& data) const; |
There was a problem hiding this comment.
The HttpRequest struct uses std::string_view for its method, path, and body members, which means it does not own the underlying string data. By making parse_request public, you are exposing an API where the returned HttpRequest object contains pointers into the data string passed as an argument.
If a caller passes a temporary string (e.g., server.parse_request(std::string(buffer))) or if the source string is destroyed while the HttpRequest is still in use, these members will become dangling pointers. This leads to a Use-After-Free (UAF) vulnerability, which can cause crashes or memory corruption.
To fix this, consider changing the HttpRequest struct members to std::string so they own their data, or clearly document the lifetime requirements if performance is critical.
| EXPECT_NE(s.find("HTTP/1.1 200 OK\r\n"), std::string::npos); | ||
| EXPECT_NE(s.find("Content-Type: text/plain\r\n"), std::string::npos); | ||
| EXPECT_NE(s.find("Content-Length: 5\r\n"), std::string::npos); | ||
| // Check end of headers and body | ||
| EXPECT_NE(s.find("\r\n\r\nhello"), std::string::npos); |
There was a problem hiding this comment.
The current assertions using s.find(...) are not strict enough, as they only check for the presence of substrings and not their order or the overall structure of the HTTP response. This could allow formatting errors to go unnoticed. It's better to assert against the exact expected response string for a more robust test.
| EXPECT_NE(s.find("HTTP/1.1 200 OK\r\n"), std::string::npos); | |
| EXPECT_NE(s.find("Content-Type: text/plain\r\n"), std::string::npos); | |
| EXPECT_NE(s.find("Content-Length: 5\r\n"), std::string::npos); | |
| // Check end of headers and body | |
| EXPECT_NE(s.find("\r\n\r\nhello"), std::string::npos); | |
| EXPECT_EQ(s, "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 5\r\n\r\nhello"); |
| EXPECT_NE(s.find("HTTP/1.1 404 Not Found\r\n"), std::string::npos); | ||
| EXPECT_NE(s.find("Content-Length: 0\r\n"), std::string::npos); |
There was a problem hiding this comment.
Similar to the other response formatting tests, using s.find(...) is not very strict. Asserting against the exact expected string ensures the response is perfectly formatted and makes the test more robust against future changes.
| EXPECT_NE(s.find("HTTP/1.1 404 Not Found\r\n"), std::string::npos); | |
| EXPECT_NE(s.find("Content-Length: 0\r\n"), std::string::npos); | |
| EXPECT_EQ(s, "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n"); |
| EXPECT_NE(s.find("HTTP/1.1 201 Created\r\n"), std::string::npos); | ||
| EXPECT_NE(s.find("Content-Type: application/json\r\n"), std::string::npos); | ||
| EXPECT_NE(s.find("Location: /items/123\r\n"), std::string::npos); | ||
| EXPECT_NE(s.find("\r\n\r\n{\"id\": 123}"), std::string::npos); |
There was a problem hiding this comment.
These checks are not very strict. They don't verify the order of headers or the exact structure of the response. Also, the automatically added Content-Length header is not being checked. A single, exact match assertion would be more robust. Since resp.headers is a std::map, header order is predictable ("Content-Type" then "Location").
| EXPECT_NE(s.find("HTTP/1.1 201 Created\r\n"), std::string::npos); | |
| EXPECT_NE(s.find("Content-Type: application/json\r\n"), std::string::npos); | |
| EXPECT_NE(s.find("Location: /items/123\r\n"), std::string::npos); | |
| EXPECT_NE(s.find("\r\n\r\n{\"id\": 123}"), std::string::npos); | |
| EXPECT_EQ(s, "HTTP/1.1 201 Created\r\nContent-Type: application/json\r\nLocation: /items/123\r\nContent-Length: 12\r\n\r\n{\"id\": 123}"); |
- Make parse_request() and format_response() public for testability - Create heidi-dashd-lib static library for shared use by daemon and tests - Add comprehensive HttpServer tests (9 new test cases) - No production behavior changes - security fixes remain intact Test coverage: - Valid GET/POST request parsing - Request body handling - Incomplete/empty request handling - Response formatting (200, 404, custom headers) - Path with query strings - Method case preservation All 29 tests passing (10 config + 2 ipc + 2 metrics + 6 job + 9 http)
81b3f22 to
08ec6ba
Compare
Revives test coverage from closed PR #26.
Changes
Test Coverage
Verification
Safety Check
Production http.cpp diff is empty - no security regressions.