summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2021-10-17 16:21:04 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2021-10-17 16:21:04 +0300
commit4ad019fd53931ae2346e894afaa469bafdb23d15 (patch)
tree56b41b2fb837da588617ca92af66198a9c4665b1
parent0c39b804357b2572b323f63d8be0d6a0517b46c9 (diff)
Fixed parsing of bare CR as end-of-line in HTTP headers
-rw-r--r--src/microhttpd/connection.c74
1 files changed, 43 insertions, 31 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 0143986e..53e3b9ec 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -2549,42 +2549,54 @@ get_next_header_line (struct MHD_Connection *connection,
return NULL;
pos = 0;
rbuf = connection->read_buffer;
- while ( (pos < connection->read_buffer_offset - 1) &&
- ('\r' != rbuf[pos]) &&
- ('\n' != rbuf[pos]) )
- pos++;
- if ( (pos == connection->read_buffer_offset - 1) &&
- ('\n' != rbuf[pos]) )
+ mhd_assert (NULL != rbuf);
+
+ do
{
- /* not found, consider growing... */
- if ( (connection->read_buffer_offset == connection->read_buffer_size) &&
- (! try_grow_read_buffer (connection, true)) )
+ const char c = rbuf[pos];
+ bool found;
+ found = false;
+ if ( ('\r' == c) && (pos < connection->read_buffer_offset - 1) &&
+ ('\n' == rbuf[pos + 1]) )
+ { /* Found CRLF */
+ found = true;
+ if (line_len)
+ *line_len = pos;
+ rbuf[pos++] = 0; /* Replace CR with zero */
+ rbuf[pos++] = 0; /* Replace LF with zero */
+ }
+ else if ('\n' == c) /* TODO: Add MHD option to disallow */
+ { /* Found bare LF */
+ found = true;
+ if (line_len)
+ *line_len = pos;
+ rbuf[pos++] = 0; /* Replace LF with zero */
+ }
+ if (found)
{
- if (NULL != connection->url)
- transmit_error_response_static (connection,
- MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE,
- REQUEST_TOO_BIG);
- else
- transmit_error_response_static (connection,
- MHD_HTTP_URI_TOO_LONG,
- REQUEST_TOO_BIG);
+ connection->read_buffer += pos;
+ connection->read_buffer_size -= pos;
+ connection->read_buffer_offset -= pos;
+ return rbuf;
}
- if (line_len)
- *line_len = 0;
- return NULL;
- }
+ } while (++pos < connection->read_buffer_offset);
+ /* not found, consider growing... */
+ if ( (connection->read_buffer_offset == connection->read_buffer_size) &&
+ (! try_grow_read_buffer (connection, true)) )
+ {
+ if (NULL != connection->url)
+ transmit_error_response_static (connection,
+ MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE,
+ REQUEST_TOO_BIG);
+ else
+ transmit_error_response_static (connection,
+ MHD_HTTP_URI_TOO_LONG,
+ REQUEST_TOO_BIG);
+ }
if (line_len)
- *line_len = pos;
- /* found, check if we have proper CRLF */
- if ( ('\r' == rbuf[pos]) &&
- ('\n' == rbuf[pos + 1]) )
- rbuf[pos++] = '\0'; /* skip CR if any */
- rbuf[pos++] = '\0'; /* skip LF */
- connection->read_buffer += pos;
- connection->read_buffer_size -= pos;
- connection->read_buffer_offset -= pos;
- return rbuf;
+ *line_len = 0;
+ return NULL;
}