client: fix invalid data access through invalid content-length values
[project/uhttpd.git] / client.c
index 04d26f11af9a0c8501b66c2dcebb48d2ab04c5e1..92f760937a12ea207b10fc872401cab05f475e6b 100644 (file)
--- a/client.c
+++ b/client.c
@@ -40,6 +40,9 @@ const char * const http_methods[] = {
        [UH_HTTP_MSG_POST] = "POST",
        [UH_HTTP_MSG_HEAD] = "HEAD",
        [UH_HTTP_MSG_OPTIONS] = "OPTIONS",
+       [UH_HTTP_MSG_PUT] = "PUT",
+       [UH_HTTP_MSG_PATCH] = "PATCH",
+       [UH_HTTP_MSG_DELETE] = "DELETE",
 };
 
 void uh_http_header(struct client *cl, int code, const char *summary)
@@ -343,7 +346,7 @@ static void client_parse_header(struct client *cl, char *data)
                }
        } else if (!strcmp(data, "content-length")) {
                r->content_length = strtoul(val, &err, 0);
-               if (err && *err) {
+               if ((err && *err) || r->content_length < 0) {
                        uh_header_error(cl, 400, "Bad Request");
                        return;
                }
@@ -441,7 +444,7 @@ void client_poll_post_data(struct client *cl)
                ustream_consume(cl->us, sep + 2 - buf);
 
                /* invalid chunk length */
-               if (sep && *sep) {
+               if ((sep && *sep) || r->content_length < 0) {
                        r->content_length = 0;
                        r->transfer_chunked = 0;
                        break;
@@ -554,11 +557,13 @@ void uh_client_notify_state(struct client *cl)
                if (!s->eof || s->w.data_bytes)
                        return;
 
+#ifdef HAVE_TLS
                if (cl->tls && cl->ssl.conn && cl->ssl.conn->w.data_bytes) {
                        cl->ssl.conn->eof = s->eof;
                        if (!ustream_write_pending(cl->ssl.conn))
                                return;
                }
+#endif
        }
 
        return client_close(cl);