Skip to content

Commit

Permalink
Fixes #1520: crash in activating HTTP/1 observer (#1521)
Browse files Browse the repository at this point in the history
Add more HTTP/1.x observer and decoder unit tests and bugfixes.
  • Loading branch information
kgiusti authored Jun 11, 2024
1 parent fc31f23 commit 1b1d4b9
Show file tree
Hide file tree
Showing 5 changed files with 564 additions and 108 deletions.
23 changes: 8 additions & 15 deletions src/decoders/http1/http1_decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -749,42 +749,35 @@ static bool parse_header(qd_http1_decoder_connection_t *hconn, decoder_t *decode
// need more data
return false;

size_t in_octets = strlen(line);
char *eol = &line[in_octets]; // eol points to null terminator

debug_print_line("header:", line);

if (in_octets == 0) {
if (*line == '\0') {
// empty header == end of headers
bool ok = headers_done(hconn, decoder);
if (!ok)
return false;
return !!(*length);
}

// TODO: support obsolete line folding. For now I punt:
// TODO: support obsolete line folding. For now I punt and ignore the continued header
if (*line == ' ' || *line == '\t')
return !!(*length);

// parse out key/value

char *saveptr = 0;
char *key = strtok_r(line, ":", &saveptr);
char *value = strtok_r(0, "", &saveptr);

if (!key) {
parser_error(hconn, "Malformed header key");
return false;
if (!key || *key == '\0' || !value) {
// Unable to parse this header, skip it
return !!(*length);
}

// According to RFC9112, the key is immediately followed by ':'. Value may start and end with whitespace which must
// be removed before value can be processed.

char *value = &key[strlen(key)]; // value points to null at end of key
if (value < eol) {
value++; // skip to start of value
value = trim_whitespace(value);
truncate_whitespace(value);
}
value = trim_whitespace(value);
truncate_whitespace(value);

if (hconn->config->rx_header) {
assert(decoder->hrs);
Expand Down
9 changes: 6 additions & 3 deletions src/observers/tcp_observer.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,17 @@ static void activate_inner(qdpo_transport_handle_t *th, qd_protocol_t inner_prot
break;
}

// pass save data to new observer
// Pass save data to new observer. The observer may deregister itself if a parse error is encountered so avoid
// passing data if that occurs.

th->observe(th, true, save.prefix, save.prefix_len);
th->observe(th, true, data, length);
if (th->observe)
th->observe(th, true, data, length);
qd_buffer_t *buf = DEQ_HEAD(save.server_data);
while (buf) {
DEQ_REMOVE_HEAD(save.server_data);
th->observe(th, false, qd_buffer_base(buf), qd_buffer_size(buf));
if (th->observe)
th->observe(th, false, qd_buffer_base(buf), qd_buffer_size(buf));
qd_buffer_free(buf);
buf = DEQ_HEAD(save.server_data);
}
Expand Down
Loading

0 comments on commit 1b1d4b9

Please sign in to comment.