Skip to content

Commit a75db17

Browse files
committed
Ensure helper->next_request won't be used if pointing to empty string
1 parent 9d4e11d commit a75db17

File tree

1 file changed

+29
-21
lines changed

1 file changed

+29
-21
lines changed

src/lib/lwan-request.c

+29-21
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
#define HEADER_TERMINATOR_LEN (sizeof("\r\n") - 1)
5151
#define MIN_REQUEST_SIZE (sizeof("GET / HTTP/1.1\r\n\r\n") - 1)
5252

53+
static const char *next_request_empty = "";
54+
5355
enum lwan_read_finalizer {
5456
FINALIZER_DONE,
5557
FINALIZER_TRY_AGAIN,
@@ -933,32 +935,38 @@ static void save_to_corpus_for_fuzzing(struct lwan_value buffer)
933935
}
934936
#endif
935937

936-
static enum lwan_http_status
937-
client_read(struct lwan_request *request,
938-
struct lwan_value *buffer,
939-
const size_t want_to_read,
940-
enum lwan_read_finalizer (*finalizer)(const struct lwan_value *buffer,
941-
size_t want_to_read,
942-
const struct lwan_request *request,
943-
int n_packets))
938+
static enum lwan_http_status client_read(
939+
struct lwan_request *request,
940+
struct lwan_value *buffer,
941+
const size_t want_to_read,
942+
enum lwan_read_finalizer (*finalizer)(const struct lwan_value *buffer,
943+
size_t want_to_read,
944+
const struct lwan_request *request,
945+
int n_packets))
944946
{
945947
struct lwan_request_parser_helper *helper = request->helper;
946948
int n_packets = 0;
947949

948950
if (helper->next_request) {
949-
const size_t next_request_len = (size_t)(helper->next_request - buffer->value);
950-
size_t new_len;
951-
952-
if (__builtin_sub_overflow(buffer->len, next_request_len, &new_len)) {
951+
if (UNLIKELY(helper->next_request == next_request_empty)) {
953952
helper->next_request = NULL;
954-
} else if (new_len) {
955-
/* FIXME: This memmove() could be eventually removed if a better
956-
* stucture (maybe a ringbuffer, reading with readv(), and each
957-
* pointer is coro_strdup() if they wrap around?) were used for
958-
* the request buffer. */
959-
buffer->len = new_len;
960-
memmove(buffer->value, helper->next_request, new_len);
961-
goto try_to_finalize;
953+
} else {
954+
const size_t next_request_len =
955+
(size_t)(helper->next_request - buffer->value);
956+
size_t new_len;
957+
958+
if (__builtin_sub_overflow(buffer->len, next_request_len,
959+
&new_len)) {
960+
helper->next_request = NULL;
961+
} else if (new_len) {
962+
/* FIXME: This memmove() could be eventually removed if a better
963+
* stucture (maybe a ringbuffer, reading with readv(), and each
964+
* pointer is coro_strdup() if they wrap around?) were used for
965+
* the request buffer. */
966+
buffer->len = new_len;
967+
memmove(buffer->value, helper->next_request, new_len);
968+
goto try_to_finalize;
969+
}
962970
}
963971
}
964972

@@ -1289,7 +1297,7 @@ get_remaining_body_data_length(struct lwan_request *request,
12891297
if (UNLIKELY((size_t)parsed_size >= max_size))
12901298
return HTTP_TOO_LARGE;
12911299
if (UNLIKELY(!parsed_size)) {
1292-
helper->next_request = "";
1300+
helper->next_request = (char *)next_request_empty;
12931301
*total = *have = 0;
12941302
} else {
12951303
*total = (size_t)parsed_size;

0 commit comments

Comments
 (0)